From e681a316a1fc307e82012130cb8e7facc5089a1d Mon Sep 17 00:00:00 2001 From: Bill Date: Wed, 11 Aug 2021 23:07:23 -0400 Subject: [PATCH] Add planet & particle systems to furni --- src/Main.ts | 4 +- src/common/converters/Converter.ts | 2 +- src/common/converters/ConverterType.ts | 7 + src/common/converters/IConverter.ts | 2 +- src/converters/catalog/CatalogConverter.ts | 2 +- src/converters/effect/EffectConverter.ts | 2 +- .../effectmap/EffectMapConverter.ts | 2 +- .../externaltexts/ExternalTextsConverter.ts | 2 +- src/converters/figure/FigureConverter.ts | 2 +- .../figuredata/FigureDataConverter.ts | 2 +- .../figuremap/FigureMapConverter.ts | 2 +- .../furniture/FurnitureConverter.ts | 2 +- .../furniture/FurnitureDownloader.ts | 2 +- .../furnituredata/FurnitureDataConverter.ts | 2 +- src/converters/pet/PetConverter.ts | 2 +- .../productdata/ProductDataConverter.ts | 2 +- src/mapping/json/asset/IAssetData.ts | 4 + src/mapping/json/asset/IPlanetSystem.ts | 11 ++ src/mapping/json/asset/index.ts | 1 + .../asset/particlesystem/IParticleSystem.ts | 11 ++ .../particlesystem/IParticleSystemEmitter.ts | 15 ++ .../particlesystem/IParticleSystemParticle.ts | 7 + .../IParticleSystemSimulation.ts | 9 ++ .../json/asset/particlesystem/index.ts | 4 + src/mapping/mappers/asset/LogicMapper.ts | 147 +++++++++++++++++- src/mapping/xml/asset/logic/LogicXML.ts | 34 +++- .../asset/logic/ParticleSystemEmitterXML.ts | 91 +++++++++++ .../asset/logic/ParticleSystemObjectXML.ts | 65 ++++++++ .../asset/logic/ParticleSystemParticleXML.ts | 50 ++++++ .../logic/ParticleSystemSimulationXML.ts | 55 +++++++ .../xml/asset/logic/ParticleSystemXML.ts | 24 +++ .../xml/asset/logic/PlanetSystemObjectXML.ts | 68 ++++++++ .../xml/asset/logic/PlanetSystemXML.ts | 24 +++ src/mapping/xml/asset/logic/index.ts | 7 + .../xml/asset/manifest/ManifestLibraryXML.ts | 10 ++ src/swf/HabboAssetSWF.ts | 108 ++++++++----- 36 files changed, 723 insertions(+), 61 deletions(-) create mode 100644 src/common/converters/ConverterType.ts create mode 100644 src/mapping/json/asset/IPlanetSystem.ts create mode 100644 src/mapping/json/asset/particlesystem/IParticleSystem.ts create mode 100644 src/mapping/json/asset/particlesystem/IParticleSystemEmitter.ts create mode 100644 src/mapping/json/asset/particlesystem/IParticleSystemParticle.ts create mode 100644 src/mapping/json/asset/particlesystem/IParticleSystemSimulation.ts create mode 100644 src/mapping/json/asset/particlesystem/index.ts create mode 100644 src/mapping/xml/asset/logic/ParticleSystemEmitterXML.ts create mode 100644 src/mapping/xml/asset/logic/ParticleSystemObjectXML.ts create mode 100644 src/mapping/xml/asset/logic/ParticleSystemParticleXML.ts create mode 100644 src/mapping/xml/asset/logic/ParticleSystemSimulationXML.ts create mode 100644 src/mapping/xml/asset/logic/ParticleSystemXML.ts create mode 100644 src/mapping/xml/asset/logic/PlanetSystemObjectXML.ts create mode 100644 src/mapping/xml/asset/logic/PlanetSystemXML.ts diff --git a/src/Main.ts b/src/Main.ts index c4aa86c..b1b51e5 100644 --- a/src/Main.ts +++ b/src/Main.ts @@ -27,11 +27,13 @@ import { ProductDataConverter } from './converters/productdata/ProductDataConver FigureDataConverter ]; + const [ arg1, arg2, ...rest ] = process.argv; + for(const converterClass of converters) { const converter = (container.resolve(converterClass) as IConverter); - await converter.convertAsync(); + await converter.convertAsync(rest); } })(); diff --git a/src/common/converters/Converter.ts b/src/common/converters/Converter.ts index 766be8c..0ce6736 100644 --- a/src/common/converters/Converter.ts +++ b/src/common/converters/Converter.ts @@ -2,7 +2,7 @@ import { IConverter } from './IConverter'; export class Converter implements IConverter { - public async convertAsync(): Promise + public async convertAsync(args: string[] = []): Promise { return; } diff --git a/src/common/converters/ConverterType.ts b/src/common/converters/ConverterType.ts new file mode 100644 index 0000000..2b744fa --- /dev/null +++ b/src/common/converters/ConverterType.ts @@ -0,0 +1,7 @@ +export class ConverterType +{ + public static EFFECT_CONVERTER: string = 'effect'; + public static FIGURE_CONVERTER: string = 'figure'; + public static FURNITURE_CONVERTER: string = 'furni'; + public static PET_CONVERTER: string = 'pet'; +} diff --git a/src/common/converters/IConverter.ts b/src/common/converters/IConverter.ts index 7375373..3041112 100644 --- a/src/common/converters/IConverter.ts +++ b/src/common/converters/IConverter.ts @@ -1,4 +1,4 @@ export interface IConverter { - convertAsync(): Promise; + convertAsync(args?: string[]): Promise; } diff --git a/src/converters/catalog/CatalogConverter.ts b/src/converters/catalog/CatalogConverter.ts index a669c21..ae11b3f 100644 --- a/src/converters/catalog/CatalogConverter.ts +++ b/src/converters/catalog/CatalogConverter.ts @@ -20,7 +20,7 @@ export class CatalogConverter extends SWFConverter super(); } - public async convertAsync(): Promise + public async convertAsync(args: string[] = []): Promise { if(!this._configuration.getBoolean('convert.catalog')) return; diff --git a/src/converters/effect/EffectConverter.ts b/src/converters/effect/EffectConverter.ts index 9de51d1..2f9a07d 100644 --- a/src/converters/effect/EffectConverter.ts +++ b/src/converters/effect/EffectConverter.ts @@ -22,7 +22,7 @@ export class EffectConverter extends SWFConverter super(); } - public async convertAsync(): Promise + public async convertAsync(args: string[] = []): Promise { if(!this._configuration.getBoolean('convert.effect')) return; diff --git a/src/converters/effectmap/EffectMapConverter.ts b/src/converters/effectmap/EffectMapConverter.ts index 5c254ce..c28bc60 100644 --- a/src/converters/effectmap/EffectMapConverter.ts +++ b/src/converters/effectmap/EffectMapConverter.ts @@ -21,7 +21,7 @@ export class EffectMapConverter extends Converter super(); } - public async convertAsync(): Promise + public async convertAsync(args: string[] = []): Promise { return new Promise((resolve, reject) => { diff --git a/src/converters/externaltexts/ExternalTextsConverter.ts b/src/converters/externaltexts/ExternalTextsConverter.ts index 44167b6..f119084 100644 --- a/src/converters/externaltexts/ExternalTextsConverter.ts +++ b/src/converters/externaltexts/ExternalTextsConverter.ts @@ -19,7 +19,7 @@ export class ExternalTextsConverter extends Converter super(); } - public async convertAsync(): Promise + public async convertAsync(args: string[] = []): Promise { if(!this._configuration.getBoolean('convert.externaltexts')) return; diff --git a/src/converters/figure/FigureConverter.ts b/src/converters/figure/FigureConverter.ts index 84e65a5..ada1123 100644 --- a/src/converters/figure/FigureConverter.ts +++ b/src/converters/figure/FigureConverter.ts @@ -22,7 +22,7 @@ export class FigureConverter extends SWFConverter super(); } - public async convertAsync(): Promise + public async convertAsync(args: string[] = []): Promise { if(!this._configuration.getBoolean('convert.figure')) return; diff --git a/src/converters/figuredata/FigureDataConverter.ts b/src/converters/figuredata/FigureDataConverter.ts index 04f7335..e396206 100644 --- a/src/converters/figuredata/FigureDataConverter.ts +++ b/src/converters/figuredata/FigureDataConverter.ts @@ -21,7 +21,7 @@ export class FigureDataConverter extends Converter super(); } - public async convertAsync(): Promise + public async convertAsync(args: string[] = []): Promise { if(!this._configuration.getBoolean('convert.figuredata')) return; diff --git a/src/converters/figuremap/FigureMapConverter.ts b/src/converters/figuremap/FigureMapConverter.ts index 1b9c996..dc17567 100644 --- a/src/converters/figuremap/FigureMapConverter.ts +++ b/src/converters/figuremap/FigureMapConverter.ts @@ -21,7 +21,7 @@ export class FigureMapConverter extends Converter super(); } - public async convertAsync(): Promise + public async convertAsync(args: string[] = []): Promise { return new Promise((resolve, reject) => { diff --git a/src/converters/furniture/FurnitureConverter.ts b/src/converters/furniture/FurnitureConverter.ts index d4fe950..347cd99 100644 --- a/src/converters/furniture/FurnitureConverter.ts +++ b/src/converters/furniture/FurnitureConverter.ts @@ -38,7 +38,7 @@ export class FurnitureConverter extends SWFConverter { await this._furniDownloader.download(directory, async (habboAssetSwf: HabboAssetSWF) => { - spinner.text = (`Parsing Furniture: ${ habboAssetSwf.getDocumentClass() } (${ this._furniDownloader.totalFinished } / ${ this._furniDownloader.totalItems })`); + spinner.text = (`Parsing Furniture: ${ habboAssetSwf.getDocumentClass() } (${ (this._furniDownloader.totalFinished + 1) } / ${ this._furniDownloader.totalItems })`); spinner.render(); diff --git a/src/converters/furniture/FurnitureDownloader.ts b/src/converters/furniture/FurnitureDownloader.ts index df4b920..edecb60 100644 --- a/src/converters/furniture/FurnitureDownloader.ts +++ b/src/converters/furniture/FurnitureDownloader.ts @@ -121,7 +121,7 @@ export class FurnitureDownloader if(!url || !url.length) return; - url = url.replace('%revision%', revision.toString()); + //url = url.replace('%revision%', revision.toString()); url = url.replace('%className%', className); const logDownloads = this._configuration.getBoolean('misc.log_download_urls'); diff --git a/src/converters/furnituredata/FurnitureDataConverter.ts b/src/converters/furnituredata/FurnitureDataConverter.ts index fb026bf..ff9b8b8 100644 --- a/src/converters/furnituredata/FurnitureDataConverter.ts +++ b/src/converters/furnituredata/FurnitureDataConverter.ts @@ -23,7 +23,7 @@ export class FurnitureDataConverter extends Converter super(); } - public async convertAsync(): Promise + public async convertAsync(args: string[] = []): Promise { return new Promise((resolve, reject) => { diff --git a/src/converters/pet/PetConverter.ts b/src/converters/pet/PetConverter.ts index 538fae7..654c37f 100644 --- a/src/converters/pet/PetConverter.ts +++ b/src/converters/pet/PetConverter.ts @@ -22,7 +22,7 @@ export class PetConverter extends SWFConverter super(); } - public async convertAsync(): Promise + public async convertAsync(args: string[] = []): Promise { if(!this._configuration.getBoolean('convert.pet')) return; diff --git a/src/converters/productdata/ProductDataConverter.ts b/src/converters/productdata/ProductDataConverter.ts index 58340dc..b23ce15 100644 --- a/src/converters/productdata/ProductDataConverter.ts +++ b/src/converters/productdata/ProductDataConverter.ts @@ -19,7 +19,7 @@ export class ProductDataConverter extends Converter super(); } - public async convertAsync(): Promise + public async convertAsync(args: string[] = []): Promise { if(!this._configuration.getBoolean('convert.productdata')) return; diff --git a/src/mapping/json/asset/IAssetData.ts b/src/mapping/json/asset/IAssetData.ts index 058e21c..2bccf86 100644 --- a/src/mapping/json/asset/IAssetData.ts +++ b/src/mapping/json/asset/IAssetData.ts @@ -3,7 +3,9 @@ import { IAsset } from './IAsset'; import { IAssetAlias } from './IAssetAlias'; import { IAssetDimension } from './IAssetDimension'; import { IAssetPalette } from './IAssetPalette'; +import { IPlanetSystem } from './IPlanetSystem'; import { ISoundSample } from './ISoundSample'; +import { IParticleSystem } from './particlesystem'; import { ISpritesheetData } from './spritesheet'; import { IAssetVisualizationData } from './visualization'; @@ -16,6 +18,8 @@ export interface IAssetData { credits?: string; soundSample?: ISoundSample; action?: { link?: string, startState?: number }; + planetSystems?: IPlanetSystem[]; + particleSystems?: IParticleSystem[]; spritesheet?: ISpritesheetData; dimensions?: IAssetDimension; directions?: number[]; diff --git a/src/mapping/json/asset/IPlanetSystem.ts b/src/mapping/json/asset/IPlanetSystem.ts new file mode 100644 index 0000000..16acf87 --- /dev/null +++ b/src/mapping/json/asset/IPlanetSystem.ts @@ -0,0 +1,11 @@ +export interface IPlanetSystem +{ + id?: number; + name?: string; + parent?: string; + radius?: number; + arcSpeed?: number; + arcOffset?: number; + blend?: number; + height?: number; +} diff --git a/src/mapping/json/asset/index.ts b/src/mapping/json/asset/index.ts index eb113bd..88559df 100644 --- a/src/mapping/json/asset/index.ts +++ b/src/mapping/json/asset/index.ts @@ -4,5 +4,6 @@ export * from './IAssetAlias'; export * from './IAssetData'; export * from './IAssetDimension'; export * from './IAssetPalette'; +export * from './IPlanetSystem'; export * from './spritesheet'; export * from './visualization'; diff --git a/src/mapping/json/asset/particlesystem/IParticleSystem.ts b/src/mapping/json/asset/particlesystem/IParticleSystem.ts new file mode 100644 index 0000000..871f5f3 --- /dev/null +++ b/src/mapping/json/asset/particlesystem/IParticleSystem.ts @@ -0,0 +1,11 @@ +import { IParticleSystemEmitter } from './IParticleSystemEmitter'; + +export interface IParticleSystem +{ + size?: number; + canvasId?: number; + offsetY?: number; + blend?: number; + bgColor?: string; + emitters?: IParticleSystemEmitter[]; +} diff --git a/src/mapping/json/asset/particlesystem/IParticleSystemEmitter.ts b/src/mapping/json/asset/particlesystem/IParticleSystemEmitter.ts new file mode 100644 index 0000000..fa175e2 --- /dev/null +++ b/src/mapping/json/asset/particlesystem/IParticleSystemEmitter.ts @@ -0,0 +1,15 @@ +import { IParticleSystemParticle } from './IParticleSystemParticle'; +import { IParticleSystemSimulation } from './IParticleSystemSimulation'; + +export interface IParticleSystemEmitter +{ + id?: number; + name?: string; + spriteId?: number; + maxNumParticles?: number; + particlesPerFrame?: number; + burstPulse?: number; + fuseTime?: number; + simulation?: IParticleSystemSimulation; + particles?: IParticleSystemParticle[]; +} diff --git a/src/mapping/json/asset/particlesystem/IParticleSystemParticle.ts b/src/mapping/json/asset/particlesystem/IParticleSystemParticle.ts new file mode 100644 index 0000000..99281fa --- /dev/null +++ b/src/mapping/json/asset/particlesystem/IParticleSystemParticle.ts @@ -0,0 +1,7 @@ +export interface IParticleSystemParticle +{ + isEmitter?: boolean; + lifeTime?: number; + fade?: boolean; + frames?: string[]; +} diff --git a/src/mapping/json/asset/particlesystem/IParticleSystemSimulation.ts b/src/mapping/json/asset/particlesystem/IParticleSystemSimulation.ts new file mode 100644 index 0000000..fef400c --- /dev/null +++ b/src/mapping/json/asset/particlesystem/IParticleSystemSimulation.ts @@ -0,0 +1,9 @@ +export interface IParticleSystemSimulation +{ + force?: number; + direction?: number; + gravity?: number; + airFriction?: number; + shape?: string; + energy?: number; +} diff --git a/src/mapping/json/asset/particlesystem/index.ts b/src/mapping/json/asset/particlesystem/index.ts new file mode 100644 index 0000000..428f6fc --- /dev/null +++ b/src/mapping/json/asset/particlesystem/index.ts @@ -0,0 +1,4 @@ +export * from './IParticleSystem'; +export * from './IParticleSystemEmitter'; +export * from './IParticleSystemParticle'; +export * from './IParticleSystemSimulation'; diff --git a/src/mapping/mappers/asset/LogicMapper.ts b/src/mapping/mappers/asset/LogicMapper.ts index c0a4ba5..5b39f9d 100644 --- a/src/mapping/mappers/asset/LogicMapper.ts +++ b/src/mapping/mappers/asset/LogicMapper.ts @@ -1,5 +1,6 @@ -import { IAssetData } from '../../json'; -import { LogicXML } from '../../xml'; +import { IAssetData, IPlanetSystem } from '../../json'; +import { IParticleSystem, IParticleSystemEmitter, IParticleSystemParticle, IParticleSystemSimulation } from '../../json/asset/particlesystem'; +import { LogicXML, ParticleSystemEmitterXML, ParticleSystemObjectXML, ParticleSystemParticleXML, ParticleSystemSimulationXML, PlanetSystemObjectXML } from '../../xml'; import { Mapper } from './Mapper'; export class LogicMapper extends Mapper @@ -71,5 +72,147 @@ export class LogicMapper extends Mapper noPitch: xml.soundSample.noPitch }; } + + if(xml.planetSystem !== undefined) + { + if(!output.planetSystems) + { + output.planetSystems = []; + } + + if(xml.planetSystem.objects !== undefined) LogicMapper.mapPlanetSystemXML(xml.planetSystem.objects, output.planetSystems); + } + + if(xml.particleSystem !== undefined) + { + if(!output.particleSystems) + { + output.particleSystems = []; + } + + if(xml.particleSystem.objects !== undefined) LogicMapper.mapParticleSystemXML(xml.particleSystem.objects, output.particleSystems); + } + } + + private static mapPlanetSystemXML(xml: PlanetSystemObjectXML[], output: IPlanetSystem[]): void + { + if(!xml || !xml.length || !output) return; + + for(const planetSystemObjectXML of xml) + { + const planetObject: IPlanetSystem = {}; + + if(planetSystemObjectXML.id !== undefined) planetObject.id = planetSystemObjectXML.id; + if(planetSystemObjectXML.name !== undefined) planetObject.name = planetSystemObjectXML.name; + if(planetSystemObjectXML.parent !== undefined) planetObject.parent = planetSystemObjectXML.parent; + if(planetSystemObjectXML.radius !== undefined) planetObject.radius = planetSystemObjectXML.radius; + if(planetSystemObjectXML.arcSpeed !== undefined) planetObject.arcSpeed = planetSystemObjectXML.arcSpeed; + if(planetSystemObjectXML.arcOffset !== undefined) planetObject.arcOffset = planetSystemObjectXML.arcOffset; + if(planetSystemObjectXML.blend !== undefined) planetObject.blend = planetSystemObjectXML.blend; + if(planetSystemObjectXML.height !== undefined) planetObject.height = planetSystemObjectXML.height; + + output.push(planetObject); + } + } + + private static mapParticleSystemXML(xml: ParticleSystemObjectXML[], output: IParticleSystem[]): void + { + if(!xml || !xml.length || !output) return; + + for(const particleSystemXML of xml) + { + const particleObject: IParticleSystem = {}; + + if(particleSystemXML.size !== undefined) particleObject.size = particleSystemXML.size; + if(particleSystemXML.canvasId !== undefined) particleObject.canvasId = particleSystemXML.canvasId; + if(particleSystemXML.offsetY !== undefined) particleObject.offsetY = particleSystemXML.offsetY; + if(particleSystemXML.blend !== undefined) particleObject.blend = particleSystemXML.blend; + if(particleSystemXML.bgColor !== undefined) particleObject.bgColor = particleSystemXML.bgColor; + + if(particleSystemXML.emitters !== undefined) + { + if(particleSystemXML.emitters.length) + { + particleObject.emitters = []; + + LogicMapper.mapParticleSystemEmitterXML(particleSystemXML.emitters, particleObject.emitters); + } + } + + output.push(particleObject); + } + } + + private static mapParticleSystemEmitterXML(xml: ParticleSystemEmitterXML[], output: IParticleSystemEmitter[]): void + { + if(!xml || !xml.length || !output) return; + + for(const particleSystemEmitterXML of xml) + { + const particleEmitter: IParticleSystemEmitter = {}; + + if(particleSystemEmitterXML.id !== undefined) particleEmitter.id = particleSystemEmitterXML.id; + if(particleSystemEmitterXML.name !== undefined) particleEmitter.name = particleSystemEmitterXML.name; + if(particleSystemEmitterXML.spriteId !== undefined) particleEmitter.spriteId = particleSystemEmitterXML.spriteId; + if(particleSystemEmitterXML.maxNumParticles !== undefined) particleEmitter.maxNumParticles = particleSystemEmitterXML.maxNumParticles; + if(particleSystemEmitterXML.particlesPerFrame !== undefined) particleEmitter.particlesPerFrame = particleSystemEmitterXML.particlesPerFrame; + if(particleSystemEmitterXML.burstPulse !== undefined) particleEmitter.burstPulse = particleSystemEmitterXML.burstPulse; + if(particleSystemEmitterXML.fuseTime !== undefined) particleEmitter.fuseTime = particleSystemEmitterXML.fuseTime; + + if(particleSystemEmitterXML.simulation !== undefined) + { + particleEmitter.simulation = {}; + + LogicMapper.mapParticleSystemSimulationXML(particleSystemEmitterXML.simulation, particleEmitter.simulation); + } + + if(particleSystemEmitterXML.particles !== undefined) + { + if(particleSystemEmitterXML.particles.length) + { + particleEmitter.particles = []; + + LogicMapper.mapParticleSystemParticleXML(particleSystemEmitterXML.particles, particleEmitter.particles); + } + } + + output.push(particleEmitter); + } + } + + private static mapParticleSystemSimulationXML(xml: ParticleSystemSimulationXML, output: IParticleSystemSimulation): void + { + if(!xml || !output) return; + + if(xml.force !== undefined) output.force = xml.force; + if(xml.direction !== undefined) output.direction = xml.direction; + if(xml.gravity !== undefined) output.gravity = xml.gravity; + if(xml.airFriction !== undefined) output.airFriction = xml.airFriction; + if(xml.shape !== undefined) output.shape = xml.shape; + if(xml.energy !== undefined) output.energy = xml.energy; + } + + private static mapParticleSystemParticleXML(xml: ParticleSystemParticleXML[], output: IParticleSystemParticle[]): void + { + if(!xml || !xml.length || !output) return; + + for(const particleSystemParticleXML of xml) + { + const particle: IParticleSystemParticle = {}; + + if(particleSystemParticleXML.isEmitter !== undefined) particle.isEmitter = particleSystemParticleXML.isEmitter; + if(particleSystemParticleXML.lifeTime !== undefined) particle.lifeTime = particleSystemParticleXML.lifeTime; + if(particleSystemParticleXML.fade !== undefined) particle.fade = particleSystemParticleXML.fade; + + if(particleSystemParticleXML.frames !== undefined) + { + if(particleSystemParticleXML.frames.length) + { + particle.frames = particleSystemParticleXML.frames; + } + } + + output.push(particle); + } } } diff --git a/src/mapping/xml/asset/logic/LogicXML.ts b/src/mapping/xml/asset/logic/LogicXML.ts index 9f05ab3..6a64ad1 100644 --- a/src/mapping/xml/asset/logic/LogicXML.ts +++ b/src/mapping/xml/asset/logic/LogicXML.ts @@ -2,7 +2,9 @@ import { ActionXML } from './ActionXML'; import { CreditsXML } from './CreditsXML'; import { MaskXML } from './MaskXML'; import { ModelXML } from './model/ModelXML'; -import {SoundSampleXML} from "./SoundSampleXML"; +import { ParticleSystemXML } from './ParticleSystemXML'; +import { PlanetSystemXML } from './PlanetSystemXML'; +import { SoundSampleXML } from './SoundSampleXML'; export class LogicXML { @@ -12,6 +14,8 @@ export class LogicXML private readonly _mask: MaskXML; private readonly _credits: CreditsXML; private readonly _soundSample: SoundSampleXML; + private readonly _planetSystem: PlanetSystemXML; + private readonly _particleSystem: ParticleSystemXML; constructor(xml: any) { @@ -46,6 +50,16 @@ export class LogicXML { if(xml.sound[0] !== undefined) this._soundSample = new SoundSampleXML(xml.sound[0].sample); } + + if(xml.planetsystem !== undefined) + { + if(xml.planetsystem[0] !== undefined) this._planetSystem = new PlanetSystemXML(xml.planetsystem[0]); + } + + if(xml.particlesystems !== undefined) + { + if(xml.particlesystems[0] !== undefined) this._particleSystem = new ParticleSystemXML(xml.particlesystems[0]); + } } public get type(): string @@ -58,23 +72,33 @@ export class LogicXML return this._model; } - public get action(): ActionXML | undefined + public get action(): ActionXML { return this._action; } - public get mask(): MaskXML | undefined + public get mask(): MaskXML { return this._mask; } - public get credits(): CreditsXML | undefined + public get credits(): CreditsXML { return this._credits; } - public get soundSample(): SoundSampleXML | undefined + public get soundSample(): SoundSampleXML { return this._soundSample; } + + public get planetSystem(): PlanetSystemXML + { + return this._planetSystem; + } + + public get particleSystem(): ParticleSystemXML + { + return this._particleSystem; + } } diff --git a/src/mapping/xml/asset/logic/ParticleSystemEmitterXML.ts b/src/mapping/xml/asset/logic/ParticleSystemEmitterXML.ts new file mode 100644 index 0000000..9a4706a --- /dev/null +++ b/src/mapping/xml/asset/logic/ParticleSystemEmitterXML.ts @@ -0,0 +1,91 @@ +import { ParticleSystemParticleXML } from './ParticleSystemParticleXML'; +import { ParticleSystemSimulationXML } from './ParticleSystemSimulationXML'; + +export class ParticleSystemEmitterXML +{ + private _id: number; + private _name: string; + private _spriteId: number; + private _maxNumParticles: number; + private _particlesPerFrame: number; + private _burstPulse: number = 1; + private _fuseTime: number; + private _simulation: ParticleSystemSimulationXML; + private _particles: ParticleSystemParticleXML[]; + + constructor(xml: any) + { + const attributes = xml.$; + + if(attributes !== undefined) + { + if(attributes.id !== undefined) this._id = parseInt(attributes.id); + if(attributes.name !== undefined) this._name = attributes.name; + if(attributes.sprite_id !== undefined) this._spriteId = parseInt(attributes.sprite_id); + if(attributes.max_num_particles !== undefined) this._maxNumParticles = parseInt(attributes.max_num_particles); + if(attributes.particles_per_frame !== undefined) this._particlesPerFrame = parseInt(attributes.particles_per_frame); + if(attributes.burst_pulse !== undefined) this._burstPulse = parseInt(attributes.burst_pulse); + if(attributes.fuse_time !== undefined) this._fuseTime = parseInt(attributes.fuse_time); + } + + if(xml.simulation !== undefined) + { + if(xml.simulation[0] !== undefined) this._simulation = new ParticleSystemSimulationXML(xml.simulation[0]); + } + + if((xml.particles !== undefined) && (xml.particles[0] !== undefined)) + { + if(Array.isArray(xml.particles[0].particle)) + { + this._particles = []; + + for(const particle of xml.particles[0].particle) this._particles.push(new ParticleSystemParticleXML(particle)); + } + } + } + + public get id(): number + { + return this._id; + } + + public get name(): string + { + return this._name; + } + + public get spriteId(): number + { + return this._spriteId; + } + + public get maxNumParticles(): number + { + return this._maxNumParticles; + } + + public get particlesPerFrame(): number + { + return this._particlesPerFrame; + } + + public get burstPulse(): number + { + return this._burstPulse; + } + + public get fuseTime(): number + { + return this._fuseTime; + } + + public get simulation(): ParticleSystemSimulationXML + { + return this._simulation; + } + + public get particles(): ParticleSystemParticleXML[] + { + return this._particles; + } +} diff --git a/src/mapping/xml/asset/logic/ParticleSystemObjectXML.ts b/src/mapping/xml/asset/logic/ParticleSystemObjectXML.ts new file mode 100644 index 0000000..47f6802 --- /dev/null +++ b/src/mapping/xml/asset/logic/ParticleSystemObjectXML.ts @@ -0,0 +1,65 @@ +import { ParticleSystemEmitterXML } from './ParticleSystemEmitterXML'; + +export class ParticleSystemObjectXML +{ + private readonly _size: number; + private readonly _canvasId: number; + private readonly _offsetY: number; + private readonly _blend: number; + private readonly _bgColor: string; + private readonly _emitters: ParticleSystemEmitterXML[]; + + constructor(xml: any) + { + const attributes = xml.$; + + if(attributes !== undefined) + { + if(attributes.size !== undefined) this._size = parseInt(attributes.size); + if(attributes.canvas_id !== undefined) this._canvasId = parseInt(attributes.canvas_id); + if(attributes.offset_y !== undefined) this._offsetY = parseFloat(attributes.offset_y); + if(attributes.blend !== undefined) this._blend = parseFloat(attributes.blend); + if(attributes.bgcolor !== undefined) this._bgColor = attributes.bgcolor; + } + + if(xml.emitter !== undefined) + { + if(Array.isArray(xml.emitter)) + { + this._emitters = []; + + for(const emitter of xml.emitter) this._emitters.push(new ParticleSystemEmitterXML(emitter)); + } + } + } + + public get size(): number + { + return this._size; + } + + public get canvasId(): number + { + return this._canvasId; + } + + public get offsetY(): number + { + return this._offsetY; + } + + public get blend(): number + { + return this._blend; + } + + public get bgColor(): string + { + return this._bgColor; + } + + public get emitters(): ParticleSystemEmitterXML[] + { + return this._emitters; + } +} diff --git a/src/mapping/xml/asset/logic/ParticleSystemParticleXML.ts b/src/mapping/xml/asset/logic/ParticleSystemParticleXML.ts new file mode 100644 index 0000000..b31c37e --- /dev/null +++ b/src/mapping/xml/asset/logic/ParticleSystemParticleXML.ts @@ -0,0 +1,50 @@ + +export class ParticleSystemParticleXML +{ + private readonly _isEmitter: boolean; + private readonly _lifeTime: number; + private readonly _fade: boolean; + private readonly _frames: string[]; + + constructor(xml: any) + { + const attributes = xml.$; + + if(attributes !== undefined) + { + if(attributes.is_emitter !== undefined) this._isEmitter = (attributes.is_emitter === 'true'); + if(attributes.lifetime !== undefined) this._lifeTime = parseInt(attributes.lifetime); + if(attributes.fade !== undefined) this._fade = (attributes.fade === 'true'); + } + + if(xml.frame !== undefined) + { + if(Array.isArray(xml.frame)) + { + this._frames = []; + + for(const frame of xml.frame) this._frames.push(frame.$.name); + } + } + } + + public get isEmitter(): boolean + { + return this._isEmitter; + } + + public get lifeTime(): number + { + return this._lifeTime; + } + + public get fade(): boolean + { + return this._fade; + } + + public get frames(): string[] + { + return this._frames; + } +} diff --git a/src/mapping/xml/asset/logic/ParticleSystemSimulationXML.ts b/src/mapping/xml/asset/logic/ParticleSystemSimulationXML.ts new file mode 100644 index 0000000..d11f806 --- /dev/null +++ b/src/mapping/xml/asset/logic/ParticleSystemSimulationXML.ts @@ -0,0 +1,55 @@ + +export class ParticleSystemSimulationXML +{ + private _force: number; + private _direction: number; + private _gravity: number; + private _airFriction: number; + private _shape: string; + private _energy: number; + + constructor(xml: any) + { + const attributes = xml.$; + + if(attributes !== undefined) + { + if(attributes.force !== undefined) this._force = parseFloat(attributes.force); + if(attributes.direction !== undefined) this._direction = parseFloat(attributes.direction); + if(attributes.gravity !== undefined) this._gravity = parseFloat(attributes.gravity); + if(attributes.airfriction !== undefined) this._airFriction = parseFloat(attributes.airfriction); + if(attributes.shape !== undefined) this._shape = attributes.shape; + if(attributes.energy !== undefined) this._energy = parseFloat(attributes.energy); + } + } + + public get force(): number + { + return this._force; + } + + public get direction(): number + { + return this._direction; + } + + public get gravity(): number + { + return this._gravity; + } + + public get airFriction(): number + { + return this._airFriction; + } + + public get shape(): string + { + return this._shape; + } + + public get energy(): number + { + return this._energy; + } +} diff --git a/src/mapping/xml/asset/logic/ParticleSystemXML.ts b/src/mapping/xml/asset/logic/ParticleSystemXML.ts new file mode 100644 index 0000000..a8a3c93 --- /dev/null +++ b/src/mapping/xml/asset/logic/ParticleSystemXML.ts @@ -0,0 +1,24 @@ +import { ParticleSystemObjectXML } from './ParticleSystemObjectXML'; + +export class ParticleSystemXML +{ + private readonly _objects: ParticleSystemObjectXML[]; + + constructor(xml: any) + { + if(xml.particlesystem !== undefined) + { + if(Array.isArray(xml.particlesystem)) + { + this._objects = []; + + for(const object of xml.particlesystem) this._objects.push(new ParticleSystemObjectXML(object)); + } + } + } + + public get objects(): ParticleSystemObjectXML[] + { + return this._objects; + } +} diff --git a/src/mapping/xml/asset/logic/PlanetSystemObjectXML.ts b/src/mapping/xml/asset/logic/PlanetSystemObjectXML.ts new file mode 100644 index 0000000..fb9d718 --- /dev/null +++ b/src/mapping/xml/asset/logic/PlanetSystemObjectXML.ts @@ -0,0 +1,68 @@ +export class PlanetSystemObjectXML +{ + private readonly _id: number; + private readonly _name: string; + private readonly _parent: string; + private readonly _radius: number; + private readonly _arcSpeed: number; + private readonly _arcOffset: number; + private readonly _blend: number; + private readonly _height: number; + + constructor(xml: any) + { + const attributes = xml.$; + + if(attributes !== undefined) + { + if(attributes.id !== undefined) this._id = parseInt(attributes.id); + if(attributes.name !== undefined) this._name = attributes.name; + if(attributes.parent !== undefined) this._parent = attributes.parent; + if(attributes.radius !== undefined) this._radius = parseFloat(attributes.radius); + if(attributes.arcspeed !== undefined) this._arcSpeed = parseFloat(attributes.arcspeed); + if(attributes.arcoffset !== undefined) this._arcOffset = parseFloat(attributes.arcoffset); + if(attributes.blend !== undefined) this._blend = parseFloat(attributes.blend); + if(attributes.height !== undefined) this._height = parseFloat(attributes.height); + } + } + + public get id(): number + { + return this._id; + } + + public get name(): string + { + return this._name; + } + + public get parent(): string + { + return this._parent; + } + + public get radius(): number + { + return this._radius; + } + + public get arcSpeed(): number + { + return this._arcSpeed; + } + + public get arcOffset(): number + { + return this._arcOffset; + } + + public get blend(): number + { + return this._blend; + } + + public get height(): number + { + return this._height; + } +} diff --git a/src/mapping/xml/asset/logic/PlanetSystemXML.ts b/src/mapping/xml/asset/logic/PlanetSystemXML.ts new file mode 100644 index 0000000..4374064 --- /dev/null +++ b/src/mapping/xml/asset/logic/PlanetSystemXML.ts @@ -0,0 +1,24 @@ +import { PlanetSystemObjectXML } from './PlanetSystemObjectXML'; + +export class PlanetSystemXML +{ + private readonly _objects: PlanetSystemObjectXML[]; + + constructor(xml: any) + { + if(xml.object !== undefined) + { + if(Array.isArray(xml.object)) + { + this._objects = []; + + for(const object of xml.object) this._objects.push(new PlanetSystemObjectXML(object)); + } + } + } + + public get objects(): PlanetSystemObjectXML[] + { + return this._objects; + } +} diff --git a/src/mapping/xml/asset/logic/index.ts b/src/mapping/xml/asset/logic/index.ts index 5a6c823..8876f19 100644 --- a/src/mapping/xml/asset/logic/index.ts +++ b/src/mapping/xml/asset/logic/index.ts @@ -3,4 +3,11 @@ export * from './CreditsXML'; export * from './LogicXML'; export * from './MaskXML'; export * from './model'; +export * from './ParticleSystemEmitterXML'; +export * from './ParticleSystemObjectXML'; +export * from './ParticleSystemParticleXML'; +export * from './ParticleSystemSimulationXML'; +export * from './ParticleSystemXML'; +export * from './PlanetSystemObjectXML'; +export * from './PlanetSystemXML'; export * from './SoundSampleXML'; diff --git a/src/mapping/xml/asset/manifest/ManifestLibraryXML.ts b/src/mapping/xml/asset/manifest/ManifestLibraryXML.ts index 50ff89b..b27516d 100644 --- a/src/mapping/xml/asset/manifest/ManifestLibraryXML.ts +++ b/src/mapping/xml/asset/manifest/ManifestLibraryXML.ts @@ -51,6 +51,16 @@ export class ManifestLibraryXML } } + public get name(): string + { + return this._name; + } + + public get version(): string + { + return this._version; + } + public get assets(): ManifestLibraryAssetXML[] { return this._assets; diff --git a/src/swf/HabboAssetSWF.ts b/src/swf/HabboAssetSWF.ts index 41880e0..875ba14 100644 --- a/src/swf/HabboAssetSWF.ts +++ b/src/swf/HabboAssetSWF.ts @@ -1,26 +1,31 @@ import CustomIterator from '../utils/CustomIterator'; -import {readImagesDefineBitsLossless, readImagesJPEG3or4, readSwfAsync} from '../utils/SwfReader'; -import {CharacterTag} from './tags/CharacterTag'; -import {DefineBinaryDataTag} from './tags/DefineBinaryDataTag'; -import {ImageTag} from './tags/ImageTag'; -import {ITag} from './tags/ITag'; -import {SymbolClassTag} from './tags/SymbolClassTag'; +import { readImagesDefineBitsLossless, readImagesJPEG3or4, readSwfAsync } from '../utils/SwfReader'; +import { CharacterTag } from './tags/CharacterTag'; +import { DefineBinaryDataTag } from './tags/DefineBinaryDataTag'; +import { ImageTag } from './tags/ImageTag'; +import { ITag } from './tags/ITag'; +import { SymbolClassTag } from './tags/SymbolClassTag'; -export class HabboAssetSWF { +export class HabboAssetSWF +{ private readonly _tags: Array; private _documentClass: string | null = null; constructor( private readonly _data: string | Buffer - ) { + ) + { this._tags = new Array(); } - async setupAsync() { + async setupAsync() + { const swf = await readSwfAsync(this._data); - for (const tag of swf.tags) { + for(const tag of swf.tags) + { - switch (tag.header.code) { + switch(tag.header.code) + { case 76: this._tags.push(new SymbolClassTag(tag.symbols)); break; @@ -97,37 +102,47 @@ export class HabboAssetSWF { this.assignClassesToSymbols(); } - public imageTags(): Array { + public imageTags(): Array + { return this._tags.filter((tag: ITag) => tag instanceof ImageTag).map(x => x as ImageTag); } - public symbolTags(): Array { + public symbolTags(): Array + { return this._tags.filter((tag: ITag) => tag instanceof SymbolClassTag).map(x => x as SymbolClassTag); } - private binaryTags(): Array { + private binaryTags(): Array + { return this._tags.filter((tag: ITag) => tag instanceof DefineBinaryDataTag).map(x => x as DefineBinaryDataTag); } - private assignClassesToSymbols() { + private assignClassesToSymbols() + { const classes: Map = new Map(); let iterator: CustomIterator = new CustomIterator(this._tags); // eslint-disable-next-line no-constant-condition - while (true) { + while(true) + { let t: ITag; - do { - if (!iterator.hasNext()) { + do + { + if(!iterator.hasNext()) + { iterator = new CustomIterator(this._tags); - while (iterator.hasNext()) { + while(iterator.hasNext()) + { t = iterator.next(); - if (t instanceof CharacterTag) { + if(t instanceof CharacterTag) + { const ct = t as CharacterTag; - if (classes.has(ct.characterId)) { + if(classes.has(ct.characterId)) + { // @ts-ignore ct.className = classes.get(ct.characterId); } @@ -138,37 +153,46 @@ export class HabboAssetSWF { } t = iterator.next(); - } while (!(t instanceof SymbolClassTag)); + } while(!(t instanceof SymbolClassTag)); const sct = t as SymbolClassTag; - for (let i = 0; i < sct.tags.length; ++i) { - if (!classes.has(sct.tags[i]) && !Array.from(classes.values()).includes(sct.names[i])) { + for(let i = 0; i < sct.tags.length; ++i) + { + if(!classes.has(sct.tags[i]) && !Array.from(classes.values()).includes(sct.names[i])) + { classes.set(sct.tags[i], sct.names[i]); } } } } - public getBinaryTagByName(name: string): DefineBinaryDataTag | null { + public getBinaryTagByName(name: string): DefineBinaryDataTag | null + { const streamTag = this.binaryTags() .filter(tag => tag.className === name)[0]; - if (streamTag === undefined) return null; + if(streamTag === undefined) return null; return streamTag; } - public getFullClassName(type: string, documentNameTwice: boolean): string { + public getFullClassName(type: string, documentNameTwice: boolean): string + { return this.getFullClassNameSnake(type, documentNameTwice, false); } - public getFullClassNameSnake(type: string, documentNameTwice: boolean, snakeCase: boolean): string { + public getFullClassNameSnake(type: string, documentNameTwice: boolean, snakeCase: boolean): string + { let result: string = this.getDocumentClass() + '_'; - if (documentNameTwice) { - if (snakeCase) { + if(documentNameTwice) + { + if(snakeCase) + { //result += CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, this.swf.getDocumentClass()) + "_"; - } else { + } + else + { result += this.getDocumentClass() + '_'; } } @@ -176,26 +200,32 @@ export class HabboAssetSWF { return result + type; } - public getDocumentClass(): string { - if (this._documentClass !== null) return this._documentClass; + public getDocumentClass(): string + { + if(this._documentClass !== null) return this._documentClass; const iterator: CustomIterator = new CustomIterator(this._tags); // eslint-disable-next-line no-constant-condition - while (true) { + while(true) + { let t: ITag; - do { - if (!iterator.hasNext()) { + do + { + if(!iterator.hasNext()) + { return ''; } t = iterator.next(); - } while (!(t instanceof SymbolClassTag)); + } while(!(t instanceof SymbolClassTag)); const sc = t as SymbolClassTag; - for (let i = 0; i < sc.tags.length; ++i) { - if (sc.tags[i] == 0) { + for(let i = 0; i < sc.tags.length; ++i) + { + if(sc.tags[i] == 0) + { this._documentClass = sc.names[i]; return this._documentClass; }