mirror of
https://github.com/duckietm/Nitro-Cool-UI.git
synced 2025-06-21 22:36:58 +00:00
✌️ V3 Startup
This commit is contained in:
parent
f52bff5bdb
commit
8edee0d5b4
110
.eslintrc.json
110
.eslintrc.json
@ -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
2
.gitignore
vendored
@ -27,3 +27,5 @@ Thumbs.db
|
||||
/build
|
||||
*.zip
|
||||
.env
|
||||
public/renderer-config*
|
||||
public/ui-config*
|
||||
|
@ -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
32
.vscode/settings.json
vendored
@ -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": "."
|
||||
}
|
32
README.md
32
README.md
@ -1,6 +1,4 @@
|
||||
# Nitro React v2.1
|
||||
|
||||
Credits: Thanks to Genaro on discord for this release!
|
||||
# v2.2.0 - Cool UI Beta !! Use at Own Risk as it is still in Beta !!
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@ -11,12 +9,16 @@ Credits: Thanks to Genaro on discord for this release!
|
||||
|
||||
## Installation
|
||||
|
||||
- First you should open terminal and navigate to the folder where you want to clone Nitro
|
||||
- Clone Nitro
|
||||
- `git clone https://github.com/duckietm/Nitro-Cool-UI.git`
|
||||
- Install the dependencies
|
||||
- First you should open terminal and navigate to the folder where you want to clone Nitro and Nitro-Renderer
|
||||
- Clone Nitro (Expl. C:\Github\)
|
||||
- `git clone https://github.com/duckietm/Nitro-Cool-UI.git` <== For now switch to Dev-RendererV2
|
||||
- `git clone https://github.com/duckietm/Nitro-Cool-UI-Renderer.git`
|
||||
- Install the dependencies for the renderer : cd C:\Github\Nitro-Cool-UI-Renderer
|
||||
- `yarn install`
|
||||
- This may take some time, please be patient
|
||||
- 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 `public/renderer-config.json.example` to `public/renderer-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`
|
||||
- Open `public/ui-config.json`
|
||||
- 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
|
||||
|
||||
- Make the following changes
|
||||
- ExternalTesxts.json
|
||||
`"room.mute.button.text": "Hide chat",`
|
||||
`"room.unmute.button.text": "Unhide chat",`
|
||||
|
||||
## Usage
|
||||
|
||||
- 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
|
||||
|
||||
@ -49,13 +48,8 @@ yarn start
|
||||
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
|
||||
- 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 !!
|
||||
|
73
css-utils/CSSColorUtils.js
Normal file
73
css-utils/CSSColorUtils.js
Normal 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
138
eslint.config.mjs
Normal 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",
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
74
index.html
74
index.html
@ -1,33 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" crossorigin="use-credentials" href="/site.webmanifest">
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#000000">
|
||||
<meta name="apple-mobile-web-app-title" content="Nitro">
|
||||
<meta name="application-name" content="Nitro">
|
||||
<meta name="msapplication-TileColor" content="#000000">
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="/apple-touch-icon.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="/favicon-32x32.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="/favicon-16x16.png"
|
||||
/>
|
||||
<link
|
||||
rel="manifest"
|
||||
crossorigin="use-credentials"
|
||||
href="/site.webmanifest"
|
||||
/>
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#000000" />
|
||||
<meta name="apple-mobile-web-app-title" content="Nitro" />
|
||||
<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="./">
|
||||
<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-100 h-100"></div>
|
||||
<div id="root" class="w-full h-full"></div>
|
||||
<script>
|
||||
const 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),
|
||||
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>
|
||||
|
70
package.json
70
package.json
@ -1,47 +1,49 @@
|
||||
{
|
||||
"name": "nitro-react",
|
||||
"version": "2.1.1",
|
||||
"version": "2.2",
|
||||
"homepage": ".",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "vite --base=/client/ --host",
|
||||
"build": "vite build --base=/client/",
|
||||
"preview": "vite preview --base=/client/ --host",
|
||||
"start": "vite --host",
|
||||
"build": "vite build",
|
||||
"build:prod": "npx browserslist@latest --update-db && yarn build",
|
||||
"eslint": "eslint src --ext .ts,.tsx"
|
||||
"eslint": "eslint ./src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emoji-mart/data": "^1.1.2",
|
||||
"@emoji-mart/react": "^1.1.1",
|
||||
"@nitrots/nitro-renderer": "file:submodules/renderer",
|
||||
"@tanstack/react-virtual": "^3.0.0-beta.60",
|
||||
"dompurify": "^3.0.11",
|
||||
"emoji-mart": "^5.5.2",
|
||||
"emoji-toolkit": "8.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.7.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^5.0.1",
|
||||
"react-slider": "^2.0.0",
|
||||
"@babel/runtime": "^7.26.9",
|
||||
"@tanstack/react-virtual": "3.2.0",
|
||||
"@types/react-transition-group": "^4.4.10",
|
||||
"dompurify": "^3.1.5",
|
||||
"framer-motion": "^11.2.12",
|
||||
"react": "^18.3.1",
|
||||
"react-bootstrap": "^2.10.9",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-icons": "^5.2.1",
|
||||
"react-slider": "^2.0.6",
|
||||
"react-tiny-popover": "^8.0.4",
|
||||
"react-youtube": "^7.13.1",
|
||||
"typescript": "^4.3.5",
|
||||
"use-between": "^1.3.4",
|
||||
"yarn": "^1.22.19"
|
||||
"use-between": "^1.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.15.3",
|
||||
"@types/react": "^18.0.28",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"@types/react-slider": "^1.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.55.0",
|
||||
"@typescript-eslint/parser": "^5.55.0",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"eslint": "^8.36.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||
"eslint-plugin-react": "^7.32.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"sass": "1.64.2",
|
||||
"vite": "^5.0.11"
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@types/node": "^20.11.30",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react-slider": "^1.3.6",
|
||||
"@typescript-eslint/eslint-plugin": "^7.13.1",
|
||||
"@typescript-eslint/parser": "^7.13.1",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"eslint": "^9.5.0",
|
||||
"eslint-plugin-react": "^7.34.2",
|
||||
"eslint-plugin-react-hooks": "^5.1.0-rc-1434af3d22-20240618",
|
||||
"postcss": "^8.4.38",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"sass": "^1.77.4",
|
||||
"tailwindcss": "^3.4.4",
|
||||
"typescript": "^5.4.5",
|
||||
"typescript-eslint": "^7.13.1",
|
||||
"vite": "^5.2.13",
|
||||
"vite-tsconfig-paths": "^4.3.2"
|
||||
}
|
||||
}
|
||||
|
8
postcss.config.js
Normal file
8
postcss.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
/** @type {import("postcss-load-config").Config} */
|
||||
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
}
|
@ -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
28
src/App.scss
28
src/App.scss
@ -21,26 +21,21 @@ $toolbar-height: 55px;
|
||||
$achievement-width: 375px;
|
||||
$achievement-height: 405px;
|
||||
|
||||
$avatar-editor-width: 520px;
|
||||
$avatar-editor-height: 553px;
|
||||
$avatar-editor-width: 620px;
|
||||
$avatar-editor-height: 374px;
|
||||
|
||||
$catalog-width: 650px;
|
||||
$catalog-height: 480px;
|
||||
$catalog-width: 630px;
|
||||
$catalog-height: 400px;
|
||||
|
||||
$inventory-width: 528px;
|
||||
$inventory-height: 370px;
|
||||
$inventory-height: 320px;
|
||||
|
||||
$navigator-width: 425px;
|
||||
$navigator-height: 560px;
|
||||
$navigator-min-height: 205px;
|
||||
|
||||
$nitro-room-creator-width: 585px;
|
||||
$nitro-room-creator-height: 365px;
|
||||
$navigator-width: 420px;
|
||||
$navigator-height: 440px;
|
||||
|
||||
$chat-input-style-selector-widget-width: 210px;
|
||||
$chat-input-style-selector-widget-height: 200px;
|
||||
|
||||
|
||||
$user-profile-width: 470px;
|
||||
$user-profile-height: 460px;
|
||||
|
||||
@ -65,17 +60,14 @@ $help-height: 290px;
|
||||
$nitropedia-width: 400px;
|
||||
$nitropedia-height: 400px;
|
||||
|
||||
$nitrobubblehidden-width: 400px;
|
||||
$nitrobubblehidden-height: 400px;
|
||||
|
||||
$messenger-width: 580px;
|
||||
$messenger-height: 455px;
|
||||
$messenger-width: 500px;
|
||||
$messenger-height: 370px;
|
||||
|
||||
$marketplace-post-offer-width: 430px;
|
||||
$marketplace-post-offer-height: 250px;
|
||||
|
||||
$camera-editor-width: 600px;
|
||||
$camera-editor-height: 540px;
|
||||
$camera-editor-height: 500px;
|
||||
|
||||
$camera-checkout-width: 350px;
|
||||
|
||||
|
209
src/App.tsx
209
src/App.tsx
@ -1,141 +1,104 @@
|
||||
import { ConfigurationEvent, GetAssetManager, HabboWebTools, LegacyExternalInterface, Nitro, NitroCommunicationDemoEvent, NitroConfiguration, NitroEvent, NitroLocalizationEvent, NitroVersion, RoomEngineEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetCommunication, GetConfiguration, GetNitroInstance, GetUIVersion } from './api';
|
||||
import { Base, TransitionAnimation, TransitionAnimationTypes } from './common';
|
||||
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, useEffect, useState } from 'react';
|
||||
import { GetUIVersion } from './api';
|
||||
import { MainView } from './components/MainView';
|
||||
import { LoadingView } from './components/loading/LoadingView';
|
||||
import { MainView } from './components/main/MainView';
|
||||
import { useConfigurationEvent, useLocalizationEvent, useMainEvent, useRoomEngineEvent } from './hooks';
|
||||
import { useMessageEvent } from './hooks';
|
||||
import { classNames } from './layout';
|
||||
|
||||
NitroVersion.UI_VERSION = GetUIVersion();
|
||||
|
||||
export const App: FC<{}> = props =>
|
||||
export const App: FC<{}> = (props) =>
|
||||
{
|
||||
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);
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
|
||||
if(!GetNitroInstance())
|
||||
useMessageEvent<LoadGameUrlEvent>(LoadGameUrlEvent, (event) =>
|
||||
{
|
||||
//@ts-ignore
|
||||
if(!NitroConfig) throw new Error('NitroConfig is not defined!');
|
||||
const parser = event.getParser();
|
||||
|
||||
Nitro.bootstrap();
|
||||
}
|
||||
if(!parser) return;
|
||||
|
||||
const handler = useCallback(async (event: NitroEvent) =>
|
||||
{
|
||||
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);
|
||||
LegacyExternalInterface.callGame('showGame', parser.url);
|
||||
});
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
GetNitroInstance().core.configuration.init();
|
||||
|
||||
const resize = (event: UIEvent) => setImageRendering(!(window.devicePixelRatio % 1));
|
||||
|
||||
window.addEventListener('resize', resize);
|
||||
|
||||
resize(null);
|
||||
|
||||
return () =>
|
||||
const prepare = async (width: number, height: number) =>
|
||||
{
|
||||
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 (
|
||||
<Base fit overflow="hidden" className={ imageRendering && 'image-rendering-pixelated' }>
|
||||
{ (!isReady || isError) &&
|
||||
<LoadingView isError={ isError } message={ message } percent={ percent } /> }
|
||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ (isReady) }>
|
||||
<MainView />
|
||||
</TransitionAnimation>
|
||||
<Base id="draggable-windows-container" />
|
||||
</Base>
|
||||
<div
|
||||
className={classNames( 'w-full h-full overflow-hidden text-base bg-black', !(window.devicePixelRatio % 1) && '[image-rendering:pixelated]')}>
|
||||
{!isReady && <LoadingView />}
|
||||
{isReady && <MainView />}
|
||||
<div id="draggable-windows-container" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -1 +1 @@
|
||||
export const GetUIVersion = () => '2.1.1';
|
||||
export const GetUIVersion = () => '2.2.0';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { AchievementData } from '@nitrots/nitro-renderer';
|
||||
import { GetConfiguration, GetLocalization } from '../nitro';
|
||||
import { AchievementData, GetLocalizationManager } from '@nitrots/nitro-renderer';
|
||||
import { GetConfigurationValue } from '../nitro';
|
||||
import { IAchievementCategory } from './IAchievementCategory';
|
||||
|
||||
export class AchievementUtilities
|
||||
@ -10,14 +10,14 @@ export class AchievementUtilities
|
||||
|
||||
let badgeId = achievement.badgeId;
|
||||
|
||||
if(!achievement.finalLevel) badgeId = GetLocalization().getPreviousLevelBadgeId(badgeId);
|
||||
if(!achievement.finalLevel) badgeId = GetLocalizationManager().getPreviousLevelBadgeId(badgeId);
|
||||
|
||||
return badgeId;
|
||||
}
|
||||
|
||||
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_';
|
||||
|
||||
@ -77,7 +77,7 @@ export class AchievementUtilities
|
||||
{
|
||||
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 index = ignored.indexOf(value);
|
||||
|
||||
|
17
src/api/avatar/AvatarEditorColorSorter.ts
Normal file
17
src/api/avatar/AvatarEditorColorSorter.ts
Normal 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;
|
||||
};
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
35
src/api/avatar/AvatarEditorPartSorter.ts
Normal file
35
src/api/avatar/AvatarEditorPartSorter.ts
Normal 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;
|
||||
};
|
||||
};
|
196
src/api/avatar/AvatarEditorThumbnailsHelper.ts
Normal file
196
src/api/avatar/AvatarEditorThumbnailsHelper.ts
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
9
src/api/avatar/IAvatarEditorCategory.ts
Normal file
9
src/api/avatar/IAvatarEditorCategory.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { IPartColor } from '@nitrots/nitro-renderer';
|
||||
import { IAvatarEditorCategoryPartItem } from './IAvatarEditorCategoryPartItem';
|
||||
|
||||
export interface IAvatarEditorCategory
|
||||
{
|
||||
setType: string;
|
||||
partItems: IAvatarEditorCategoryPartItem[];
|
||||
colorItems: IPartColor[][];
|
||||
}
|
@ -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;
|
||||
}
|
10
src/api/avatar/IAvatarEditorCategoryPartItem.ts
Normal file
10
src/api/avatar/IAvatarEditorCategoryPartItem.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { IFigurePartSet } from '@nitrots/nitro-renderer';
|
||||
|
||||
export interface IAvatarEditorCategoryPartItem
|
||||
{
|
||||
id?: number;
|
||||
partSet?: IFigurePartSet;
|
||||
usesColor?: boolean;
|
||||
maxPaletteCount?: number;
|
||||
isClear?: boolean;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -1,13 +1,6 @@
|
||||
export * from './AvatarEditorAction';
|
||||
export * from './AvatarEditorGridColorItem';
|
||||
export * from './AvatarEditorGridPartItem';
|
||||
export * from './AvatarEditorUtilities';
|
||||
export * from './BodyModel';
|
||||
export * from './CategoryBaseModel';
|
||||
export * from './CategoryData';
|
||||
export * from './FigureData';
|
||||
export * from './FigureGenerator';
|
||||
export * from './HeadModel';
|
||||
export * from './IAvatarEditorCategoryModel';
|
||||
export * from './LegModel';
|
||||
export * from './TorsoModel';
|
||||
export * from './AvatarEditorColorSorter';
|
||||
export * from './AvatarEditorPartSorter';
|
||||
export * from './AvatarEditorThumbnailsHelper';
|
||||
export * from './IAvatarEditorCategory';
|
||||
export * from './IAvatarEditorCategoryPartItem';
|
||||
|
@ -1,16 +1,15 @@
|
||||
import { SellablePetPaletteData } from '@nitrots/nitro-renderer';
|
||||
import { GetRoomEngine } from '../nitro';
|
||||
import { GetRoomEngine, SellablePetPaletteData } from '@nitrots/nitro-renderer';
|
||||
import { ICatalogNode } from './ICatalogNode';
|
||||
|
||||
export const GetPixelEffectIcon = (id: number) =>
|
||||
{
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
export const GetSubscriptionProductIcon = (id: number) =>
|
||||
{
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
export const GetOfferNodes = (offerNodes: Map<number, ICatalogNode[]>, offerId: number) =>
|
||||
{
|
||||
@ -28,7 +27,7 @@ export const GetOfferNodes = (offerNodes: Map<number, ICatalogNode[]>, offerId:
|
||||
}
|
||||
|
||||
return allowedNodes;
|
||||
}
|
||||
};
|
||||
|
||||
export const FilterCatalogNode = (search: string, furniLines: string[], node: ICatalogNode, nodes: ICatalogNode[]) =>
|
||||
{
|
||||
@ -60,7 +59,7 @@ export const FilterCatalogNode = (search: string, furniLines: string[], node: IC
|
||||
}
|
||||
|
||||
for(const child of node.children) FilterCatalogNode(search, furniLines, child, nodes);
|
||||
}
|
||||
};
|
||||
|
||||
export function GetPetIndexFromLocalization(localization: string)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { GetProductOfferComposer, IFurnitureData } from '@nitrots/nitro-renderer';
|
||||
import { GetProductDataForLocalization, SendMessageComposer } from '..';
|
||||
import { GetProductDataForLocalization, SendMessageComposer } from '../nitro';
|
||||
import { ICatalogPage } from './ICatalogPage';
|
||||
import { IProduct } from './IProduct';
|
||||
import { IPurchasableOffer } from './IPurchasableOffer';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { GetRoomEngine } from '../nitro';
|
||||
import { GetRoomEngine } from '@nitrots/nitro-renderer';
|
||||
import { ProductTypeEnum } from './ProductTypeEnum';
|
||||
|
||||
export const GetImageIconUrlForProduct = (productType: string, productClassId: number, extraData: string = null) =>
|
||||
@ -16,4 +16,4 @@ export const GetImageIconUrlForProduct = (productType: string, productClassId: n
|
||||
}
|
||||
|
||||
return imageUrl;
|
||||
}
|
||||
};
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { GetConfiguration } from '../nitro';
|
||||
import { GetConfigurationValue } from '../nitro';
|
||||
import { IPageLocalization } from './IPageLocalization';
|
||||
|
||||
export class PageLocalization implements IPageLocalization
|
||||
{
|
||||
private _images: string[];
|
||||
private _texts: string[]
|
||||
private _texts: string[];
|
||||
|
||||
constructor(images: string[], texts: string[])
|
||||
{
|
||||
@ -27,7 +27,7 @@ export class PageLocalization implements IPageLocalization
|
||||
|
||||
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);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { IFurnitureData, IObjectData, IProductData } from '@nitrots/nitro-renderer';
|
||||
import { GetConfiguration, GetRoomEngine, GetSessionDataManager } from '../nitro';
|
||||
import { GetRoomEngine, GetSessionDataManager, IFurnitureData, IObjectData, IProductData } from '@nitrots/nitro-renderer';
|
||||
import { GetConfigurationValue } from '../nitro';
|
||||
import { GetPixelEffectIcon, GetSubscriptionProductIcon } from './CatalogUtilities';
|
||||
import { IProduct } from './IProduct';
|
||||
import { IPurchasableOffer } from './IPurchasableOffer';
|
||||
@ -65,7 +65,7 @@ export class Product implements IProduct
|
||||
|
||||
if(iconName !== '')
|
||||
{
|
||||
const assetUrl = GetConfiguration<string>('catalog.asset.url');
|
||||
const assetUrl = GetConfigurationValue<string>('catalog.asset.url');
|
||||
|
||||
return `${ assetUrl }/${ iconName }.png`;
|
||||
}
|
||||
|
@ -3,4 +3,4 @@ export const ChatHistoryCurrentDate = () =>
|
||||
const currentTime = new Date();
|
||||
|
||||
return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`;
|
||||
}
|
||||
};
|
||||
|
@ -3,4 +3,4 @@ export const MessengerHistoryCurrentDate = (secondsSinceNow: number = 0) =>
|
||||
const currentTime = secondsSinceNow ? new Date(Date.now() - secondsSinceNow * 1000) : new Date();
|
||||
|
||||
return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
||||
import { GetNitroInstance } from '../nitro';
|
||||
import { GetEventDispatcher, NitroEvent } from '@nitrots/nitro-renderer';
|
||||
import { DispatchEvent } from './DispatchEvent';
|
||||
|
||||
export const DispatchMainEvent = (event: NitroEvent) => DispatchEvent(GetNitroInstance().events, event);
|
||||
export const DispatchMainEvent = (event: NitroEvent) => DispatchEvent(GetEventDispatcher(), event);
|
||||
|
@ -10,4 +10,4 @@ export const GetGroupChatData = (extraData: string) =>
|
||||
const userId = parseInt(splitData[2]);
|
||||
|
||||
return ({ username: username, figure: figure, userId: userId } as IGroupChatData);
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { CreateLinkEvent } from '..';
|
||||
import { CreateLinkEvent } from '@nitrots/nitro-renderer';
|
||||
|
||||
export function OpenMessengerChat(friendId: number = 0): void
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { GroupInformationComposer } from '@nitrots/nitro-renderer';
|
||||
import { SendMessageComposer } from '..';
|
||||
import { SendMessageComposer } from '../nitro';
|
||||
|
||||
export function GetGroupInformation(groupId: number): void
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { CreateLinkEvent } from '..';
|
||||
import { CreateLinkEvent } from '@nitrots/nitro-renderer';
|
||||
|
||||
export function GetGroupManager(groupId: number): void
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { CreateLinkEvent } from '..';
|
||||
import { CreateLinkEvent } from '@nitrots/nitro-renderer';
|
||||
|
||||
export function GetGroupMembers(groupId: number, levelId?: number): void
|
||||
{
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
export class GroupBadgePart
|
||||
{
|
||||
public static BASE: string = 'b';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { GroupFavoriteComposer, GroupUnfavoriteComposer, HabboGroupEntryData } from '@nitrots/nitro-renderer';
|
||||
import { SendMessageComposer } from '..';
|
||||
import { SendMessageComposer } from '../nitro';
|
||||
|
||||
export const ToggleFavoriteGroup = (group: HabboGroupEntryData) =>
|
||||
{
|
||||
SendMessageComposer(group.favourite ? new GroupUnfavoriteComposer(group.groupId) : new GroupFavoriteComposer(group.groupId));
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { GroupJoinComposer } from '@nitrots/nitro-renderer';
|
||||
import { SendMessageComposer } from '..';
|
||||
import { SendMessageComposer } from '../nitro';
|
||||
|
||||
export const TryJoinGroup = (groupId: number) => SendMessageComposer(new GroupJoinComposer(groupId));
|
||||
|
@ -8,4 +8,4 @@ export const GetClubBadge = (badgeCodes: string[]) =>
|
||||
BADGES.forEach(badge => ((badgeCodes.indexOf(badge) > -1) && (badgeCode = badge)));
|
||||
|
||||
return (badgeCode || DEFAULT_BADGE);
|
||||
}
|
||||
};
|
||||
|
@ -5,4 +5,4 @@ export const GetCloseReasonKey = (code: number) =>
|
||||
if(code === 2) return 'abusive';
|
||||
|
||||
return 'resolved';
|
||||
}
|
||||
};
|
||||
|
@ -1,3 +1,5 @@
|
||||
export * from './GetRendererVersion';
|
||||
export * from './GetUIVersion';
|
||||
export * from './achievements';
|
||||
export * from './avatar';
|
||||
export * from './camera';
|
||||
@ -6,8 +8,6 @@ export * from './catalog';
|
||||
export * from './chat-history';
|
||||
export * from './events';
|
||||
export * from './friends';
|
||||
export * from './GetRendererVersion';
|
||||
export * from './GetUIVersion';
|
||||
export * from './groups';
|
||||
export * from './guide-tool';
|
||||
export * from './hc-center';
|
||||
@ -16,14 +16,13 @@ export * from './inventory';
|
||||
export * from './mod-tools';
|
||||
export * from './navigator';
|
||||
export * from './nitro';
|
||||
export * from './nitro/avatar';
|
||||
export * from './nitro/camera';
|
||||
export * from './nitro/core';
|
||||
export * from './nitro/room';
|
||||
export * from './nitro/session';
|
||||
export * from './notification';
|
||||
export * from './purse';
|
||||
export * from './room';
|
||||
export * from './room/events';
|
||||
export * from './room/widgets';
|
||||
export * from './user';
|
||||
export * from './utils';
|
||||
export * from './wired';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { FurnitureListItemParser, IObjectData } from '@nitrots/nitro-renderer';
|
||||
import { GetRoomEngine } from '../nitro';
|
||||
import { FurnitureListItemParser, GetRoomEngine, IObjectData } from '@nitrots/nitro-renderer';
|
||||
import { FurniCategory } from './FurniCategory';
|
||||
import { FurnitureItem } from './FurnitureItem';
|
||||
import { GroupItem } from './GroupItem';
|
||||
@ -36,7 +35,7 @@ const addSingleFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: b
|
||||
}
|
||||
|
||||
return groupItem;
|
||||
}
|
||||
};
|
||||
|
||||
const addGroupableFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: boolean) =>
|
||||
{
|
||||
@ -109,7 +108,7 @@ const addGroupableFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen
|
||||
}
|
||||
|
||||
return existingGroup;
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
return merged;
|
||||
}
|
||||
};
|
||||
|
||||
export const getAllItemIds = (groupItems: GroupItem[]) =>
|
||||
{
|
||||
@ -169,4 +168,4 @@ export const getAllItemIds = (groupItems: GroupItem[]) =>
|
||||
}
|
||||
|
||||
return itemIds;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { FurniturePlacePaintComposer, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType } from '@nitrots/nitro-renderer';
|
||||
import { CreateLinkEvent, GetRoomEngine, GetRoomSessionManager, SendMessageComposer } from '../nitro';
|
||||
import { CreateLinkEvent, FurniturePlacePaintComposer, GetRoomEngine, GetRoomSessionManager, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType } from '@nitrots/nitro-renderer';
|
||||
import { SendMessageComposer } from '../nitro';
|
||||
import { FurniCategory } from './FurniCategory';
|
||||
import { GroupItem } from './GroupItem';
|
||||
import { IBotItem } from './IBotItem';
|
||||
@ -24,7 +24,7 @@ export const cancelRoomObjectPlacement = () =>
|
||||
|
||||
setPlacingItemId(-1);
|
||||
setObjectMoverRequested(false);
|
||||
}
|
||||
};
|
||||
|
||||
export const attemptPetPlacement = (petItem: IPetItem, flag: boolean = false) =>
|
||||
{
|
||||
@ -47,7 +47,7 @@ export const attemptPetPlacement = (petItem: IPetItem, flag: boolean = false) =>
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
export const attemptItemPlacement = (groupItem: GroupItem, flag: boolean = false) =>
|
||||
{
|
||||
@ -92,7 +92,7 @@ export const attemptItemPlacement = (groupItem: GroupItem, flag: boolean = false
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const attemptBotPlacement = (botItem: IBotItem, flag: boolean = false) =>
|
||||
@ -114,4 +114,4 @@ export const attemptBotPlacement = (botItem: IBotItem, flag: boolean = false) =>
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { PetData } from '@nitrots/nitro-renderer';
|
||||
import { CreateLinkEvent } from '../nitro';
|
||||
import { cancelRoomObjectPlacement, getPlacingItemId } from './InventoryUtilities';
|
||||
import { CreateLinkEvent, PetData } from '@nitrots/nitro-renderer';
|
||||
import { IPetItem } from './IPetItem';
|
||||
import { cancelRoomObjectPlacement, getPlacingItemId } from './InventoryUtilities';
|
||||
import { UnseenItemCategory } from './UnseenItemCategory';
|
||||
|
||||
export const getAllPetIds = (petItems: IPetItem[]) => petItems.map(item => item.petData.id);
|
||||
@ -22,7 +21,7 @@ export const addSinglePetItem = (petData: PetData, set: IPetItem[], unseen: bool
|
||||
}
|
||||
|
||||
return petItem;
|
||||
}
|
||||
};
|
||||
|
||||
export const removePetItemById = (id: number, set: IPetItem[]) =>
|
||||
{
|
||||
@ -50,7 +49,7 @@ export const removePetItemById = (id: number, set: IPetItem[]) =>
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
return merged;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { AdvancedMap, IObjectData, ItemDataStructure, StringDataType } from '@nitrots/nitro-renderer';
|
||||
import { GetSessionDataManager } from '../nitro';
|
||||
import { AdvancedMap, GetSessionDataManager, IObjectData, ItemDataStructure, StringDataType } from '@nitrots/nitro-renderer';
|
||||
import { FurniCategory } from './FurniCategory';
|
||||
import { FurnitureItem } from './FurnitureItem';
|
||||
import { createGroupItem } from './FurnitureUtilities';
|
||||
@ -50,7 +49,7 @@ export const parseTradeItems = (items: ItemDataStructure[]) =>
|
||||
}
|
||||
|
||||
return existingItems;
|
||||
}
|
||||
};
|
||||
|
||||
export const getGuildFurniType = (spriteId: number, stuffData: IObjectData) =>
|
||||
{
|
||||
@ -68,4 +67,4 @@ export const getGuildFurniType = (spriteId: number, stuffData: IObjectData) =>
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
};
|
||||
|
@ -4,9 +4,9 @@ export * from './FurnitureUtilities';
|
||||
export * from './GroupItem';
|
||||
export * from './IBotItem';
|
||||
export * from './IFurnitureItem';
|
||||
export * from './InventoryUtilities';
|
||||
export * from './IPetItem';
|
||||
export * from './IUnseenItemTracker';
|
||||
export * from './InventoryUtilities';
|
||||
export * from './PetUtilities';
|
||||
export * from './TradeState';
|
||||
export * from './TradeUserData';
|
||||
|
@ -32,4 +32,4 @@ export const GetIssueCategoryName = (categoryId: number) =>
|
||||
}
|
||||
|
||||
return 'Unknown';
|
||||
}
|
||||
};
|
||||
|
@ -5,6 +5,6 @@ const BuildMaxVisitorsList = () =>
|
||||
for(let i = 10; i <= 100; i = i + 10) list.push(i);
|
||||
|
||||
return list;
|
||||
}
|
||||
};
|
||||
|
||||
export const GetMaxVisitorsList = BuildMaxVisitorsList();
|
||||
|
@ -1,7 +0,0 @@
|
||||
import { ILinkEventTracker } from '@nitrots/nitro-renderer';
|
||||
import { GetNitroInstance } from './GetNitroInstance';
|
||||
|
||||
export function AddEventLinkTracker(tracker: ILinkEventTracker): void
|
||||
{
|
||||
GetNitroInstance().addLinkEventTracker(tracker);
|
||||
}
|
@ -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);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { INitroCommunicationManager } from '@nitrots/nitro-renderer';
|
||||
import { GetNitroInstance } from './GetNitroInstance';
|
||||
|
||||
export function GetCommunication(): INitroCommunicationManager
|
||||
{
|
||||
return GetNitroInstance()?.communication;
|
||||
}
|
@ -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);
|
||||
}
|
6
src/api/nitro/GetConfigurationValue.ts
Normal file
6
src/api/nitro/GetConfigurationValue.ts
Normal 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);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { IConnection } from '@nitrots/nitro-renderer';
|
||||
import { GetCommunication } from './GetCommunication';
|
||||
|
||||
export function GetConnection(): IConnection
|
||||
{
|
||||
return GetCommunication()?.connection;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { INitroLocalizationManager } from '@nitrots/nitro-renderer';
|
||||
import { GetNitroInstance } from './GetNitroInstance';
|
||||
|
||||
export function GetLocalization(): INitroLocalizationManager
|
||||
{
|
||||
return GetNitroInstance().localization;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import { INitro, Nitro } from '@nitrots/nitro-renderer';
|
||||
|
||||
export function GetNitroInstance(): INitro
|
||||
{
|
||||
return Nitro.instance;
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
import { HabboWebTools } from '@nitrots/nitro-renderer';
|
||||
import { CreateLinkEvent } from './CreateLinkEvent';
|
||||
import { CreateLinkEvent, HabboWebTools } from '@nitrots/nitro-renderer';
|
||||
|
||||
export const OpenUrl = (url: string) =>
|
||||
{
|
||||
@ -13,4 +12,4 @@ export const OpenUrl = (url: string) =>
|
||||
{
|
||||
CreateLinkEvent(url);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,7 +0,0 @@
|
||||
import { ILinkEventTracker } from '@nitrots/nitro-renderer';
|
||||
import { GetNitroInstance } from './GetNitroInstance';
|
||||
|
||||
export function RemoveLinkEventTracker(tracker: ILinkEventTracker): void
|
||||
{
|
||||
GetNitroInstance().removeLinkEventTracker(tracker);
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
import { IMessageComposer } from '@nitrots/nitro-renderer';
|
||||
import { GetConnection } from './GetConnection';
|
||||
import { GetCommunication, IMessageComposer } from '@nitrots/nitro-renderer';
|
||||
|
||||
export const SendMessageComposer = (event: IMessageComposer<unknown[]>) => GetConnection().send(event);
|
||||
export const SendMessageComposer = (event: IMessageComposer<unknown[]>) => GetCommunication().connection.send(event);
|
||||
|
@ -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);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { IAvatarRenderManager } from '@nitrots/nitro-renderer';
|
||||
import { GetNitroInstance } from '../GetNitroInstance';
|
||||
|
||||
export function GetAvatarRenderManager(): IAvatarRenderManager
|
||||
{
|
||||
return GetNitroInstance().avatar;
|
||||
}
|
@ -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);
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export * from './GetAvatarPalette';
|
||||
export * from './GetAvatarRenderManager';
|
||||
export * from './GetAvatarSetType';
|
@ -1,7 +0,0 @@
|
||||
import { IRoomCameraWidgetManager } from '@nitrots/nitro-renderer';
|
||||
import { GetNitroInstance } from '../GetNitroInstance';
|
||||
|
||||
export function GetRoomCameraWidgetManager(): IRoomCameraWidgetManager
|
||||
{
|
||||
return GetNitroInstance().cameraManager;
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './GetRoomCameraWidgetManager';
|
@ -1,7 +0,0 @@
|
||||
import { IConfigurationManager } from '@nitrots/nitro-renderer';
|
||||
import { GetNitroCore } from './GetNitroCore';
|
||||
|
||||
export function GetConfigurationManager(): IConfigurationManager
|
||||
{
|
||||
return GetNitroCore().configuration;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { INitroCore } from '@nitrots/nitro-renderer';
|
||||
import { GetNitroInstance } from '..';
|
||||
|
||||
export function GetNitroCore(): INitroCore
|
||||
{
|
||||
return GetNitroInstance().core;
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
export * from './GetConfigurationManager';
|
||||
export * from './GetNitroCore';
|
@ -1,15 +1,5 @@
|
||||
export * from './AddLinkEventTracker';
|
||||
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 './GetConfigurationValue';
|
||||
export * from './OpenUrl';
|
||||
export * from './RemoveLinkEventTracker';
|
||||
export * from './room';
|
||||
export * from './SendMessageComposer';
|
||||
export * from './room';
|
||||
export * from './session';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { MouseEventType } from '@nitrots/nitro-renderer';
|
||||
import { GetRoomEngine } from './GetRoomEngine';
|
||||
import { GetRoomEngine, MouseEventType } from '@nitrots/nitro-renderer';
|
||||
|
||||
let didMouseMove = false;
|
||||
let lastClick = 0;
|
||||
@ -52,4 +51,4 @@ export const DispatchMouseEvent = (event: MouseEvent, canvasId: number = 1) =>
|
||||
}
|
||||
|
||||
GetRoomEngine().dispatchMouseEvent(canvasId, x, y, eventType, event.altKey, (event.ctrlKey || event.metaKey), event.shiftKey, false);
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { MouseEventType, TouchEventType } from '@nitrots/nitro-renderer';
|
||||
import { GetRoomEngine } from './GetRoomEngine';
|
||||
import { GetRoomEngine, MouseEventType, TouchEventType } from '@nitrots/nitro-renderer';
|
||||
|
||||
let didMouseMove = false;
|
||||
let lastClick = 0;
|
||||
@ -73,10 +72,10 @@ export const DispatchTouchEvent = (event: TouchEvent, canvasId: number = 1, long
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (eventType === TouchEventType.TOUCH_START)
|
||||
if(eventType === TouchEventType.TOUCH_START)
|
||||
{
|
||||
GetRoomEngine().dispatchMouseEvent(canvasId, x, y, eventType, altKey, ctrlKey, shiftKey, false);
|
||||
}
|
||||
|
||||
GetRoomEngine().dispatchMouseEvent(canvasId, x, y, eventType, altKey, ctrlKey, shiftKey, false);
|
||||
}
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { IRoomObjectController, RoomObjectCategory } from '@nitrots/nitro-renderer';
|
||||
import { GetRoomSession, GetSessionDataManager } from '../session';
|
||||
import { GetRoomEngine } from './GetRoomEngine';
|
||||
import { GetRoomEngine, GetSessionDataManager, IRoomObjectController, RoomObjectCategory } from '@nitrots/nitro-renderer';
|
||||
import { GetRoomSession } from '../session';
|
||||
|
||||
export function GetOwnRoomObject(): IRoomObjectController
|
||||
{
|
||||
|
@ -1,7 +0,0 @@
|
||||
import { IRoomEngine } from '@nitrots/nitro-renderer';
|
||||
import { GetNitroInstance } from '../GetNitroInstance';
|
||||
|
||||
export function GetRoomEngine(): IRoomEngine
|
||||
{
|
||||
return GetNitroInstance().roomEngine;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { GetRoomEngine } from './GetRoomEngine';
|
||||
import { GetRoomEngine } from '@nitrots/nitro-renderer';
|
||||
|
||||
export const GetRoomObjectBounds = (roomId: number, objectId: number, category: number, canvasId = 1) =>
|
||||
{
|
||||
@ -10,4 +10,4 @@ export const GetRoomObjectBounds = (roomId: number, objectId: number, category:
|
||||
rectangle.y = Math.round(rectangle.y);
|
||||
|
||||
return rectangle;
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { GetRoomEngine } from './GetRoomEngine';
|
||||
import { GetRoomEngine } from '@nitrots/nitro-renderer';
|
||||
|
||||
export const GetRoomObjectScreenLocation = (roomId: number, objectId: number, category: number, canvasId = 1) =>
|
||||
{
|
||||
@ -10,4 +10,4 @@ export const GetRoomObjectScreenLocation = (roomId: number, objectId: number, ca
|
||||
point.y = Math.round(point.y);
|
||||
|
||||
return point;
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { GetRoomEngine } from './GetRoomEngine';
|
||||
import { GetRoomEngine } from '@nitrots/nitro-renderer';
|
||||
|
||||
export const InitializeRoomInstanceRenderingCanvas = (width: number, height: number, canvasId: number = 1) =>
|
||||
{
|
||||
@ -6,4 +6,4 @@ export const InitializeRoomInstanceRenderingCanvas = (width: number, height: num
|
||||
const roomId = roomEngine.activeRoomId;
|
||||
|
||||
roomEngine.initializeRoomInstanceRenderingCanvas(roomId, canvasId, width, height);
|
||||
}
|
||||
};
|
||||
|
@ -1,6 +1,4 @@
|
||||
import { RoomEngineObjectEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
||||
import { GetSessionDataManager } from '../..';
|
||||
import { GetRoomEngine } from './GetRoomEngine';
|
||||
import { GetRoomEngine, GetSessionDataManager, RoomEngineObjectEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
||||
|
||||
export function IsFurnitureSelectionDisabled(event: RoomEngineObjectEvent): boolean
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { GetRoomEngine } from './GetRoomEngine';
|
||||
import { GetRoomEngine } from '@nitrots/nitro-renderer';
|
||||
|
||||
export function ProcessRoomObjectOperation(objectId: number, category: number, operation: string): void
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { GetRoomEngine } from './GetRoomEngine';
|
||||
import { GetRoomEngine } from '@nitrots/nitro-renderer';
|
||||
|
||||
export function SetActiveRoomId(roomId: number): void
|
||||
{
|
||||
|
@ -1,7 +1,6 @@
|
||||
export * from './DispatchMouseEvent';
|
||||
export * from './DispatchTouchEvent';
|
||||
export * from './GetOwnRoomObject';
|
||||
export * from './GetRoomEngine';
|
||||
export * from './GetRoomObjectBounds';
|
||||
export * from './GetRoomObjectScreenLocation';
|
||||
export * from './InitializeRoomInstanceRenderingCanvas';
|
||||
|
@ -1,6 +1,4 @@
|
||||
import { IRoomSession, RoomControllerLevel } from '@nitrots/nitro-renderer';
|
||||
import { GetSessionDataManager } from '../..';
|
||||
import { GetRoomEngine } from '../room/GetRoomEngine';
|
||||
import { GetRoomEngine, GetSessionDataManager, IRoomSession, RoomControllerLevel } from '@nitrots/nitro-renderer';
|
||||
import { IsOwnerOfFurniture } from './IsOwnerOfFurniture';
|
||||
|
||||
export function CanManipulateFurniture(roomSession: IRoomSession, objectId: number, category: number): boolean
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { GetRoomSessionManager } from './GetRoomSessionManager';
|
||||
import { GetRoomSessionManager } from '@nitrots/nitro-renderer';
|
||||
|
||||
export function CreateRoomSession(roomId: number, password: string = null): void
|
||||
{
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { HabboClubLevelEnum } from '@nitrots/nitro-renderer';
|
||||
import { GetConfiguration } from '..';
|
||||
import { GetSessionDataManager } from './GetSessionDataManager';
|
||||
import { GetSessionDataManager, HabboClubLevelEnum } from '@nitrots/nitro-renderer';
|
||||
import { GetConfigurationValue } from '../GetConfigurationValue';
|
||||
|
||||
export function GetClubMemberLevel(): number
|
||||
{
|
||||
if(GetConfiguration<boolean>('hc.disabled', false)) return HabboClubLevelEnum.VIP;
|
||||
if(GetConfigurationValue<boolean>('hc.disabled', false)) return HabboClubLevelEnum.VIP;
|
||||
|
||||
return GetSessionDataManager().clubLevel;
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { IFurnitureData } from '@nitrots/nitro-renderer';
|
||||
import { GetSessionDataManager } from '.';
|
||||
import { GetSessionDataManager, IFurnitureData } from '@nitrots/nitro-renderer';
|
||||
import { ProductTypeEnum } from '../../catalog';
|
||||
|
||||
export function GetFurnitureData(furniClassId: number, productType: string): IFurnitureData
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { CatalogPageMessageProductData, FurnitureType, IFurnitureData } from '@nitrots/nitro-renderer';
|
||||
import { GetSessionDataManager } from './GetSessionDataManager';
|
||||
import { CatalogPageMessageProductData, FurnitureType, GetSessionDataManager, IFurnitureData } from '@nitrots/nitro-renderer';
|
||||
|
||||
export function GetFurnitureDataForProductOffer(offer: CatalogPageMessageProductData): IFurnitureData
|
||||
{
|
||||
if(!offer) return null;
|
||||
if (!offer) return null;
|
||||
|
||||
let furniData: IFurnitureData = null;
|
||||
|
||||
switch((offer.productType.toUpperCase()))
|
||||
switch ((offer.productType.toUpperCase()) as FurnitureType)
|
||||
{
|
||||
case FurnitureType.FLOOR:
|
||||
furniData = GetSessionDataManager().getFloorItemData(offer.furniClassId);
|
||||
|
@ -1,6 +1,4 @@
|
||||
import { IFurnitureData, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
||||
import { GetRoomEngine } from '../room';
|
||||
import { GetSessionDataManager } from './GetSessionDataManager';
|
||||
import { GetRoomEngine, GetSessionDataManager, IFurnitureData, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
||||
|
||||
export function GetFurnitureDataForRoomObject(roomId: number, objectId: number, category: number): IFurnitureData
|
||||
{
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { IProductData } from '@nitrots/nitro-renderer';
|
||||
import { GetSessionDataManager } from './GetSessionDataManager';
|
||||
import { GetSessionDataManager, IProductData } from '@nitrots/nitro-renderer';
|
||||
|
||||
export function GetProductDataForLocalization(localizationId: string): IProductData
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user