✌️ V3 Startup

This commit is contained in:
duckietm 2025-03-10 15:27:54 +01:00
parent f52bff5bdb
commit 8edee0d5b4
3888 changed files with 15885 additions and 153959 deletions

View File

@ -1,110 +0,0 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"settings": {
"react": {
"pragma": "React",
"version": "18.0.0"
}
},
"env": {
"browser": true,
"es2021": true
},
"extends": [
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"plugin:react-hooks/recommended"
],
"plugins": [
"@typescript-eslint",
"react"
],
"rules": {
"linebreak-style": [
"off"
],
"quotes": [
"error",
"single"
],
"@typescript-eslint/indent": [
"error",
4,
{
"SwitchCase": 1
}
],
"array-bracket-spacing": [
"error",
"always"
],
"brace-style": [
"error",
"allman"
],
"template-curly-spacing": [
"error",
"always"
],
"no-multi-spaces": [
"error"
],
"@typescript-eslint/object-curly-spacing": [
"error",
"always",
{
"arraysInObjects": true,
"objectsInObjects": false
}
],
"@typescript-eslint/ban-types": [
"error",
{
"types": {
"String": true,
"Boolean": true,
"Number": true,
"Symbol": true,
"{}": false,
"Object": false,
"object": false,
"Function": false
},
"extendDefaults": true
}
],
"no-switch-case-fall-through": [
"off"
],
"jsx-quotes": [
"error"
],
"react/prop-types": [
"off"
],
"react/jsx-curly-spacing": [
"error",
{
"when": "always",
"children": true
}
],
"react/jsx-equals-spacing": [
"error"
],
"react/jsx-newline": [
"error",
{
"prevent": true
}
]
}
}

2
.gitignore vendored
View File

@ -27,3 +27,5 @@ Thumbs.db
/build /build
*.zip *.zip
.env .env
public/renderer-config*
public/ui-config*

View File

@ -1,29 +0,0 @@
image: node:16.13
stages:
- install-dependencies
- build
Install Dependencies:
stage: install-dependencies
script:
- yarn install
cache:
key: ${CI_COMMIT_BRANCH}
paths:
- node_modules
Build Nitro:
stage: build
script:
- cp public/renderer-config.json.example public/renderer-config.json
- cp public/ui-config.json.example public/ui-config.json
- yarn build:prod
cache:
key: ${CI_COMMIT_BRANCH}
paths:
- node_modules
artifacts:
expire_in: 2 weeks
paths:
- build/*

32
.vscode/settings.json vendored
View File

@ -1,32 +0,0 @@
{
"typescript.tsdk": "node_modules\\typescript\\lib",
"typescript.preferences.importModuleSpecifier": "relative",
"typescript.preferences.quoteStyle": "single",
"typescript.format.placeOpenBraceOnNewLineForControlBlocks": true,
"typescript.format.placeOpenBraceOnNewLineForFunctions": true,
"editor.wordWrap": "on",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.sortJSON": false,
"source.organizeImports": true
},
"editor.formatOnSave": false,
"git.ignoreLimitWarning": true,
"files.eol": "\n",
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
"emmet.showExpandedAbbreviation": "never",
"eslint.format.enable": true,
"eslint.validate": [
"javascript",
"typescript"
],
"eslint.workingDirectories": [
{
"pattern": "./src"
}
],
"javascript.format.enable": false,
"thunder-client.saveToWorkspace": false,
"thunder-client.workspaceRelativePath": "."
}

View File

@ -1,6 +1,4 @@
# Nitro React v2.1 # v2.2.0 - Cool UI Beta !! Use at Own Risk as it is still in Beta !!
Credits: Thanks to Genaro on discord for this release!
## Prerequisites ## Prerequisites
@ -11,12 +9,16 @@ Credits: Thanks to Genaro on discord for this release!
## Installation ## Installation
- First you should open terminal and navigate to the folder where you want to clone Nitro - First you should open terminal and navigate to the folder where you want to clone Nitro and Nitro-Renderer
- Clone Nitro - Clone Nitro (Expl. C:\Github\)
- `git clone https://github.com/duckietm/Nitro-Cool-UI.git` - `git clone https://github.com/duckietm/Nitro-Cool-UI.git` <== For now switch to Dev-RendererV2
- Install the dependencies - `git clone https://github.com/duckietm/Nitro-Cool-UI-Renderer.git`
- `yarn install` - Install the dependencies for the renderer : cd C:\Github\Nitro-Cool-UI-Renderer
- This may take some time, please be patient - `yarn install`
- Now we will create a Link for the CoolUI : `yarn link` This will give you a link address `yarn link "@nitrots/nitro-renderer"`
- Install the dependencies for Cool UI : cd C:\Github\Nitro-Cool-UI
- `yarn install`
- `yarn link "@nitrots/nitro-renderer` <== This will link the renderer in the project
- Rename a few files - Rename a few files
- Rename `public/renderer-config.json.example` to `public/renderer-config.json` - Rename `public/renderer-config.json.example` to `public/renderer-config.json`
- Rename `public/ui-config.json.example` to `public/ui-config.json` - Rename `public/ui-config.json.example` to `public/ui-config.json`
@ -25,16 +27,13 @@ Credits: Thanks to Genaro on discord for this release!
- Update `socket.url, asset.url, image.library.url, & hof.furni.url` - Update `socket.url, asset.url, image.library.url, & hof.furni.url`
- Open `public/ui-config.json` - Open `public/ui-config.json`
- Update `camera.url, thumbnails.url, url.prefix, habbopages.url` - Update `camera.url, thumbnails.url, url.prefix, habbopages.url`
- `yarn build` <== the final step to build the DIST folder this is where your browser needs to point / or upload this to your /client if you do the compile on a other machine (preferd)
- You can override any variable by passing it to `NitroConfig` in the index.html - You can override any variable by passing it to `NitroConfig` in the index.html
- Make the following changes
- ExternalTesxts.json
`"room.mute.button.text": "Hide chat",`
`"room.unmute.button.text": "Unhide chat",`
## Usage ## Usage
- To use Nitro you need `.nitro` assets generated, see [nitro-converter](https://git.krews.org/nitro/nitro-converter) for instructions - To use Nitro you need `.nitro` assets generated, see [nitro-converter](https://git.krews.org/nitro/nitro-converter) for instructions
- See [Morningstar Websockets](https://git.krews.org/nitro/ms-websockets) for instructions on configuring websockets on your server
### Development ### Development
@ -49,13 +48,8 @@ yarn start
To build a production version of Nitro just run the following command To build a production version of Nitro just run the following command
``` ```
yarn build yarn build:prod
``` ```
- A `dist` folder will be generated, these are the files that must be uploaded to your webserver - A `dist` folder will be generated, these are the files that must be uploaded to your webserver
- Consult your CMS documentation for compatibility with Nitro and how to add the production files - Consult your CMS documentation for compatibility with Nitro and how to add the production files
# Want to help !
Discord: https://discord.gg/txfNucJv
Please beware all is Free so don't get scammed !!

View File

@ -0,0 +1,73 @@
const lightenHexColor = (hex, percent) =>
{
// Remove the hash symbol if present
hex = hex.replace(/^#/, '');
// Convert hex to RGB
let r = parseInt(hex.substring(0, 2), 16);
let g = parseInt(hex.substring(2, 4), 16);
let b = parseInt(hex.substring(4, 6), 16);
// Adjust RGB values
r = Math.round(Math.min(255, r + 255 * percent));
g = Math.round(Math.min(255, g + 255 * percent));
b = Math.round(Math.min(255, b + 255 * percent));
// Convert RGB back to hex
const result = ((r << 16) | (g << 8) | b).toString(16);
// Make sure result has 6 digits
return '#' + result.padStart(6, '0');
}
const darkenHexColor = (hex, percent) =>
{
// Remove the hash symbol if present
hex = hex.replace(/^#/, '');
// Convert hex to RGB
let r = parseInt(hex.substring(0, 2), 16);
let g = parseInt(hex.substring(2, 4), 16);
let b = parseInt(hex.substring(4, 6), 16);
// Calculate the darkened RGB values
r = Math.round(Math.max(0, r - 255 * percent));
g = Math.round(Math.max(0, g - 255 * percent));
b = Math.round(Math.max(0, b - 255 * percent));
// Convert RGB back to hex
const result = ((r << 16) | (g << 8) | b).toString(16);
// Make sure result has 6 digits
return '#' + result.padStart(6, '0');
};
const generateShades = (colors) =>
{
for (let color in colors)
{
let hex = colors[color]
let extended = {}
const shades = [ 50, 100, 200, 300, 400, 500, 600, 700, 900, 950 ];
for (let i = 0; i < shades.length; i++)
{
let shade = shades[i];
extended[shade] = lightenHexColor(hex, shades[(shades.length - 1 - i) ] / 950);
extended[-shade] = darkenHexColor(hex, shades[(shades.length - 1 - i) ] / 950)
}
colors[color] = {
DEFAULT: hex,
...extended
}
}
return colors;
}
module.exports = {
generateShades,
lightenHexColor
}

138
eslint.config.mjs Normal file
View File

@ -0,0 +1,138 @@
import typescriptEslintPlugin from "@typescript-eslint/eslint-plugin";
import typescriptEslintParser from "@typescript-eslint/parser";
import reactPlugin from "eslint-plugin-react";
import reactHooksPlugin from "eslint-plugin-react-hooks";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export default [
{
files: ["**/*.jsx", "**/*.js", "**/*.tsx", "**/*.ts"],
plugins: {
react: reactPlugin,
"react-hooks": reactHooksPlugin,
"@typescript-eslint": typescriptEslintPlugin,
},
languageOptions: {
parser: typescriptEslintParser,
ecmaVersion: "latest",
parserOptions: {
sourceType: "module",
project: "./tsconfig.json",
tsconfigRootDir: __dirname,
ecmaFeatures: {
jsx: true,
},
},
},
rules: {
...reactPlugin.configs.recommended.rules,
...reactHooksPlugin.configs.recommended.rules,
...typescriptEslintPlugin.configs.recommended.rules,
...typescriptEslintPlugin.configs[
"recommended-requiring-type-checking"
].rules,
'indent': [
'error',
4,
{
'SwitchCase': 1
}
],
'no-multi-spaces': [
'error'
],
'no-trailing-spaces': [
'error',
{
'skipBlankLines': false,
'ignoreComments': true
}
],
'linebreak-style': [
'off'
],
'quotes': [
'error',
'single'
],
'semi': [
'error',
'always'
],
'brace-style': [
'error',
'allman'
],
'object-curly-spacing': [
'error',
'always'
],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/require-await': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-misused-promises': 'off',
'@typescript-eslint/explicit-module-boundary-types': [
'off',
{
'allowedNames': [
'getMessageArray'
]
}
],
'@typescript-eslint/unbound-method': [
'off'
],
'@typescript-eslint/ban-ts-comment': [
'off'
],
'@typescript-eslint/no-empty-function': [
'error',
{
'allow': [
'functions',
'arrowFunctions',
'generatorFunctions',
'methods',
'generatorMethods',
'constructors'
]
}
],
'@typescript-eslint/no-unused-vars': [
'off'
],
'@typescript-eslint/ban-types': [
'error',
{
'types':
{
'String': true,
'Boolean': true,
'Number': true,
'Symbol': true,
'{}': false,
'Object': false,
'object': false,
'Function': false
},
'extendDefaults': true
}
],
'react/react-in-jsx-scope': 'off'
},
settings: {
react: {
version: "18.3.1",
},
},
},
];

View File

@ -1,35 +1,69 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" /> <meta
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"> name="viewport"
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"> content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1"
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> />
<link rel="manifest" crossorigin="use-credentials" href="/site.webmanifest"> <link
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#000000"> rel="apple-touch-icon"
<meta name="apple-mobile-web-app-title" content="Nitro"> sizes="180x180"
<meta name="application-name" content="Nitro"> href="/apple-touch-icon.png"
<meta name="msapplication-TileColor" content="#000000"> />
<meta name="theme-color" content="#000000" /> <link
<meta name="apple-mobile-web-app-capable" content="yes"> rel="icon"
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> type="image/png"
<base href="./"> sizes="32x32"
<title>Nitro</title> href="/favicon-32x32.png"
</head> />
<body> <link
<noscript>You need to enable JavaScript to run this app.</noscript> rel="icon"
<div id="root" class="w-100 h-100"></div> type="image/png"
<script> sizes="16x16"
const NitroConfig = { href="/favicon-16x16.png"
"config.urls": [ '/renderer-config.json', '/ui-config.json' ], />
"sso.ticket": (new URLSearchParams(window.location.search).get('sso') || null), <link
"forward.type": (new URLSearchParams(window.location.search).get('room') ? 2 : -1), rel="manifest"
"forward.id": (new URLSearchParams(window.location.search).get('room') || 0), crossorigin="use-credentials"
"friend.id": (new URLSearchParams(window.location.search).get('friend') || 0), href="/site.webmanifest"
}; />
</script> <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#000000" />
<script type="module" src="./src/index.tsx"></script> <meta name="apple-mobile-web-app-title" content="Nitro" />
</body> <meta name="application-name" content="Nitro" />
<meta name="msapplication-TileColor" content="#000000" />
<meta name="theme-color" content="#000000" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>
<base href="./" />
<title>Nitro</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" class="w-full h-full"></div>
<script>
window.NitroConfig = {
"config.urls": ["/renderer-config.json", "/ui-config.json"],
"sso.ticket":
new URLSearchParams(window.location.search).get("sso") ||
null,
"forward.type": new URLSearchParams(window.location.search).get(
"room",
)
? 2
: -1,
"forward.id":
new URLSearchParams(window.location.search).get("room") ||
0,
"friend.id":
new URLSearchParams(window.location.search).get("friend") ||
0,
};
</script>
<script type="module" src="./src/index.tsx"></script>
</body>
</html> </html>

View File

@ -1,47 +1,49 @@
{ {
"name": "nitro-react", "name": "nitro-react",
"version": "2.1.1", "version": "2.2",
"homepage": ".", "homepage": ".",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "vite --base=/client/ --host", "start": "vite --host",
"build": "vite build --base=/client/", "build": "vite build",
"preview": "vite preview --base=/client/ --host", "build:prod": "npx browserslist@latest --update-db && yarn build",
"build:prod": "npx browserslist@latest --update-db && yarn build", "eslint": "eslint ./src"
"eslint": "eslint src --ext .ts,.tsx" },
}, "dependencies": {
"dependencies": { "@babel/runtime": "^7.26.9",
"@emoji-mart/data": "^1.1.2", "@tanstack/react-virtual": "3.2.0",
"@emoji-mart/react": "^1.1.1", "@types/react-transition-group": "^4.4.10",
"@nitrots/nitro-renderer": "file:submodules/renderer", "dompurify": "^3.1.5",
"@tanstack/react-virtual": "^3.0.0-beta.60", "framer-motion": "^11.2.12",
"dompurify": "^3.0.11", "react": "^18.3.1",
"emoji-mart": "^5.5.2", "react-bootstrap": "^2.10.9",
"emoji-toolkit": "8.0.0", "react-dom": "^18.3.1",
"react": "^18.2.0", "react-icons": "^5.2.1",
"react-bootstrap": "^2.7.2", "react-slider": "^2.0.6",
"react-dom": "^18.2.0", "react-tiny-popover": "^8.0.4",
"react-icons": "^5.0.1", "react-youtube": "^7.13.1",
"react-slider": "^2.0.0", "use-between": "^1.3.5"
"react-youtube": "^7.13.1", },
"typescript": "^4.3.5", "devDependencies": {
"use-between": "^1.3.4", "@tailwindcss/forms": "^0.5.7",
"yarn": "^1.22.19" "@types/node": "^20.11.30",
}, "@types/react": "^18.3.3",
"devDependencies": { "@types/react-dom": "^18.3.0",
"@types/node": "^18.15.3", "@types/react-slider": "^1.3.6",
"@types/react": "^18.0.28", "@typescript-eslint/eslint-plugin": "^7.13.1",
"@types/react-dom": "^18.0.11", "@typescript-eslint/parser": "^7.13.1",
"@types/react-slider": "^1.3.1", "@vitejs/plugin-react": "^4.3.1",
"@typescript-eslint/eslint-plugin": "^5.55.0", "autoprefixer": "^10.4.19",
"@typescript-eslint/parser": "^5.55.0", "eslint": "^9.5.0",
"@vitejs/plugin-react": "^4.2.1", "eslint-plugin-react": "^7.34.2",
"eslint": "^8.36.0", "eslint-plugin-react-hooks": "^5.1.0-rc-1434af3d22-20240618",
"eslint-plugin-import": "^2.27.5", "postcss": "^8.4.38",
"eslint-plugin-jsx-a11y": "^6.7.1", "postcss-nested": "^6.0.1",
"eslint-plugin-react": "^7.32.2", "sass": "^1.77.4",
"eslint-plugin-react-hooks": "^4.6.0", "tailwindcss": "^3.4.4",
"sass": "1.64.2", "typescript": "^5.4.5",
"vite": "^5.0.11" "typescript-eslint": "^7.13.1",
} "vite": "^5.2.13",
"vite-tsconfig-paths": "^4.3.2"
}
} }

8
postcss.config.js Normal file
View File

@ -0,0 +1,8 @@
/** @type {import("postcss-load-config").Config} */
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
}

View File

@ -1,110 +0,0 @@
{
"socket.url": "wss://ws.website.com:2096",
"asset.url": "https://website.com",
"image.library.url": "https://website.com/c_images/",
"hof.furni.url": "https://website.com/dcr/hof_furni",
"images.url": "${asset.url}/images",
"gamedata.url": "${asset.url}/gamedata",
"sounds.url": "${asset.url}/sounds/%sample%.mp3",
"external.texts.url": [ "${gamedata.url}/ExternalTexts.json", "${gamedata.url}/UITexts.json" ],
"external.samples.url": "${hof.furni.url}/mp3/sound_machine_sample_%sample%.mp3",
"furnidata.url": "${gamedata.url}/FurnitureData.json",
"productdata.url": "${gamedata.url}/ProductData.json",
"avatar.actions.url": "${gamedata.url}/HabboAvatarActions.json",
"avatar.figuredata.url": "${gamedata.url}/FigureData.json",
"avatar.figuremap.url": "${gamedata.url}/FigureMap.json",
"avatar.effectmap.url": "${gamedata.url}/EffectMap.json",
"avatar.asset.url": "${asset.url}/bundled/figure/%libname%.nitro",
"avatar.asset.effect.url": "${asset.url}/bundled/effect/%libname%.nitro",
"furni.asset.url": "${asset.url}/bundled/furniture/%libname%.nitro",
"furni.asset.icon.url": "${hof.furni.url}/icons/%libname%%param%_icon.png",
"pet.asset.url": "${asset.url}/bundled/pet/%libname%.nitro",
"generic.asset.url": "${asset.url}/bundled/generic/%libname%.nitro",
"badge.asset.url": "${image.library.url}album1584/%badgename%.gif",
"furni.rotation.bounce.steps": 20,
"furni.rotation.bounce.height": 0.0625,
"enable.avatar.arrow": false,
"system.log.debug": false,
"system.log.warn": false,
"system.log.error": false,
"system.log.events": false,
"system.log.packets": false,
"system.fps.animation": 24,
"system.fps.max": 60,
"system.pong.manually": true,
"system.pong.interval.ms": 20000,
"room.color.skip.transition": true,
"room.landscapes.enabled": true,
"avatar.mandatory.libraries": [
"bd:1",
"li:0"
],
"avatar.mandatory.effect.libraries": [
"dance.1",
"dance.2",
"dance.3",
"dance.4"
],
"avatar.default.figuredata": {"palettes":[{"id":1,"colors":[{"id":99999,"index":1001,"club":0,"selectable":false,"hexCode":"DDDDDD"},{"id":99998,"index":1001,"club":0,"selectable":false,"hexCode":"FAFAFA"}]},{"id":3,"colors":[{"id":10001,"index":1001,"club":0,"selectable":false,"hexCode":"EEEEEE"},{"id":10002,"index":1002,"club":0,"selectable":false,"hexCode":"FA3831"},{"id":10003,"index":1003,"club":0,"selectable":false,"hexCode":"FD92A0"},{"id":10004,"index":1004,"club":0,"selectable":false,"hexCode":"2AC7D2"},{"id":10005,"index":1005,"club":0,"selectable":false,"hexCode":"35332C"},{"id":10006,"index":1006,"club":0,"selectable":false,"hexCode":"EFFF92"},{"id":10007,"index":1007,"club":0,"selectable":false,"hexCode":"C6FF98"},{"id":10008,"index":1008,"club":0,"selectable":false,"hexCode":"FF925A"},{"id":10009,"index":1009,"club":0,"selectable":false,"hexCode":"9D597E"},{"id":10010,"index":1010,"club":0,"selectable":false,"hexCode":"B6F3FF"},{"id":10011,"index":1011,"club":0,"selectable":false,"hexCode":"6DFF33"},{"id":10012,"index":1012,"club":0,"selectable":false,"hexCode":"3378C9"},{"id":10013,"index":1013,"club":0,"selectable":false,"hexCode":"FFB631"},{"id":10014,"index":1014,"club":0,"selectable":false,"hexCode":"DFA1E9"},{"id":10015,"index":1015,"club":0,"selectable":false,"hexCode":"F9FB32"},{"id":10016,"index":1016,"club":0,"selectable":false,"hexCode":"CAAF8F"},{"id":10017,"index":1017,"club":0,"selectable":false,"hexCode":"C5C6C5"},{"id":10018,"index":1018,"club":0,"selectable":false,"hexCode":"47623D"},{"id":10019,"index":1019,"club":0,"selectable":false,"hexCode":"8A8361"},{"id":10020,"index":1020,"club":0,"selectable":false,"hexCode":"FF8C33"},{"id":10021,"index":1021,"club":0,"selectable":false,"hexCode":"54C627"},{"id":10022,"index":1022,"club":0,"selectable":false,"hexCode":"1E6C99"},{"id":10023,"index":1023,"club":0,"selectable":false,"hexCode":"984F88"},{"id":10024,"index":1024,"club":0,"selectable":false,"hexCode":"77C8FF"},{"id":10025,"index":1025,"club":0,"selectable":false,"hexCode":"FFC08E"},{"id":10026,"index":1026,"club":0,"selectable":false,"hexCode":"3C4B87"},{"id":10027,"index":1027,"club":0,"selectable":false,"hexCode":"7C2C47"},{"id":10028,"index":1028,"club":0,"selectable":false,"hexCode":"D7FFE3"},{"id":10029,"index":1029,"club":0,"selectable":false,"hexCode":"8F3F1C"},{"id":10030,"index":1030,"club":0,"selectable":false,"hexCode":"FF6393"},{"id":10031,"index":1031,"club":0,"selectable":false,"hexCode":"1F9B79"},{"id":10032,"index":1032,"club":0,"selectable":false,"hexCode":"FDFF33"}]}],"setTypes":[{"type":"hd","paletteId":1,"mandatory_f_0":true,"mandatory_f_1":true,"mandatory_m_0":true,"mandatory_m_1":true,"sets":[{"id":99999,"gender":"U","club":0,"colorable":true,"selectable":false,"preselectable":false,"sellable":false,"parts":[{"id":1,"type":"bd","colorable":true,"index":0,"colorindex":1},{"id":1,"type":"hd","colorable":true,"index":0,"colorindex":1},{"id":1,"type":"lh","colorable":true,"index":0,"colorindex":1},{"id":1,"type":"rh","colorable":true,"index":0,"colorindex":1}]}]},{"type":"bds","paletteId":1,"mandatory_f_0":false,"mandatory_f_1":false,"mandatory_m_0":false,"mandatory_m_1":false,"sets":[{"id":10001,"gender":"U","club":0,"colorable":true,"selectable":false,"preselectable":false,"sellable":false,"parts":[{"id":10001,"type":"bds","colorable":true,"index":0,"colorindex":1},{"id":10001,"type":"lhs","colorable":true,"index":0,"colorindex":1},{"id":10001,"type":"rhs","colorable":true,"index":0,"colorindex":1}],"hiddenLayers":[{"partType":"bd"},{"partType":"rh"},{"partType":"lh"}]}]},{"type":"ss","paletteId":3,"mandatory_f_0":false,"mandatory_f_1":false,"mandatory_m_0":false,"mandatory_m_1":false,"sets":[{"id":10010,"gender":"F","club":0,"colorable":true,"selectable":false,"preselectable":false,"sellable":false,"parts":[{"id":10001,"type":"ss","colorable":true,"index":0,"colorindex":1}],"hiddenLayers":[{"partType":"ch"},{"partType":"lg"},{"partType":"ca"},{"partType":"wa"},{"partType":"sh"},{"partType":"ls"},{"partType":"rs"},{"partType":"lc"},{"partType":"rc"},{"partType":"cc"},{"partType":"cp"}]},{"id":10011,"gender":"M","club":0,"colorable":true,"selectable":false,"preselectable":false,"sellable":false,"parts":[{"id":10002,"type":"ss","colorable":true,"index":0,"colorindex":1}],"hiddenLayers":[{"partType":"ch"},{"partType":"lg"},{"partType":"ca"},{"partType":"wa"},{"partType":"sh"},{"partType":"ls"},{"partType":"rs"},{"partType":"lc"},{"partType":"rc"},{"partType":"cc"},{"partType":"cp"}]}]}]},
"avatar.default.actions": {
"actions": [
{
"id": "Default",
"state": "std",
"precedence": 1000,
"main": true,
"isDefault": true,
"geometryType": "vertical",
"activePartSet": "figure",
"assetPartDefinition": "std"
}
]
},
"pet.types": [
"dog",
"cat",
"croco",
"terrier",
"bear",
"pig",
"lion",
"rhino",
"spider",
"turtle",
"chicken",
"frog",
"dragon",
"monster",
"monkey",
"horse",
"monsterplant",
"bunnyeaster",
"bunnyevil",
"bunnydepressed",
"bunnylove",
"pigeongood",
"pigeonevil",
"demonmonkey",
"bearbaby",
"terrierbaby",
"gnome",
"leprechaun",
"kittenbaby",
"puppybaby",
"pigletbaby",
"haloompa",
"fools",
"pterosaur",
"velociraptor",
"cow",
"dragondog"
],
"preload.assets.urls": [
"${asset.url}/bundled/generic/avatar_additions.nitro",
"${asset.url}/bundled/generic/group_badge.nitro",
"${asset.url}/bundled/generic/floor_editor.nitro",
"${images.url}/loading_icon.png",
"${images.url}/clear_icon.png",
"${images.url}/big_arrow.png"
]
}

File diff suppressed because it is too large Load Diff

View File

@ -21,26 +21,21 @@ $toolbar-height: 55px;
$achievement-width: 375px; $achievement-width: 375px;
$achievement-height: 405px; $achievement-height: 405px;
$avatar-editor-width: 520px; $avatar-editor-width: 620px;
$avatar-editor-height: 553px; $avatar-editor-height: 374px;
$catalog-width: 650px; $catalog-width: 630px;
$catalog-height: 480px; $catalog-height: 400px;
$inventory-width: 528px; $inventory-width: 528px;
$inventory-height: 370px; $inventory-height: 320px;
$navigator-width: 425px; $navigator-width: 420px;
$navigator-height: 560px; $navigator-height: 440px;
$navigator-min-height: 205px;
$nitro-room-creator-width: 585px;
$nitro-room-creator-height: 365px;
$chat-input-style-selector-widget-width: 210px; $chat-input-style-selector-widget-width: 210px;
$chat-input-style-selector-widget-height: 200px; $chat-input-style-selector-widget-height: 200px;
$user-profile-width: 470px; $user-profile-width: 470px;
$user-profile-height: 460px; $user-profile-height: 460px;
@ -65,17 +60,14 @@ $help-height: 290px;
$nitropedia-width: 400px; $nitropedia-width: 400px;
$nitropedia-height: 400px; $nitropedia-height: 400px;
$nitrobubblehidden-width: 400px; $messenger-width: 500px;
$nitrobubblehidden-height: 400px; $messenger-height: 370px;
$messenger-width: 580px;
$messenger-height: 455px;
$marketplace-post-offer-width: 430px; $marketplace-post-offer-width: 430px;
$marketplace-post-offer-height: 250px; $marketplace-post-offer-height: 250px;
$camera-editor-width: 600px; $camera-editor-width: 600px;
$camera-editor-height: 540px; $camera-editor-height: 500px;
$camera-checkout-width: 350px; $camera-checkout-width: 350px;

View File

@ -1,141 +1,104 @@
import { ConfigurationEvent, GetAssetManager, HabboWebTools, LegacyExternalInterface, Nitro, NitroCommunicationDemoEvent, NitroConfiguration, NitroEvent, NitroLocalizationEvent, NitroVersion, RoomEngineEvent } from '@nitrots/nitro-renderer'; import { GetAssetManager, GetAvatarRenderManager, GetCommunication, GetConfiguration, GetLocalizationManager, GetRoomEngine, GetRoomSessionManager, GetSessionDataManager, GetSoundManager, GetStage, GetTexturePool, GetTicker, HabboWebTools, LegacyExternalInterface, LoadGameUrlEvent, NitroLogger, NitroVersion, PrepareRenderer } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { GetCommunication, GetConfiguration, GetNitroInstance, GetUIVersion } from './api'; import { GetUIVersion } from './api';
import { Base, TransitionAnimation, TransitionAnimationTypes } from './common'; import { MainView } from './components/MainView';
import { LoadingView } from './components/loading/LoadingView'; import { LoadingView } from './components/loading/LoadingView';
import { MainView } from './components/main/MainView'; import { useMessageEvent } from './hooks';
import { useConfigurationEvent, useLocalizationEvent, useMainEvent, useRoomEngineEvent } from './hooks'; import { classNames } from './layout';
NitroVersion.UI_VERSION = GetUIVersion(); NitroVersion.UI_VERSION = GetUIVersion();
export const App: FC<{}> = props => export const App: FC<{}> = (props) =>
{ {
const [ isReady, setIsReady ] = useState(false); const [isReady, setIsReady] = useState(false);
const [ isError, setIsError ] = useState(false);
const [ message, setMessage ] = useState('Getting Ready');
const [ percent, setPercent ] = useState(0);
const [ imageRendering, setImageRendering ] = useState<boolean>(true);
if(!GetNitroInstance()) useMessageEvent<LoadGameUrlEvent>(LoadGameUrlEvent, (event) =>
{ {
//@ts-ignore const parser = event.getParser();
if(!NitroConfig) throw new Error('NitroConfig is not defined!');
Nitro.bootstrap(); if(!parser) return;
}
const handler = useCallback(async (event: NitroEvent) => LegacyExternalInterface.callGame('showGame', parser.url);
{ });
switch(event.type)
{
case ConfigurationEvent.LOADED:
GetNitroInstance().localization.init();
setPercent(prevValue => (prevValue + 20));
return;
case ConfigurationEvent.FAILED:
setIsError(true);
setMessage('Configuration Failed');
return;
case Nitro.WEBGL_UNAVAILABLE:
setIsError(true);
setMessage('WebGL Required');
return;
case Nitro.WEBGL_CONTEXT_LOST:
setIsError(true);
setMessage('WebGL Context Lost - Reloading');
setTimeout(() => window.location.reload(), 1500);
return;
case NitroCommunicationDemoEvent.CONNECTION_HANDSHAKING:
setPercent(prevValue => (prevValue + 20));
return;
case NitroCommunicationDemoEvent.CONNECTION_HANDSHAKE_FAILED:
setIsError(true);
setMessage('Handshake Failed');
return;
case NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED:
setPercent(prevValue => (prevValue + 20));
GetNitroInstance().init();
if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'authentication', 'authok', []);
return;
case NitroCommunicationDemoEvent.CONNECTION_ERROR:
setIsError(true);
setMessage('Connection Error');
return;
case NitroCommunicationDemoEvent.CONNECTION_CLOSED:
//if(GetNitroInstance().roomEngine) GetNitroInstance().roomEngine.dispose();
//setIsError(true);
setMessage('Connection Error');
HabboWebTools.send(-1, 'client.init.handshake.fail');
return;
case RoomEngineEvent.ENGINE_INITIALIZED:
setPercent(prevValue => (prevValue + 20));
setTimeout(() => setIsReady(true), 300);
return;
case NitroLocalizationEvent.LOADED: {
const assetUrls = GetConfiguration<string[]>('preload.assets.urls');
const urls: string[] = [];
if(assetUrls && assetUrls.length) for(const url of assetUrls) urls.push(NitroConfiguration.interpolate(url));
const status = await GetAssetManager().downloadAssets(urls);
if(status)
{
GetCommunication().init();
setPercent(prevValue => (prevValue + 20))
}
else
{
setIsError(true);
setMessage('Assets Failed');
}
return;
}
}
}, []);
useMainEvent(Nitro.WEBGL_UNAVAILABLE, handler);
useMainEvent(Nitro.WEBGL_CONTEXT_LOST, handler);
useMainEvent(NitroCommunicationDemoEvent.CONNECTION_HANDSHAKING, handler);
useMainEvent(NitroCommunicationDemoEvent.CONNECTION_HANDSHAKE_FAILED, handler);
useMainEvent(NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED, handler);
useMainEvent(NitroCommunicationDemoEvent.CONNECTION_ERROR, handler);
useMainEvent(NitroCommunicationDemoEvent.CONNECTION_CLOSED, handler);
useRoomEngineEvent(RoomEngineEvent.ENGINE_INITIALIZED, handler);
useLocalizationEvent(NitroLocalizationEvent.LOADED, handler);
useConfigurationEvent(ConfigurationEvent.LOADED, handler);
useConfigurationEvent(ConfigurationEvent.FAILED, handler);
useEffect(() => useEffect(() =>
{ {
GetNitroInstance().core.configuration.init(); const prepare = async (width: number, height: number) =>
const resize = (event: UIEvent) => setImageRendering(!(window.devicePixelRatio % 1));
window.addEventListener('resize', resize);
resize(null);
return () =>
{ {
window.removeEventListener('resize', resize); try
} {
if(!window.NitroConfig)
throw new Error('NitroConfig is not defined!');
const renderer = await PrepareRenderer({
width: Math.floor(width),
height: Math.floor(height),
resolution: window.devicePixelRatio,
autoDensity: true,
backgroundAlpha: 0,
preference: 'webgl',
eventMode: 'none',
failIfMajorPerformanceCaveat: false,
roundPixels: true
});
await GetConfiguration().init();
GetTicker().maxFPS = GetConfiguration().getValue<number>('system.fps.max', 24);
NitroLogger.LOG_DEBUG = GetConfiguration().getValue<boolean>('system.log.debug', true);
NitroLogger.LOG_WARN = GetConfiguration().getValue<boolean>('system.log.warn', false);
NitroLogger.LOG_ERROR = GetConfiguration().getValue<boolean>('system.log.error', false);
NitroLogger.LOG_EVENTS = GetConfiguration().getValue<boolean>('system.log.events', false);
NitroLogger.LOG_PACKETS = GetConfiguration().getValue<boolean>('system.log.packets', false);
const assetUrls = GetConfiguration().getValue<string[]>('preload.assets.urls').map(url => GetConfiguration().interpolate(url)) ?? [];
await Promise.all(
[
GetAssetManager().downloadAssets(assetUrls),
GetLocalizationManager().init(),
GetAvatarRenderManager().init(),
GetSoundManager().init(),
GetSessionDataManager().init(),
GetRoomSessionManager().init()
]
);
await GetRoomEngine().init();
await GetCommunication().init();
// new GameMessageHandler();
if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'authentication', 'authok', []);
HabboWebTools.sendHeartBeat();
setInterval(() => HabboWebTools.sendHeartBeat(), 10000);
GetTicker().add((ticker) => GetRoomEngine().update(ticker));
GetTicker().add((ticker) => renderer.render(GetStage()));
GetTicker().add((ticker) => GetTexturePool().run());
setIsReady(true);
// handle socket close
//canvas.addEventListener('webglcontextlost', () => instance.events.dispatchEvent(new NitroEvent(Nitro.WEBGL_CONTEXT_LOST)));
}
catch (err)
{
NitroLogger.error(err);
}
};
prepare(window.innerWidth, window.innerHeight);
}, []); }, []);
return ( return (
<Base fit overflow="hidden" className={ imageRendering && 'image-rendering-pixelated' }> <div
{ (!isReady || isError) && className={classNames( 'w-full h-full overflow-hidden text-base bg-black', !(window.devicePixelRatio % 1) && '[image-rendering:pixelated]')}>
<LoadingView isError={ isError } message={ message } percent={ percent } /> } {!isReady && <LoadingView />}
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ (isReady) }> {isReady && <MainView />}
<MainView /> <div id="draggable-windows-container" />
</TransitionAnimation> </div>
<Base id="draggable-windows-container" />
</Base>
); );
} };

View File

@ -1 +1 @@
export const GetUIVersion = () => '2.1.1'; export const GetUIVersion = () => '2.2.0';

View File

@ -1,5 +1,5 @@
import { AchievementData } from '@nitrots/nitro-renderer'; import { AchievementData, GetLocalizationManager } from '@nitrots/nitro-renderer';
import { GetConfiguration, GetLocalization } from '../nitro'; import { GetConfigurationValue } from '../nitro';
import { IAchievementCategory } from './IAchievementCategory'; import { IAchievementCategory } from './IAchievementCategory';
export class AchievementUtilities export class AchievementUtilities
@ -7,91 +7,91 @@ export class AchievementUtilities
public static getAchievementBadgeCode(achievement: AchievementData): string public static getAchievementBadgeCode(achievement: AchievementData): string
{ {
if(!achievement) return null; if(!achievement) return null;
let badgeId = achievement.badgeId; let badgeId = achievement.badgeId;
if(!achievement.finalLevel) badgeId = GetLocalization().getPreviousLevelBadgeId(badgeId); if(!achievement.finalLevel) badgeId = GetLocalizationManager().getPreviousLevelBadgeId(badgeId);
return badgeId; return badgeId;
} }
public static getAchievementCategoryImageUrl(category: IAchievementCategory, progress: number = null, icon: boolean = false): string public static getAchievementCategoryImageUrl(category: IAchievementCategory, progress: number = null, icon: boolean = false): string
{ {
const imageUrl = GetConfiguration<string>('achievements.images.url'); const imageUrl = GetConfigurationValue<string>('achievements.images.url');
let imageName = icon ? 'achicon_' : 'achcategory_'; let imageName = icon ? 'achicon_' : 'achcategory_';
imageName += category.code; imageName += category.code;
if(progress !== null) imageName += `_${ ((progress > 0) ? 'active' : 'inactive') }`; if(progress !== null) imageName += `_${ ((progress > 0) ? 'active' : 'inactive') }`;
return imageUrl.replace('%image%', imageName); return imageUrl.replace('%image%', imageName);
} }
public static getAchievementCategoryMaxProgress(category: IAchievementCategory): number public static getAchievementCategoryMaxProgress(category: IAchievementCategory): number
{ {
if(!category) return 0; if(!category) return 0;
let progress = 0; let progress = 0;
for(const achievement of category.achievements) for(const achievement of category.achievements)
{ {
progress += achievement.levelCount; progress += achievement.levelCount;
} }
return progress; return progress;
} }
public static getAchievementCategoryProgress(category: IAchievementCategory): number public static getAchievementCategoryProgress(category: IAchievementCategory): number
{ {
if(!category) return 0; if(!category) return 0;
let progress = 0; let progress = 0;
for(const achievement of category.achievements) progress += (achievement.finalLevel ? achievement.level : (achievement.level - 1)); for(const achievement of category.achievements) progress += (achievement.finalLevel ? achievement.level : (achievement.level - 1));
return progress; return progress;
} }
public static getAchievementCategoryTotalUnseen(category: IAchievementCategory): number public static getAchievementCategoryTotalUnseen(category: IAchievementCategory): number
{ {
if(!category) return 0; if(!category) return 0;
let unseen = 0; let unseen = 0;
for(const achievement of category.achievements) ((achievement.unseen > 0) && unseen++); for(const achievement of category.achievements) ((achievement.unseen > 0) && unseen++);
return unseen; return unseen;
} }
public static getAchievementHasStarted(achievement: AchievementData): boolean public static getAchievementHasStarted(achievement: AchievementData): boolean
{ {
if(!achievement) return false; if(!achievement) return false;
if(achievement.finalLevel || ((achievement.level - 1) > 0)) return true; if(achievement.finalLevel || ((achievement.level - 1) > 0)) return true;
return false; return false;
} }
public static getAchievementIsIgnored(achievement: AchievementData): boolean public static getAchievementIsIgnored(achievement: AchievementData): boolean
{ {
if(!achievement) return false; if(!achievement) return false;
const ignored = GetConfiguration<string[]>('achievements.unseen.ignored'); const ignored = GetConfigurationValue<string[]>('achievements.unseen.ignored');
const value = achievement.badgeId.replace(/[0-9]/g, ''); const value = achievement.badgeId.replace(/[0-9]/g, '');
const index = ignored.indexOf(value); const index = ignored.indexOf(value);
if(index >= 0) return true; if(index >= 0) return true;
return false; return false;
} }
public static getAchievementLevel(achievement: AchievementData): number public static getAchievementLevel(achievement: AchievementData): number
{ {
if(!achievement) return 0; if(!achievement) return 0;
if(achievement.finalLevel) return achievement.level; if(achievement.finalLevel) return achievement.level;
return (achievement.level - 1); return (achievement.level - 1);
} }
} }

View File

@ -0,0 +1,17 @@
import { IPartColor } from '@nitrots/nitro-renderer';
export const AvatarEditorColorSorter = (a: IPartColor, b: IPartColor) =>
{
const clubLevelA = (!a ? -1 : a.clubLevel);
const clubLevelB = (!b ? -1 : b.clubLevel);
if(clubLevelA < clubLevelB) return -1;
if(clubLevelA > clubLevelB) return 1;
if(a.index < b.index) return -1;
if(a.index > b.index) return 1;
return 0;
};

View File

@ -1,65 +0,0 @@
import { ColorConverter, IPartColor } from '@nitrots/nitro-renderer';
export class AvatarEditorGridColorItem
{
private _partColor: IPartColor;
private _isDisabled: boolean;
private _isHC: boolean;
private _isSelected: boolean;
private _notifier: () => void;
constructor(partColor: IPartColor, isDisabled: boolean = false)
{
this._partColor = partColor;
this._isDisabled = isDisabled;
this._isHC = (this._partColor.clubLevel > 0);
this._isSelected = false;
}
public dispose(): void
{
this._partColor = null;
}
public get partColor(): IPartColor
{
return this._partColor;
}
public get color(): string
{
return ColorConverter.int2rgb(this._partColor.rgb);
}
public get isDisabled(): boolean
{
return this._isDisabled;
}
public get isHC(): boolean
{
return this._isHC;
}
public get isSelected(): boolean
{
return this._isSelected;
}
public set isSelected(flag: boolean)
{
this._isSelected = flag;
if(this.notify) this.notify();
}
public get notify(): () => void
{
return this._notifier;
}
public set notify(notifier: () => void)
{
this._notifier = notifier;
}
}

View File

@ -1,337 +0,0 @@
import { AvatarFigurePartType, IAvatarImageListener, IAvatarRenderManager, IFigurePart, IFigurePartSet, IGraphicAsset, IPartColor, NitroAlphaFilter, NitroContainer, NitroSprite, TextureUtils } from '@nitrots/nitro-renderer';
import { GetAvatarRenderManager } from '../nitro';
import { FigureData } from './FigureData';
export class AvatarEditorGridPartItem implements IAvatarImageListener
{
private static ALPHA_FILTER: NitroAlphaFilter = new NitroAlphaFilter(0.2);
private static THUMB_DIRECTIONS: number[] = [ 2, 6, 0, 4, 3, 1 ];
private static DRAW_ORDER: string[] = [
AvatarFigurePartType.LEFT_HAND_ITEM,
AvatarFigurePartType.LEFT_HAND,
AvatarFigurePartType.LEFT_SLEEVE,
AvatarFigurePartType.LEFT_COAT_SLEEVE,
AvatarFigurePartType.BODY,
AvatarFigurePartType.SHOES,
AvatarFigurePartType.LEGS,
AvatarFigurePartType.CHEST,
AvatarFigurePartType.CHEST_ACCESSORY,
AvatarFigurePartType.COAT_CHEST,
AvatarFigurePartType.CHEST_PRINT,
AvatarFigurePartType.WAIST_ACCESSORY,
AvatarFigurePartType.RIGHT_HAND,
AvatarFigurePartType.RIGHT_SLEEVE,
AvatarFigurePartType.RIGHT_COAT_SLEEVE,
AvatarFigurePartType.HEAD,
AvatarFigurePartType.FACE,
AvatarFigurePartType.EYES,
AvatarFigurePartType.HAIR,
AvatarFigurePartType.HAIR_BIG,
AvatarFigurePartType.FACE_ACCESSORY,
AvatarFigurePartType.EYE_ACCESSORY,
AvatarFigurePartType.HEAD_ACCESSORY,
AvatarFigurePartType.HEAD_ACCESSORY_EXTRA,
AvatarFigurePartType.RIGHT_HAND_ITEM,
];
private _renderManager: IAvatarRenderManager;
private _partSet: IFigurePartSet;
private _partColors: IPartColor[];
private _useColors: boolean;
private _isDisabled: boolean;
private _thumbContainer: NitroContainer;
private _imageUrl: string;
private _maxColorIndex: number;
private _isValidFigure: boolean;
private _isHC: boolean;
private _isSellable: boolean;
private _isClear: boolean;
private _isSelected: boolean;
private _disposed: boolean;
private _isInitalized: boolean;
private _notifier: () => void;
constructor(partSet: IFigurePartSet, partColors: IPartColor[], useColors: boolean = true, isDisabled: boolean = false)
{
this._renderManager = GetAvatarRenderManager();
this._partSet = partSet;
this._partColors = partColors;
this._useColors = useColors;
this._isDisabled = isDisabled;
this._thumbContainer = null;
this._imageUrl = null;
this._maxColorIndex = 0;
this._isValidFigure = false;
this._isHC = false;
this._isSellable = false;
this._isClear = false;
this._isSelected = false;
this._disposed = false;
this._isInitalized = false;
if(partSet)
{
const colors = partSet.parts;
for(const color of colors) this._maxColorIndex = Math.max(this._maxColorIndex, color.colorLayerIndex);
}
}
public init(): void
{
if(this._isInitalized) return;
this._isInitalized = true;
this.update();
}
public dispose(): void
{
if(this._disposed) return;
this._renderManager = null;
this._partSet = null;
this._partColors = null;
this._imageUrl = null;
this._disposed = true;
this._isInitalized = false;
if(this._thumbContainer)
{
this._thumbContainer.destroy();
this._thumbContainer = null;
}
}
public update(): void
{
this.updateThumbVisualization();
}
private analyzeFigure(): boolean
{
if(!this._renderManager || !this._partSet || !this._partSet.parts || !this._partSet.parts.length) return false;
const figureContainer = this._renderManager.createFigureContainer(((this.partSet.type + '-') + this.partSet.id));
if(!this._renderManager.isFigureContainerReady(figureContainer))
{
this._renderManager.downloadAvatarFigure(figureContainer, this);
return false;
}
this._isValidFigure = true;
return true;
}
private renderThumb(): NitroContainer
{
if(!this._renderManager || !this._partSet) return null;
if(!this._isValidFigure)
{
if(!this.analyzeFigure()) return null;
}
const parts = this._partSet.parts.concat().sort(this.sortByDrawOrder);
const container = new NitroContainer();
for(const part of parts)
{
if(!part) continue;
let asset: IGraphicAsset = null;
let direction = 0;
let hasAsset = false;
while(!hasAsset && (direction < AvatarEditorGridPartItem.THUMB_DIRECTIONS.length))
{
const assetName = ((((((((((FigureData.SCALE + '_') + FigureData.STD) + '_') + part.type) + '_') + part.id) + '_') + AvatarEditorGridPartItem.THUMB_DIRECTIONS[direction]) + '_') + FigureData.DEFAULT_FRAME);
asset = this._renderManager.getAssetByName(assetName);
if(asset && asset.texture)
{
hasAsset = true;
}
else
{
direction++;
}
}
if(!hasAsset) continue;
const x = asset.offsetX;
const y = asset.offsetY;
let partColor: IPartColor = null;
if(this._useColors && (part.colorLayerIndex > 0))
{
const color = this._partColors[(part.colorLayerIndex - 1)];
if(color) partColor = color;
}
const sprite = new NitroSprite(asset.texture);
sprite.position.set(x, y);
if(partColor) sprite.tint = partColor.rgb;
container.addChild(sprite);
}
return container;
}
private updateThumbVisualization(): void
{
if(!this._isInitalized) return;
let container = this._thumbContainer;
if(!container) container = this.renderThumb();
if(!container) return;
if(this._partSet)
{
this._isHC = (this._partSet.clubLevel > 0);
this._isSellable = this._partSet.isSellable;
}
else
{
this._isHC = false;
this._isSellable = false;
}
if(this._isDisabled) this.setAlpha(container, 0.2);
this._imageUrl = TextureUtils.generateImageUrl(container);
if(this.notify) this.notify();
}
private setAlpha(container: NitroContainer, alpha: number): NitroContainer
{
container.filters = [ AvatarEditorGridPartItem.ALPHA_FILTER ];
return container;
}
private sortByDrawOrder(a: IFigurePart, b: IFigurePart): number
{
const indexA = AvatarEditorGridPartItem.DRAW_ORDER.indexOf(a.type);
const indexB = AvatarEditorGridPartItem.DRAW_ORDER.indexOf(b.type);
if(indexA < indexB) return -1;
if(indexA > indexB) return 1;
if(a.index < b.index) return -1;
if(a.index > b.index) return 1;
return 0;
}
public resetFigure(figure: string): void
{
if(!this.analyzeFigure()) return;
this.update();
}
public get disposed(): boolean
{
return this._disposed;
}
public get id(): number
{
if(!this._partSet) return -1;
return this._partSet.id;
}
public get partSet(): IFigurePartSet
{
return this._partSet;
}
public set partColors(partColors: IPartColor[])
{
this._partColors = partColors;
this.update();
}
public get isDisabled(): boolean
{
return this._isDisabled;
}
public set thumbContainer(container: NitroContainer)
{
this._thumbContainer = container;
this.update();
}
public get imageUrl(): string
{
return this._imageUrl;
}
public get maxColorIndex(): number
{
return this._maxColorIndex;
}
public get isHC(): boolean
{
return this._isHC;
}
public get isSellable(): boolean
{
return this._isSellable;
}
public get isClear(): boolean
{
return this._isClear;
}
public set isClear(flag: boolean)
{
this._isClear = flag;
}
public get isSelected(): boolean
{
return this._isSelected;
}
public set isSelected(flag: boolean)
{
this._isSelected = flag;
if(this.notify) this.notify();
}
public get notify(): () => void
{
return this._notifier;
}
public set notify(notifier: () => void)
{
this._notifier = notifier;
}
}

View File

@ -0,0 +1,35 @@
import { IFigurePartSet } from '@nitrots/nitro-renderer';
export const AvatarEditorPartSorter = (hcFirst: boolean) =>
{
return (a: { partSet: IFigurePartSet, usesColor: boolean, isClear?: boolean }, b: { partSet: IFigurePartSet, usesColor: boolean, isClear?: boolean }) =>
{
const clubLevelA = (!a.partSet ? -1 : a.partSet.clubLevel);
const clubLevelB = (!b.partSet ? -1 : b.partSet.clubLevel);
const isSellableA = (!a.partSet ? false : a.partSet.isSellable);
const isSellableB = (!b.partSet ? false : b.partSet.isSellable);
if(isSellableA && !isSellableB) return 1;
if(isSellableB && !isSellableA) return -1;
if(hcFirst)
{
if(clubLevelA > clubLevelB) return -1;
if(clubLevelA < clubLevelB) return 1;
}
else
{
if(clubLevelA < clubLevelB) return -1;
if(clubLevelA > clubLevelB) return 1;
}
if(a.partSet.id < b.partSet.id) return -1;
if(a.partSet.id > b.partSet.id) return 1;
return 0;
};
};

View File

@ -0,0 +1,196 @@
import { AvatarFigurePartType, AvatarScaleType, AvatarSetType, GetAssetManager, GetAvatarRenderManager, IFigurePart, IGraphicAsset, IPartColor, NitroAlphaFilter, NitroContainer, NitroRectangle, NitroSprite, TextureUtils } from '@nitrots/nitro-renderer';
import { IAvatarEditorCategoryPartItem } from './IAvatarEditorCategoryPartItem';
export class AvatarEditorThumbnailsHelper
{
private static THUMBNAIL_CACHE: Map<string, string> = new Map();
private static THUMB_DIRECTIONS: number[] = [ 2, 6, 0, 4, 3, 1 ];
private static ALPHA_FILTER: NitroAlphaFilter = new NitroAlphaFilter({ alpha: 0.2 });
private static DRAW_ORDER: string[] = [
AvatarFigurePartType.LEFT_HAND_ITEM,
AvatarFigurePartType.LEFT_HAND,
AvatarFigurePartType.LEFT_SLEEVE,
AvatarFigurePartType.LEFT_COAT_SLEEVE,
AvatarFigurePartType.BODY,
AvatarFigurePartType.SHOES,
AvatarFigurePartType.LEGS,
AvatarFigurePartType.CHEST,
AvatarFigurePartType.CHEST_ACCESSORY,
AvatarFigurePartType.COAT_CHEST,
AvatarFigurePartType.CHEST_PRINT,
AvatarFigurePartType.WAIST_ACCESSORY,
AvatarFigurePartType.RIGHT_HAND,
AvatarFigurePartType.RIGHT_SLEEVE,
AvatarFigurePartType.RIGHT_COAT_SLEEVE,
AvatarFigurePartType.HEAD,
AvatarFigurePartType.FACE,
AvatarFigurePartType.EYES,
AvatarFigurePartType.HAIR,
AvatarFigurePartType.HAIR_BIG,
AvatarFigurePartType.FACE_ACCESSORY,
AvatarFigurePartType.EYE_ACCESSORY,
AvatarFigurePartType.HEAD_ACCESSORY,
AvatarFigurePartType.HEAD_ACCESSORY_EXTRA,
AvatarFigurePartType.RIGHT_HAND_ITEM,
];
private static getThumbnailKey(setType: string, part: IAvatarEditorCategoryPartItem): string
{
return `${ setType }-${ part.partSet.id }`;
}
public static clearCache(): void
{
this.THUMBNAIL_CACHE.clear();
}
public static async build(setType: string, part: IAvatarEditorCategoryPartItem, useColors: boolean, partColors: IPartColor[], isDisabled: boolean = false): Promise<string>
{
if(!setType || !setType.length || !part || !part.partSet || !part.partSet.parts || !part.partSet.parts.length) return null;
const thumbnailKey = this.getThumbnailKey(setType, part);
const cached = this.THUMBNAIL_CACHE.get(thumbnailKey);
if(cached) return cached;
const buildContainer = (part: IAvatarEditorCategoryPartItem, useColors: boolean, partColors: IPartColor[], isDisabled: boolean = false) =>
{
const container = new NitroContainer();
const parts = part.partSet.parts.concat().sort(this.sortByDrawOrder);
for(const part of parts)
{
if(!part) continue;
let asset: IGraphicAsset = null;
let direction = 0;
let hasAsset = false;
while(!hasAsset && (direction < AvatarEditorThumbnailsHelper.THUMB_DIRECTIONS.length))
{
const assetName = `${ AvatarFigurePartType.SCALE }_${ AvatarFigurePartType.STD }_${ part.type }_${ part.id }_${ AvatarEditorThumbnailsHelper.THUMB_DIRECTIONS[direction] }_${ AvatarFigurePartType.DEFAULT_FRAME }`;
asset = GetAssetManager().getAsset(assetName);
if(asset && asset.texture)
{
hasAsset = true;
}
else
{
direction++;
}
}
if(!hasAsset)
{
console.log(`${ AvatarFigurePartType.SCALE }_${ AvatarFigurePartType.STD }_${ part.type }_${ part.id }`);
continue;
}
const x = asset.offsetX;
const y = asset.offsetY;
const sprite = new NitroSprite(asset.texture);
sprite.position.set(x, y);
if(useColors && (part.colorLayerIndex > 0) && partColors && partColors.length)
{
const color = partColors[(part.colorLayerIndex - 1)];
if(color) sprite.tint = color.rgb;
}
if(isDisabled) container.filters = [ AvatarEditorThumbnailsHelper.ALPHA_FILTER ];
container.addChild(sprite);
}
return container;
};
return new Promise(async (resolve, reject) =>
{
const resetFigure = async (figure: string) =>
{
const container = buildContainer(part, useColors, partColors, isDisabled);
const imageUrl = await TextureUtils.generateImageUrl(container);
AvatarEditorThumbnailsHelper.THUMBNAIL_CACHE.set(thumbnailKey, imageUrl);
resolve(imageUrl);
};
const figureContainer = GetAvatarRenderManager().createFigureContainer(`${ setType }-${ part.partSet.id }`);
if(!GetAvatarRenderManager().isFigureContainerReady(figureContainer))
{
GetAvatarRenderManager().downloadAvatarFigure(figureContainer, {
resetFigure,
dispose: null,
disposed: false
});
}
else
{
resetFigure(null);
}
});
}
public static async buildForFace(figureString: string, isDisabled: boolean = false): Promise<string>
{
if(!figureString || !figureString.length) return null;
const thumbnailKey = figureString;
const cached = this.THUMBNAIL_CACHE.get(thumbnailKey);
if(cached) return cached;
return new Promise(async (resolve, reject) =>
{
const resetFigure = async (figure: string) =>
{
const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, null, { resetFigure, dispose: null, disposed: false });
if(avatarImage.isPlaceholder()) return;
const texture = avatarImage.processAsTexture(AvatarSetType.HEAD, false);
const sprite = new NitroSprite(texture);
if(isDisabled) sprite.filters = [ AvatarEditorThumbnailsHelper.ALPHA_FILTER ];
const imageUrl = await TextureUtils.generateImageUrl({
target: sprite,
frame: new NitroRectangle(0, 0, texture.width, texture.height)
});
sprite.destroy();
avatarImage.dispose();
AvatarEditorThumbnailsHelper.THUMBNAIL_CACHE.set(thumbnailKey, imageUrl);
resolve(imageUrl);
};
resetFigure(figureString);
});
}
private static sortByDrawOrder(a: IFigurePart, b: IFigurePart): number
{
const indexA = AvatarEditorThumbnailsHelper.DRAW_ORDER.indexOf(a.type);
const indexB = AvatarEditorThumbnailsHelper.DRAW_ORDER.indexOf(b.type);
if(indexA < indexB) return -1;
if(indexA > indexB) return 1;
if(a.index < b.index) return -1;
if(a.index > b.index) return 1;
return 0;
}
}

View File

@ -1,277 +0,0 @@
import { IPartColor } from '@nitrots/nitro-renderer';
import { GetAvatarPalette, GetAvatarRenderManager, GetAvatarSetType, GetClubMemberLevel, GetConfiguration } from '../nitro';
import { AvatarEditorGridColorItem } from './AvatarEditorGridColorItem';
import { AvatarEditorGridPartItem } from './AvatarEditorGridPartItem';
import { CategoryBaseModel } from './CategoryBaseModel';
import { CategoryData } from './CategoryData';
import { FigureData } from './FigureData';
export class AvatarEditorUtilities
{
private static MAX_PALETTES: number = 2;
public static CURRENT_FIGURE: FigureData = null;
public static FIGURE_SET_IDS: number[] = [];
public static BOUND_FURNITURE_NAMES: string[] = [];
public static getGender(gender: string): string
{
switch(gender)
{
case FigureData.MALE:
case 'm':
case 'M':
gender = FigureData.MALE;
break;
case FigureData.FEMALE:
case 'f':
case 'F':
gender = FigureData.FEMALE;
break;
default:
gender = FigureData.MALE;
}
return gender;
}
public static hasFigureSetId(setId: number): boolean
{
return (this.FIGURE_SET_IDS.indexOf(setId) >= 0);
}
public static createCategory(model: CategoryBaseModel, name: string): CategoryData
{
if(!model || !name || !this.CURRENT_FIGURE) return null;
const partItems: AvatarEditorGridPartItem[] = [];
const colorItems: AvatarEditorGridColorItem[][] = [];
let i = 0;
while(i < this.MAX_PALETTES)
{
colorItems.push([]);
i++;
}
const setType = GetAvatarSetType(name);
if(!setType) return null;
const palette = GetAvatarPalette(setType.paletteID);
if(!palette) return null;
let colorIds = this.CURRENT_FIGURE.getColorIds(name);
if(!colorIds) colorIds = [];
const partColors: IPartColor[] = new Array(colorIds.length);
const clubItemsDimmed = this.clubItemsDimmed;
const clubMemberLevel = GetClubMemberLevel();
for(const partColor of palette.colors.getValues())
{
if(partColor.isSelectable && (clubItemsDimmed || (clubMemberLevel >= partColor.clubLevel)))
{
let i = 0;
while(i < this.MAX_PALETTES)
{
const isDisabled = (clubMemberLevel < partColor.clubLevel);
const colorItem = new AvatarEditorGridColorItem(partColor, isDisabled);
colorItems[i].push(colorItem);
i++;
}
if(name !== FigureData.FACE)
{
let i = 0;
while(i < colorIds.length)
{
if(partColor.id === colorIds[i]) partColors[i] = partColor;
i++;
}
}
}
}
let mandatorySetIds: string[] = [];
if(clubItemsDimmed)
{
mandatorySetIds = GetAvatarRenderManager().getMandatoryAvatarPartSetIds(this.CURRENT_FIGURE.gender, 2);
}
else
{
mandatorySetIds = GetAvatarRenderManager().getMandatoryAvatarPartSetIds(this.CURRENT_FIGURE.gender, clubMemberLevel);
}
const isntMandatorySet = (mandatorySetIds.indexOf(name) === -1);
if(isntMandatorySet)
{
const partItem = new AvatarEditorGridPartItem(null, null, false);
partItem.isClear = true;
partItems.push(partItem);
}
const usesColors = (name !== FigureData.FACE);
const partSets = setType.partSets;
const totalPartSets = partSets.length;
i = (totalPartSets - 1);
while(i >= 0)
{
const partSet = partSets.getWithIndex(i);
let isValidGender = false;
if(partSet.gender === FigureData.UNISEX)
{
isValidGender = true;
}
else if(partSet.gender === this.CURRENT_FIGURE.gender)
{
isValidGender = true;
}
if(partSet.isSelectable && isValidGender && (clubItemsDimmed || (clubMemberLevel >= partSet.clubLevel)))
{
const isDisabled = (clubMemberLevel < partSet.clubLevel);
let isValid = true;
if(partSet.isSellable) isValid = this.hasFigureSetId(partSet.id);
if(isValid) partItems.push(new AvatarEditorGridPartItem(partSet, partColors, usesColors, isDisabled));
}
i--;
}
partItems.sort(this.clubItemsFirst ? this.clubSorter : this.noobSorter);
// if(this._forceSellableClothingVisibility || GetNitroInstance().getConfiguration<boolean>("avatareditor.support.sellablefurni", false))
// {
// _local_31 = (this._manager.windowManager.assets.getAssetByName("camera_zoom_in") as BitmapDataAsset);
// _local_32 = (_local_31.content as BitmapData).clone();
// _local_33 = (AvatarEditorView._Str_6802.clone() as IWindowContainer);
// _local_33.name = AvatarEditorGridView.GET_MORE;
// _local_7 = new AvatarEditorGridPartItem(_local_33, k, null, null, false);
// _local_7._Str_3093 = _local_32;
// _local_3.push(_local_7);
// }
i = 0;
while(i < this.MAX_PALETTES)
{
colorItems[i].sort(this.colorSorter);
i++;
}
return new CategoryData(name, partItems, colorItems);
}
public static clubSorter(a: AvatarEditorGridPartItem, b: AvatarEditorGridPartItem): number
{
const clubLevelA = (!a.partSet ? 9999999999 : a.partSet.clubLevel);
const clubLevelB = (!b.partSet ? 9999999999 : b.partSet.clubLevel);
const isSellableA = (!a.partSet ? false : a.partSet.isSellable);
const isSellableB = (!b.partSet ? false : b.partSet.isSellable);
if(isSellableA && !isSellableB) return 1;
if(isSellableB && !isSellableA) return -1;
if(clubLevelA > clubLevelB) return -1;
if(clubLevelA < clubLevelB) return 1;
if(a.partSet.id > b.partSet.id) return -1;
if(a.partSet.id < b.partSet.id) return 1;
return 0;
}
public static colorSorter(a: AvatarEditorGridColorItem, b: AvatarEditorGridColorItem): number
{
const clubLevelA = (!a.partColor ? -1 : a.partColor.clubLevel);
const clubLevelB = (!b.partColor ? -1 : b.partColor.clubLevel);
if(clubLevelA < clubLevelB) return -1;
if(clubLevelA > clubLevelB) return 1;
if(a.partColor.index < b.partColor.index) return -1;
if(a.partColor.index > b.partColor.index) return 1;
return 0;
}
public static noobSorter(a: AvatarEditorGridPartItem, b: AvatarEditorGridPartItem): number
{
const clubLevelA = (!a.partSet ? -1 : a.partSet.clubLevel);
const clubLevelB = (!b.partSet ? -1 : b.partSet.clubLevel);
const isSellableA = (!a.partSet ? false : a.partSet.isSellable);
const isSellableB = (!b.partSet ? false : b.partSet.isSellable);
if(isSellableA && !isSellableB) return 1;
if(isSellableB && !isSellableA) return -1;
if(clubLevelA < clubLevelB) return -1;
if(clubLevelA > clubLevelB) return 1;
if(a.partSet.id < b.partSet.id) return -1;
if(a.partSet.id > b.partSet.id) return 1;
return 0;
}
public static avatarSetFirstSelectableColor(name: string): number
{
const setType = GetAvatarSetType(name);
if(!setType) return -1;
const palette = GetAvatarPalette(setType.paletteID);
if(!palette) return -1;
for(const color of palette.colors.getValues())
{
if(!color.isSelectable || (GetClubMemberLevel() < color.clubLevel)) continue;
return color.id;
}
return -1;
}
public static get clubItemsFirst(): boolean
{
return GetConfiguration<boolean>('avatareditor.show.clubitems.first', true);
}
public static get clubItemsDimmed(): boolean
{
return GetConfiguration<boolean>('avatareditor.show.clubitems.dimmed', true);
}
}

View File

@ -1,76 +0,0 @@
import { AvatarEditorFigureCategory, AvatarScaleType, AvatarSetType } from '@nitrots/nitro-renderer';
import { GetAvatarRenderManager } from '../nitro';
import { AvatarEditorUtilities } from './AvatarEditorUtilities';
import { CategoryBaseModel } from './CategoryBaseModel';
import { FigureData } from './FigureData';
export class BodyModel extends CategoryBaseModel
{
private _imageCallBackHandled: boolean = false;
public init(): void
{
super.init();
this.addCategory(FigureData.FACE);
this._isInitalized = true;
}
public selectColor(category: string, colorIndex: number, paletteId: number): void
{
super.selectColor(category, colorIndex, paletteId);
this.updateSelectionsFromFigure(FigureData.FACE);
}
protected updateSelectionsFromFigure(name: string): void
{
if(!this._categories || !AvatarEditorUtilities.CURRENT_FIGURE) return;
const category = this._categories.get(name);
if(!category) return;
const setId = AvatarEditorUtilities.CURRENT_FIGURE.getPartSetId(name);
let colorIds = AvatarEditorUtilities.CURRENT_FIGURE.getColorIds(name);
if(!colorIds) colorIds = [];
category.selectPartId(setId);
category.selectColorIds(colorIds);
for(const part of category.parts)
{
const resetFigure = (figure: string) =>
{
const figureString = AvatarEditorUtilities.CURRENT_FIGURE.getFigureStringWithFace(part.id);
const avatarImage = GetAvatarRenderManager().createAvatarImage(figureString, AvatarScaleType.LARGE, null, { resetFigure, dispose: null, disposed: false });
const sprite = avatarImage.getImageAsSprite(AvatarSetType.HEAD);
if(sprite)
{
sprite.y = 10;
part.thumbContainer = sprite;
setTimeout(() => avatarImage.dispose(), 0);
}
}
resetFigure(null);
}
}
public get canSetGender(): boolean
{
return true;
}
public get name(): string
{
return AvatarEditorFigureCategory.GENERIC;
}
}

View File

@ -1,246 +0,0 @@
import { AvatarEditorUtilities } from './AvatarEditorUtilities';
import { CategoryData } from './CategoryData';
import { IAvatarEditorCategoryModel } from './IAvatarEditorCategoryModel';
export class CategoryBaseModel implements IAvatarEditorCategoryModel
{
protected _categories: Map<string, CategoryData>;
protected _isInitalized: boolean;
protected _maxPaletteCount: number;
private _disposed: boolean;
constructor()
{
this._isInitalized = false;
this._maxPaletteCount = 0;
}
public dispose(): void
{
this._categories = null;
this._disposed = true;
}
public get disposed(): boolean
{
return this._disposed;
}
public init(): void
{
if(!this._categories) this._categories = new Map();
}
public reset(): void
{
this._isInitalized = false;
if(this._categories)
{
for(const category of this._categories.values()) (category && category.dispose());
}
this._categories = new Map();
}
protected addCategory(name: string): void
{
let existing = this._categories.get(name);
if(existing) return;
existing = AvatarEditorUtilities.createCategory(this, name);
if(!existing) return;
this._categories.set(name, existing);
this.updateSelectionsFromFigure(name);
}
protected updateSelectionsFromFigure(figure: string): void
{
const category = this._categories.get(figure);
if(!category) return;
const setId = AvatarEditorUtilities.CURRENT_FIGURE.getPartSetId(figure);
let colorIds = AvatarEditorUtilities.CURRENT_FIGURE.getColorIds(figure);
if(!colorIds) colorIds = [];
category.selectPartId(setId);
category.selectColorIds(colorIds);
}
public hasClubSelectionsOverLevel(level: number): boolean
{
if(!this._categories) return false;
for(const category of this._categories.values())
{
if(!category) continue;
if(category.hasClubSelectionsOverLevel(level)) return true;
}
return false;
}
public hasInvalidSelectedItems(ownedItems: number[]): boolean
{
if(!this._categories) return false;
for(const category of this._categories.values())
{
if(category.hasInvalidSelectedItems(ownedItems)) return true;
}
return false;
}
public stripClubItemsOverLevel(level: number): boolean
{
if(!this._categories) return false;
let didStrip = false;
for(const [ name, category ] of this._categories.entries())
{
let isValid = false;
if(category.stripClubItemsOverLevel(level)) isValid = true;
if(category.stripClubColorsOverLevel(level)) isValid = true;
if(isValid)
{
const partItem = category.getCurrentPart();
if(partItem && AvatarEditorUtilities.CURRENT_FIGURE)
{
AvatarEditorUtilities.CURRENT_FIGURE.savePartData(name, partItem.id, category.getSelectedColorIds(), true);
}
didStrip = true;
}
}
return didStrip;
}
public stripInvalidSellableItems(): boolean
{
if(!this._categories) return false;
let didStrip = false;
for(const [ name, category ] of this._categories.entries())
{
const isValid = false;
// if(category._Str_8360(this._Str_2278.manager.inventory)) _local_6 = true;
if(isValid)
{
const partItem = category.getCurrentPart();
if(partItem && AvatarEditorUtilities.CURRENT_FIGURE)
{
AvatarEditorUtilities.CURRENT_FIGURE.savePartData(name, partItem.id, category.getSelectedColorIds(), true);
}
didStrip = true;
}
}
return didStrip;
}
public selectPart(category: string, partIndex: number): void
{
const categoryData = this._categories.get(category);
if(!categoryData) return;
const selectedPartIndex = categoryData.selectedPartIndex;
categoryData.selectPartIndex(partIndex);
const partItem = categoryData.getCurrentPart();
if(!partItem) return;
if(partItem.isDisabled)
{
categoryData.selectPartIndex(selectedPartIndex);
// open hc window
return;
}
this._maxPaletteCount = partItem.maxColorIndex;
AvatarEditorUtilities.CURRENT_FIGURE.savePartData(category, partItem.id, categoryData.getSelectedColorIds(), true);
}
public selectColor(category: string, colorIndex: number, paletteId: number): void
{
const categoryData = this._categories.get(category);
if(!categoryData) return;
const paletteIndex = categoryData.getCurrentColorIndex(paletteId);
categoryData.selectColorIndex(colorIndex, paletteId);
const colorItem = categoryData.getSelectedColor(paletteId);
if(colorItem.isDisabled)
{
categoryData.selectColorIndex(paletteIndex, paletteId);
// open hc window
return;
}
AvatarEditorUtilities.CURRENT_FIGURE.savePartSetColourId(category, categoryData.getSelectedColorIds(), true);
}
public getCategoryData(category: string): CategoryData
{
if(!this._isInitalized) this.init();
if(!this._categories) return null;
return this._categories.get(category);
}
public get categories(): Map<string, CategoryData>
{
return this._categories;
}
public get canSetGender(): boolean
{
return false;
}
public get maxPaletteCount(): number
{
return (this._maxPaletteCount || 1);
}
public set maxPaletteCount(count: number)
{
this._maxPaletteCount = count;
}
public get name(): string
{
return null;
}
}

View File

@ -1,487 +0,0 @@
import { IPartColor } from '@nitrots/nitro-renderer';
import { AvatarEditorGridColorItem } from './AvatarEditorGridColorItem';
import { AvatarEditorGridPartItem } from './AvatarEditorGridPartItem';
export class CategoryData
{
private _name: string;
private _parts: AvatarEditorGridPartItem[];
private _palettes: AvatarEditorGridColorItem[][];
private _selectedPartIndex: number = -1;
private _paletteIndexes: number[];
constructor(name: string, partItems: AvatarEditorGridPartItem[], colorItems: AvatarEditorGridColorItem[][])
{
this._name = name;
this._parts = partItems;
this._palettes = colorItems;
this._selectedPartIndex = -1;
}
private static defaultColorId(palettes: AvatarEditorGridColorItem[], clubLevel: number): number
{
if(!palettes || !palettes.length) return -1;
let i = 0;
while(i < palettes.length)
{
const colorItem = palettes[i];
if(colorItem.partColor && (colorItem.partColor.clubLevel <= clubLevel))
{
return colorItem.partColor.id;
}
i++;
}
return -1;
}
public init(): void
{
for(const part of this._parts)
{
if(!part) continue;
part.init();
}
}
public dispose(): void
{
if(this._parts)
{
for(const part of this._parts) part.dispose();
this._parts = null;
}
if(this._palettes)
{
for(const palette of this._palettes) for(const colorItem of palette) colorItem.dispose();
this._palettes = null;
}
this._selectedPartIndex = -1;
this._paletteIndexes = null;
}
public selectPartId(partId: number): void
{
if(!this._parts) return;
let i = 0;
while(i < this._parts.length)
{
const partItem = this._parts[i];
if(partItem.id === partId)
{
this.selectPartIndex(i);
return;
}
i++;
}
}
public selectColorIds(colorIds: number[]): void
{
if(!colorIds || !this._palettes) return;
this._paletteIndexes = new Array(colorIds.length);
let i = 0;
while(i < this._palettes.length)
{
const palette = this.getPalette(i);
if(palette)
{
let colorId = 0;
if(colorIds.length > i)
{
colorId = colorIds[i];
}
else
{
const colorItem = palette[0];
if(colorItem && colorItem.partColor) colorId = colorItem.partColor.id;
}
let j = 0;
while(j < palette.length)
{
const colorItem = palette[j];
if(colorItem.partColor.id === colorId)
{
this._paletteIndexes[i] = j;
colorItem.isSelected = true;
}
else
{
colorItem.isSelected = false;
}
j++;
}
}
i++;
}
this.updatePartColors();
}
public selectPartIndex(partIndex: number): AvatarEditorGridPartItem
{
if(!this._parts) return null;
if((this._selectedPartIndex >= 0) && (this._parts.length > this._selectedPartIndex))
{
const partItem = this._parts[this._selectedPartIndex];
if(partItem) partItem.isSelected = false;
}
if(this._parts.length > partIndex)
{
const partItem = this._parts[partIndex];
if(partItem)
{
partItem.isSelected = true;
this._selectedPartIndex = partIndex;
return partItem;
}
}
return null;
}
public selectColorIndex(colorIndex: number, paletteId: number): AvatarEditorGridColorItem
{
const palette = this.getPalette(paletteId);
if(!palette) return null;
if(palette.length <= colorIndex) return null;
this.deselectColorIndex(this._paletteIndexes[paletteId], paletteId);
this._paletteIndexes[paletteId] = colorIndex;
const colorItem = palette[colorIndex];
if(!colorItem) return null;
colorItem.isSelected = true;
this.updatePartColors();
return colorItem;
}
public getCurrentColorIndex(k: number): number
{
return this._paletteIndexes[k];
}
private deselectColorIndex(colorIndex: number, paletteIndex: number): void
{
const palette = this.getPalette(paletteIndex);
if(!palette) return;
if(palette.length <= colorIndex) return;
const colorItem = palette[colorIndex];
if(!colorItem) return;
colorItem.isSelected = false;
}
public getSelectedColorIds(): number[]
{
if(!this._paletteIndexes || !this._paletteIndexes.length) return null;
if(!this._palettes || !this._palettes.length) return null;
const palette = this._palettes[0];
if(!palette || (!palette.length)) return null;
const colorItem = palette[0];
if(!colorItem || !colorItem.partColor) return null;
const colorId = colorItem.partColor.id;
const colorIds: number[] = [];
let i = 0;
while(i < this._paletteIndexes.length)
{
const paletteSet = this._palettes[i];
if(!((!(paletteSet)) || (paletteSet.length <= i)))
{
if(paletteSet.length > this._paletteIndexes[i])
{
const color = paletteSet[this._paletteIndexes[i]];
if(color && color.partColor)
{
colorIds.push(color.partColor.id);
}
else
{
colorIds.push(colorId);
}
}
else
{
colorIds.push(colorId);
}
}
i++;
}
const partItem = this.getCurrentPart();
if(!partItem) return null;
return colorIds.slice(0, Math.max(partItem.maxColorIndex, 1));
}
private getSelectedColors(): IPartColor[]
{
const partColors: IPartColor[] = [];
let i = 0;
while(i < this._paletteIndexes.length)
{
const colorItem = this.getSelectedColor(i);
if(colorItem)
{
partColors.push(colorItem.partColor);
}
else
{
partColors.push(null);
}
i++;
}
return partColors;
}
public getSelectedColor(paletteId: number): AvatarEditorGridColorItem
{
const palette = this.getPalette(paletteId);
if(!palette || (palette.length <= this._paletteIndexes[paletteId])) return null;
return palette[this._paletteIndexes[paletteId]];
}
public getSelectedColorId(paletteId: number): number
{
const colorItem = this.getSelectedColor(paletteId);
if(colorItem && (colorItem.partColor)) return colorItem.partColor.id;
return 0;
}
public getPalette(paletteId: number): AvatarEditorGridColorItem[]
{
if(!this._paletteIndexes || !this._palettes || (this._palettes.length <= paletteId))
{
return null;
}
return this._palettes[paletteId];
}
public getCurrentPart(): AvatarEditorGridPartItem
{
return this._parts[this._selectedPartIndex] as AvatarEditorGridPartItem;
}
private updatePartColors(): void
{
const partColors = this.getSelectedColors();
for(const partItem of this._parts)
{
if(partItem) partItem.partColors = partColors;
}
}
public hasClubSelectionsOverLevel(level: number): boolean
{
let hasInvalidSelections = false;
const partColors = this.getSelectedColors();
if(partColors)
{
let i = 0;
while(i < partColors.length)
{
const partColor = partColors[i];
if(partColor && (partColor.clubLevel > level)) hasInvalidSelections = true;
i++;
}
}
const partItem = this.getCurrentPart();
if(partItem && partItem.partSet)
{
const partSet = partItem.partSet;
if(partSet && (partSet.clubLevel > level)) hasInvalidSelections = true;
}
return hasInvalidSelections;
}
public hasInvalidSelectedItems(ownedItems: number[]): boolean
{
const part = this.getCurrentPart();
if(!part) return false;
const partSet = part.partSet;
if(!partSet || !partSet.isSellable) return;
return (ownedItems.indexOf(partSet.id) > -1);
}
public stripClubItemsOverLevel(level: number): boolean
{
const partItem = this.getCurrentPart();
if(partItem && partItem.partSet)
{
const partSet = partItem.partSet;
if(partSet.clubLevel > level)
{
const newPartItem = this.selectPartIndex(0);
if(newPartItem && !newPartItem.partSet) this.selectPartIndex(1);
return true;
}
}
return false;
}
public stripClubColorsOverLevel(level: number): boolean
{
const colorIds: number[] = [];
const partColors = this.getSelectedColors();
const colorItems = this.getPalette(0);
let didStrip = false;
const colorId = CategoryData.defaultColorId(colorItems, level);
if(colorId === -1) return false;
let i = 0;
while(i < partColors.length)
{
const partColor = partColors[i];
if(!partColor)
{
colorIds.push(colorId);
didStrip = true;
}
else
{
if(partColor.clubLevel > level)
{
colorIds.push(colorId);
didStrip = true;
}
else
{
colorIds.push(partColor.id);
}
}
i++;
}
if(didStrip) this.selectColorIds(colorIds);
return didStrip;
}
// public stripInvalidSellableItems(k:IHabboInventory): boolean
// {
// var _local_3:IFigurePartSet;
// var _local_4:AvatarEditorGridPartItem;
// var _local_2:AvatarEditorGridPartItem = this._Str_6315();
// if (((_local_2) && (_local_2.partSet)))
// {
// _local_3 = _local_2.partSet;
// if (((_local_3.isSellable) && (!(k._Str_14439(_local_3.id)))))
// {
// _local_4 = this._Str_8066(0);
// if (((!(_local_4 == null)) && (_local_4.partSet == null)))
// {
// this._Str_8066(1);
// }
// return true;
// }
// }
// return false;
// }
public get name(): string
{
return this._name;
}
public get parts(): AvatarEditorGridPartItem[]
{
return this._parts;
}
public get selectedPartIndex(): number
{
return this._selectedPartIndex;
}
}

View File

@ -1,287 +0,0 @@
import { AvatarEditorUtilities } from './AvatarEditorUtilities';
export class FigureData
{
private static DEFAULT_DIRECTION: number = 4;
public static MALE: string = 'M';
public static FEMALE: string = 'F';
public static UNISEX: string = 'U';
public static SCALE: string = 'h';
public static STD: string = 'std';
public static DEFAULT_FRAME: string = '0';
public static FACE: string = 'hd';
public static HAIR: string = 'hr';
public static HAT: string = 'ha';
public static HEAD_ACCESSORIES: string = 'he';
public static EYE_ACCESSORIES: string = 'ea';
public static FACE_ACCESSORIES: string = 'fa';
public static JACKET: string = 'cc';
public static SHIRT: string = 'ch';
public static CHEST_ACCESSORIES: string = 'ca';
public static CHEST_PRINTS: string = 'cp';
public static TROUSERS: string = 'lg';
public static SHOES: string = 'sh';
public static TROUSER_ACCESSORIES: string = 'wa';
public static SET_TYPES = [ FigureData.FACE, FigureData.HAIR, FigureData.HAT, FigureData.HEAD_ACCESSORIES, FigureData.EYE_ACCESSORIES, FigureData.FACE_ACCESSORIES, FigureData.JACKET, FigureData.SHIRT, FigureData.CHEST_ACCESSORIES, FigureData.CHEST_PRINTS, FigureData.TROUSERS, FigureData.SHOES, FigureData.TROUSERS ];
private _data: Map<string, number>;
private _colors: Map<string, number[]>;
private _gender: string = 'M';
private _direction: number = FigureData.DEFAULT_DIRECTION;
private _avatarEffectType: number = -1;
private _notifier: () => void = null;
public loadAvatarData(figureString: string, gender: string): void
{
this._data = new Map();
this._colors = new Map();
this._gender = gender;
this.parseFigureString(figureString);
this.updateView();
}
private parseFigureString(figure: string): void
{
if(!figure) return;
const sets = figure.split('.');
if(!sets || !sets.length) return;
for(const set of sets)
{
const parts = set.split('-');
if(!parts.length) continue;
const setType = parts[0];
const setId = parseInt(parts[1]);
const colorIds: number[] = [];
let offset = 2;
while(offset < parts.length)
{
colorIds.push(parseInt(parts[offset]));
offset++;
}
if(!colorIds.length) colorIds.push(0);
this.savePartSetId(setType, setId, false);
this.savePartSetColourId(setType, colorIds, false);
}
}
public getPartSetId(setType: string): number
{
const existing = this._data.get(setType);
if(existing !== undefined) return existing;
return -1;
}
public getColorIds(setType: string): number[]
{
const existing = this._colors.get(setType);
if(existing !== undefined) return existing;
return [ AvatarEditorUtilities.avatarSetFirstSelectableColor(setType) ];
}
public getFigureString(): string
{
let figureString = '';
const setParts: string[] = [];
for(const [ setType, setId ] of this._data.entries())
{
const colorIds = this._colors.get(setType);
let setPart = ((setType + '-') + setId);
if(colorIds && colorIds.length)
{
let i = 0;
while(i < colorIds.length)
{
setPart = (setPart + ('-' + colorIds[i]));
i++;
}
}
setParts.push(setPart);
}
let i = 0;
while(i < setParts.length)
{
figureString = (figureString + setParts[i]);
if(i < (setParts.length - 1)) figureString = (figureString + '.');
i++;
}
return figureString;
}
public savePartData(setType: string, partId: number, colorIds: number[], update: boolean = false): void
{
this.savePartSetId(setType, partId, update);
this.savePartSetColourId(setType, colorIds, update);
}
private savePartSetId(setType: string, partId: number, update: boolean = true): void
{
switch(setType)
{
case FigureData.FACE:
case FigureData.HAIR:
case FigureData.HAT:
case FigureData.HEAD_ACCESSORIES:
case FigureData.EYE_ACCESSORIES:
case FigureData.FACE_ACCESSORIES:
case FigureData.SHIRT:
case FigureData.JACKET:
case FigureData.CHEST_ACCESSORIES:
case FigureData.CHEST_PRINTS:
case FigureData.TROUSERS:
case FigureData.SHOES:
case FigureData.TROUSER_ACCESSORIES:
if(partId >= 0)
{
this._data.set(setType, partId);
}
else
{
this._data.delete(setType);
}
break;
}
if(update) this.updateView();
}
public savePartSetColourId(setType: string, colorIds: number[], update: boolean = true): void
{
switch(setType)
{
case FigureData.FACE:
case FigureData.HAIR:
case FigureData.HAT:
case FigureData.HEAD_ACCESSORIES:
case FigureData.EYE_ACCESSORIES:
case FigureData.FACE_ACCESSORIES:
case FigureData.SHIRT:
case FigureData.JACKET:
case FigureData.CHEST_ACCESSORIES:
case FigureData.CHEST_PRINTS:
case FigureData.TROUSERS:
case FigureData.SHOES:
case FigureData.TROUSER_ACCESSORIES:
this._colors.set(setType, colorIds);
break;
}
if(update) this.updateView();
}
public getFigureStringWithFace(k: number, override = true): string
{
let figureString = '';
const setTypes: string[] = [ FigureData.FACE ];
const figureSets: string[] = [];
for(const setType of setTypes)
{
const colors = this._colors.get(setType);
if(!colors) continue;
let setId = this._data.get(setType);
if((setType === FigureData.FACE) && override) setId = k;
let figureSet = ((setType + '-') + setId);
if(setId >= 0)
{
let i = 0;
while(i < colors.length)
{
figureSet = (figureSet + ('-' + colors[i]));
i++;
}
}
figureSets.push(figureSet);
}
let i = 0;
while(i < figureSets.length)
{
figureString = (figureString + figureSets[i]);
if(i < (figureSets.length - 1)) figureString = (figureString + '.');
i++;
}
return figureString;
}
public updateView(): void
{
if(this.notify) this.notify();
}
public get gender(): string
{
return this._gender;
}
public get direction(): number
{
return this._direction;
}
public set direction(direction: number)
{
this._direction = direction;
this.updateView();
}
public set avatarEffectType(k: number)
{
this._avatarEffectType = k;
}
public get avatarEffectType(): number
{
return this._avatarEffectType;
}
public get notify(): () => void
{
return this._notifier;
}
public set notify(notifier: () => void)
{
this._notifier = notifier;
}
}

View File

@ -1,90 +0,0 @@
import { AvatarFigureContainer, IFigurePartSet, IPalette, IPartColor, SetType } from '@nitrots/nitro-renderer';
import { GetAvatarRenderManager } from '../nitro';
import { Randomizer } from '../utils';
import { FigureData } from './FigureData';
function getTotalColors(partSet: IFigurePartSet): number
{
const parts = partSet.parts;
let totalColors = 0;
for(const part of parts) totalColors = Math.max(totalColors, part.colorLayerIndex);
return totalColors;
}
function getRandomSetTypes(requiredSets: string[], options: string[]): string[]
{
options = options.filter(option => (requiredSets.indexOf(option) === -1));
return [ ...requiredSets, ...Randomizer.getRandomElements(options, (Randomizer.getRandomNumber(options.length) + 1)) ];
}
function getRandomPartSet(setType: SetType, gender: string, clubLevel: number = 0, figureSetIds: number[] = []): IFigurePartSet
{
if(!setType) return null;
const options = setType.partSets.getValues().filter(option =>
{
if(!option.isSelectable || ((option.gender !== 'U') && (option.gender !== gender)) || (option.clubLevel > clubLevel) || (option.isSellable && (figureSetIds.indexOf(option.id) === -1))) return null;
return option;
});
if(!options || !options.length) return null;
return Randomizer.getRandomElement(options);
}
function getRandomColors(palette: IPalette, partSet: IFigurePartSet, clubLevel: number = 0): IPartColor[]
{
if(!palette) return [];
const options = palette.colors.getValues().filter(option =>
{
if(!option.isSelectable || (option.clubLevel > clubLevel)) return null;
return option;
});
if(!options || !options.length) return null;
return Randomizer.getRandomElements(options, getTotalColors(partSet));
}
export function generateRandomFigure(figureData: FigureData, gender: string, clubLevel: number = 0, figureSetIds: number[] = [], ignoredSets: string[] = []): string
{
const structure = GetAvatarRenderManager().structure;
const figureContainer = new AvatarFigureContainer('');
const requiredSets = getRandomSetTypes(structure.getMandatorySetTypeIds(gender, clubLevel), FigureData.SET_TYPES);
for(const setType of ignoredSets)
{
const partSetId = figureData.getPartSetId(setType);
const colors = figureData.getColorIds(setType);
figureContainer.updatePart(setType, partSetId, colors);
}
for(const type of requiredSets)
{
if(figureContainer.hasPartType(type)) continue;
const setType = (structure.figureData.getSetType(type) as SetType);
const selectedSet = getRandomPartSet(setType, gender, clubLevel, figureSetIds);
if(!selectedSet) continue;
let selectedColors: number[] = [];
if(selectedSet.isColorable)
{
selectedColors = getRandomColors(structure.figureData.getPalette(setType.paletteID), selectedSet, clubLevel).map(color => color.id);
}
figureContainer.updatePart(setType.type, selectedSet.id, selectedColors);
}
return figureContainer.getFigureString();
}

View File

@ -1,24 +0,0 @@
import { AvatarEditorFigureCategory } from '@nitrots/nitro-renderer';
import { CategoryBaseModel } from './CategoryBaseModel';
import { FigureData } from './FigureData';
export class HeadModel extends CategoryBaseModel
{
public init(): void
{
super.init();
this.addCategory(FigureData.HAIR);
this.addCategory(FigureData.HAT);
this.addCategory(FigureData.HEAD_ACCESSORIES);
this.addCategory(FigureData.EYE_ACCESSORIES);
this.addCategory(FigureData.FACE_ACCESSORIES);
this._isInitalized = true;
}
public get name(): string
{
return AvatarEditorFigureCategory.HEAD;
}
}

View File

@ -0,0 +1,9 @@
import { IPartColor } from '@nitrots/nitro-renderer';
import { IAvatarEditorCategoryPartItem } from './IAvatarEditorCategoryPartItem';
export interface IAvatarEditorCategory
{
setType: string;
partItems: IAvatarEditorCategoryPartItem[];
colorItems: IPartColor[][];
}

View File

@ -1,19 +0,0 @@
import { CategoryData } from './CategoryData';
export interface IAvatarEditorCategoryModel
{
init(): void;
dispose(): void;
reset(): void;
getCategoryData(category: string): CategoryData;
selectPart(category: string, partIndex: number): void;
selectColor(category: string, colorIndex: number, paletteId: number): void;
hasClubSelectionsOverLevel(level: number): boolean;
hasInvalidSelectedItems(ownedItems: number[]): boolean;
stripClubItemsOverLevel(level: number): boolean;
stripInvalidSellableItems(): boolean;
categories: Map<string, CategoryData>;
canSetGender: boolean;
maxPaletteCount: number;
name: string;
}

View File

@ -0,0 +1,10 @@
import { IFigurePartSet } from '@nitrots/nitro-renderer';
export interface IAvatarEditorCategoryPartItem
{
id?: number;
partSet?: IFigurePartSet;
usesColor?: boolean;
maxPaletteCount?: number;
isClear?: boolean;
}

View File

@ -1,22 +0,0 @@
import { AvatarEditorFigureCategory } from '@nitrots/nitro-renderer';
import { CategoryBaseModel } from './CategoryBaseModel';
import { FigureData } from './FigureData';
export class LegModel extends CategoryBaseModel
{
public init(): void
{
super.init();
this.addCategory(FigureData.TROUSERS);
this.addCategory(FigureData.SHOES);
this.addCategory(FigureData.TROUSER_ACCESSORIES);
this._isInitalized = true;
}
public get name(): string
{
return AvatarEditorFigureCategory.LEGS;
}
}

View File

@ -1,23 +0,0 @@
import { AvatarEditorFigureCategory } from '@nitrots/nitro-renderer';
import { CategoryBaseModel } from './CategoryBaseModel';
import { FigureData } from './FigureData';
export class TorsoModel extends CategoryBaseModel
{
public init(): void
{
super.init();
this.addCategory(FigureData.SHIRT);
this.addCategory(FigureData.CHEST_PRINTS);
this.addCategory(FigureData.JACKET);
this.addCategory(FigureData.CHEST_ACCESSORIES);
this._isInitalized = true;
}
public get name(): string
{
return AvatarEditorFigureCategory.TORSO;
}
}

View File

@ -1,13 +1,6 @@
export * from './AvatarEditorAction'; export * from './AvatarEditorAction';
export * from './AvatarEditorGridColorItem'; export * from './AvatarEditorColorSorter';
export * from './AvatarEditorGridPartItem'; export * from './AvatarEditorPartSorter';
export * from './AvatarEditorUtilities'; export * from './AvatarEditorThumbnailsHelper';
export * from './BodyModel'; export * from './IAvatarEditorCategory';
export * from './CategoryBaseModel'; export * from './IAvatarEditorCategoryPartItem';
export * from './CategoryData';
export * from './FigureData';
export * from './FigureGenerator';
export * from './HeadModel';
export * from './IAvatarEditorCategoryModel';
export * from './LegModel';
export * from './TorsoModel';

View File

@ -4,6 +4,6 @@ export class CameraPicture
{ {
constructor( constructor(
public texture: NitroTexture, public texture: NitroTexture,
public imageUrl: string) public imageUrl: string)
{} {}
} }

View File

@ -2,6 +2,6 @@ export class CameraPictureThumbnail
{ {
constructor( constructor(
public effectName: string, public effectName: string,
public thumbnailUrl: string) public thumbnailUrl: string)
{} {}
} }

View File

@ -1,7 +1,7 @@
import { NodeData } from '@nitrots/nitro-renderer'; import { NodeData } from '@nitrots/nitro-renderer';
import { ICatalogNode } from './ICatalogNode'; import { ICatalogNode } from './ICatalogNode';
export class CatalogNode implements ICatalogNode export class CatalogNode implements ICatalogNode
{ {
private _depth: number = 0; private _depth: number = 0;
private _localization: string = ''; private _localization: string = '';

View File

@ -1,4 +1,4 @@
export class CatalogPageName export class CatalogPageName
{ {
public static DUCKET_INFO: string = 'ducket_info'; public static DUCKET_INFO: string = 'ducket_info';
public static CREDITS: string = 'credits'; public static CREDITS: string = 'credits';

View File

@ -5,6 +5,6 @@ export class CatalogPetPalette
constructor( constructor(
public readonly breed: string, public readonly breed: string,
public readonly palettes: SellablePetPaletteData[] public readonly palettes: SellablePetPaletteData[]
) )
{} {}
} }

View File

@ -1,16 +1,15 @@
import { SellablePetPaletteData } from '@nitrots/nitro-renderer'; import { GetRoomEngine, SellablePetPaletteData } from '@nitrots/nitro-renderer';
import { GetRoomEngine } from '../nitro';
import { ICatalogNode } from './ICatalogNode'; import { ICatalogNode } from './ICatalogNode';
export const GetPixelEffectIcon = (id: number) => export const GetPixelEffectIcon = (id: number) =>
{ {
return ''; return '';
} };
export const GetSubscriptionProductIcon = (id: number) => export const GetSubscriptionProductIcon = (id: number) =>
{ {
return ''; return '';
} };
export const GetOfferNodes = (offerNodes: Map<number, ICatalogNode[]>, offerId: number) => export const GetOfferNodes = (offerNodes: Map<number, ICatalogNode[]>, offerId: number) =>
{ {
@ -22,20 +21,20 @@ export const GetOfferNodes = (offerNodes: Map<number, ICatalogNode[]>, offerId:
for(const node of nodes) for(const node of nodes)
{ {
if(!node.isVisible) continue; if(!node.isVisible) continue;
allowedNodes.push(node); allowedNodes.push(node);
} }
} }
return allowedNodes; return allowedNodes;
} };
export const FilterCatalogNode = (search: string, furniLines: string[], node: ICatalogNode, nodes: ICatalogNode[]) => export const FilterCatalogNode = (search: string, furniLines: string[], node: ICatalogNode, nodes: ICatalogNode[]) =>
{ {
if(node.isVisible && (node.pageId > 0)) if(node.isVisible && (node.pageId > 0))
{ {
let nodeAdded = false; let nodeAdded = false;
const hayStack = [ node.pageName, node.localization ].join(' ').toLowerCase().replace(/ /gi, ''); const hayStack = [ node.pageName, node.localization ].join(' ').toLowerCase().replace(/ /gi, '');
if(hayStack.indexOf(search) > -1) if(hayStack.indexOf(search) > -1)
@ -60,7 +59,7 @@ export const FilterCatalogNode = (search: string, furniLines: string[], node: IC
} }
for(const child of node.children) FilterCatalogNode(search, furniLines, child, nodes); for(const child of node.children) FilterCatalogNode(search, furniLines, child, nodes);
} };
export function GetPetIndexFromLocalization(localization: string) export function GetPetIndexFromLocalization(localization: string)
{ {

View File

@ -1,5 +1,5 @@
import { GetProductOfferComposer, IFurnitureData } from '@nitrots/nitro-renderer'; import { GetProductOfferComposer, IFurnitureData } from '@nitrots/nitro-renderer';
import { GetProductDataForLocalization, SendMessageComposer } from '..'; import { GetProductDataForLocalization, SendMessageComposer } from '../nitro';
import { ICatalogPage } from './ICatalogPage'; import { ICatalogPage } from './ICatalogPage';
import { IProduct } from './IProduct'; import { IProduct } from './IProduct';
import { IPurchasableOffer } from './IPurchasableOffer'; import { IPurchasableOffer } from './IPurchasableOffer';

View File

@ -1,4 +1,4 @@
import { GetRoomEngine } from '../nitro'; import { GetRoomEngine } from '@nitrots/nitro-renderer';
import { ProductTypeEnum } from './ProductTypeEnum'; import { ProductTypeEnum } from './ProductTypeEnum';
export const GetImageIconUrlForProduct = (productType: string, productClassId: number, extraData: string = null) => export const GetImageIconUrlForProduct = (productType: string, productClassId: number, extraData: string = null) =>
@ -16,4 +16,4 @@ export const GetImageIconUrlForProduct = (productType: string, productClassId: n
} }
return imageUrl; return imageUrl;
} };

View File

@ -1,4 +1,4 @@
export interface ICatalogNode export interface ICatalogNode
{ {
activate(): void; activate(): void;
deactivate(): void; deactivate(): void;

View File

@ -1,4 +1,4 @@
export class MarketPlaceOfferState export class MarketPlaceOfferState
{ {
public static readonly ONGOING = 1; public static readonly ONGOING = 1;
public static readonly ONGOING_OWN = 1; public static readonly ONGOING_OWN = 1;

View File

@ -60,7 +60,7 @@ export class Offer implements IPurchasableOffer
public activate(): void public activate(): void
{ {
} }
public get clubLevel(): number public get clubLevel(): number
@ -228,7 +228,7 @@ export class Offer implements IPurchasableOffer
{ {
const products: IProduct[] = []; const products: IProduct[] = [];
const productData = GetProductDataForLocalization(this.localizationId); const productData = GetProductDataForLocalization(this.localizationId);
for(const product of this._products) for(const product of this._products)
{ {
const furnitureData = GetFurnitureData(product.productClassId, product.productType); const furnitureData = GetFurnitureData(product.productClassId, product.productType);

View File

@ -1,10 +1,10 @@
import { GetConfiguration } from '../nitro'; import { GetConfigurationValue } from '../nitro';
import { IPageLocalization } from './IPageLocalization'; import { IPageLocalization } from './IPageLocalization';
export class PageLocalization implements IPageLocalization export class PageLocalization implements IPageLocalization
{ {
private _images: string[]; private _images: string[];
private _texts: string[] private _texts: string[];
constructor(images: string[], texts: string[]) constructor(images: string[], texts: string[])
{ {
@ -27,7 +27,7 @@ export class PageLocalization implements IPageLocalization
if(!imageName || !imageName.length) return null; if(!imageName || !imageName.length) return null;
let assetUrl = GetConfiguration<string>('catalog.asset.image.url'); let assetUrl = GetConfigurationValue<string>('catalog.asset.image.url');
assetUrl = assetUrl.replace('%name%', imageName); assetUrl = assetUrl.replace('%name%', imageName);

View File

@ -11,7 +11,7 @@ export class PlacedObjectPurchaseData
public readonly x: number, public readonly x: number,
public readonly y: number, public readonly y: number,
public readonly direction: number, public readonly direction: number,
public readonly offer: IPurchasableOffer) public readonly offer: IPurchasableOffer)
{} {}
public get offerId(): number public get offerId(): number

View File

@ -1,5 +1,5 @@
import { IFurnitureData, IObjectData, IProductData } from '@nitrots/nitro-renderer'; import { GetRoomEngine, GetSessionDataManager, IFurnitureData, IObjectData, IProductData } from '@nitrots/nitro-renderer';
import { GetConfiguration, GetRoomEngine, GetSessionDataManager } from '../nitro'; import { GetConfigurationValue } from '../nitro';
import { GetPixelEffectIcon, GetSubscriptionProductIcon } from './CatalogUtilities'; import { GetPixelEffectIcon, GetSubscriptionProductIcon } from './CatalogUtilities';
import { IProduct } from './IProduct'; import { IProduct } from './IProduct';
import { IPurchasableOffer } from './IPurchasableOffer'; import { IPurchasableOffer } from './IPurchasableOffer';
@ -65,7 +65,7 @@ export class Product implements IProduct
if(iconName !== '') if(iconName !== '')
{ {
const assetUrl = GetConfiguration<string>('catalog.asset.url'); const assetUrl = GetConfigurationValue<string>('catalog.asset.url');
return `${ assetUrl }/${ iconName }.png`; return `${ assetUrl }/${ iconName }.png`;
} }

View File

@ -1,4 +1,4 @@
export class RequestedPage export class RequestedPage
{ {
public static REQUEST_TYPE_NONE: number = 0; public static REQUEST_TYPE_NONE: number = 0;
public static REQUEST_TYPE_ID: number = 1; public static REQUEST_TYPE_ID: number = 1;

View File

@ -6,6 +6,6 @@ export class SearchResult
constructor( constructor(
public readonly searchValue: string, public readonly searchValue: string,
public readonly offers: IPurchasableOffer[], public readonly offers: IPurchasableOffer[],
public readonly filteredNodes: ICatalogNode[]) public readonly filteredNodes: ICatalogNode[])
{} {}
} }

View File

@ -3,4 +3,4 @@ export const ChatHistoryCurrentDate = () =>
const currentTime = new Date(); const currentTime = new Date();
return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`; return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`;
} };

View File

@ -1,6 +1,6 @@
export const MessengerHistoryCurrentDate = (secondsSinceNow: number = 0) => export const MessengerHistoryCurrentDate = (secondsSinceNow: number = 0) =>
{ {
const currentTime = secondsSinceNow ? new Date(Date.now() - secondsSinceNow * 1000) : new Date(); const currentTime = secondsSinceNow ? new Date(Date.now() - secondsSinceNow * 1000) : new Date();
return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`; return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`;
} };

View File

@ -1,5 +1,4 @@
import { NitroEvent } from '@nitrots/nitro-renderer'; import { GetEventDispatcher, NitroEvent } from '@nitrots/nitro-renderer';
import { GetNitroInstance } from '../nitro';
import { DispatchEvent } from './DispatchEvent'; import { DispatchEvent } from './DispatchEvent';
export const DispatchMainEvent = (event: NitroEvent) => DispatchEvent(GetNitroInstance().events, event); export const DispatchMainEvent = (event: NitroEvent) => DispatchEvent(GetEventDispatcher(), event);

View File

@ -3,11 +3,11 @@ import { IGroupChatData } from './IGroupChatData';
export const GetGroupChatData = (extraData: string) => export const GetGroupChatData = (extraData: string) =>
{ {
if(!extraData || !extraData.length) return null; if(!extraData || !extraData.length) return null;
const splitData = extraData.split('/'); const splitData = extraData.split('/');
const username = splitData[0]; const username = splitData[0];
const figure = splitData[1]; const figure = splitData[1];
const userId = parseInt(splitData[2]); const userId = parseInt(splitData[2]);
return ({ username: username, figure: figure, userId: userId } as IGroupChatData); return ({ username: username, figure: figure, userId: userId } as IGroupChatData);
} };

View File

@ -6,6 +6,6 @@ export class MessengerSettings
public userFriendLimit: number = 0, public userFriendLimit: number = 0,
public normalFriendLimit: number = 0, public normalFriendLimit: number = 0,
public extendedFriendLimit: number = 0, public extendedFriendLimit: number = 0,
public categories: FriendCategoryData[] = []) public categories: FriendCategoryData[] = [])
{} {}
} }

View File

@ -40,7 +40,7 @@ export class MessengerThread
group.addChat(chat); group.addChat(chat);
this._lastUpdated = new Date(); this._lastUpdated = new Date();
this._unreadCount++; this._unreadCount++;
return chat; return chat;

View File

@ -1,4 +1,4 @@
import { CreateLinkEvent } from '..'; import { CreateLinkEvent } from '@nitrots/nitro-renderer';
export function OpenMessengerChat(friendId: number = 0): void export function OpenMessengerChat(friendId: number = 0): void
{ {

View File

@ -1,5 +1,5 @@
import { GroupInformationComposer } from '@nitrots/nitro-renderer'; import { GroupInformationComposer } from '@nitrots/nitro-renderer';
import { SendMessageComposer } from '..'; import { SendMessageComposer } from '../nitro';
export function GetGroupInformation(groupId: number): void export function GetGroupInformation(groupId: number): void
{ {

View File

@ -1,4 +1,4 @@
import { CreateLinkEvent } from '..'; import { CreateLinkEvent } from '@nitrots/nitro-renderer';
export function GetGroupManager(groupId: number): void export function GetGroupManager(groupId: number): void
{ {

View File

@ -1,4 +1,4 @@
import { CreateLinkEvent } from '..'; import { CreateLinkEvent } from '@nitrots/nitro-renderer';
export function GetGroupMembers(groupId: number, levelId?: number): void export function GetGroupMembers(groupId: number, levelId?: number): void
{ {

View File

@ -1,4 +1,3 @@
export class GroupBadgePart export class GroupBadgePart
{ {
public static BASE: string = 'b'; public static BASE: string = 'b';
@ -20,7 +19,7 @@ export class GroupBadgePart
public get code(): string public get code(): string
{ {
if((this.key === 0) && (this.type !== GroupBadgePart.BASE)) return null; if((this.key === 0) && (this.type !== GroupBadgePart.BASE)) return null;
return GroupBadgePart.getCode(this.type, this.key, this.color, this.position); return GroupBadgePart.getCode(this.type, this.key, this.color, this.position);
} }

View File

@ -1,4 +1,4 @@
export class GroupType export class GroupType
{ {
public static REGULAR: number = 0; public static REGULAR: number = 0;
public static EXCLUSIVE: number = 1; public static EXCLUSIVE: number = 1;

View File

@ -1,7 +1,7 @@
import { GroupFavoriteComposer, GroupUnfavoriteComposer, HabboGroupEntryData } from '@nitrots/nitro-renderer'; import { GroupFavoriteComposer, GroupUnfavoriteComposer, HabboGroupEntryData } from '@nitrots/nitro-renderer';
import { SendMessageComposer } from '..'; import { SendMessageComposer } from '../nitro';
export const ToggleFavoriteGroup = (group: HabboGroupEntryData) => export const ToggleFavoriteGroup = (group: HabboGroupEntryData) =>
{ {
SendMessageComposer(group.favourite ? new GroupUnfavoriteComposer(group.groupId) : new GroupFavoriteComposer(group.groupId)); SendMessageComposer(group.favourite ? new GroupUnfavoriteComposer(group.groupId) : new GroupFavoriteComposer(group.groupId));
} };

View File

@ -1,4 +1,4 @@
import { GroupJoinComposer } from '@nitrots/nitro-renderer'; import { GroupJoinComposer } from '@nitrots/nitro-renderer';
import { SendMessageComposer } from '..'; import { SendMessageComposer } from '../nitro';
export const TryJoinGroup = (groupId: number) => SendMessageComposer(new GroupJoinComposer(groupId)); export const TryJoinGroup = (groupId: number) => SendMessageComposer(new GroupJoinComposer(groupId));

View File

@ -2,7 +2,7 @@ export class GuideToolMessage
{ {
private _message: string; private _message: string;
private _roomId: number; private _roomId: number;
constructor(message: string, roomId?: number) constructor(message: string, roomId?: number)
{ {
this._message = message; this._message = message;

View File

@ -1,4 +1,4 @@
export class ClubStatus export class ClubStatus
{ {
public static ACTIVE: string = 'active'; public static ACTIVE: string = 'active';
public static NONE: string = 'none'; public static NONE: string = 'none';

View File

@ -8,4 +8,4 @@ export const GetClubBadge = (badgeCodes: string[]) =>
BADGES.forEach(badge => ((badgeCodes.indexOf(badge) > -1) && (badgeCode = badge))); BADGES.forEach(badge => ((badgeCodes.indexOf(badge) > -1) && (badgeCode = badge)));
return (badgeCode || DEFAULT_BADGE); return (badgeCode || DEFAULT_BADGE);
} };

View File

@ -5,4 +5,4 @@ export const GetCloseReasonKey = (code: number) =>
if(code === 2) return 'abusive'; if(code === 2) return 'abusive';
return 'resolved'; return 'resolved';
} };

View File

@ -1,3 +1,5 @@
export * from './GetRendererVersion';
export * from './GetUIVersion';
export * from './achievements'; export * from './achievements';
export * from './avatar'; export * from './avatar';
export * from './camera'; export * from './camera';
@ -6,8 +8,6 @@ export * from './catalog';
export * from './chat-history'; export * from './chat-history';
export * from './events'; export * from './events';
export * from './friends'; export * from './friends';
export * from './GetRendererVersion';
export * from './GetUIVersion';
export * from './groups'; export * from './groups';
export * from './guide-tool'; export * from './guide-tool';
export * from './hc-center'; export * from './hc-center';
@ -16,14 +16,13 @@ export * from './inventory';
export * from './mod-tools'; export * from './mod-tools';
export * from './navigator'; export * from './navigator';
export * from './nitro'; export * from './nitro';
export * from './nitro/avatar';
export * from './nitro/camera';
export * from './nitro/core';
export * from './nitro/room'; export * from './nitro/room';
export * from './nitro/session'; export * from './nitro/session';
export * from './notification'; export * from './notification';
export * from './purse'; export * from './purse';
export * from './room'; export * from './room';
export * from './room/events';
export * from './room/widgets';
export * from './user'; export * from './user';
export * from './utils'; export * from './utils';
export * from './wired'; export * from './wired';

View File

@ -29,7 +29,7 @@ export class FurnitureItem implements IFurnitureItem
constructor(parser: IFurnitureItemData) constructor(parser: IFurnitureItemData)
{ {
if(!parser) return; if(!parser) return;
this._locked = false; this._locked = false;
this._id = parser.itemId; this._id = parser.itemId;
this._type = parser.spriteId; this._type = parser.spriteId;

View File

@ -1,5 +1,4 @@
import { FurnitureListItemParser, IObjectData } from '@nitrots/nitro-renderer'; import { FurnitureListItemParser, GetRoomEngine, IObjectData } from '@nitrots/nitro-renderer';
import { GetRoomEngine } from '../nitro';
import { FurniCategory } from './FurniCategory'; import { FurniCategory } from './FurniCategory';
import { FurnitureItem } from './FurnitureItem'; import { FurnitureItem } from './FurnitureItem';
import { GroupItem } from './GroupItem'; import { GroupItem } from './GroupItem';
@ -36,7 +35,7 @@ const addSingleFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: b
} }
return groupItem; return groupItem;
} };
const addGroupableFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: boolean) => const addGroupableFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: boolean) =>
{ {
@ -86,7 +85,7 @@ const addGroupableFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen
const index = set.indexOf(existingGroup); const index = set.indexOf(existingGroup);
if(index >= 0) set.splice(index, 1); if(index >= 0) set.splice(index, 1);
set.unshift(existingGroup); set.unshift(existingGroup);
} }
@ -109,7 +108,7 @@ const addGroupableFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen
} }
return existingGroup; return existingGroup;
} };
export const addFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: boolean) => export const addFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: boolean) =>
{ {
@ -121,7 +120,7 @@ export const addFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen:
{ {
addGroupableFurnitureItem(set, item, unseen); addGroupableFurnitureItem(set, item, unseen);
} }
} };
export const mergeFurniFragments = (fragment: Map<number, FurnitureListItemParser>, totalFragments: number, fragmentNumber: number, fragments: Map<number, FurnitureListItemParser>[]) => export const mergeFurniFragments = (fragment: Map<number, FurnitureListItemParser>, totalFragments: number, fragmentNumber: number, fragments: Map<number, FurnitureListItemParser>[]) =>
{ {
@ -146,7 +145,7 @@ export const mergeFurniFragments = (fragment: Map<number, FurnitureListItemParse
fragments = null; fragments = null;
return merged; return merged;
} };
export const getAllItemIds = (groupItems: GroupItem[]) => export const getAllItemIds = (groupItems: GroupItem[]) =>
{ {
@ -169,4 +168,4 @@ export const getAllItemIds = (groupItems: GroupItem[]) =>
} }
return itemIds; return itemIds;
} };

View File

@ -1,5 +1,5 @@
import { FurniturePlacePaintComposer, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType } from '@nitrots/nitro-renderer'; import { CreateLinkEvent, FurniturePlacePaintComposer, GetRoomEngine, GetRoomSessionManager, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType } from '@nitrots/nitro-renderer';
import { CreateLinkEvent, GetRoomEngine, GetRoomSessionManager, SendMessageComposer } from '../nitro'; import { SendMessageComposer } from '../nitro';
import { FurniCategory } from './FurniCategory'; import { FurniCategory } from './FurniCategory';
import { GroupItem } from './GroupItem'; import { GroupItem } from './GroupItem';
import { IBotItem } from './IBotItem'; import { IBotItem } from './IBotItem';
@ -19,12 +19,12 @@ export const setPlacingItemId = (id: number) => (itemIdInPlacing = id);
export const cancelRoomObjectPlacement = () => export const cancelRoomObjectPlacement = () =>
{ {
if(getPlacingItemId() === -1) return; if(getPlacingItemId() === -1) return;
GetRoomEngine().cancelRoomObjectPlacement(); GetRoomEngine().cancelRoomObjectPlacement();
setPlacingItemId(-1); setPlacingItemId(-1);
setObjectMoverRequested(false); setObjectMoverRequested(false);
} };
export const attemptPetPlacement = (petItem: IPetItem, flag: boolean = false) => export const attemptPetPlacement = (petItem: IPetItem, flag: boolean = false) =>
{ {
@ -47,7 +47,7 @@ export const attemptPetPlacement = (petItem: IPetItem, flag: boolean = false) =>
} }
return true; return true;
} };
export const attemptItemPlacement = (groupItem: GroupItem, flag: boolean = false) => export const attemptItemPlacement = (groupItem: GroupItem, flag: boolean = false) =>
{ {
@ -92,7 +92,7 @@ export const attemptItemPlacement = (groupItem: GroupItem, flag: boolean = false
} }
return true; return true;
} };
export const attemptBotPlacement = (botItem: IBotItem, flag: boolean = false) => export const attemptBotPlacement = (botItem: IBotItem, flag: boolean = false) =>
@ -114,4 +114,4 @@ export const attemptBotPlacement = (botItem: IBotItem, flag: boolean = false) =>
} }
return true; return true;
} };

View File

@ -1,7 +1,6 @@
import { PetData } from '@nitrots/nitro-renderer'; import { CreateLinkEvent, PetData } from '@nitrots/nitro-renderer';
import { CreateLinkEvent } from '../nitro';
import { cancelRoomObjectPlacement, getPlacingItemId } from './InventoryUtilities';
import { IPetItem } from './IPetItem'; import { IPetItem } from './IPetItem';
import { cancelRoomObjectPlacement, getPlacingItemId } from './InventoryUtilities';
import { UnseenItemCategory } from './UnseenItemCategory'; import { UnseenItemCategory } from './UnseenItemCategory';
export const getAllPetIds = (petItems: IPetItem[]) => petItems.map(item => item.petData.id); export const getAllPetIds = (petItems: IPetItem[]) => petItems.map(item => item.petData.id);
@ -13,7 +12,7 @@ export const addSinglePetItem = (petData: PetData, set: IPetItem[], unseen: bool
if(unseen) if(unseen)
{ {
//petItem.isUnseen = true; //petItem.isUnseen = true;
set.unshift(petItem); set.unshift(petItem);
} }
else else
@ -22,7 +21,7 @@ export const addSinglePetItem = (petData: PetData, set: IPetItem[], unseen: bool
} }
return petItem; return petItem;
} };
export const removePetItemById = (id: number, set: IPetItem[]) => export const removePetItemById = (id: number, set: IPetItem[]) =>
{ {
@ -40,7 +39,7 @@ export const removePetItemById = (id: number, set: IPetItem[]) =>
CreateLinkEvent('inventory/open'); CreateLinkEvent('inventory/open');
} }
set.splice(index, 1); set.splice(index, 1);
return petItem; return petItem;
@ -50,7 +49,7 @@ export const removePetItemById = (id: number, set: IPetItem[]) =>
} }
return null; return null;
} };
export const processPetFragment = (set: IPetItem[], fragment: Map<number, PetData>, isUnseen: (category: number, itemId: number) => boolean) => export const processPetFragment = (set: IPetItem[], fragment: Map<number, PetData>, isUnseen: (category: number, itemId: number) => boolean) =>
{ {
@ -76,7 +75,7 @@ export const processPetFragment = (set: IPetItem[], fragment: Map<number, PetDat
} }
return set; return set;
} };
export const mergePetFragments = (fragment: Map<number, PetData>, totalFragments: number, fragmentNumber: number, fragments: Map<number, PetData>[]) => export const mergePetFragments = (fragment: Map<number, PetData>, totalFragments: number, fragmentNumber: number, fragments: Map<number, PetData>[]) =>
{ {
@ -101,4 +100,4 @@ export const mergePetFragments = (fragment: Map<number, PetData>, totalFragments
fragments = null; fragments = null;
return merged; return merged;
} };

View File

@ -10,6 +10,6 @@ export class TradeUserData
public itemCount: number = 0, public itemCount: number = 0,
public creditsCount: number = 0, public creditsCount: number = 0,
public accepts: boolean = false, public accepts: boolean = false,
public canTrade: boolean = false) public canTrade: boolean = false)
{} {}
} }

View File

@ -1,5 +1,4 @@
import { AdvancedMap, IObjectData, ItemDataStructure, StringDataType } from '@nitrots/nitro-renderer'; import { AdvancedMap, GetSessionDataManager, IObjectData, ItemDataStructure, StringDataType } from '@nitrots/nitro-renderer';
import { GetSessionDataManager } from '../nitro';
import { FurniCategory } from './FurniCategory'; import { FurniCategory } from './FurniCategory';
import { FurnitureItem } from './FurnitureItem'; import { FurnitureItem } from './FurnitureItem';
import { createGroupItem } from './FurnitureUtilities'; import { createGroupItem } from './FurnitureUtilities';
@ -18,39 +17,39 @@ export const parseTradeItems = (items: ItemDataStructure[]) =>
{ {
const spriteId = item.spriteId; const spriteId = item.spriteId;
const category = item.category; const category = item.category;
let name = (item.furniType + spriteId); let name = (item.furniType + spriteId);
if(!item.isGroupable || isExternalImage(spriteId)) if(!item.isGroupable || isExternalImage(spriteId))
{ {
name = ('itemid' + item.itemId); name = ('itemid' + item.itemId);
} }
if(item.category === FurniCategory.POSTER) if(item.category === FurniCategory.POSTER)
{ {
name = (item.itemId + 'poster' + item.stuffData.getLegacyString()); name = (item.itemId + 'poster' + item.stuffData.getLegacyString());
} }
else if(item.category === FurniCategory.GUILD_FURNI) else if(item.category === FurniCategory.GUILD_FURNI)
{ {
name = ''; name = '';
} }
let groupItem = ((item.isGroupable && !isExternalImage(item.spriteId)) ? existingItems.getValue(name) : null); let groupItem = ((item.isGroupable && !isExternalImage(item.spriteId)) ? existingItems.getValue(name) : null);
if(!groupItem) if(!groupItem)
{ {
groupItem = createGroupItem(spriteId, category, item.stuffData); groupItem = createGroupItem(spriteId, category, item.stuffData);
existingItems.add(name, groupItem); existingItems.add(name, groupItem);
} }
groupItem.push(new FurnitureItem(item)); groupItem.push(new FurnitureItem(item));
} }
} }
return existingItems; return existingItems;
} };
export const getGuildFurniType = (spriteId: number, stuffData: IObjectData) => export const getGuildFurniType = (spriteId: number, stuffData: IObjectData) =>
{ {
@ -68,4 +67,4 @@ export const getGuildFurniType = (spriteId: number, stuffData: IObjectData) =>
} }
return type; return type;
} };

View File

@ -4,9 +4,9 @@ export * from './FurnitureUtilities';
export * from './GroupItem'; export * from './GroupItem';
export * from './IBotItem'; export * from './IBotItem';
export * from './IFurnitureItem'; export * from './IFurnitureItem';
export * from './InventoryUtilities';
export * from './IPetItem'; export * from './IPetItem';
export * from './IUnseenItemTracker'; export * from './IUnseenItemTracker';
export * from './InventoryUtilities';
export * from './PetUtilities'; export * from './PetUtilities';
export * from './TradeState'; export * from './TradeState';
export * from './TradeUserData'; export * from './TradeUserData';

View File

@ -32,4 +32,4 @@ export const GetIssueCategoryName = (categoryId: number) =>
} }
return 'Unknown'; return 'Unknown';
} };

View File

@ -5,6 +5,6 @@ const BuildMaxVisitorsList = () =>
for(let i = 10; i <= 100; i = i + 10) list.push(i); for(let i = 10; i <= 100; i = i + 10) list.push(i);
return list; return list;
} };
export const GetMaxVisitorsList = BuildMaxVisitorsList(); export const GetMaxVisitorsList = BuildMaxVisitorsList();

View File

@ -1,7 +0,0 @@
import { ILinkEventTracker } from '@nitrots/nitro-renderer';
import { GetNitroInstance } from './GetNitroInstance';
export function AddEventLinkTracker(tracker: ILinkEventTracker): void
{
GetNitroInstance().addLinkEventTracker(tracker);
}

View File

@ -1,8 +0,0 @@
import { GetNitroInstance } from './GetNitroInstance';
export function CreateLinkEvent(link: string): void
{
link = (link.startsWith('event:') ? link.substring(6) : link);
GetNitroInstance().createLinkEvent(link);
}

View File

@ -1,7 +0,0 @@
import { INitroCommunicationManager } from '@nitrots/nitro-renderer';
import { GetNitroInstance } from './GetNitroInstance';
export function GetCommunication(): INitroCommunicationManager
{
return GetNitroInstance()?.communication;
}

View File

@ -1,6 +0,0 @@
import { NitroConfiguration } from '@nitrots/nitro-renderer';
export function GetConfiguration<T>(key: string, value: T = null): T
{
return NitroConfiguration.getValue(key, value);
}

View File

@ -0,0 +1,6 @@
import { GetConfiguration } from '@nitrots/nitro-renderer';
export function GetConfigurationValue<T = string>(key: string, value: T = null): T
{
return GetConfiguration().getValue(key, value);
}

View File

@ -1,7 +0,0 @@
import { IConnection } from '@nitrots/nitro-renderer';
import { GetCommunication } from './GetCommunication';
export function GetConnection(): IConnection
{
return GetCommunication()?.connection;
}

View File

@ -1,7 +0,0 @@
import { INitroLocalizationManager } from '@nitrots/nitro-renderer';
import { GetNitroInstance } from './GetNitroInstance';
export function GetLocalization(): INitroLocalizationManager
{
return GetNitroInstance().localization;
}

View File

@ -1,6 +0,0 @@
import { INitro, Nitro } from '@nitrots/nitro-renderer';
export function GetNitroInstance(): INitro
{
return Nitro.instance;
}

View File

@ -1,10 +1,9 @@
import { HabboWebTools } from '@nitrots/nitro-renderer'; import { CreateLinkEvent, HabboWebTools } from '@nitrots/nitro-renderer';
import { CreateLinkEvent } from './CreateLinkEvent';
export const OpenUrl = (url: string) => export const OpenUrl = (url: string) =>
{ {
if(!url || !url.length) return; if(!url || !url.length) return;
if(url.startsWith('http')) if(url.startsWith('http'))
{ {
HabboWebTools.openWebPage(url); HabboWebTools.openWebPage(url);
@ -13,4 +12,4 @@ export const OpenUrl = (url: string) =>
{ {
CreateLinkEvent(url); CreateLinkEvent(url);
} }
} };

View File

@ -1,7 +0,0 @@
import { ILinkEventTracker } from '@nitrots/nitro-renderer';
import { GetNitroInstance } from './GetNitroInstance';
export function RemoveLinkEventTracker(tracker: ILinkEventTracker): void
{
GetNitroInstance().removeLinkEventTracker(tracker);
}

View File

@ -1,4 +1,3 @@
import { IMessageComposer } from '@nitrots/nitro-renderer'; import { GetCommunication, IMessageComposer } from '@nitrots/nitro-renderer';
import { GetConnection } from './GetConnection';
export const SendMessageComposer = (event: IMessageComposer<unknown[]>) => GetConnection().send(event); export const SendMessageComposer = (event: IMessageComposer<unknown[]>) => GetCommunication().connection.send(event);

View File

@ -1,7 +0,0 @@
import { IPalette } from '@nitrots/nitro-renderer';
import { GetAvatarRenderManager } from './GetAvatarRenderManager';
export function GetAvatarPalette(paletteId: number): IPalette
{
return GetAvatarRenderManager().structureData.getPalette(paletteId);
}

View File

@ -1,7 +0,0 @@
import { IAvatarRenderManager } from '@nitrots/nitro-renderer';
import { GetNitroInstance } from '../GetNitroInstance';
export function GetAvatarRenderManager(): IAvatarRenderManager
{
return GetNitroInstance().avatar;
}

View File

@ -1,7 +0,0 @@
import { ISetType } from '@nitrots/nitro-renderer';
import { GetAvatarRenderManager } from './GetAvatarRenderManager';
export function GetAvatarSetType(setType: string): ISetType
{
return GetAvatarRenderManager().structureData.getSetType(setType);
}

View File

@ -1,3 +0,0 @@
export * from './GetAvatarPalette';
export * from './GetAvatarRenderManager';
export * from './GetAvatarSetType';

View File

@ -1,7 +0,0 @@
import { IRoomCameraWidgetManager } from '@nitrots/nitro-renderer';
import { GetNitroInstance } from '../GetNitroInstance';
export function GetRoomCameraWidgetManager(): IRoomCameraWidgetManager
{
return GetNitroInstance().cameraManager;
}

View File

@ -1 +0,0 @@
export * from './GetRoomCameraWidgetManager';

View File

@ -1,7 +0,0 @@
import { IConfigurationManager } from '@nitrots/nitro-renderer';
import { GetNitroCore } from './GetNitroCore';
export function GetConfigurationManager(): IConfigurationManager
{
return GetNitroCore().configuration;
}

View File

@ -1,7 +0,0 @@
import { INitroCore } from '@nitrots/nitro-renderer';
import { GetNitroInstance } from '..';
export function GetNitroCore(): INitroCore
{
return GetNitroInstance().core;
}

View File

@ -1,2 +0,0 @@
export * from './GetConfigurationManager';
export * from './GetNitroCore';

View File

@ -1,15 +1,5 @@
export * from './AddLinkEventTracker'; export * from './GetConfigurationValue';
export * from './avatar';
export * from './camera';
export * from './core';
export * from './CreateLinkEvent';
export * from './GetCommunication';
export * from './GetConfiguration';
export * from './GetConnection';
export * from './GetLocalization';
export * from './GetNitroInstance';
export * from './OpenUrl'; export * from './OpenUrl';
export * from './RemoveLinkEventTracker';
export * from './room';
export * from './SendMessageComposer'; export * from './SendMessageComposer';
export * from './room';
export * from './session'; export * from './session';

Some files were not shown because too many files have changed in this diff Show More