diff --git a/todo/Game.ts b/todo/Game.ts new file mode 100644 index 0000000..998541e --- /dev/null +++ b/todo/Game.ts @@ -0,0 +1,62 @@ +import { Stage } from '@pixi/layers' +import type { Application as GameApplication, ICanvas } from 'pixi.js' +import { Application, BaseTexture, Container, SCALE_MODES, settings } from 'pixi.js' + +import { GameLogger } from './GameLogger' +import type { GameConfigType } from './config' +import { GameConfig } from './config' + +export interface IGame extends GameConfigType { + container: HTMLCanvasElement + width: number + height: number +} + +export class Game { + private static INSTANCE: Game + private static readonly logger = new GameLogger('🕹ī¸ Habbo Game') + + private readonly _canvas: ICanvas + private readonly _application: GameApplication + + // private readonly _manager = RoomManager + + constructor(renderer: IGame) { + /** Change the PixiJS settings and default settings */ + settings.RESOLUTION = 1 + Container.defaultSortableChildren = true + BaseTexture.defaultOptions.scaleMode = SCALE_MODES.NEAREST + + /** Create the PixiJS application */ + this._application = new Application({ + width: renderer.width, + height: renderer.height, + resolution: 1, + antialias: false + }) + + /** Support for PIXI.js dev-tool */ + // @ts-expect-error + if (import.meta.env.DEV) globalThis.__PIXI_APP__ = this._application + + /** Initiate configuration */ + this._application.stage = new Stage() + // RoomManager.init() + + /** Append it to the canvas */ + this._canvas = this._application.view + renderer.container.append(this._application.view as unknown as Node) + } + + public static launch(config: GameConfigType): void { + if (Object.keys(GameConfig.current).length === 0) GameConfig.init(config) + if (this.INSTANCE != null) return this.logger.error('An instance of the game already exists.') + + this.INSTANCE = new this({ + container: document.getElementById('root') as HTMLCanvasElement, + width: window.innerWidth, + height: window.innerHeight, + config + }) + } +} diff --git a/todo/GameConfig.ts b/todo/GameConfig.ts new file mode 100644 index 0000000..6432a18 --- /dev/null +++ b/todo/GameConfig.ts @@ -0,0 +1,74 @@ +import type { ZodError, z } from 'zod' +import { fromZodError } from 'zod-validation-error' + +import { GameConfigSchema } from './schemas' +import { GameLogger } from '../GameLogger' + +type KeyOf = T extends object + ? { + [K in keyof T]-?: K | `${K & string}.${KeyOf & string}` + }[keyof T] + : never + +type ValueOf> = K extends `${infer U}.${infer R}` + ? U extends keyof T + ? ValueOf>> + : never + : K extends keyof T + ? T[K] + : never + +export type GameCoreConfig = z.infer +export type GameConfigType = Record + +export class GameConfig { + private static _config = {} as GameCoreConfig + private static readonly _logger = new GameLogger('🛠ī¸ GameConfig', false) + + private static _isValid = false + + public static init(config: GameConfigType): void { + try { + GameConfigSchema.parse(config) + + this._config = config as GameCoreConfig + this._isValid = true + } catch (error) { + const validationError = fromZodError(error as ZodError, { + issueSeparator: '\n', + prefixSeparator: '', + prefix: '' + }) + + const lines = validationError.message.split('\n') + + const errors = lines + .map((error, index) => { + const shouldSkipLine = index === 0 && lines.length > 1 + return (error = `${shouldSkipLine ? '\n\n' : ''}â€ĸ ${error}`) + }) + .join('\n') + + this._isValid = false + this._logger.error(errors) + } + } + + public static getValue>(key: K): ValueOf { + if (Object.keys(GameConfig.current).length === 0) throw new Error('Cannot log this out') + + const keys = key.split('.') + const value = keys.reduce((obj: any, key) => obj[key], this._config) + + // refactor!(): obj value changes but its type doesn't | temporary any type for now + return value + } + + public static get current(): GameCoreConfig { + return this._config + } + + public static get valid(): boolean { + return this._isValid + } +} diff --git a/todo/GameLogger.ts b/todo/GameLogger.ts new file mode 100644 index 0000000..d387572 --- /dev/null +++ b/todo/GameLogger.ts @@ -0,0 +1,66 @@ +import chalk from 'chalk' + +import { GameConfig } from './config/GameConfig' + +type LoggerTypes = 'DEBUG' | 'WARNING' | 'ERROR' | 'EVENTS' | 'PACKETS' + +const GAME_VERSION = '0.0.0' + +export class GameLogger { + private readonly _SUB_PREFIX!: string + + private readonly _PREFIX = (color: { bg: `#${string}`; text: `#${string}` }, type: LoggerTypes): string => + chalk.bgHex('#3742fa').white.bold(` ${this._SUB_PREFIX} `) + chalk.bgHex(color.bg).hex(color.text).bold(` ${type} `) + + private LOG_DEBUG = true + private LOG_WARN = true + private LOG_ERROR = true + private LOG_EVENTS = true + private LOG_PACKETS = true + + constructor(subPrefix: string, setupConfig: boolean = true) { + this._SUB_PREFIX = subPrefix + + if (setupConfig) this.initConfig() + } + + private initConfig(): void { + this.LOG_DEBUG = !GameConfig.getValue('system.logs.debug') + this.LOG_WARN = !GameConfig.getValue('system.logs.warn') + this.LOG_ERROR = !GameConfig.getValue('system.logs.error') + this.LOG_EVENTS = !GameConfig.getValue('system.logs.events') + this.LOG_PACKETS = !GameConfig.getValue('system.logs.packets') + } + + public log(...messages: unknown[]): void { + if (!this.LOG_DEBUG) return + return console.log(this._PREFIX({ bg: '#353b48', text: '#FFF' }, 'DEBUG'), ...messages) + } + + public warn(...messages: unknown[]): void { + if (!this.LOG_WARN) return + return console.warn(this._PREFIX({ bg: '#f39c12', text: '#000' }, 'WARNING'), ...messages) + } + + public error(...messages: unknown[]): void { + if (!this.LOG_ERROR) return + return console.error(this._PREFIX({ bg: '#c0392b', text: '#FFF' }, 'ERROR'), ...messages) + } + + public events(...messages: unknown[]): void { + if (!this.LOG_EVENTS) return + return console.log(this._PREFIX({ bg: '#27ae60', text: '#FFF' }, 'EVENTS'), ...messages) + } + + public packets(...messages: unknown[]): void { + if (!this.LOG_PACKETS) return + return console.log(this._PREFIX({ bg: '#e17055', text: '#FFF' }, 'PACKETS'), ...messages) + } + + public welcome(): void { + return console.log( + `%c Game Version | 🏷ī¸ ${GAME_VERSION}`, + 'padding: 0.6rem 1rem 0.5rem 0.6rem; font-size: 1.1em; font-weight: bold; font-family: Courier New; text-transform: uppercase; color: white; border-radius: 4px; background-image: linear-gradient(-225deg, #AC32E4 0%, #7918F2 48%, #4801FF 100%)' + ) + } +} diff --git a/todo/GameManager.ts b/todo/GameManager.ts new file mode 100644 index 0000000..6870694 --- /dev/null +++ b/todo/GameManager.ts @@ -0,0 +1,15 @@ +import type { RoomManager } from './RoomManager' + +export interface IGameManager { + init: () => void +} + +export class GameManager implements IGameManager { + private readonly _soundManager + private readonly _cameraManager + private readonly _roomManager: RoomManager + + init(): void { + console.log('feur') + } +} diff --git a/todo/SocketConnection.ts b/todo/SocketConnection.ts new file mode 100644 index 0000000..ea1be53 --- /dev/null +++ b/todo/SocketConnection.ts @@ -0,0 +1,20 @@ +import type { Socket } from 'socket.io-client' +import io from 'socket.io-client' + +import { GameLogger } from './GameLogger' +import { GameConfig } from './config' + +export class SocketConnection { + private static _connection: Socket + + private static readonly _logger = new GameLogger('đŸ“ļ SocketConnection') + + public static createConnection(): void { + if (this._connection == null) this._connection = io(GameConfig.getValue('url.socket')) + else return this._logger.error('Cannot establish connection, a connection is already up and going!') + + this._connection.on('message', (message) => { + console.log(message) + }) + } +} diff --git a/todo/avatar/Avatar.ts b/todo/avatar/Avatar.ts new file mode 100644 index 0000000..fff9a58 --- /dev/null +++ b/todo/avatar/Avatar.ts @@ -0,0 +1,7 @@ +export class Avatar { + private static readonly DEFAULT_FIGURE = 'hd-99999-99999' + + private readonly _placeholder: this + + // create a figure +} diff --git a/todo/avatar/HabboAvatarAnimations.ts b/todo/avatar/HabboAvatarAnimations.ts new file mode 100644 index 0000000..a9225e1 --- /dev/null +++ b/todo/avatar/HabboAvatarAnimations.ts @@ -0,0 +1,827 @@ +export const HabboAvatarAnimations = { + animations: [ + { + id: 'Move', + parts: [ + { + setType: 'bd', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'bds', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'ss', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'lg', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'sh', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'lh', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'lhs', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'ls', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'lc', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'rh', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'rhs', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'rs', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'rc', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + }, + { + setType: 'ch', + frames: [ + { + number: 0, + assetPartDefinition: 'wlk' + }, + { + number: 1, + assetPartDefinition: 'wlk' + }, + { + number: 2, + assetPartDefinition: 'wlk' + }, + { + number: 3, + assetPartDefinition: 'wlk' + } + ] + } + ] + }, + { + id: 'Wave', + parts: [ + { + setType: 'lh', + frames: [ + { + number: 0, + assetPartDefinition: 'wav' + }, + { + number: 1, + assetPartDefinition: 'wav' + } + ] + }, + { + setType: 'lhs', + frames: [ + { + number: 0, + assetPartDefinition: 'wav' + }, + { + number: 1, + assetPartDefinition: 'wav' + } + ] + }, + { + setType: 'ls', + frames: [ + { + number: 0, + assetPartDefinition: 'wav' + }, + { + number: 1, + assetPartDefinition: 'wav' + } + ] + }, + { + setType: 'lc', + frames: [ + { + number: 0, + assetPartDefinition: 'wav' + }, + { + number: 1, + assetPartDefinition: 'wav' + } + ] + }, + { + setType: 'ch', + frames: [ + { + number: 0, + assetPartDefinition: 'wav' + }, + { + number: 1, + assetPartDefinition: 'wav' + }, + { + number: 2, + assetPartDefinition: 'wav' + }, + { + number: 3, + assetPartDefinition: 'wav' + } + ] + } + ] + }, + { + id: 'Talk', + parts: [ + { + setType: 'hd', + frames: [ + { + number: 0, + assetPartDefinition: 'spk' + }, + { + number: 1, + assetPartDefinition: 'spk' + } + ] + }, + { + setType: 'fc', + frames: [ + { + number: 0, + assetPartDefinition: 'spk' + }, + { + number: 1, + assetPartDefinition: 'spk' + } + ] + }, + { + setType: 'fa', + frames: [ + { + number: 0, + assetPartDefinition: 'spk' + }, + { + number: 1, + assetPartDefinition: 'spk' + } + ] + } + ] + }, + { + id: 'Sign', + parts: [ + { + setType: 'lh', + frames: [ + { + number: 0, + assetPartDefinition: 'sig' + } + ] + }, + { + setType: 'li', + frames: [ + { + number: 0, + assetPartDefinition: 'sig' + } + ] + }, + { + setType: 'ls', + frames: [ + { + number: 0, + assetPartDefinition: 'wav' + } + ] + }, + { + setType: 'lc', + frames: [ + { + number: 0, + assetPartDefinition: 'wav' + } + ] + } + ] + }, + { + id: 'Respect', + parts: [ + { + setType: 'lh', + frames: [ + { + number: 0, + assetPartDefinition: 'respect', + repeats: 15 + }, + { + number: 1, + assetPartDefinition: 'respect', + repeats: 15 + } + ] + }, + { + setType: 'ls', + frames: [ + { + number: 0, + assetPartDefinition: 'wav', + repeats: 15 + }, + { + number: 1, + assetPartDefinition: 'wav', + repeats: 15 + } + ] + }, + { + setType: 'lc', + frames: [ + { + number: 0, + assetPartDefinition: 'wav', + repeats: 15 + }, + { + number: 1, + assetPartDefinition: 'wav', + repeats: 15 + } + ] + } + ] + }, + { + id: 'Blow', + parts: [ + { + setType: 'rh', + frames: [ + { + number: 0, + assetPartDefinition: 'blw', + repeats: 10 + }, + { + number: 1, + assetPartDefinition: 'blw', + repeats: 10 + } + ] + }, + { + setType: 'rs', + frames: [ + { + number: 0, + assetPartDefinition: 'drk' + } + ] + }, + { + setType: 'rc', + frames: [ + { + number: 0, + assetPartDefinition: 'drk' + } + ] + }, + { + setType: 'ri', + frames: [ + { + number: 0, + assetPartDefinition: '' + } + ] + }, + { + setType: 'ey', + frames: [ + { + number: 0, + assetPartDefinition: 'std', + repeats: 10 + }, + { + number: 0, + assetPartDefinition: 'eyb', + repeats: 10 + } + ] + }, + { + setType: 'fc', + frames: [ + { + number: 0, + assetPartDefinition: 'std', + repeats: 10 + }, + { + number: 0, + assetPartDefinition: 'blw', + repeats: 10 + } + ] + } + ] + }, + { + id: 'Laugh', + parts: [ + { + setType: 'rh', + frames: [ + { + number: 0, + assetPartDefinition: 'blw' + } + ] + }, + { + setType: 'rs', + frames: [ + { + number: 0, + assetPartDefinition: 'drk' + } + ] + }, + { + setType: 'rc', + frames: [ + { + number: 0, + assetPartDefinition: 'drk' + } + ] + }, + { + setType: 'ri', + frames: [ + { + number: 0, + assetPartDefinition: '' + } + ] + }, + { + setType: 'ey', + frames: [ + { + number: 0, + assetPartDefinition: 'std', + repeats: 2 + } + ] + }, + { + setType: 'fc', + frames: [ + { + number: 0, + assetPartDefinition: 'sml' + } + ] + } + ], + offsets: { + frames: [ + { + id: 0, + directions: [ + { + id: 0, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 1 + } + ] + }, + { + id: 1, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 1 + } + ] + }, + { + id: 2, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 1 + } + ] + }, + { + id: 3, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 1 + } + ] + }, + { + id: 4, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 1 + } + ] + }, + { + id: 5, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 1 + } + ] + }, + { + id: 6, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 1 + } + ] + }, + { + id: 7, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 1 + } + ] + } + ] + }, + { + id: 1, + directions: [ + { + id: 0, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 0 + } + ] + }, + { + id: 1, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 0 + } + ] + }, + { + id: 2, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 0 + } + ] + }, + { + id: 3, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 0 + } + ] + }, + { + id: 4, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 0 + } + ] + }, + { + id: 5, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 0 + } + ] + }, + { + id: 6, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 0 + } + ] + }, + { + id: 7, + bodyParts: [ + { + id: 'head', + dx: 0, + dy: 0 + } + ] + } + ] + } + ] + } + } + ] +} diff --git a/todo/avatar/HabboAvatarGeometry.ts b/todo/avatar/HabboAvatarGeometry.ts new file mode 100644 index 0000000..c607878 --- /dev/null +++ b/todo/avatar/HabboAvatarGeometry.ts @@ -0,0 +1,1830 @@ +export const HabboAvatarGeometry = { + geometry: { + direction: 0, + camera: { + x: 0, + y: 0, + z: 10 + }, + canvases: [ + { + scale: 'h', + geometries: [ + { + id: 'vertical', + width: 90, + height: 130, + dx: 0, + dy: 0 + }, + { + id: 'sitting', + width: 90, + height: 130, + dx: 0, + dy: 0 + }, + { + id: 'horizontal', + width: 128, + height: 80, + dx: 30, + dy: 0 + }, + { + id: 'swhorizontal', + width: 192, + height: 120, + dx: 0, + dy: -40 + } + ] + }, + { + scale: 'sh', + geometries: [ + { + id: 'vertical', + width: 45, + height: 72, + dx: 0, + dy: 0 + }, + { + id: 'sitting', + width: 45, + height: 72, + dx: 0, + dy: 0 + }, + { + id: 'horizontal', + width: 64, + height: 50, + dx: 15, + dy: -10 + }, + { + id: 'swhorizontal', + width: 96, + height: 70, + dx: 0, + dy: -20 + }, + { + id: 'swim', + width: 64, + height: 70, + dx: 25, + dy: 10 + } + ] + } + ], + avatarSets: [ + { + id: 'full', + avatarSets: [ + { + id: 'body', + main: true, + bodyParts: [ + { + id: 'top' + }, + { + id: 'bottom' + }, + { + id: 'behind' + }, + { + id: 'torso' + }, + { + id: 'leftitem' + }, + { + id: 'rightitem' + }, + { + id: 'leftarm' + }, + { + id: 'rightarm' + } + ] + }, + { + id: 'head', + bodyParts: [ + { + id: 'head' + } + ] + } + ] + } + ], + types: [ + { + id: 'vertical', + bodyParts: [ + { + id: 'top', + x: 0, + y: 0, + z: 0, + radius: 2 + }, + { + id: 'bottom', + x: 0, + y: 0, + z: 0, + radius: 0.001 + }, + { + id: 'behind', + x: 0, + y: 0, + z: 0.2, + radius: 0.3 + }, + { + id: 'torso', + x: 0, + y: 0, + z: 0, + radius: 0.4, + items: [ + { + id: 'bd', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'bds', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'ch', + x: 0, + y: 0, + z: 0, + radius: 0.04, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'sh', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lg', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ss', + x: 0, + y: 0, + z: 0, + radius: 0.04, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'cp', + x: 0, + y: 0, + z: 0, + radius: 0.045, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'wa', + x: 0, + y: 0, + z: 0, + radius: 0.05, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'cc', + x: 0, + y: 0, + z: 0, + radius: 0.06, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ca', + x: 0, + y: 0, + z: 0, + radius: 0.07, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'leftitem', + x: 0, + y: 0, + z: -0.29, + radius: 0.3, + items: [ + { + id: 'li', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'rightitem', + x: 0, + y: 0, + z: -0.29, + radius: 0.3, + items: [ + { + id: 'ri', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'leftarm', + x: -1, + y: 0, + z: -0.51, + radius: 0.5, + items: [ + { + id: 'lh', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lhs', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ls', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lc', + x: 0, + y: 0, + z: 0, + radius: 0.025, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'rightarm', + x: 1, + y: 0, + z: -0.51, + radius: 0.5, + items: [ + { + id: 'rh', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rhs', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rs', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rc', + x: 0, + y: 0, + z: 0, + radius: 0.025, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'head', + x: 0, + y: 0, + z: 0, + radius: 0.5, + items: [ + { + id: 'hd', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'fc', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ey', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'hr', + x: 0, + y: 0, + z: 0, + radius: 0.04, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'hrb', + x: 0, + y: 0, + z: 0, + radius: 0.05, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'fa', + x: 0, + y: 0, + z: 0, + radius: 0.06, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ea', + x: 0, + y: 0, + z: 0, + radius: 0.07, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ha', + x: 0, + y: 0, + z: 0, + radius: 0.08, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'he', + x: 0, + y: 0, + z: 0, + radius: 0.09, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + } + ] + }, + { + id: 'sitting', + bodyParts: [ + { + id: 'top', + x: 0, + y: 0, + z: 0, + radius: 2 + }, + { + id: 'bottom', + x: 0, + y: 0, + z: 0, + radius: 0.001 + }, + { + id: 'behind', + x: 0, + y: 0, + z: 0.2, + radius: 0.3 + }, + { + id: 'torso', + x: 0, + y: 0, + z: 0, + radius: 0.4, + items: [ + { + id: 'bd', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'bds', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'ch', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'sh', + x: 0, + y: 0, + z: 0, + radius: 0.04, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lg', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ss', + x: 0, + y: 0, + z: 0, + radius: 0.04, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'cp', + x: 0, + y: 0, + z: 0, + radius: 0.045, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'wa', + x: 0, + y: 0, + z: 0, + radius: 0.05, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'cc', + x: 0, + y: 0, + z: 0, + radius: 0.06, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ca', + x: 0, + y: 0, + z: 0, + radius: 0.07, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'leftitem', + x: 0, + y: 0, + z: -0.29, + radius: 0.3, + items: [ + { + id: 'li', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'rightitem', + x: 0, + y: 0, + z: -0.29, + radius: 0.3, + items: [ + { + id: 'ri', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'leftarm', + x: -1, + y: 0, + z: -0.51, + radius: 0.5, + items: [ + { + id: 'lh', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lhs', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ls', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lc', + x: 0, + y: 0, + z: 0, + radius: 0.025, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'rightarm', + x: 1, + y: 0, + z: -0.51, + radius: 0.5, + items: [ + { + id: 'rh', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rhs', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rs', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rc', + x: 0, + y: 0, + z: 0, + radius: 0.025, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'head', + x: 0, + y: 0, + z: 0, + radius: 0.5, + items: [ + { + id: 'hd', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'fc', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ey', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'hr', + x: 0, + y: 0, + z: 0, + radius: 0.04, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'hrb', + x: 0, + y: 0, + z: 0, + radius: 0.05, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'fa', + x: 0, + y: 0, + z: 0, + radius: 0.06, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ea', + x: 0, + y: 0, + z: 0, + radius: 0.07, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ha', + x: 0, + y: 0, + z: 0, + radius: 0.08, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'he', + x: 0, + y: 0, + z: 0, + radius: 0.09, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + } + ] + }, + { + id: 'horizontal', + bodyParts: [ + { + id: 'torso', + x: 0, + y: 0, + z: 0, + radius: 0.4, + items: [ + { + id: 'bd', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'bds', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'ch', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'cp', + x: 0, + y: 0, + z: 0, + radius: 0.025, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'sh', + x: 0, + y: 0, + z: 0, + radius: 0.04, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lg', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ss', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'wa', + x: 0, + y: 0, + z: 0, + radius: 0.05, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'cc', + x: 0, + y: 0, + z: 0, + radius: 0.06, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ca', + x: 0, + y: 0, + z: 0, + radius: 0.07, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'leftitem', + x: 0, + y: 0, + z: -0.29, + radius: 0.3, + items: [ + { + id: 'li', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'rightitem', + x: 0, + y: 0, + z: -0.29, + radius: 0.3, + items: [ + { + id: 'ri', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'leftarm', + x: -1, + y: 0, + z: -0.51, + radius: 0.6, + items: [ + { + id: 'lh', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lhs', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ls', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lc', + x: 0, + y: 0, + z: 0, + radius: 0.025, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'rightarm', + x: 1, + y: 0, + z: -0.51, + radius: 0.6, + items: [ + { + id: 'rh', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rhs', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rs', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rc', + x: 0, + y: 0, + z: 0, + radius: 0.025, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'head', + x: 0, + y: 0, + z: 0, + radius: 0.5, + items: [ + { + id: 'hd', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'fc', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ey', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'hr', + x: 0, + y: 0, + z: 0, + radius: 0.04, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'hrb', + x: 0, + y: 0, + z: 0, + radius: 0.05, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'fa', + x: 0, + y: 0, + z: 0, + radius: 0.06, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ea', + x: 0, + y: 0, + z: 0, + radius: 0.07, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ha', + x: 0, + y: 0, + z: 0, + radius: 0.08, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'he', + x: 0, + y: 0, + z: 0, + radius: 0.09, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + } + ] + }, + { + id: 'swhorizontal', + bodyParts: [ + { + id: 'torso', + x: 0, + y: 0, + z: 0, + radius: 0.4, + items: [ + { + id: 'bd', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'bds', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'ch', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'cp', + x: 0, + y: 0, + z: 0, + radius: 0.025, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'sh', + x: 0, + y: 0, + z: 0, + radius: 0.04, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lg', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ss', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'wa', + x: 0, + y: 0, + z: 0, + radius: 0.05, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'cc', + x: 0, + y: 0, + z: 0, + radius: 0.06, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ca', + x: 0, + y: 0, + z: 0, + radius: 0.07, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'leftitem', + x: 0, + y: 0, + z: -0.29, + radius: 0.3, + items: [ + { + id: 'li', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'rightitem', + x: 0, + y: 0, + z: -0.29, + radius: 0.3, + items: [ + { + id: 'ri', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'leftarm', + x: -1, + y: 0, + z: -0.51, + radius: 0.6, + items: [ + { + id: 'lh', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lhs', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ls', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'lc', + x: 0, + y: 0, + z: 0, + radius: 0.025, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'rightarm', + x: 1, + y: 0, + z: -0.51, + radius: 0.6, + items: [ + { + id: 'rh', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rhs', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rs', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'rc', + x: 0, + y: 0, + z: 0, + radius: 0.025, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'head', + x: 0, + y: 0, + z: 0, + radius: 0.5, + items: [ + { + id: 'hd', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'fc', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ey', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'hr', + x: 0, + y: 0, + z: 0, + radius: 0.04, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'hrb', + x: 0, + y: 0, + z: 0, + radius: 0.05, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'fa', + x: 0, + y: 0, + z: 0, + radius: 0.06, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ea', + x: 0, + y: 0, + z: 0, + radius: 0.07, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ha', + x: 0, + y: 0, + z: 0, + radius: 0.08, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'he', + x: 0, + y: 0, + z: 0, + radius: 0.09, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + } + ] + }, + { + id: 'swim', + bodyParts: [ + { + id: 'torso', + x: 0, + y: 0, + z: 0, + radius: 0.4, + items: [ + { + id: 'bds', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'ss', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + }, + { + id: 'head', + x: 0, + y: 0, + z: 0, + radius: 0.5, + items: [ + { + id: 'hd', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'fc', + x: 0, + y: 0, + z: 0, + radius: 0.02, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ey', + x: 0, + y: 0, + z: 0, + radius: 0.03, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'hr', + x: 0, + y: 0, + z: 0, + radius: 0.04, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'hrb', + x: 0, + y: 0, + z: 0, + radius: 0.05, + nx: 0, + ny: 0, + nz: -1, + double: true + }, + { + id: 'fa', + x: 0, + y: 0, + z: 0, + radius: 0.06, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ea', + x: 0, + y: 0, + z: 0, + radius: 0.07, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'ha', + x: 0, + y: 0, + z: 0, + radius: 0.08, + nx: 0, + ny: 0, + nz: -1, + double: false + }, + { + id: 'he', + x: 0, + y: 0, + z: 0, + radius: 0.09, + nx: 0, + ny: 0, + nz: -1, + double: false + } + ] + } + ] + } + ] + } +} diff --git a/todo/avatar/HabboAvatarPartSets.ts b/todo/avatar/HabboAvatarPartSets.ts new file mode 100644 index 0000000..f22512b --- /dev/null +++ b/todo/avatar/HabboAvatarPartSets.ts @@ -0,0 +1,418 @@ +export const HabboAvatarPartSets = { + partSets: { + partSet: [ + { + setType: 'ri', + flippedSetType: 'ri' + }, + { + setType: 'ri', + flippedSetType: 'ri' + }, + { + setType: 'rh', + flippedSetType: 'lh' + }, + { + setType: 'rhs', + flippedSetType: 'lhs' + }, + { + setType: 'rs', + swim: '0', + flippedSetType: 'ls' + }, + { + setType: 'rc', + flippedSetType: 'lc' + }, + { + setType: 'bd' + }, + { + setType: 'bds' + }, + { + setType: 'ss' + }, + { + setType: 'sh' + }, + { + setType: 'lg' + }, + { + setType: 'ch' + }, + { + setType: 'cp' + }, + { + setType: 'cc' + }, + { + setType: 'hd' + }, + { + setType: 'fc' + }, + { + setType: 'ey' + }, + { + setType: 'hr' + }, + { + setType: 'hrb', + removeSetType: 'hr' + }, + { + setType: 'li', + flippedSetType: 'li' + }, + { + setType: 'lh', + flippedSetType: 'rh' + }, + { + setType: 'lhs', + flippedSetType: 'rhs' + }, + { + setType: 'ls', + flippedSetType: 'rs' + }, + { + setType: 'lc', + flippedSetType: 'rc' + }, + { + setType: 'wa' + }, + { + setType: 'ea' + }, + { + setType: 'ca' + }, + { + setType: 'fa' + }, + { + setType: 'ha' + }, + { + setType: 'he' + } + ], + activePartSets: [ + { + id: 'figure', + activeParts: [ + { + setType: 'rh' + }, + { + setType: 'rh' + }, + { + setType: 'rhs' + }, + { + setType: 'rs' + }, + { + setType: 'rc' + }, + { + setType: 'bd' + }, + { + setType: 'bds' + }, + { + setType: 'ss' + }, + { + setType: 'sh' + }, + { + setType: 'lg' + }, + { + setType: 'ch' + }, + { + setType: 'cp' + }, + { + setType: 'cc' + }, + { + setType: 'wa' + }, + { + setType: 'hd' + }, + { + setType: 'fc' + }, + { + setType: 'ey' + }, + { + setType: 'hr' + }, + { + setType: 'hrb' + }, + { + setType: 'lh' + }, + { + setType: 'lhs' + }, + { + setType: 'ls' + }, + { + setType: 'lc' + }, + { + setType: 'ea' + }, + { + setType: 'ca' + }, + { + setType: 'fa' + }, + { + setType: 'ha' + }, + { + setType: 'he' + } + ] + }, + { + id: 'head', + activeParts: [ + { + setType: 'hd' + }, + { + setType: 'fc' + }, + { + setType: 'ey' + }, + { + setType: 'hr' + }, + { + setType: 'hrb' + }, + { + setType: 'ea' + }, + { + setType: 'fa' + }, + { + setType: 'ha' + }, + { + setType: 'he' + } + ] + }, + { + id: 'speak', + activeParts: [ + { + setType: 'hd' + }, + { + setType: 'hr' + }, + { + setType: 'hrb' + }, + { + setType: 'fc' + }, + { + setType: 'fa' + }, + { + setType: 'ha' + } + ] + }, + { + id: 'gesture', + activeParts: [ + { + setType: 'ey' + }, + { + setType: 'fc' + } + ] + }, + { + id: 'eye', + activeParts: [ + { + setType: 'ey' + } + ] + }, + { + id: 'handRight', + activeParts: [ + { + setType: 'rh' + }, + { + setType: 'rhs' + }, + { + setType: 'rs' + }, + { + setType: 'rc' + }, + { + setType: 'ri' + } + ] + }, + { + id: 'handRightAndHead', + activeParts: [ + { + setType: 'rh' + }, + { + setType: 'rhs' + }, + { + setType: 'rs' + }, + { + setType: 'rc' + }, + { + setType: 'ri' + }, + { + setType: 'ey' + }, + { + setType: 'fc' + }, + { + setType: 'hd' + } + ] + }, + { + id: 'handLeft', + activeParts: [ + { + setType: 'lh' + }, + { + setType: 'lhs' + }, + { + setType: 'ls' + }, + { + setType: 'lc' + }, + { + setType: 'li' + } + ] + }, + { + id: 'walk', + activeParts: [ + { + setType: 'bd' + }, + { + setType: 'bds' + }, + { + setType: 'ss' + }, + { + setType: 'lg' + }, + { + setType: 'lh' + }, + { + setType: 'lhs' + }, + { + setType: 'rh' + }, + { + setType: 'rhs' + }, + { + setType: 'ls' + }, + { + setType: 'lc' + }, + { + setType: 'rs' + }, + { + setType: 'rc' + }, + { + setType: 'sh' + } + ] + }, + { + id: 'sit', + activeParts: [ + { + setType: 'bd' + }, + { + setType: 'bds' + }, + { + setType: 'ss' + }, + { + setType: 'lg' + }, + { + setType: 'sh' + }, + { + setType: 'cc' + } + ] + }, + { + id: 'itemRight', + activeParts: [ + { + setType: 'ri' + } + ] + } + ] + } +} diff --git a/todo/package.json b/todo/package.json new file mode 100644 index 0000000..111e35a --- /dev/null +++ b/todo/package.json @@ -0,0 +1,31 @@ +{ + "name": "game", + "version": "0.0.0", + "description": "Habbo Game core engine", + "license": "MIT", + "scripts": { + "build-fast": "tsup src/index.ts --format cjs,esm --dts", + "build": "pnpm run build-fast -- --dts-resolve", + "test": "vitest run", + "prepublishOnly": "pnpm run build" + }, + "dependencies": { + "@pixi/layers": "^2.1.0", + "@pixi/utils": "^7.2.4", + "@pixi/core": "7.2.4", + "gsap": "^3.12.2", + "pixi.js": "^7.2.4" + }, + "devDependencies": { + "config": "workspace:*", + "@types/node": "20.4.2", + "socket.io-client": "4.7.1", + "pako": "2.1.0", + "zod": "3.21.4", + "chalk": "5.3.0", + "zod-validation-error": "1.3.1", + "tsup": "7.1.0", + "typescript": "5.1.6", + "vitest": "0.33.0" + } +} diff --git a/todo/schemas.ts b/todo/schemas.ts new file mode 100644 index 0000000..ee90073 --- /dev/null +++ b/todo/schemas.ts @@ -0,0 +1,58 @@ +import { z } from 'zod' + +const SystemConfig = z.strictObject({ + logs: z.strictObject({ + debug: z.boolean(), + warn: z.boolean(), + error: z.boolean(), + events: z.boolean(), + packets: z.boolean() + }), + + fps: z + .strictObject({ + max: z.number(), + animation: z.number().min(24) + }) + .refine( + (ctx) => ctx.animation <= ctx.max, + (ctx) => ({ message: `Number must not exceed ${ctx.max} max FPS`, path: ['animation'] }) + ), + + pong: z.strictObject({ + manually: z.boolean(), + interval: z + .number() + .min(5 * 1000) + .max(60 * 1000) + }) +}) + +const URLConfig = z.strictObject({ + socket: z.string().refine((value) => value.startsWith('ws://') && /\b(?:\d{1,3}\.){3}\d{1,3}:\d{1,5}\b/.test(value), { + message: 'Invalid socket URL format' + }), + client: z + .string() + .refine((value) => /^(ht{2}ps?:\/{2})?((([\da-z-]+\.)+[a-z]{2,})|((?:\d{1,3}\.){3}\d{1,3}))(\/.*)?$/i.test(value), { + message: 'Invalid HTTP URL format' + }) +}) + +const CommonKeys = { + enabled: z.boolean() +} + +const GameSchema = z.strictObject({ + hc: z.strictObject({ ...CommonKeys }), + camera: z.strictObject({ ...CommonKeys }), + pets: z.array(z.string()) +}) + +const GameConfigSchema = z.strictObject({ + system: SystemConfig, + url: URLConfig, + game: GameSchema +}) + +export { GameConfigSchema } diff --git a/todo/tsconfig.json b/todo/tsconfig.json new file mode 100644 index 0000000..1dc6b7f --- /dev/null +++ b/todo/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "strict": true, + "esModuleInterop": true, + "moduleResolution": "node", + "noUnusedLocals": true, + "noImplicitAny": true, + "allowJs": true, + "noEmit": true, + "outDir": "dist", + "resolveJsonModule": true + } +}