Move to Renderer V2

This commit is contained in:
duckietm
2024-04-03 09:27:56 +02:00
parent 110c3ad393
commit b3134ce50b
4080 changed files with 115593 additions and 66375 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"extends": [ "@nitrots/eslint-config" ]
}
+51
View File
@@ -0,0 +1,51 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events*.json
speed-measure-plugin*.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
.git
# System Files
.DS_Store
Thumbs.db
*.zip
*.as
*.bin
+1
View File
@@ -0,0 +1 @@
export * from './src';
+26
View File
@@ -0,0 +1,26 @@
{
"name": "@nitrots/room",
"description": "Nitro room module",
"version": "1.0.0",
"type": "module",
"license": "GPL-3.0",
"scripts": {
"compile": "tsc --project ./tsconfig.json --noEmit false",
"eslint": "eslint ./src --fix"
},
"main": "./index",
"dependencies": {
"@nitrots/api": "1.0.0",
"@nitrots/assets": "1.0.0",
"@nitrots/avatar": "1.0.0",
"@nitrots/communication": "1.0.0",
"@nitrots/configuration": "1.0.0",
"@nitrots/eslint-config": "1.0.0",
"@nitrots/events": "1.0.0",
"@nitrots/session": "1.0.0",
"pixi.js": "^8.0.4"
},
"devDependencies": {
"typescript": "~5.4.2"
}
}
@@ -0,0 +1,5 @@
import { RoomContentLoader } from './RoomContentLoader';
const roomContentLoader = new RoomContentLoader();
export const GetRoomContentLoader = () => roomContentLoader;
+5
View File
@@ -0,0 +1,5 @@
import { RoomEngine } from './RoomEngine';
const roomEngine = new RoomEngine();
export const GetRoomEngine = () => roomEngine;
+5
View File
@@ -0,0 +1,5 @@
import { RoomManager } from './RoomManager';
const roomManager = new RoomManager();
export const GetRoomManager = () => roomManager;
@@ -0,0 +1,5 @@
import { RoomMessageHandler } from './RoomMessageHandler';
const roomMessageHandler = new RoomMessageHandler();
export const GetRoomMessageHandler = () => roomMessageHandler;
@@ -0,0 +1,5 @@
import { RoomObjectLogicFactory } from './RoomObjectLogicFactory';
const roomObjectLogicFactory = new RoomObjectLogicFactory();
export const GetRoomObjectLogicFactory = () => roomObjectLogicFactory;
@@ -0,0 +1,5 @@
import { RoomObjectVisualizationFactory } from './RoomObjectVisualizationFactory';
const roomObjectVisualizationFactory = new RoomObjectVisualizationFactory();
export const GetRoomObjectVisualizationFactory = () => roomObjectVisualizationFactory;
+19
View File
@@ -0,0 +1,19 @@
import { IImageResult } from '@nitrots/api';
import { TextureUtils } from '@nitrots/utils';
import { Texture } from 'pixi.js';
export class ImageResult implements IImageResult
{
public id: number = 0;
public data: Texture = null;
public image: HTMLImageElement = null;
public async getImage(): Promise<HTMLImageElement>
{
if(this.image) return this.image;
if(!this.data) return null;
return await TextureUtils.generateImage(this.data);
}
}
+61
View File
@@ -0,0 +1,61 @@
import { IPetColorResult } from '@nitrots/api';
export class PetColorResult implements IPetColorResult
{
private static COLOR_TAGS: string[] = ['Null', 'Black', 'White', 'Grey', 'Red', 'Orange', 'Pink', 'Green', 'Lime', 'Blue', 'Light-Blue', 'Dark-Blue', 'Yellow', 'Brown', 'Dark-Brown', 'Beige', 'Cyan', 'Purple', 'Gold'];
private _breed: number;
private _tag: string;
private _id: string;
private _primaryColor: number;
private _secondaryColor: number;
private _isMaster: boolean;
private _layerTags: string[];
constructor(primaryColor: number, secondaryColor: number, breed: number, tag: number, id: string, isMaster: boolean, layerTags: string[])
{
this._layerTags = [];
this._primaryColor = (primaryColor & 0xFFFFFF);
this._secondaryColor = (secondaryColor & 0xFFFFFF);
this._breed = breed;
this._tag = (((tag > -1) && (tag < PetColorResult.COLOR_TAGS.length)) ? PetColorResult.COLOR_TAGS[tag] : '');
this._id = id;
this._isMaster = isMaster;
this._layerTags = layerTags;
}
public get primaryColor(): number
{
return this._primaryColor;
}
public get secondaryColor(): number
{
return this._secondaryColor;
}
public get breed(): number
{
return this._breed;
}
public get tag(): string
{
return this._tag;
}
public get id(): string
{
return this._id;
}
public get isMaster(): boolean
{
return this._isMaster;
}
public get layerTags(): string[]
{
return this._layerTags;
}
}
+512
View File
@@ -0,0 +1,512 @@
import { FurnitureType, IEventDispatcher, IFurnitureData, IGraphicAssetCollection, IPetColorResult, IRoomContentListener, IRoomContentLoader, IRoomObject, RoomObjectCategory, RoomObjectUserType, RoomObjectVariable, RoomObjectVisualizationType } from '@nitrots/api';
import { GetAssetManager } from '@nitrots/assets';
import { GetConfiguration } from '@nitrots/configuration';
import { GetEventDispatcher, RoomContentLoadedEvent } from '@nitrots/events';
import { GetSessionDataManager } from '@nitrots/session';
import { NitroLogger } from '@nitrots/utils';
import { Texture } from 'pixi.js';
import { PetColorResult } from './PetColorResult';
export class RoomContentLoader implements IRoomContentLoader
{
private static PLACE_HOLDER: string = 'place_holder';
private static PLACE_HOLDER_WALL: string = 'place_holder_wall';
private static PLACE_HOLDER_PET: string = 'place_holder_pet';
private static PLACE_HOLDER_DEFAULT: string = RoomContentLoader.PLACE_HOLDER;
private static ROOM: string = 'room';
private static TILE_CURSOR: string = 'tile_cursor';
private static SELECTION_ARROW: string = 'selection_arrow';
public static MANDATORY_LIBRARIES: string[] = [RoomContentLoader.PLACE_HOLDER, RoomContentLoader.PLACE_HOLDER_WALL, RoomContentLoader.PLACE_HOLDER_PET, RoomContentLoader.ROOM, RoomContentLoader.TILE_CURSOR, RoomContentLoader.SELECTION_ARROW];
private _iconListener: IRoomContentListener;
private _images: Map<string, HTMLImageElement> = new Map();
private _activeObjects: { [index: string]: number } = {};
private _activeObjectTypes: Map<number, string> = new Map();
private _activeObjectTypeIds: Map<string, number> = new Map();
private _objectTypeAdUrls: Map<string, string> = new Map();
private _wallItems: { [index: string]: number } = {};
private _wallItemTypes: Map<number, string> = new Map();
private _wallItemTypeIds: Map<string, number> = new Map();
private _furniRevisions: Map<string, number> = new Map();
private _pets: { [index: string]: number } = {};
private _petColors: Map<number, Map<number, IPetColorResult>> = new Map();
private _objectAliases: Map<string, string> = new Map();
private _objectOriginalNames: Map<string, string> = new Map();
private _pendingContentTypes: string[] = [];
public async init(): Promise<void>
{
this.processFurnitureData(GetSessionDataManager().getAllFurnitureData());
for(const [index, name] of GetConfiguration().getValue<string[]>('pet.types').entries()) this._pets[name] = index;
await Promise.all(RoomContentLoader.MANDATORY_LIBRARIES.map(value => this.downloadAsset(value)));
}
public processFurnitureData(furnitureData: IFurnitureData[]): void
{
if(!furnitureData) return;
for(const furniture of furnitureData)
{
if(!furniture) continue;
const id = furniture.id;
let className = furniture.className;
if(furniture.hasIndexedColor) className = ((className + '*') + furniture.colorIndex);
const revision = furniture.revision;
const adUrl = furniture.adUrl;
if(adUrl && adUrl.length > 0) this._objectTypeAdUrls.set(className, adUrl);
let name = furniture.className;
if(furniture.type === FurnitureType.FLOOR)
{
this._activeObjectTypes.set(id, className);
this._activeObjectTypeIds.set(className, id);
if(!this._activeObjects[name]) this._activeObjects[name] = 1;
}
else if(furniture.type === FurnitureType.WALL)
{
if(name === 'post.it')
{
className = 'post_it';
name = 'post_it';
}
if(name === 'post.it.vd')
{
className = 'post_it_vd';
name = 'post_id_vd';
}
this._wallItemTypes.set(id, className);
this._wallItemTypeIds.set(className, id);
if(!this._wallItems[name]) this._wallItems[name] = 1;
}
const existingRevision = this._furniRevisions.get(name);
if(revision > existingRevision)
{
this._furniRevisions.delete(name);
this._furniRevisions.set(name, revision);
}
}
}
public getFurnitureFloorNameForTypeId(typeId: number): string
{
const type = this._activeObjectTypes.get(typeId);
return this.removeColorIndex(type);
}
public getFurnitureWallNameForTypeId(typeId: number, extra: string = null): string
{
let type = this._wallItemTypes.get(typeId);
if((type === 'poster') && (extra !== null)) type = (type + extra);
return this.removeColorIndex(type);
}
public getFurnitureFloorColorIndex(typeId: number): number
{
const type = this._activeObjectTypes.get(typeId);
if(!type) return -1;
return this.getColorIndexFromName(type);
}
public getFurnitureWallColorIndex(typeId: number): number
{
const type = this._wallItemTypes.get(typeId);
if(!type) return -1;
return this.getColorIndexFromName(type);
}
private getColorIndexFromName(name: string): number
{
if(!name) return -1;
const index = name.indexOf('*');
if(index === -1) return 0;
return parseInt(name.substr(index + 1));
}
private removeColorIndex(name: string): string
{
if(!name) return null;
const index = name.indexOf('*');
if(index === -1) return name;
return name.substr(0, index);
}
public getRoomObjectAdUrl(type: string): string
{
const value = this._objectTypeAdUrls.get(type);
if(!value) return '';
return value;
}
public getPetColorResult(petIndex: number, paletteIndex: number): IPetColorResult
{
const colorResults = this._petColors.get(petIndex);
if(!colorResults) return null;
return colorResults.get(paletteIndex);
}
public getPetColorResultsForTag(petIndex: number, tagName: string): IPetColorResult[]
{
const colorResults = this._petColors.get(petIndex);
const results: IPetColorResult[] = [];
if(colorResults)
{
for(const result of colorResults.values())
{
if(result.tag === tagName) results.push(result);
}
}
return results;
}
public getCollection(name: string): IGraphicAssetCollection
{
return GetAssetManager().getCollection(name);
}
public getImage(name: string): HTMLImageElement
{
if(!name) return null;
const existing = this._images.get(name);
if(!existing) return null;
const image = new Image();
image.src = existing.src;
return image;
}
public addAssetToCollection(collectionName: string, assetName: string, texture: Texture, override: boolean = true): boolean
{
return GetAssetManager().addAssetToCollection(collectionName, assetName, texture, override);
}
public getPlaceholderName(type: string): string
{
const category = this.getCategoryForType(type);
switch(category)
{
case RoomObjectCategory.FLOOR:
return RoomContentLoader.PLACE_HOLDER;
case RoomObjectCategory.WALL:
return RoomContentLoader.PLACE_HOLDER_WALL;
default:
if(this._pets[type] !== undefined) return RoomContentLoader.PLACE_HOLDER_PET;
return RoomContentLoader.PLACE_HOLDER_DEFAULT;
}
}
public getCategoryForType(type: string): number
{
if(!type) return RoomObjectCategory.MINIMUM;
if(this._activeObjects[type] !== undefined) return RoomObjectCategory.FLOOR;
if(this._wallItems[type] !== undefined) return RoomObjectCategory.WALL;
if(this._pets[type] !== undefined) return RoomObjectCategory.UNIT;
if(type.indexOf('poster') === 0) return RoomObjectCategory.WALL;
if(type === 'room') return RoomObjectCategory.ROOM;
if(type === RoomObjectUserType.USER) return RoomObjectCategory.UNIT;
if(type === RoomObjectUserType.PET) return RoomObjectCategory.UNIT;
if(type === RoomObjectUserType.BOT) return RoomObjectCategory.UNIT;
if(type === RoomObjectUserType.RENTABLE_BOT) return RoomObjectCategory.UNIT;
if((type === RoomContentLoader.TILE_CURSOR) || (type === RoomContentLoader.SELECTION_ARROW)) return RoomObjectCategory.CURSOR;
return RoomObjectCategory.MINIMUM;
}
public getPetNameForType(type: number): string
{
return GetConfiguration().getValue<string[]>('pet.types')[type] || null;
}
public isLoaderType(type: string): boolean
{
type = RoomObjectUserType.getRealType(type);
if(type === RoomObjectVisualizationType.USER) return false;
return true;
}
public downloadImage(id: number, type: string, param: string, events: IEventDispatcher = null): boolean
{
let typeName: string = null;
let assetUrls: string[] = [];
if(type && (type.indexOf(',') >= 0))
{
typeName = type;
type = typeName.split(',')[0];
}
if(typeName)
{
assetUrls = this.getAssetUrls(typeName, param, true);
}
else
{
assetUrls = this.getAssetUrls(type, param, true);
}
if(assetUrls && assetUrls.length)
{
const url = assetUrls[0];
const image = new Image();
image.src = url;
image.onload = () =>
{
image.onerror = null;
this._images.set(([type, param].join('_')), image);
this._iconListener.onRoomContentLoaded(id, [type, param].join('_'), true);
};
image.onerror = () =>
{
image.onload = null;
NitroLogger.error('Failed to download asset', url);
this._iconListener.onRoomContentLoaded(id, [type, param].join('_'), false);
};
return true;
}
return false;
}
public async downloadAsset(type: string): Promise<void>
{
const assetUrl: string = this.getAssetUrls(type)?.[0];
if(!assetUrl || !assetUrl.length) return;
if((this._pendingContentTypes.indexOf(type) >= 0)) return;
this._pendingContentTypes.push(type);
if(!await GetAssetManager().downloadAsset(assetUrl))
{
GetEventDispatcher().dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_FAILURE, type));
return;
}
const petIndex = this._pets[type];
if(petIndex !== undefined)
{
const collection = this.getCollection(type);
const keys = collection.getPaletteNames();
const palettes: Map<number, IPetColorResult> = new Map();
for(const key of keys)
{
const palette = collection.getPalette(key);
const paletteData = collection.data.palettes[key];
const primaryColor = palette.primaryColor;
const secondaryColor = palette.secondaryColor;
const breed = ((paletteData.breed !== undefined) ? paletteData.breed : 0);
const tag = ((paletteData.colorTag !== undefined) ? paletteData.colorTag : -1);
const master = ((paletteData.master !== undefined) ? paletteData.master : false);
const layerTags = ((paletteData.tags !== undefined) ? paletteData.tags : []);
palettes.set(parseInt(key), new PetColorResult(primaryColor, secondaryColor, breed, tag, key, master, layerTags));
}
this._petColors.set(petIndex, palettes);
}
GetEventDispatcher().dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_SUCCESS, type));
}
public getAssetAliasName(name: string): string
{
const existing = this._objectAliases.get(name);
if(!existing) return name;
return existing;
}
public setAssetAliasName(name: string, originalName: string): void
{
this._objectAliases.set(name, originalName);
this._objectOriginalNames.set(originalName, name);
}
private getAssetOriginalName(name: string): string
{
const existing = this._objectOriginalNames.get(name);
if(!existing) return name;
return existing;
}
public getAssetUrls(type: string, param: string = null, icon: boolean = false): string[]
{
switch(type)
{
case RoomContentLoader.PLACE_HOLDER:
return [this.getAssetUrlWithGenericBase(RoomContentLoader.PLACE_HOLDER)];
case RoomContentLoader.PLACE_HOLDER_WALL:
return [this.getAssetUrlWithGenericBase(RoomContentLoader.PLACE_HOLDER_WALL)];
case RoomContentLoader.PLACE_HOLDER_PET:
return [this.getAssetUrlWithGenericBase(RoomContentLoader.PLACE_HOLDER_PET)];
case RoomContentLoader.ROOM:
return [this.getAssetUrlWithGenericBase('room')];
case RoomContentLoader.TILE_CURSOR:
return [this.getAssetUrlWithGenericBase(RoomContentLoader.TILE_CURSOR)];
case RoomContentLoader.SELECTION_ARROW:
return [this.getAssetUrlWithGenericBase(RoomContentLoader.SELECTION_ARROW)];
default: {
const category = this.getCategoryForType(type);
if((category === RoomObjectCategory.FLOOR) || (category === RoomObjectCategory.WALL))
{
const name = this.getAssetAliasName(type);
let assetUrl = (icon ? this.getAssetUrlWithFurniIconBase(name) : this.getAssetUrlWithFurniBase(type));
if(icon)
{
const active = (param && (param !== '') && (this._activeObjectTypeIds.has((name + '*' + param))));
assetUrl = (assetUrl.replace(/%param%/gi, (active ? ('_' + param) : '')));
}
return [assetUrl];
}
if(category === RoomObjectCategory.UNIT)
{
return [this.getAssetUrlWithPetBase(type)];
}
return null;
}
}
}
public getAssetIconUrl(type: string, colorIndex: string): string
{
let assetName: string = null;
let assetUrls: string[] = [];
if(type && (type.indexOf(',') >= 0))
{
assetName = type;
type = assetName.split(',')[0];
}
if(assetName)
{
assetUrls = this.getAssetUrls(assetName, colorIndex, true);
}
else
{
assetUrls = this.getAssetUrls(type, colorIndex, true);
}
if(assetUrls && assetUrls.length) return assetUrls[0];
return null;
}
private getAssetUrlWithGenericBase(assetName: string): string
{
return (GetConfiguration().getValue<string>('generic.asset.url').replace(/%libname%/gi, assetName));
}
public getAssetUrlWithFurniBase(assetName: string): string
{
return (GetConfiguration().getValue<string>('furni.asset.url').replace(/%libname%/gi, assetName));
}
public getAssetUrlWithFurniIconBase(assetName: string): string
{
return (GetConfiguration().getValue<string>('furni.asset.icon.url').replace(/%libname%/gi, assetName));
}
public getAssetUrlWithPetBase(assetName: string): string
{
return (GetConfiguration().getValue<string>('pet.asset.url').replace(/%libname%/gi, assetName));
}
public setRoomObjectRoomId(object: IRoomObject, roomId: string): void
{
const model = object && object.model;
if(!model) return;
model.setValue(RoomObjectVariable.OBJECT_ROOM_ID, roomId);
}
public setIconListener(listener: IRoomContentListener): void
{
this._iconListener = listener;
}
public get pets(): { [index: string]: number }
{
return this._pets;
}
}
File diff suppressed because it is too large Load Diff
+287
View File
@@ -0,0 +1,287 @@
import { IRoomInstance, IRoomInstanceContainer, IRoomObject, IRoomObjectController, IRoomObjectManager, IRoomObjectModel, IRoomRendererBase } from '@nitrots/api';
import { RoomObjectModel } from './object';
export class RoomInstance implements IRoomInstance
{
private _id: string;
private _container: IRoomInstanceContainer;
private _renderer: IRoomRendererBase = null;
private _managers: Map<number, IRoomObjectManager> = new Map();
private _updateCategories: number[] = [];
private _model: IRoomObjectModel = new RoomObjectModel();
constructor(id: string, container: IRoomInstanceContainer)
{
this._id = id;
this._container = container;
}
public dispose(): void
{
this.removeAllManagers();
this.destroyRenderer();
this._container = null;
this._model.dispose();
}
public setRenderer(renderer: IRoomRendererBase): void
{
if(renderer === this._renderer) return;
if(this._renderer) this.destroyRenderer();
this._renderer = renderer;
if(!this._renderer) return;
this._renderer.reset();
if(this._managers.size)
{
for(const manager of this._managers.values())
{
if(!manager) continue;
const objects = manager.objects;
if(!objects.length) continue;
for(const object of objects.getValues())
{
if(!object) continue;
this._renderer.addObject(object);
}
}
}
}
private destroyRenderer(): void
{
if(!this._renderer) return;
this._renderer.dispose();
this._renderer = null;
}
public getManager(category: number): IRoomObjectManager
{
const manager = this._managers.get(category);
if(!manager) return null;
return manager;
}
private getManagerOrCreate(category: number): IRoomObjectManager
{
let manager = this.getManager(category);
if(manager) return manager;
manager = this._container.createRoomObjectManager(category);
if(!manager) return null;
this._managers.set(category, manager);
return manager;
}
public getTotalObjectsForManager(category: number): number
{
const manager = this.getManager(category);
if(!manager) return 0;
return manager.totalObjects;
}
public getRoomObject(id: number, category: number): IRoomObject
{
const manager = this.getManager(category);
if(!manager) return null;
const object = manager.getObject(id);
if(!object) return null;
return object;
}
public getRoomObjectsForCategory(category: number): IRoomObject[]
{
const manager = this.getManager(category);
return (manager ? manager.objects.getValues() : []);
}
public getRoomObjectByIndex(index: number, category: number): IRoomObject
{
const manager = this.getManager(category);
if(!manager) return null;
const object = manager.getObjectByIndex(index);
if(!object) return null;
return object;
}
public createRoomObject(id: number, stateCount: number, type: string, category: number): IRoomObjectController
{
const manager = this.getManagerOrCreate(category);
if(!manager) return null;
const object = manager.createObject(id, stateCount, type);
if(!object) return null;
if(this._renderer) this._renderer.addObject(object);
return object;
}
public createRoomObjectAndInitalize(objectId: number, type: string, category: number): IRoomObject
{
if(!this._container) return null;
return this._container.createRoomObjectAndInitalize(this._id, objectId, type, category);
}
public removeRoomObject(id: number, category: number): void
{
const manager = this.getManager(category);
if(!manager) return;
const object = manager.getObject(id);
if(!object) return;
object.tearDown();
if(this._renderer) this._renderer.removeObject(object);
manager.removeObject(id);
}
public removeAllManagers(): void
{
for(const manager of this._managers.values())
{
if(!manager) continue;
if(this._renderer)
{
const objects = manager.objects;
if(objects.length)
{
for(const object of objects.getValues())
{
if(!object) continue;
this._renderer.removeObject(object);
}
}
}
manager.dispose();
}
this._managers.clear();
}
public addUpdateCategory(category: number): void
{
const index = this._updateCategories.indexOf(category);
if(index >= 0) return;
this._updateCategories.push(category);
}
public removeUpdateCategory(category: number): void
{
const index = this._updateCategories.indexOf(category);
if(index === -1) return;
this._updateCategories.splice(index, 1);
}
public update(time: number, update: boolean = false): void
{
for(const category of this._updateCategories)
{
const manager = this.getManager(category);
if(!manager) continue;
const objects = manager.objects;
if(!objects.length) continue;
for(const object of objects.getValues())
{
if(!object) continue;
const logic = object.logic;
(logic && logic.update(time));
}
}
this._renderer && this._renderer.update(time, update);
}
public hasUninitializedObjects(): boolean
{
for(const manager of this._managers.values())
{
if(!manager) continue;
for(const object of manager.objects.getValues())
{
if(!object) continue;
if(!object.isReady) return true;
}
}
return false;
}
public get id(): string
{
return this._id;
}
public get container(): IRoomInstanceContainer
{
return this._container;
}
public get renderer(): IRoomRendererBase
{
return this._renderer;
}
public get managers(): Map<number, IRoomObjectManager>
{
return this._managers;
}
public get model(): IRoomObjectModel
{
return this._model;
}
}
+308
View File
@@ -0,0 +1,308 @@
import { IGraphicAssetCollection, IRoomInstance, IRoomInstanceContainer, IRoomManager, IRoomManagerListener, IRoomObject, IRoomObjectController, IRoomObjectManager } from '@nitrots/api';
import { GetEventDispatcher, RoomContentLoadedEvent } from '@nitrots/events';
import { NitroLogger } from '@nitrots/utils';
import { GetRoomContentLoader } from './GetRoomContentLoader';
import { GetRoomObjectLogicFactory } from './GetRoomObjectLogicFactory';
import { GetRoomObjectVisualizationFactory } from './GetRoomObjectVisualizationFactory';
import { RoomInstance } from './RoomInstance';
import { RoomObjectManager } from './RoomObjectManager';
export class RoomManager implements IRoomManager, IRoomInstanceContainer
{
private _rooms: Map<string, IRoomInstance> = new Map();
private _updateCategories: number[] = [];
private _listener: IRoomManagerListener;
private _pendingContentTypes: string[] = [];
private _skipContentProcessing: boolean = false;
constructor()
{
this.onRoomContentLoadedEvent = this.onRoomContentLoadedEvent.bind(this);
}
public async init(listener: IRoomManagerListener): Promise<void>
{
this._listener = listener;
GetEventDispatcher().addEventListener(RoomContentLoadedEvent.RCLE_SUCCESS, this.onRoomContentLoadedEvent);
GetEventDispatcher().addEventListener(RoomContentLoadedEvent.RCLE_FAILURE, this.onRoomContentLoadedEvent);
GetEventDispatcher().addEventListener(RoomContentLoadedEvent.RCLE_CANCEL, this.onRoomContentLoadedEvent);
}
public getRoomInstance(roomId: string): IRoomInstance
{
const existing = this._rooms.get(roomId);
if(!existing) return null;
return existing;
}
public createRoomInstance(roomId: string): IRoomInstance
{
if(this._rooms.get(roomId)) return null;
const instance = new RoomInstance(roomId, this);
this._rooms.set(instance.id, instance);
if(this._updateCategories.length)
{
for(const category of this._updateCategories)
{
instance.addUpdateCategory(category);
}
}
return instance;
}
public removeRoomInstance(roomId: string): boolean
{
const existing = this._rooms.get(roomId);
if(!existing) return false;
this._rooms.delete(roomId);
existing.dispose();
return true;
}
public createRoomObjectAndInitalize(roomId: string, objectId: number, type: string, category: number): IRoomObject
{
const instance = this.getRoomInstance(roomId);
if(!instance) return null;
let visualization = type;
let logic = type;
let assetName = type;
let asset: IGraphicAssetCollection = null;
let isLoading = false;
if(GetRoomContentLoader().isLoaderType(type))
{
asset = GetRoomContentLoader().getCollection(type);
if(!asset)
{
isLoading = true;
GetRoomContentLoader().downloadAsset(type);
assetName = GetRoomContentLoader().getPlaceholderName(type);
asset = GetRoomContentLoader().getCollection(assetName);
if(!asset) return null;
}
visualization = asset.data.visualizationType;
logic = asset.data.logicType;
}
const object = (instance.createRoomObject(objectId, 1, type, category) as IRoomObjectController);
if(!object) return null;
const visualizationInstance = GetRoomObjectVisualizationFactory().getVisualization(visualization);
if(!visualizationInstance)
{
instance.removeRoomObject(objectId, category);
return null;
}
visualizationInstance.asset = asset;
const visualizationData = GetRoomObjectVisualizationFactory().getVisualizationData(assetName, visualization, ((asset && asset.data) || null));
if(!visualizationData || !visualizationInstance.initialize(visualizationData))
{
instance.removeRoomObject(objectId, category);
return null;
}
object.setVisualization(visualizationInstance);
const logicInstance = GetRoomObjectLogicFactory().getLogic(logic);
object.setLogic(logicInstance);
if(logicInstance)
{
logicInstance.initialize((asset && asset.data) || null);
}
if(!isLoading) object.isReady = true;
GetRoomContentLoader().setRoomObjectRoomId(object, roomId);
return object;
}
private reinitializeRoomObjectsByType(type: string): void
{
if(!type || !GetRoomContentLoader()) return;
const asset = GetRoomContentLoader().getCollection(type);
if(!asset) return;
const visualization = asset.data.visualizationType;
const logic = asset.data.logicType;
const visualizationData = GetRoomObjectVisualizationFactory().getVisualizationData(type, visualization, asset.data);
for(const room of this._rooms.values())
{
if(!room) continue;
for(const [category, manager] of room.managers.entries())
{
if(!manager) continue;
for(const object of manager.objects.getValues())
{
if(!object || object.type !== type) continue;
const visualizationInstance = GetRoomObjectVisualizationFactory().getVisualization(visualization);
if(visualizationInstance)
{
visualizationInstance.asset = asset;
if(!visualizationData || !visualizationInstance.initialize(visualizationData))
{
manager.removeObject(object.id);
}
else
{
object.setVisualization(visualizationInstance);
const logicInstance = GetRoomObjectLogicFactory().getLogic(logic);
object.setLogic(logicInstance);
if(logicInstance)
{
logicInstance.initialize(asset.data);
}
object.isReady = true;
if(this._listener) this._listener.objectInitialized(room.id, object.id, category);
}
}
else
{
manager.removeObject(object.id);
}
}
}
}
}
public addUpdateCategory(category: number): void
{
const index = this._updateCategories.indexOf(category);
if(index >= 0) return;
this._updateCategories.push(category);
if(!this._rooms.size) return;
for(const room of this._rooms.values())
{
if(!room) continue;
room.addUpdateCategory(category);
}
}
public removeUpdateCategory(category: number): void
{
const index = this._updateCategories.indexOf(category);
if(index === -1) return;
this._updateCategories.splice(index, 1);
if(!this._rooms.size) return;
for(const room of this._rooms.values())
{
if(!room) continue;
room.removeUpdateCategory(category);
}
}
private processPendingContentTypes(time: number): void
{
if(this._skipContentProcessing)
{
this._skipContentProcessing = false;
return;
}
while(this._pendingContentTypes.length)
{
const type = this._pendingContentTypes.shift();
const collection = GetRoomContentLoader().getCollection(type);
if(!collection)
{
if(this._listener)
{
this._listener.initalizeTemporaryObjectsByType(type, false);
}
NitroLogger.log('Invalid Collection', type);
continue;
}
this.reinitializeRoomObjectsByType(type);
if(this._listener) this._listener.initalizeTemporaryObjectsByType(type, true);
}
}
private onRoomContentLoadedEvent(event: RoomContentLoadedEvent): void
{
if(!GetRoomContentLoader()) return;
const contentType = event.contentType;
if(this._pendingContentTypes.indexOf(contentType) >= 0) return;
this._pendingContentTypes.push(contentType);
}
public update(time: number, update: boolean = false): void
{
this.processPendingContentTypes(time);
if(!this._rooms.size) return;
for(const room of this._rooms.values()) room && room.update(time, update);
}
public createRoomObjectManager(category: number): IRoomObjectManager
{
return new RoomObjectManager();
}
public get rooms(): Map<string, IRoomInstance>
{
return this._rooms;
}
}
+960
View File
@@ -0,0 +1,960 @@
import { AvatarGuideStatus, IConnection, IRoomCreator, IVector3D, LegacyDataType, ObjectRolling, PetType, RoomObjectType, RoomObjectUserType, RoomObjectVariable } from '@nitrots/api';
import { DiceValueMessageEvent, FloorHeightMapEvent, FurnitureAliasesComposer, FurnitureAliasesEvent, FurnitureDataEvent, FurnitureFloorAddEvent, FurnitureFloorDataParser, FurnitureFloorEvent, FurnitureFloorRemoveEvent, FurnitureFloorUpdateEvent, FurnitureWallAddEvent, FurnitureWallDataParser, FurnitureWallEvent, FurnitureWallRemoveEvent, FurnitureWallUpdateEvent, GetCommunication, GetRoomEntryDataMessageComposer, GuideSessionEndedMessageEvent, GuideSessionErrorMessageEvent, GuideSessionStartedMessageEvent, IgnoreResultEvent, ItemDataUpdateMessageEvent, ObjectsDataUpdateEvent, ObjectsRollingEvent, OneWayDoorStatusMessageEvent, PetExperienceEvent, PetFigureUpdateEvent, RoomEntryTileMessageEvent, RoomEntryTileMessageParser, RoomHeightMapEvent, RoomHeightMapUpdateEvent, RoomPaintEvent, RoomReadyMessageEvent, RoomUnitChatEvent, RoomUnitChatShoutEvent, RoomUnitChatWhisperEvent, RoomUnitDanceEvent, RoomUnitEffectEvent, RoomUnitEvent, RoomUnitExpressionEvent, RoomUnitHandItemEvent, RoomUnitIdleEvent, RoomUnitInfoEvent, RoomUnitNumberEvent, RoomUnitRemoveEvent, RoomUnitStatusEvent, RoomUnitTypingEvent, RoomVisualizationSettingsEvent, UserInfoEvent, YouArePlayingGameEvent } from '@nitrots/communication';
import { GetRoomSessionManager, GetSessionDataManager } from '@nitrots/session';
import { Vector3d } from '@nitrots/utils';
import { GetRoomEngine } from './GetRoomEngine';
import { RoomVariableEnum } from './RoomVariableEnum';
import { RoomPlaneParser } from './object/RoomPlaneParser';
import { FurnitureStackingHeightMap, LegacyWallGeometry } from './utils';
export class RoomMessageHandler
{
private _connection: IConnection = null;
private _roomEngine: IRoomCreator = null;
private _planeParser = new RoomPlaneParser();
private _latestEntryTileEvent: RoomEntryTileMessageEvent = null;
private _currentRoomId: number = 0;
private _ownUserId: number = 0;
private _initialConnection: boolean = true;
private _guideId: number = -1;
private _requesterId: number = -1;
public async init(): Promise<void>
{
this._connection = GetCommunication().connection;
this._roomEngine = GetRoomEngine();
this._connection.addMessageEvent(new UserInfoEvent(this.onUserInfoEvent.bind(this)));
this._connection.addMessageEvent(new RoomReadyMessageEvent(this.onRoomReadyMessageEvent.bind(this)));
this._connection.addMessageEvent(new RoomPaintEvent(this.onRoomPaintEvent.bind(this)));
this._connection.addMessageEvent(new FloorHeightMapEvent(this.onRoomModelEvent.bind(this)));
this._connection.addMessageEvent(new RoomHeightMapEvent(this.onRoomHeightMapEvent.bind(this)));
this._connection.addMessageEvent(new RoomHeightMapUpdateEvent(this.onRoomHeightMapUpdateEvent.bind(this)));
this._connection.addMessageEvent(new RoomVisualizationSettingsEvent(this.onRoomThicknessEvent.bind(this)));
this._connection.addMessageEvent(new RoomEntryTileMessageEvent(this.onRoomDoorEvent.bind(this)));
this._connection.addMessageEvent(new ObjectsRollingEvent(this.onRoomRollingEvent.bind(this)));
this._connection.addMessageEvent(new ObjectsDataUpdateEvent(this.onObjectsDataUpdateEvent.bind(this)));
this._connection.addMessageEvent(new FurnitureAliasesEvent(this.onFurnitureAliasesEvent.bind(this)));
this._connection.addMessageEvent(new FurnitureFloorAddEvent(this.onFurnitureFloorAddEvent.bind(this)));
this._connection.addMessageEvent(new FurnitureFloorEvent(this.onFurnitureFloorEvent.bind(this)));
this._connection.addMessageEvent(new FurnitureFloorRemoveEvent(this.onFurnitureFloorRemoveEvent.bind(this)));
this._connection.addMessageEvent(new FurnitureFloorUpdateEvent(this.onFurnitureFloorUpdateEvent.bind(this)));
this._connection.addMessageEvent(new FurnitureWallAddEvent(this.onFurnitureWallAddEvent.bind(this)));
this._connection.addMessageEvent(new FurnitureWallEvent(this.onFurnitureWallEvent.bind(this)));
this._connection.addMessageEvent(new FurnitureWallRemoveEvent(this.onFurnitureWallRemoveEvent.bind(this)));
this._connection.addMessageEvent(new FurnitureWallUpdateEvent(this.onFurnitureWallUpdateEvent.bind(this)));
this._connection.addMessageEvent(new FurnitureDataEvent(this.onFurnitureDataEvent.bind(this)));
this._connection.addMessageEvent(new ItemDataUpdateMessageEvent(this.onItemDataUpdateMessageEvent.bind(this)));
this._connection.addMessageEvent(new OneWayDoorStatusMessageEvent(this.onOneWayDoorStatusMessageEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitDanceEvent(this.onRoomUnitDanceEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitEffectEvent(this.onRoomUnitEffectEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitEvent(this.onRoomUnitEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitExpressionEvent(this.onRoomUnitExpressionEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitHandItemEvent(this.onRoomUnitHandItemEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitIdleEvent(this.onRoomUnitIdleEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitInfoEvent(this.onRoomUnitInfoEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitNumberEvent(this.onRoomUnitNumberEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitRemoveEvent(this.onRoomUnitRemoveEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitStatusEvent(this.onRoomUnitStatusEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitChatEvent(this.onRoomUnitChatEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitChatShoutEvent(this.onRoomUnitChatEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitChatWhisperEvent(this.onRoomUnitChatEvent.bind(this)));
this._connection.addMessageEvent(new RoomUnitTypingEvent(this.onRoomUnitTypingEvent.bind(this)));
this._connection.addMessageEvent(new PetFigureUpdateEvent(this.onPetFigureUpdateEvent.bind(this)));
this._connection.addMessageEvent(new PetExperienceEvent(this.onPetExperienceEvent.bind(this)));
this._connection.addMessageEvent(new YouArePlayingGameEvent(this.onYouArePlayingGameEvent.bind(this)));
this._connection.addMessageEvent(new DiceValueMessageEvent(this.onDiceValueMessageEvent.bind(this)));
this._connection.addMessageEvent(new IgnoreResultEvent(this.onIgnoreResultEvent.bind(this)));
this._connection.addMessageEvent(new GuideSessionStartedMessageEvent(this.onGuideSessionStartedMessageEvent.bind(this)));
this._connection.addMessageEvent(new GuideSessionEndedMessageEvent(this.onGuideSessionEndedMessageEvent.bind(this)));
this._connection.addMessageEvent(new GuideSessionErrorMessageEvent(this.onGuideSessionErrorMessageEvent.bind(this)));
}
public setRoomId(id: number): void
{
if(this._currentRoomId !== 0)
{
if(this._roomEngine) this._roomEngine.destroyRoom(this._currentRoomId);
}
this._currentRoomId = id;
this._latestEntryTileEvent = null;
}
public clearRoomId(): void
{
this._currentRoomId = 0;
this._latestEntryTileEvent = null;
}
private onUserInfoEvent(event: UserInfoEvent): void
{
if(!(event instanceof UserInfoEvent) || !event.connection) return;
const parser = event.getParser();
if(!parser) return;
this._ownUserId = parser.userInfo.userId;
}
private onRoomReadyMessageEvent(event: RoomReadyMessageEvent): void
{
const parser = event.getParser();
if(this._currentRoomId !== parser.roomId)
{
this.setRoomId(parser.roomId);
}
if(this._roomEngine)
{
this._roomEngine.setRoomInstanceModelName(parser.roomId, parser.name);
}
if(this._initialConnection)
{
event.connection.send(new FurnitureAliasesComposer());
this._initialConnection = false;
return;
}
event.connection.send(new GetRoomEntryDataMessageComposer());
}
private onRoomPaintEvent(event: RoomPaintEvent): void
{
if(!(event instanceof RoomPaintEvent)) return;
const parser = event.getParser();
if(!parser) return;
const floorType = parser.floorType;
const wallType = parser.wallType;
const landscapeType = parser.landscapeType;
if(this._roomEngine)
{
this._roomEngine.updateRoomInstancePlaneType(this._currentRoomId, floorType, wallType, landscapeType);
}
}
private onRoomModelEvent(event: FloorHeightMapEvent): void
{
if(!(event instanceof FloorHeightMapEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser) return;
const wallGeometry = this._roomEngine.getLegacyWallGeometry(this._currentRoomId);
if(!wallGeometry) return;
this._planeParser.reset();
const width = parser.width;
const height = parser.height;
this._planeParser.initializeTileMap(width, height);
let entryTile: RoomEntryTileMessageParser = null;
if(this._latestEntryTileEvent) entryTile = this._latestEntryTileEvent.getParser();
let doorX = -1;
let doorY = -1;
let doorZ = 0;
let doorDirection = 0;
let y = 0;
while(y < height)
{
let x = 0;
while(x < width)
{
const tileHeight = parser.getHeight(x, y);
if(((((y > 0) && (y < (height - 1))) || ((x > 0) && (x < (width - 1)))) && (!(tileHeight == RoomPlaneParser.TILE_BLOCKED))) && ((entryTile == null) || ((x == entryTile.x) && (y == entryTile.y))))
{
if(((parser.getHeight(x, (y - 1)) == RoomPlaneParser.TILE_BLOCKED) && (parser.getHeight((x - 1), y) == RoomPlaneParser.TILE_BLOCKED)) && (parser.getHeight(x, (y + 1)) == RoomPlaneParser.TILE_BLOCKED))
{
doorX = (x + 0.5);
doorY = y;
doorZ = tileHeight;
doorDirection = 90;
}
if(((parser.getHeight(x, (y - 1)) == RoomPlaneParser.TILE_BLOCKED) && (parser.getHeight((x - 1), y) == RoomPlaneParser.TILE_BLOCKED)) && (parser.getHeight((x + 1), y) == RoomPlaneParser.TILE_BLOCKED))
{
doorX = x;
doorY = (y + 0.5);
doorZ = tileHeight;
doorDirection = 180;
}
}
this._planeParser.setTileHeight(x, y, tileHeight);
x++;
}
y++;
}
this._planeParser.setTileHeight(Math.floor(doorX), Math.floor(doorY), doorZ);
this._planeParser.initializeFromTileData(parser.wallHeight);
this._planeParser.setTileHeight(Math.floor(doorX), Math.floor(doorY), (doorZ + this._planeParser.wallHeight));
wallGeometry.scale = LegacyWallGeometry.DEFAULT_SCALE;
wallGeometry.initialize(width, height, this._planeParser.floorHeight);
let heightIterator = (parser.height - 1);
while(heightIterator >= 0)
{
let widthIterator = (parser.width - 1);
while(widthIterator >= 0)
{
wallGeometry.setHeight(widthIterator, heightIterator, this._planeParser.getTileHeight(widthIterator, heightIterator));
widthIterator--;
}
heightIterator--;
}
const roomMap = this._planeParser.getMapData();
roomMap.doors.push({
x: doorX,
y: doorY,
z: doorZ,
dir: doorDirection
});
this._roomEngine.createRoomInstance(this._currentRoomId, roomMap);
}
private onRoomHeightMapEvent(event: RoomHeightMapEvent): void
{
if(!(event instanceof RoomHeightMapEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser) return;
const width = parser.width;
const height = parser.height;
const heightMap = new FurnitureStackingHeightMap(width, height);
let y = 0;
while(y < height)
{
let x = 0;
while(x < width)
{
heightMap.setTileHeight(x, y, parser.getTileHeight(x, y));
heightMap.setStackingBlocked(x, y, parser.getStackingBlocked(x, y));
heightMap.setIsRoomTile(x, y, parser.isRoomTile(x, y));
x++;
}
y++;
}
this._roomEngine.setFurnitureStackingHeightMap(this._currentRoomId, heightMap);
}
private onRoomHeightMapUpdateEvent(event: RoomHeightMapUpdateEvent): void
{
if(!(event instanceof RoomHeightMapUpdateEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser) return;
const heightMap = this._roomEngine.getFurnitureStackingHeightMap(this._currentRoomId);
if(!heightMap) return;
while(parser.next())
{
heightMap.setTileHeight(parser.x, parser.y, parser.tileHeight());
heightMap.setStackingBlocked(parser.x, parser.y, parser.isStackingBlocked());
heightMap.setIsRoomTile(parser.x, parser.y, parser.isRoomTile());
}
this._roomEngine.refreshTileObjectMap(this._currentRoomId, 'RoomMessageHandler.onRoomHeightMapUpdateEvent()');
}
private onRoomThicknessEvent(event: RoomVisualizationSettingsEvent): void
{
if(!(event instanceof RoomVisualizationSettingsEvent)) return;
const parser = event.getParser();
if(!parser) return;
const visibleWall = !parser.hideWalls;
const visibleFloor = true;
const thicknessWall = parser.thicknessWall;
const thicknessFloor = parser.thicknessFloor;
if(this._roomEngine)
{
this._roomEngine.updateRoomInstancePlaneVisibility(this._currentRoomId, visibleWall, visibleFloor);
this._roomEngine.updateRoomInstancePlaneThickness(this._currentRoomId, thicknessWall, thicknessFloor);
}
}
private onRoomDoorEvent(event: RoomEntryTileMessageEvent): void
{
if(!(event instanceof RoomEntryTileMessageEvent)) return;
this._latestEntryTileEvent = event;
}
private onRoomRollingEvent(event: ObjectsRollingEvent): void
{
if(!(event instanceof ObjectsRollingEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.rollerId, null, null, 1, null);
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.rollerId, null, null, 2, null);
const furnitureRolling = parser.itemsRolling;
if(furnitureRolling && furnitureRolling.length)
{
for(const rollData of furnitureRolling)
{
if(!rollData) continue;
this._roomEngine.rollRoomObjectFloor(this._currentRoomId, rollData.id, rollData.location, rollData.targetLocation);
}
}
const unitRollData = parser.unitRolling;
if(unitRollData)
{
this._roomEngine.updateRoomObjectUserLocation(this._currentRoomId, unitRollData.id, unitRollData.location, unitRollData.targetLocation);
const object = this._roomEngine.getRoomObjectUser(this._currentRoomId, unitRollData.id);
if(object && object.type !== RoomObjectUserType.MONSTER_PLANT)
{
let posture = 'std';
switch(unitRollData.movementType)
{
case ObjectRolling.MOVE:
posture = 'mv';
break;
case ObjectRolling.SLIDE:
posture = 'std';
break;
}
this._roomEngine.updateRoomObjectUserPosture(this._currentRoomId, unitRollData.id, posture);
}
}
}
private onObjectsDataUpdateEvent(event: ObjectsDataUpdateEvent): void
{
if(!(event instanceof ObjectsDataUpdateEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser) return;
for(const object of parser.objects)
{
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, object.id, null, null, object.state, object.data);
}
}
private onFurnitureAliasesEvent(event: FurnitureAliasesEvent): void
{
if(!(event instanceof FurnitureAliasesEvent) || !event.connection || !this._roomEngine) return;
const alises = event.getParser().aliases;
this._connection.send(new GetRoomEntryDataMessageComposer());
}
private onFurnitureFloorAddEvent(event: FurnitureFloorAddEvent): void
{
if(!(event instanceof FurnitureFloorAddEvent) || !event.connection || !this._roomEngine) return;
const item = event.getParser().item;
if(!item) return;
this.addRoomObjectFurnitureFloor(this._currentRoomId, item);
}
private onFurnitureFloorEvent(event: FurnitureFloorEvent): void
{
if(!(event instanceof FurnitureFloorEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser) return;
const totalObjects = parser.items.length;
let iterator = 0;
while(iterator < totalObjects)
{
const object = parser.items[iterator];
if(object) this.addRoomObjectFurnitureFloor(this._currentRoomId, object);
iterator++;
}
}
private onFurnitureFloorRemoveEvent(event: FurnitureFloorRemoveEvent): void
{
if(!(event instanceof FurnitureFloorRemoveEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser) return;
if(parser.delay > 0)
{
setTimeout(() =>
{
this._roomEngine.removeRoomObjectFloor(this._currentRoomId, parser.itemId, (parser.isExpired) ? -1 : parser.userId, true);
}, parser.delay);
}
else
{
this._roomEngine.removeRoomObjectFloor(this._currentRoomId, parser.itemId, (parser.isExpired) ? -1 : parser.userId, true);
}
}
private onFurnitureFloorUpdateEvent(event: FurnitureFloorUpdateEvent): void
{
if(!(event instanceof FurnitureFloorUpdateEvent) || !event.connection || !this._roomEngine) return;
const item = event.getParser().item;
if(!item) return;
const location: IVector3D = new Vector3d(item.x, item.y, item.z);
const direction: IVector3D = new Vector3d(item.direction);
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, item.itemId, location, direction, item.data.state, item.data, item.extra);
this._roomEngine.updateRoomObjectFloorHeight(this._currentRoomId, item.itemId, item.stackHeight);
this._roomEngine.updateRoomObjectFloorExpiration(this._currentRoomId, item.itemId, item.expires);
}
private onFurnitureWallAddEvent(event: FurnitureWallAddEvent): void
{
if(!(event instanceof FurnitureWallAddEvent) || !event.connection || !this._roomEngine) return;
const data = event.getParser().item;
if(!data) return;
this.addRoomObjectFurnitureWall(this._currentRoomId, data);
}
private onFurnitureWallEvent(event: FurnitureWallEvent): void
{
if(!(event instanceof FurnitureWallEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser) return;
const totalObjects = parser.items.length;
let iterator = 0;
while(iterator < totalObjects)
{
const data = parser.items[iterator];
if(data) this.addRoomObjectFurnitureWall(this._currentRoomId, data);
iterator++;
}
}
private onFurnitureWallRemoveEvent(event: FurnitureWallRemoveEvent): void
{
if(!(event instanceof FurnitureWallRemoveEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser) return;
this._roomEngine.removeRoomObjectWall(this._currentRoomId, parser.itemId, parser.userId);
}
private onFurnitureWallUpdateEvent(event: FurnitureWallUpdateEvent): void
{
if(!(event instanceof FurnitureWallUpdateEvent) || !event.connection || !this._roomEngine) return;
const wallGeometry = this._roomEngine.getLegacyWallGeometry(this._currentRoomId);
if(!wallGeometry) return;
const item = event.getParser().item;
if(!item) return;
const location = wallGeometry.getLocation(item.width, item.height, item.localX, item.localY, item.direction);
const direction = new Vector3d(wallGeometry.getDirection(item.direction));
this._roomEngine.updateRoomObjectWall(this._currentRoomId, item.itemId, location, direction, item.state, item.stuffData);
this._roomEngine.updateRoomObjectWallExpiration(this._currentRoomId, item.itemId, item.secondsToExpiration);
}
private onFurnitureDataEvent(event: FurnitureDataEvent): void
{
if(!(event instanceof FurnitureDataEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.furnitureId, null, null, parser.objectData.state, parser.objectData);
}
private onItemDataUpdateMessageEvent(event: ItemDataUpdateMessageEvent): void
{
if(!(event instanceof ItemDataUpdateMessageEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
this._roomEngine.updateRoomObjectWallItemData(this._currentRoomId, parser.furnitureId, parser.data);
}
private onOneWayDoorStatusMessageEvent(event: OneWayDoorStatusMessageEvent): void
{
if(!(event instanceof OneWayDoorStatusMessageEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.itemId, null, null, parser.state, new LegacyDataType());
}
private onDiceValueMessageEvent(event: DiceValueMessageEvent): void
{
if(!(event instanceof DiceValueMessageEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.itemId, null, null, parser.value, new LegacyDataType());
}
private onRoomUnitDanceEvent(event: RoomUnitDanceEvent): void
{
if(!(event instanceof RoomUnitDanceEvent) || !event.connection || !this._roomEngine) return;
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_DANCE, event.getParser().danceId);
}
private onRoomUnitEffectEvent(event: RoomUnitEffectEvent): void
{
if(!(event instanceof RoomUnitEffectEvent) || !event.connection || !this._roomEngine) return;
this._roomEngine.updateRoomObjectUserEffect(this._currentRoomId, event.getParser().unitId, event.getParser().effectId, event.getParser().delay);
}
private onRoomUnitEvent(event: RoomUnitEvent): void
{
if(!(event instanceof RoomUnitEvent) || !event.connection || !this._roomEngine) return;
const users = event.getParser().users;
if(!users || !users.length) return;
for(const user of users)
{
if(!user) continue;
const location = new Vector3d(user.x, user.y, user.z);
const direction = new Vector3d(user.dir);
this._roomEngine.addRoomObjectUser(this._currentRoomId, user.roomIndex, location, direction, user.dir, user.userType, user.figure);
if(user.webID === this._ownUserId)
{
this._roomEngine.setRoomSessionOwnUser(this._currentRoomId, user.roomIndex);
this._roomEngine.updateRoomObjectUserOwn(this._currentRoomId, user.roomIndex);
}
this._roomEngine.updateRoomObjectUserFigure(this._currentRoomId, user.roomIndex, user.figure, user.sex, user.subType, user.isRiding);
if(RoomObjectUserType.getTypeString(user.userType) === RoomObjectUserType.PET)
{
if(this._roomEngine.getPetTypeId(user.figure) === PetType.MONSTERPLANT)
{
this._roomEngine.updateRoomObjectUserPosture(this._currentRoomId, user.roomIndex, user.petPosture);
}
}
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, user.roomIndex, RoomObjectVariable.FIGURE_IS_MUTED, (GetSessionDataManager().isUserIgnored(user.name) ? 1 : 0));
}
this.updateGuideMarker();
}
private onRoomUnitExpressionEvent(event: RoomUnitExpressionEvent): void
{
if(!(event instanceof RoomUnitExpressionEvent) || !event.connection || !this._roomEngine) return;
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_EXPRESSION, event.getParser().expression);
}
private onRoomUnitHandItemEvent(event: RoomUnitHandItemEvent): void
{
if(!(event instanceof RoomUnitHandItemEvent) || !event.connection || !this._roomEngine) return;
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_CARRY_OBJECT, event.getParser().handId);
}
private onRoomUnitIdleEvent(event: RoomUnitIdleEvent): void
{
if(!(event instanceof RoomUnitIdleEvent) || !event.connection || !this._roomEngine) return;
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_SLEEP, (event.getParser().isIdle ? 1 : 0));
}
private onRoomUnitInfoEvent(event: RoomUnitInfoEvent): void
{
if(!(event instanceof RoomUnitInfoEvent) || !event.connection || !this._roomEngine) return;
this._roomEngine.updateRoomObjectUserFigure(this._currentRoomId, event.getParser().unitId, event.getParser().figure, event.getParser().gender);
}
private onRoomUnitNumberEvent(event: RoomUnitNumberEvent): void
{
if(!(event instanceof RoomUnitNumberEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser) return;
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, parser.unitId, RoomObjectVariable.FIGURE_NUMBER_VALUE, parser.value);
}
private onRoomUnitRemoveEvent(event: RoomUnitRemoveEvent): void
{
if(!(event instanceof RoomUnitRemoveEvent) || !event.connection || !this._roomEngine) return;
this._roomEngine.removeRoomObjectUser(this._currentRoomId, event.getParser().unitId);
this.updateGuideMarker();
}
private onRoomUnitStatusEvent(event: RoomUnitStatusEvent): void
{
if(!(event instanceof RoomUnitStatusEvent) || !event.connection || !this._roomEngine) return;
const statuses = event.getParser().statuses;
if(!statuses || !statuses.length) return;
const roomInstance = this._roomEngine.getRoomInstance(this._currentRoomId);
if(!roomInstance) return;
const zScale = (roomInstance.model.getValue<number>(RoomVariableEnum.ROOM_Z_SCALE) || 1);
for(const status of statuses)
{
if(!status) continue;
let height = status.height;
if(height) height = (height / zScale);
const location = new Vector3d(status.x, status.y, (status.z + height));
const direction = new Vector3d(status.direction);
let goal: IVector3D = null;
if(status.didMove) goal = new Vector3d(status.targetX, status.targetY, status.targetZ);
this._roomEngine.updateRoomObjectUserLocation(this._currentRoomId, status.id, location, goal, status.canStandUp, height, direction, status.headDirection);
this._roomEngine.updateRoomObjectUserFlatControl(this._currentRoomId, status.id, null);
let isPosture = true;
let postureUpdate = false;
let postureType = RoomObjectVariable.STD;
let parameter = '';
if(status.actions && status.actions.length)
{
for(const action of status.actions)
{
if(!action) continue;
switch(action.action)
{
case 'flatctrl':
this._roomEngine.updateRoomObjectUserFlatControl(this._currentRoomId, status.id, action.value);
break;
case 'sign':
if(status.actions.length === 1) isPosture = false;
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, status.id, RoomObjectVariable.FIGURE_SIGN, parseInt(action.value));
break;
case 'gst':
if(status.actions.length === 1) isPosture = false;
this._roomEngine.updateRoomObjectUserPetGesture(this._currentRoomId, status.id, action.value);
break;
case 'wav':
case 'mv':
postureUpdate = true;
postureType = action.action;
parameter = action.value;
break;
case 'trd': break;
default:
postureUpdate = true;
postureType = action.action;
parameter = action.value;
break;
}
}
}
if(postureUpdate) this._roomEngine.updateRoomObjectUserPosture(this._currentRoomId, status.id, postureType, parameter);
else if(isPosture) this._roomEngine.updateRoomObjectUserPosture(this._currentRoomId, status.id, RoomObjectVariable.STD, '');
}
this.updateGuideMarker();
}
private onRoomUnitChatEvent(event: RoomUnitChatEvent): void
{
if(!event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser) return;
this._roomEngine.updateRoomObjectUserGesture(this._currentRoomId, parser.roomIndex, parser.gesture);
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, parser.roomIndex, RoomObjectVariable.FIGURE_TALK, (parser.message.length / 10));
}
private onRoomUnitTypingEvent(event: RoomUnitTypingEvent): void
{
if(!(event instanceof RoomUnitTypingEvent) || !event.connection || !this._roomEngine) return;
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_IS_TYPING, event.getParser().isTyping ? 1 : 0);
}
private onPetFigureUpdateEvent(event: PetFigureUpdateEvent): void
{
if(!(event instanceof PetFigureUpdateEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser) return;
this._roomEngine.updateRoomObjectUserFigure(this._currentRoomId, parser.roomIndex, parser.figureData.figuredata, '', '', parser.isRiding);
}
private onPetExperienceEvent(event: PetExperienceEvent): void
{
const parser = event.getParser();
if(!parser) return;
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, parser.roomIndex, RoomObjectVariable.FIGURE_GAINED_EXPERIENCE, parser.gainedExperience);
}
private onYouArePlayingGameEvent(event: YouArePlayingGameEvent): void
{
if(!event) return;
const parser = event.getParser();
if(!parser) return;
this._roomEngine.setRoomEngineGameMode(this._currentRoomId, parser.isPlaying);
}
private addRoomObjectFurnitureFloor(roomId: number, data: FurnitureFloorDataParser): void
{
if(!data || !this._roomEngine) return;
const location = new Vector3d(data.x, data.y, data.z);
const direction = new Vector3d(data.direction);
if(data.spriteName)
{
this._roomEngine.addFurnitureFloorByTypeName(roomId, data.itemId, data.spriteName, location, direction, data.state, data.data, data.extra, data.expires, data.usagePolicy, data.userId, data.username, true, true, data.stackHeight);
}
else
{
this._roomEngine.addFurnitureFloor(roomId, data.itemId, data.spriteId, location, direction, data.state, data.data, data.extra, data.expires, data.usagePolicy, data.userId, data.username, true, true, data.stackHeight);
}
}
private addRoomObjectFurnitureWall(roomId: number, data: FurnitureWallDataParser): void
{
if(!data || !this._roomEngine) return;
const wallGeometry = this._roomEngine.getLegacyWallGeometry(roomId);
if(!wallGeometry) return;
let location: IVector3D = null;
if(!data.isOldFormat)
{
location = wallGeometry.getLocation(data.width, data.height, data.localX, data.localY, data.direction);
}
else
{
//location = wallGeometry.getLocationOldFormat(data.y, data.z, data.direction);
}
const direction = new Vector3d(wallGeometry.getDirection(data.direction));
this._roomEngine.addFurnitureWall(roomId, data.itemId, data.spriteId, location, direction, data.state, data.stuffData, data.secondsToExpiration, data.usagePolicy, data.userId, data.username);
}
private onIgnoreResultEvent(event: IgnoreResultEvent): void
{
if(!event) return;
const parser = event.getParser();
if(!parser) return;
const roomSession = GetRoomSessionManager().getSession(this._currentRoomId);
if(!roomSession) return;
const userData = roomSession.userDataManager.getUserDataByName(parser.name);
if(!userData) return;
switch(parser.result)
{
case 1:
case 2:
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, userData.roomIndex, RoomObjectVariable.FIGURE_IS_MUTED, 1);
return;
case 3:
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, userData.roomIndex, RoomObjectVariable.FIGURE_IS_MUTED, 0);
return;
}
}
private onGuideSessionStartedMessageEvent(event: GuideSessionStartedMessageEvent): void
{
const parser = event.getParser();
this._guideId = parser.guideUserId;
this._requesterId = parser.requesterUserId;
this.updateGuideMarker();
}
private onGuideSessionEndedMessageEvent(k: GuideSessionEndedMessageEvent): void
{
this.removeGuideMarker();
}
private onGuideSessionErrorMessageEvent(k: GuideSessionErrorMessageEvent): void
{
this.removeGuideMarker();
}
private updateGuideMarker(): void
{
const userId = GetSessionDataManager().userId;
this.setUserGuideStatus(this._guideId, ((this._requesterId === userId) ? AvatarGuideStatus.GUIDE : AvatarGuideStatus.NONE));
this.setUserGuideStatus(this._requesterId, ((this._guideId === userId) ? AvatarGuideStatus.REQUESTER : AvatarGuideStatus.NONE));
}
private removeGuideMarker(): void
{
this.setUserGuideStatus(this._guideId, AvatarGuideStatus.NONE);
this.setUserGuideStatus(this._requesterId, AvatarGuideStatus.NONE);
this._guideId = -1;
this._requesterId = -1;
}
private setUserGuideStatus(userId: number, status: number): void
{
const roomSession = GetRoomSessionManager().getSession(this._currentRoomId);
if(!roomSession) return;
const userData = roomSession.userDataManager.getDataByType(userId, RoomObjectType.USER);
if(!userData) return;
this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, userData.roomIndex, RoomObjectVariable.FIGURE_GUIDE_STATUS, status);
}
// public _SafeStr_10580(event:_SafeStr_2242): void
// {
// var arrayIndex: number;
// var discoColours:Array;
// var discoTimer:Timer;
// var eventParser:_SafeStr_4576 = (event.parser as _SafeStr_4576);
// switch (eventParser._SafeStr_7025)
// {
// case 0:
// _SafeStr_4588.init(250, 5000);
// _SafeStr_4588._SafeStr_6766();
// return;
// case 1:
// _SafeStr_4231.init(250, 5000);
// _SafeStr_4231._SafeStr_6766();
// return;
// case 2:
// NitroEventDispatcher.dispatchEvent(new _SafeStr_2821(this._SafeStr_10593, -1, true));
// return;
// case 3:
// arrayIndex = 0;
// discoColours = [29371, 16731195, 16764980, 0x99FF00, 29371, 16731195, 16764980, 0x99FF00, 0];
// discoTimer = new Timer(1000, (discoColours.length + 1));
// discoTimer.addEventListener(TimerEvent.TIMER, function (k:TimerEvent): void
// {
// if (arrayIndex == discoColours.length)
// {
// _SafeStr_10592._SafeStr_21164(_SafeStr_10593, discoColours[arrayIndex++], 176, true);
// } else
// {
// _SafeStr_10592._SafeStr_21164(_SafeStr_10593, discoColours[arrayIndex++], 176, false);
// };
// });
// discoTimer.start();
// return;
// };
// }
public get currentRoomId(): number
{
return this._currentRoomId;
}
}
File diff suppressed because it is too large Load Diff
+315
View File
@@ -0,0 +1,315 @@
import { IEventDispatcher, IRoomObjectEventHandler, IRoomObjectLogicFactory, RoomObjectLogicType } from '@nitrots/api';
import { GetEventDispatcher, RoomObjectEvent } from '@nitrots/events';
import { NitroLogger } from '@nitrots/utils';
import { RoomObjectLogicBase } from '../../room';
import { AvatarLogic, FurnitureAchievementResolutionLogic, FurnitureBadgeDisplayLogic, FurnitureChangeStateWhenStepOnLogic, FurnitureClothingChangeLogic, FurnitureCounterClockLogic, FurnitureCrackableLogic, FurnitureCraftingGizmoLogic, FurnitureCreditLogic, FurnitureCuckooClockLogic, FurnitureCustomStackHeightLogic, FurnitureDiceLogic, FurnitureEcotronBoxLogic, FurnitureEditableInternalLinkLogic, FurnitureEditableRoomLinkLogic, FurnitureEffectBoxLogic, FurnitureExternalImageLogic, FurnitureFireworksLogic, FurnitureFloorHoleLogic, FurnitureGroupForumTerminalLogic, FurnitureGuildCustomizedLogic, FurnitureHabboWheelLogic, FurnitureHighScoreLogic, FurnitureHockeyScoreLogic, FurnitureHweenLovelockLogic, FurnitureIceStormLogic, FurnitureInternalLinkLogic, FurnitureJukeboxLogic, FurnitureLogic, FurnitureLoveLockLogic, FurnitureMannequinLogic, FurnitureMonsterplantSeedLogic, FurnitureMultiHeightLogic, FurnitureMultiStateLogic, FurnitureMysteryBoxLogic, FurnitureMysteryTrophyLogic, FurnitureOneWayDoorLogic, FurniturePetCustomizationLogic, FurniturePlaceholderLogic, FurniturePlanetSystemLogic, FurniturePresentLogic, FurniturePurchaseableClothingLogic, FurniturePushableLogic, FurnitureRandomStateLogic, FurnitureRandomTeleportLogic, FurnitureRentableSpaceLogic, FurnitureRoomBackgroundColorLogic, FurnitureRoomBackgroundLogic, FurnitureRoomBillboardLogic, FurnitureRoomDimmerLogic, FurnitureScoreLogic, FurnitureSongDiskLogic, FurnitureSoundBlockLogic, FurnitureSoundMachineLogic, FurnitureStickieLogic, FurnitureTrophyLogic, FurnitureVoteCounterLogic, FurnitureVoteMajorityLogic, FurnitureWelcomeGiftLogic, FurnitureWindowLogic, FurnitureYoutubeLogic, PetLogic, RoomLogic, SelectionArrowLogic, TileCursorLogic } from './object';
export class RoomObjectLogicFactory implements IRoomObjectLogicFactory
{
private _events: IEventDispatcher = GetEventDispatcher();
private _cachedEvents: Map<string, boolean> = new Map();
private _registeredEvents: Map<string, boolean> = new Map();
private _functions: ((event: RoomObjectEvent) => void)[] = [];
public getLogic(type: string): IRoomObjectEventHandler
{
const logic = this.getLogicType(type);
if(!logic) return null;
const instance = (new logic() as IRoomObjectEventHandler);
if(!instance) return null;
instance.eventDispatcher = this._events;
if(!this._cachedEvents.get(type))
{
this._cachedEvents.set(type, true);
const eventTypes = instance.getEventTypes();
for(const eventType of eventTypes)
{
if(!eventType) continue;
this.registerEventType(eventType);
}
}
return instance;
}
private registerEventType(type: string): void
{
if(this._registeredEvents.get(type)) return;
this._registeredEvents.set(type, true);
for(const func of this._functions)
{
if(!func) continue;
this._events.addEventListener(type, func);
}
}
public registerEventFunction(func: (event: RoomObjectEvent) => void): void
{
if(!func) return;
if(this._functions.indexOf(func) >= 0) return;
this._functions.push(func);
for(const eventType of this._registeredEvents.keys())
{
if(!eventType) continue;
this._events.addEventListener(eventType, func);
}
}
public removeEventFunction(func: (event: RoomObjectEvent) => void): void
{
if(!func) return;
const index = this._functions.indexOf(func);
if(index === -1) return;
this._functions.splice(index, 1);
for(const event of this._registeredEvents.keys())
{
if(!event) continue;
this._events.removeEventListener(event, func);
}
}
public getLogicType(type: string): typeof RoomObjectLogicBase
{
if(!type) return null;
let logic: typeof RoomObjectLogicBase = null;
switch(type)
{
case RoomObjectLogicType.ROOM:
logic = RoomLogic;
break;
case RoomObjectLogicType.TILE_CURSOR:
logic = TileCursorLogic;
break;
case RoomObjectLogicType.SELECTION_ARROW:
logic = SelectionArrowLogic;
break;
case RoomObjectLogicType.USER:
case RoomObjectLogicType.BOT:
case RoomObjectLogicType.RENTABLE_BOT:
logic = AvatarLogic;
break;
case RoomObjectLogicType.PET:
logic = PetLogic;
break;
case RoomObjectLogicType.FURNITURE_BASIC:
logic = FurnitureLogic;
break;
case RoomObjectLogicType.FURNITURE_BADGE_DISPLAY:
logic = FurnitureBadgeDisplayLogic;
break;
case RoomObjectLogicType.FURNITURE_CHANGE_STATE_WHEN_STEP_ON:
logic = FurnitureChangeStateWhenStepOnLogic;
break;
case RoomObjectLogicType.FURNITURE_COUNTER_CLOCK:
logic = FurnitureCounterClockLogic;
break;
case RoomObjectLogicType.FURNITURE_CRACKABLE:
logic = FurnitureCrackableLogic;
break;
case RoomObjectLogicType.FURNITURE_CREDIT:
logic = FurnitureCreditLogic;
break;
case RoomObjectLogicType.FURNITURE_CUSTOM_STACK_HEIGHT:
logic = FurnitureCustomStackHeightLogic;
break;
case RoomObjectLogicType.FURNITURE_DICE:
logic = FurnitureDiceLogic;
break;
case RoomObjectLogicType.FURNITURE_EDITABLE_INTERNAL_LINK:
logic = FurnitureEditableInternalLinkLogic;
break;
case RoomObjectLogicType.FURNITURE_EDITABLE_ROOM_LINK:
logic = FurnitureEditableRoomLinkLogic;
break;
case RoomObjectLogicType.FURNITURE_EXTERNAL_IMAGE_WALLITEM:
logic = FurnitureExternalImageLogic;
break;
case RoomObjectLogicType.FURNITURE_FIREWORKS:
logic = FurnitureFireworksLogic;
break;
case RoomObjectLogicType.FURNITURE_FLOOR_HOLE:
logic = FurnitureFloorHoleLogic;
break;
case RoomObjectLogicType.FURNITURE_GUILD_CUSTOMIZED:
logic = FurnitureGuildCustomizedLogic;
break;
case RoomObjectLogicType.FURNITURE_HIGH_SCORE:
logic = FurnitureHighScoreLogic;
break;
case RoomObjectLogicType.FURNITURE_HOCKEY_SCORE:
logic = FurnitureHockeyScoreLogic;
break;
case RoomObjectLogicType.FURNITURE_ES:
logic = FurnitureIceStormLogic;
break;
case RoomObjectLogicType.FURNITURE_MANNEQUIN:
logic = FurnitureMannequinLogic;
break;
case RoomObjectLogicType.FURNITURE_MULTIHEIGHT:
logic = FurnitureMultiHeightLogic;
break;
case RoomObjectLogicType.FURNITURE_MULTISTATE:
logic = FurnitureMultiStateLogic;
break;
case RoomObjectLogicType.FURNITURE_ONE_WAY_DOOR:
logic = FurnitureOneWayDoorLogic;
break;
case RoomObjectLogicType.FURNITURE_PET_CUSTOMIZATION:
logic = FurniturePetCustomizationLogic;
break;
case RoomObjectLogicType.FURNITURE_PRESENT:
logic = FurniturePresentLogic;
break;
case RoomObjectLogicType.FURNITURE_PURCHASABLE_CLOTHING:
logic = FurniturePurchaseableClothingLogic;
break;
case RoomObjectLogicType.FURNITURE_PUSHABLE:
logic = FurniturePushableLogic;
break;
case RoomObjectLogicType.FURNITURE_BACKGROUND_COLOR:
logic = FurnitureRoomBackgroundColorLogic;
break;
case RoomObjectLogicType.FURNITURE_BG:
logic = FurnitureRoomBackgroundLogic;
break;
case RoomObjectLogicType.FURNITURE_BB:
logic = FurnitureRoomBillboardLogic;
break;
case RoomObjectLogicType.FURNITURE_ROOMDIMMER:
logic = FurnitureRoomDimmerLogic;
break;
case RoomObjectLogicType.FURNITURE_SCORE:
logic = FurnitureScoreLogic;
break;
case RoomObjectLogicType.FURNITURE_SOUNDBLOCK:
logic = FurnitureSoundBlockLogic;
break;
case RoomObjectLogicType.FURNITURE_STICKIE:
logic = FurnitureStickieLogic;
break;
case RoomObjectLogicType.FURNITURE_TROPHY:
logic = FurnitureTrophyLogic;
break;
case RoomObjectLogicType.FURNITURE_VOTE_COUNTER:
logic = FurnitureVoteCounterLogic;
break;
case RoomObjectLogicType.FURNITURE_VOTE_MAJORITY:
logic = FurnitureVoteMajorityLogic;
break;
case RoomObjectLogicType.FURNITURE_WINDOW:
logic = FurnitureWindowLogic;
break;
case RoomObjectLogicType.FURNITURE_LOVELOCK:
logic = FurnitureLoveLockLogic;
break;
case RoomObjectLogicType.FURNITURE_YOUTUBE:
logic = FurnitureYoutubeLogic;
break;
case RoomObjectLogicType.FURNITURE_CRAFTING_GIZMO:
logic = FurnitureCraftingGizmoLogic;
break;
case RoomObjectLogicType.FURNITURE_RENTABLE_SPACE:
logic = FurnitureRentableSpaceLogic;
break;
case RoomObjectLogicType.FURNITURE_EFFECTBOX:
logic = FurnitureEffectBoxLogic;
break;
case RoomObjectLogicType.FURNITURE_MONSTERPLANT_SEED:
logic = FurnitureMonsterplantSeedLogic;
break;
case RoomObjectLogicType.FURNITURE_MYSTERYBOX:
logic = FurnitureMysteryBoxLogic;
break;
case RoomObjectLogicType.FURNITURE_MYSTERYTROPHY:
logic = FurnitureMysteryTrophyLogic;
break;
case RoomObjectLogicType.FURNITURE_RANDOM_TELEPORT:
logic = FurnitureRandomTeleportLogic;
break;
case RoomObjectLogicType.FURNITURE_CLOTHING_CHANGE:
logic = FurnitureClothingChangeLogic;
break;
case RoomObjectLogicType.FURNITURE_CUCKOO_CLOCK:
logic = FurnitureCuckooClockLogic;
break;
case RoomObjectLogicType.FURNITURE_ECOTRON_BOX:
logic = FurnitureEcotronBoxLogic;
break;
case RoomObjectLogicType.FURNITURE_GROUP_FORUM_TERMINAL:
logic = FurnitureGroupForumTerminalLogic;
break;
case RoomObjectLogicType.FURNITURE_HWEEN_LOVELOCK:
logic = FurnitureHweenLovelockLogic;
break;
case RoomObjectLogicType.FURNITURE_INTERNAL_LINK:
logic = FurnitureInternalLinkLogic;
break;
case RoomObjectLogicType.FURNITURE_JUKEBOX:
logic = FurnitureJukeboxLogic;
break;
case RoomObjectLogicType.FURNITURE_PLACEHOLDER:
logic = FurniturePlaceholderLogic;
break;
case RoomObjectLogicType.FURNITURE_PLANET_SYSTEM:
logic = FurniturePlanetSystemLogic;
break;
case RoomObjectLogicType.FURNITURE_RANDOMSTATE:
logic = FurnitureRandomStateLogic;
break;
case RoomObjectLogicType.FURNITURE_SONG_DISK:
logic = FurnitureSongDiskLogic;
break;
case RoomObjectLogicType.FURNITURE_SOUND_MACHINE:
logic = FurnitureSoundMachineLogic;
break;
case RoomObjectLogicType.FURNITURE_WELCOME_GIFT:
logic = FurnitureWelcomeGiftLogic;
break;
case RoomObjectLogicType.FURNITURE_ACHIEVEMENT_RESOLUTION:
logic = FurnitureAchievementResolutionLogic;
break;
case RoomObjectLogicType.FURNITURE_HABBOWHEEL:
logic = FurnitureHabboWheelLogic;
break;
default:
logic = FurnitureLogic;
break;
}
if(!logic)
{
NitroLogger.warn('Unknown Logic', type);
return null;
}
return logic;
}
public get events(): IEventDispatcher
{
return this._events;
}
}
+130
View File
@@ -0,0 +1,130 @@
import { IAdvancedMap, IRoomObjectController, IRoomObjectManager } from '@nitrots/api';
import { AdvancedMap } from '@nitrots/utils';
import { RoomObject } from './object';
export class RoomObjectManager implements IRoomObjectManager
{
private _objects: IAdvancedMap<number, IRoomObjectController>;
private _objectsPerType: IAdvancedMap<string, IAdvancedMap<number, IRoomObjectController>>;
constructor()
{
this._objects = new AdvancedMap();
this._objectsPerType = new AdvancedMap();
}
public dispose(): void
{
this.removeAllObjects();
}
public getObject(id: number): IRoomObjectController
{
const object = this._objects.getValue(id);
if(!object) return null;
return object;
}
public getObjectByIndex(index: number): IRoomObjectController
{
const object = this._objects.getWithIndex(index);
if(!object) return null;
return object;
}
public createObject(id: number, stateCount: number, type: string): IRoomObjectController
{
const object = new RoomObject(id, stateCount, type);
return this.addObject(id, type, object);
}
private addObject(id: number, type: string, object: IRoomObjectController): IRoomObjectController
{
if(this._objects.getValue(id))
{
object.dispose();
return null;
}
this._objects.add(id, object);
const typeMap = this.getTypeMap(type);
if(typeMap) typeMap.add(id, object);
return object;
}
public removeObject(id: number): void
{
const object = this._objects.remove(id);
if(object)
{
const typeMap = this.getTypeMap(object.type);
if(typeMap) typeMap.remove(object.id);
object.dispose();
}
}
public removeAllObjects(): void
{
let i = 0;
while(i < this._objects.length)
{
const object = this._objects.getWithIndex(i);
if(object) object.dispose();
i++;
}
this._objects.reset();
i = 0;
while(i < this._objectsPerType.length)
{
const typeMap = this._objectsPerType.getWithIndex(i);
if(typeMap) typeMap.dispose();
i++;
}
this._objectsPerType.reset();
}
private getTypeMap(k: string, _arg_2: boolean = true): IAdvancedMap<number, IRoomObjectController>
{
let existing = this._objectsPerType.getValue(k);
if(!existing && _arg_2)
{
existing = new AdvancedMap();
this._objectsPerType.add(k, existing);
}
return existing;
}
public get objects(): IAdvancedMap<number, IRoomObjectController>
{
return this._objects;
}
public get totalObjects(): number
{
return this._objects.length;
}
}
@@ -0,0 +1,225 @@
import { IAssetData, IObjectVisualizationData, IRoomObjectGraphicVisualization, IRoomObjectVisualizationFactory, RoomObjectVisualizationType } from '@nitrots/api';
import { NitroLogger } from '@nitrots/utils';
import { AvatarVisualization, AvatarVisualizationData, FurnitureAnimatedVisualization, FurnitureAnimatedVisualizationData, FurnitureBBVisualization, FurnitureBadgeDisplayVisualization, FurnitureBottleVisualization, FurnitureBuilderPlaceholderVisualization, FurnitureCounterClockVisualization, FurnitureCuboidVisualization, FurnitureExternalImageVisualization, FurnitureFireworksVisualization, FurnitureGiftWrappedFireworksVisualization, FurnitureGiftWrappedVisualization, FurnitureGuildCustomizedVisualization, FurnitureGuildIsometricBadgeVisualization, FurnitureHabboWheelVisualization, FurnitureIsometricBBVisualization, FurnitureMannequinVisualization, FurnitureMannequinVisualizationData, FurniturePartyBeamerVisualization, FurniturePlanetSystemVisualization, FurniturePosterVisualization, FurnitureQueueTileVisualization, FurnitureResettingAnimatedVisualization, FurnitureRoomBackgroundVisualization, FurnitureScoreBoardVisualization, FurnitureSoundBlockVisualization, FurnitureStickieVisualization, FurnitureValRandomizerVisualization, FurnitureVisualization, FurnitureVisualizationData, FurnitureVoteCounterVisualization, FurnitureVoteMajorityVisualization, FurnitureWaterAreaVisualization, FurnitureYoutubeVisualization, PetVisualization, PetVisualizationData, RoomObjectSpriteVisualization, RoomVisualization, RoomVisualizationData, TileCursorVisualization } from './object';
export class RoomObjectVisualizationFactory implements IRoomObjectVisualizationFactory
{
private static CACHING_ENABLED: boolean = true;
private _visualizationDatas: Map<string, IObjectVisualizationData>;
constructor()
{
this._visualizationDatas = new Map();
}
public getVisualization(type: string): IRoomObjectGraphicVisualization
{
const visualization = this.getVisualizationType(type);
if(!visualization) return null;
return new visualization();
}
public getVisualizationType(type: string): typeof RoomObjectSpriteVisualization
{
if(!type) return null;
let visualization: typeof RoomObjectSpriteVisualization = null;
switch(type)
{
case RoomObjectVisualizationType.ROOM:
visualization = RoomVisualization;
break;
case RoomObjectVisualizationType.TILE_CURSOR:
visualization = TileCursorVisualization;
break;
case RoomObjectVisualizationType.USER:
case RoomObjectVisualizationType.BOT:
case RoomObjectVisualizationType.RENTABLE_BOT:
visualization = AvatarVisualization;
break;
case RoomObjectVisualizationType.PET_ANIMATED:
visualization = PetVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_STATIC:
visualization = FurnitureVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_ANIMATED:
visualization = FurnitureAnimatedVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_RESETTING_ANIMATED:
visualization = FurnitureResettingAnimatedVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_BADGE_DISPLAY:
visualization = FurnitureBadgeDisplayVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_BG:
visualization = FurnitureRoomBackgroundVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_BB:
visualization = FurnitureBBVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_ISOMETRIC_BB:
visualization = FurnitureIsometricBBVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_BOTTLE:
visualization = FurnitureBottleVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_BUILDER_PLACEHOLDER:
visualization = FurnitureBuilderPlaceholderVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_COUNTER_CLOCK:
visualization = FurnitureCounterClockVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_CUBOID:
visualization = FurnitureCuboidVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_EXTERNAL_IMAGE:
visualization = FurnitureExternalImageVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_FIREWORKS:
visualization = FurnitureFireworksVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_GIFT_WRAPPED_FIREWORKS:
visualization = FurnitureGiftWrappedFireworksVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_GIFT_WRAPPED:
visualization = FurnitureGiftWrappedVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_GUILD_CUSTOMIZED:
visualization = FurnitureGuildCustomizedVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_GUILD_ISOMETRIC_BADGE:
visualization = FurnitureGuildIsometricBadgeVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_HABBOWHEEL:
visualization = FurnitureHabboWheelVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_MANNEQUIN:
visualization = FurnitureMannequinVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_PARTY_BEAMER:
visualization = FurniturePartyBeamerVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_PLANET_SYSTEM:
visualization = FurniturePlanetSystemVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_POSTER:
visualization = FurniturePosterVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_QUEUE_TILE:
visualization = FurnitureQueueTileVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_SCORE_BOARD:
visualization = FurnitureScoreBoardVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_SOUNDBLOCK:
visualization = FurnitureSoundBlockVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_STICKIE:
visualization = FurnitureStickieVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_VAL_RANDOMIZER:
visualization = FurnitureValRandomizerVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_VOTE_COUNTER:
visualization = FurnitureVoteCounterVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_VOTE_MAJORITY:
visualization = FurnitureVoteMajorityVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_WATER_AREA:
visualization = FurnitureWaterAreaVisualization;
break;
case RoomObjectVisualizationType.FURNITURE_YOUTUBE:
visualization = FurnitureYoutubeVisualization;
break;
}
if(!visualization)
{
NitroLogger.log('Unknown Visualization', type);
return null;
}
return visualization;
}
public getVisualizationData(type: string, visualization: string, asset: IAssetData): IObjectVisualizationData
{
const existing = this._visualizationDatas.get(type);
if(existing) return existing;
let visualizationData: IObjectVisualizationData = null;
switch(visualization)
{
case RoomObjectVisualizationType.FURNITURE_STATIC:
case RoomObjectVisualizationType.FURNITURE_GIFT_WRAPPED:
case RoomObjectVisualizationType.FURNITURE_BB:
case RoomObjectVisualizationType.FURNITURE_ISOMETRIC_BB:
case RoomObjectVisualizationType.FURNITURE_BG:
case RoomObjectVisualizationType.FURNITURE_STICKIE:
case RoomObjectVisualizationType.FURNITURE_BUILDER_PLACEHOLDER:
visualizationData = new FurnitureVisualizationData();
break;
case RoomObjectVisualizationType.FURNITURE_ANIMATED:
case RoomObjectVisualizationType.FURNITURE_RESETTING_ANIMATED:
case RoomObjectVisualizationType.FURNITURE_POSTER:
case RoomObjectVisualizationType.FURNITURE_HABBOWHEEL:
case RoomObjectVisualizationType.FURNITURE_VAL_RANDOMIZER:
case RoomObjectVisualizationType.FURNITURE_BOTTLE:
case RoomObjectVisualizationType.FURNITURE_PLANET_SYSTEM:
case RoomObjectVisualizationType.FURNITURE_QUEUE_TILE:
case RoomObjectVisualizationType.FURNITURE_PARTY_BEAMER:
case RoomObjectVisualizationType.FURNITURE_COUNTER_CLOCK:
case RoomObjectVisualizationType.FURNITURE_WATER_AREA:
case RoomObjectVisualizationType.FURNITURE_SCORE_BOARD:
case RoomObjectVisualizationType.FURNITURE_FIREWORKS:
case RoomObjectVisualizationType.FURNITURE_GIFT_WRAPPED_FIREWORKS:
case RoomObjectVisualizationType.FURNITURE_GUILD_CUSTOMIZED:
case RoomObjectVisualizationType.FURNITURE_GUILD_ISOMETRIC_BADGE:
case RoomObjectVisualizationType.FURNITURE_VOTE_COUNTER:
case RoomObjectVisualizationType.FURNITURE_VOTE_MAJORITY:
case RoomObjectVisualizationType.FURNITURE_SOUNDBLOCK:
case RoomObjectVisualizationType.FURNITURE_BADGE_DISPLAY:
case RoomObjectVisualizationType.FURNITURE_EXTERNAL_IMAGE:
case RoomObjectVisualizationType.FURNITURE_YOUTUBE:
case RoomObjectVisualizationType.TILE_CURSOR:
visualizationData = new FurnitureAnimatedVisualizationData();
break;
case RoomObjectVisualizationType.FURNITURE_MANNEQUIN:
visualizationData = new FurnitureMannequinVisualizationData();
break;
case RoomObjectVisualizationType.ROOM:
visualizationData = new RoomVisualizationData();
break;
case RoomObjectVisualizationType.USER:
case RoomObjectVisualizationType.BOT:
case RoomObjectVisualizationType.RENTABLE_BOT:
visualizationData = new AvatarVisualizationData();
break;
case RoomObjectVisualizationType.PET_ANIMATED:
visualizationData = new PetVisualizationData();
break;
}
if(!visualizationData) return null;
if(!visualizationData.initialize(asset))
{
visualizationData.dispose();
return null;
}
if(RoomObjectVisualizationFactory.CACHING_ENABLED) this._visualizationDatas.set(type, visualizationData);
return visualizationData;
}
}
+858
View File
@@ -0,0 +1,858 @@
import { IGetImageListener, IImageResult, IObjectData, IRoomEngine, IRoomObjectController, IRoomRenderingCanvas, IVector3D, LegacyDataType, RoomObjectCategory, RoomObjectUserType, RoomObjectVariable } from '@nitrots/api';
import { FloorHeightMapMessageParser, RoomEntryTileMessageParser } from '@nitrots/communication';
import { GetEventDispatcher, RoomEngineEvent, RoomEngineObjectEvent } from '@nitrots/events';
import { GetTickerTime, RoomId, Vector3d } from '@nitrots/utils';
import { Container, Point, Rectangle, Sprite, Texture } from 'pixi.js';
import { RoomEngine } from './RoomEngine';
import { ObjectRoomMapUpdateMessage } from './messages';
import { RoomPlaneParser } from './object/RoomPlaneParser';
import { LegacyWallGeometry } from './utils/LegacyWallGeometry';
export class RoomPreviewer
{
public static SCALE_NORMAL: number = 64;
public static SCALE_SMALL: number = 32;
public static PREVIEW_COUNTER: number = 0;
public static PREVIEW_CANVAS_ID: number = 1;
public static PREVIEW_OBJECT_ID: number = 1;
public static PREVIEW_OBJECT_LOCATION_X: number = 2;
public static PREVIEW_OBJECT_LOCATION_Y: number = 2;
private static ALLOWED_IMAGE_CUT: number = 0.25;
private static AUTOMATIC_STATE_CHANGE_INTERVAL: number = 2500;
private static ZOOM_ENABLED: boolean = true;
private _roomEngine: IRoomEngine;
private _planeParser: RoomPlaneParser;
private _previewRoomId: number = 1;
private _currentPreviewObjectType: number = 0;
private _currentPreviewObjectCategory: number = 0;
private _currentPreviewObjectData: string = '';
private _currentPreviewRectangle: Rectangle = null;
private _currentPreviewCanvasWidth: number = 0;
private _currentPreviewCanvasHeight: number = 0;
private _currentPreviewScale: number = 64;
private _currentPreviewNeedsZoomOut: boolean;
private _automaticStateChange: boolean;
private _previousAutomaticStateChangeTime: number;
private _addViewOffset: Point;
private _backgroundColor: number = 305148561;
private _backgroundSprite: Sprite = null;
private _disableUpdate: boolean = false;
constructor(roomEngine: IRoomEngine, roomId: number = 1)
{
this._roomEngine = roomEngine;
this._planeParser = new RoomPlaneParser();
this._previewRoomId = RoomId.makeRoomPreviewerId(roomId);
this._addViewOffset = new Point(0, 0);
this.onRoomObjectAdded = this.onRoomObjectAdded.bind(this);
this.onRoomInitializedonRoomInitialized = this.onRoomInitializedonRoomInitialized.bind(this);
if(this.isRoomEngineReady && GetEventDispatcher())
{
GetEventDispatcher().addEventListener(RoomEngineObjectEvent.ADDED, this.onRoomObjectAdded);
GetEventDispatcher().addEventListener(RoomEngineObjectEvent.CONTENT_UPDATED, this.onRoomObjectAdded);
GetEventDispatcher().addEventListener(RoomEngineEvent.INITIALIZED, this.onRoomInitializedonRoomInitialized);
}
this.createRoomForPreview();
}
public dispose(): void
{
this.reset(true);
if(this.isRoomEngineReady && GetEventDispatcher())
{
GetEventDispatcher().removeEventListener(RoomEngineObjectEvent.ADDED, this.onRoomObjectAdded);
GetEventDispatcher().removeEventListener(RoomEngineObjectEvent.CONTENT_UPDATED, this.onRoomObjectAdded);
GetEventDispatcher().removeEventListener(RoomEngineEvent.INITIALIZED, this.onRoomInitializedonRoomInitialized);
}
if(this._backgroundSprite)
{
this._backgroundSprite.destroy();
this._backgroundSprite = null;
}
if(this._planeParser)
{
this._planeParser.dispose();
this._planeParser = null;
}
}
private createRoomForPreview(): void
{
if(this.isRoomEngineReady)
{
const size = 7;
const planeParser = new RoomPlaneParser();
planeParser.initializeTileMap((size + 2), (size + 2));
let y = 1;
while(y < (1 + size))
{
let x = 1;
while(x < (1 + size))
{
planeParser.setTileHeight(x, y, 0);
x++;
}
y++;
}
planeParser.initializeFromTileData();
this._roomEngine.createRoomInstance(this._previewRoomId, planeParser.getMapData());
planeParser.dispose();
}
}
public reset(k: boolean): void
{
if(this.isRoomEngineReady)
{
this._roomEngine.removeRoomObjectFloor(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID);
this._roomEngine.removeRoomObjectWall(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID);
this._roomEngine.removeRoomObjectUser(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID);
if(!k) this.updatePreviewRoomView();
}
this._currentPreviewObjectCategory = RoomObjectCategory.MINIMUM;
}
public updatePreviewModel(model: string, wallHeight: number, scale: boolean = true): void
{
const parser = new FloorHeightMapMessageParser();
parser.flush();
parser.parseModel(model, wallHeight, scale);
//@ts-ignore
const wallGeometry = (this._roomEngine as IRoomCreator).getLegacyWallGeometry(this._previewRoomId);
if(!wallGeometry) return;
this._planeParser.reset();
const width = parser.width;
const height = parser.height;
this._planeParser.initializeTileMap(width, height);
const entryTile: RoomEntryTileMessageParser = null;
let doorX = -1;
let doorY = -1;
let doorZ = 0;
let doorDirection = 0;
let y = 0;
while(y < height)
{
let x = 0;
while(x < width)
{
const tileHeight = parser.getHeight(x, y);
if(((((y > 0) && (y < (height - 1))) || ((x > 0) && (x < (width - 1)))) && (!(tileHeight == RoomPlaneParser.TILE_BLOCKED))) && ((entryTile == null) || ((x == entryTile.x) && (y == entryTile.y))))
{
if(((parser.getHeight(x, (y - 1)) == RoomPlaneParser.TILE_BLOCKED) && (parser.getHeight((x - 1), y) == RoomPlaneParser.TILE_BLOCKED)) && (parser.getHeight(x, (y + 1)) == RoomPlaneParser.TILE_BLOCKED))
{
doorX = (x + 0.5);
doorY = y;
doorZ = tileHeight;
doorDirection = 90;
}
if(((parser.getHeight(x, (y - 1)) == RoomPlaneParser.TILE_BLOCKED) && (parser.getHeight((x - 1), y) == RoomPlaneParser.TILE_BLOCKED)) && (parser.getHeight((x + 1), y) == RoomPlaneParser.TILE_BLOCKED))
{
doorX = x;
doorY = (y + 0.5);
doorZ = tileHeight;
doorDirection = 180;
}
}
this._planeParser.setTileHeight(x, y, tileHeight);
x++;
}
y++;
}
this._planeParser.setTileHeight(Math.floor(doorX), Math.floor(doorY), doorZ);
this._planeParser.initializeFromTileData(parser.wallHeight);
this._planeParser.setTileHeight(Math.floor(doorX), Math.floor(doorY), (doorZ + this._planeParser.wallHeight));
wallGeometry.scale = LegacyWallGeometry.DEFAULT_SCALE;
wallGeometry.initialize(width, height, this._planeParser.floorHeight);
let heightIterator = (parser.height - 1);
while(heightIterator >= 0)
{
let widthIterator = (parser.width - 1);
while(widthIterator >= 0)
{
wallGeometry.setHeight(widthIterator, heightIterator, this._planeParser.getTileHeight(widthIterator, heightIterator));
widthIterator--;
}
heightIterator--;
}
const roomMap = this._planeParser.getMapData();
roomMap.doors.push({
x: doorX,
y: doorY,
z: doorZ,
dir: doorDirection
});
const roomObject = this.getRoomPreviewOwnRoomObject();
if(roomObject) roomObject.processUpdateMessage(new ObjectRoomMapUpdateMessage(roomMap));
}
public addFurnitureIntoRoom(classId: number, direction: IVector3D, objectData: IObjectData = null, extra: string = null): number
{
if(!objectData) objectData = new LegacyDataType();
if(this.isRoomEngineReady)
{
this.reset(false);
this._currentPreviewObjectType = classId;
this._currentPreviewObjectCategory = RoomObjectCategory.FLOOR;
this._currentPreviewObjectData = '';
if(this._roomEngine.addFurnitureFloor(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, classId, new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), direction, 0, objectData, NaN, -1, 0, -1, '', true, false))
{
this._previousAutomaticStateChangeTime = GetTickerTime();
this._automaticStateChange = true;
const roomObject = this._roomEngine.getRoomObject(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory);
if(roomObject && extra) roomObject.model.setValue(RoomObjectVariable.FURNITURE_EXTRAS, extra);
this.updatePreviewRoomView();
return RoomPreviewer.PREVIEW_OBJECT_ID;
}
}
return -1;
}
public addWallItemIntoRoom(classId: number, direction: IVector3D, objectData: string): number
{
if(this.isRoomEngineReady)
{
if((this._currentPreviewObjectCategory === RoomObjectCategory.WALL) && (this._currentPreviewObjectType === classId) && (this._currentPreviewObjectData === objectData)) return RoomPreviewer.PREVIEW_OBJECT_ID;
this.reset(false);
this._currentPreviewObjectType = classId;
this._currentPreviewObjectCategory = RoomObjectCategory.WALL;
this._currentPreviewObjectData = objectData;
if(this._roomEngine.addFurnitureWall(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, classId, new Vector3d(0.5, 2.3, 1.8), direction, 0, objectData, 0, 0, -1, '', false))
{
this._previousAutomaticStateChangeTime = GetTickerTime();
this._automaticStateChange = true;
this.updatePreviewRoomView();
return RoomPreviewer.PREVIEW_OBJECT_ID;
}
}
return -1;
}
public addAvatarIntoRoom(figure: string, effect: number): number
{
if(this.isRoomEngineReady)
{
this.reset(false);
this._currentPreviewObjectType = 1;
this._currentPreviewObjectCategory = RoomObjectCategory.UNIT;
this._currentPreviewObjectData = figure;
if(this._roomEngine.addRoomObjectUser(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), new Vector3d(90, 0, 0), 135, RoomObjectUserType.getTypeNumber(RoomObjectUserType.USER), figure))
{
this._previousAutomaticStateChangeTime = GetTickerTime();
this._automaticStateChange = true;
this.updateUserGesture(1);
this.updateUserEffect(effect);
this.updateUserPosture('std');
}
this.updatePreviewRoomView();
return RoomPreviewer.PREVIEW_OBJECT_ID;
}
return -1;
}
public addPetIntoRoom(figure: string): number
{
if(this.isRoomEngineReady)
{
this.reset(false);
this._currentPreviewObjectType = 1;
this._currentPreviewObjectCategory = RoomObjectCategory.UNIT;
this._currentPreviewObjectData = figure;
if(this._roomEngine.addRoomObjectUser(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), new Vector3d(90, 0, 0), 90, RoomObjectUserType.getTypeNumber(RoomObjectUserType.PET), figure))
{
this._previousAutomaticStateChangeTime = GetTickerTime();
this._automaticStateChange = false;
this.updateUserGesture(1);
this.updateUserPosture('std');
}
this.updatePreviewRoomView();
return RoomPreviewer.PREVIEW_OBJECT_ID;
}
return -1;
}
public updateUserPosture(type: string, parameter: string = ''): void
{
if(this.isRoomEngineReady) this._roomEngine.updateRoomObjectUserPosture(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, type, parameter);
}
public updateUserGesture(gestureId: number): void
{
if(this.isRoomEngineReady) this._roomEngine.updateRoomObjectUserGesture(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, gestureId);
}
public updateUserEffect(effectId: number): void
{
if(this.isRoomEngineReady) this._roomEngine.updateRoomObjectUserEffect(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, effectId);
}
public updateObjectUserFigure(figure: string, gender: string = null, subType: string = null, isRiding: boolean = false): boolean
{
if(this.isRoomEngineReady) return this._roomEngine.updateRoomObjectUserFigure(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, figure, gender, subType, isRiding);
return false;
}
public updateObjectUserAction(action: string, value: number, parameter: string = null): void
{
if(this.isRoomEngineReady) this._roomEngine.updateRoomObjectUserAction(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, action, value, parameter);
}
public updateObjectStuffData(stuffData: IObjectData): void
{
if(this.isRoomEngineReady) this._roomEngine.updateRoomObjectFloor(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, null, null, stuffData.state, stuffData);
}
public changeRoomObjectState(): void
{
if(this.isRoomEngineReady)
{
this._automaticStateChange = false;
if(this._currentPreviewObjectCategory !== RoomObjectCategory.UNIT) this._roomEngine.changeObjectState(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory);
}
}
public changeRoomObjectDirection(): void
{
if(this.isRoomEngineReady)
{
const roomObject = this._roomEngine.getRoomObject(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory);
if(!roomObject) return;
const direction = this._roomEngine.objectEventHandler.getValidRoomObjectDirection(roomObject, true);
switch(this._currentPreviewObjectCategory)
{
case RoomObjectCategory.FLOOR: {
const floorLocation = new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y);
const floorDirection = new Vector3d(direction, direction, direction);
this._roomEngine.updateRoomObjectFloor(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, floorLocation, floorDirection, null, null);
return;
}
case RoomObjectCategory.WALL:
//this._roomEngine.updateRoomObjectWall(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, null, direction, null, null);
return;
}
}
}
private checkAutomaticRoomObjectStateChange(): void
{
if(this._automaticStateChange)
{
const time = GetTickerTime();
if(time > (this._previousAutomaticStateChangeTime + RoomPreviewer.AUTOMATIC_STATE_CHANGE_INTERVAL))
{
this._previousAutomaticStateChangeTime = time;
if(this.isRoomEngineReady) this._roomEngine.changeObjectState(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory);
}
}
}
public getRoomCanvas(width: number, height: number): Container
{
if(this.isRoomEngineReady)
{
const displayObject = (this._roomEngine.getRoomInstanceDisplay(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, width, height, this._currentPreviewScale) as Container);
if(displayObject && (this._backgroundColor !== null))
{
let backgroundSprite = this._backgroundSprite;
if(!backgroundSprite)
{
backgroundSprite = new Sprite(Texture.WHITE);
displayObject.addChildAt(backgroundSprite, 0);
}
backgroundSprite.width = width;
backgroundSprite.height = height;
//backgroundSprite.tint = this._backgroundColor;
}
this._roomEngine.setRoomInstanceRenderingCanvasMask(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, true);
const geometry = this._roomEngine.getRoomInstanceGeometry(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID);
if(geometry) geometry.adjustLocation(new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), 30);
this._currentPreviewCanvasWidth = width;
this._currentPreviewCanvasHeight = height;
return displayObject;
}
return null;
}
public modifyRoomCanvas(width: number, height: number): void
{
if(this.isRoomEngineReady)
{
this._currentPreviewCanvasWidth = width;
this._currentPreviewCanvasHeight = height;
if(this._backgroundSprite)
{
this._backgroundSprite.width = width;
this._backgroundSprite.height = height;
}
this._roomEngine.initializeRoomInstanceRenderingCanvas(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, width, height);
}
}
public set addViewOffset(point: Point)
{
this._addViewOffset = point;
}
public get addViewOffset(): Point
{
return this._addViewOffset;
}
public updatePreviewObjectBoundingRectangle(point: Point = null): void
{
if(!point) point = new Point(0, 0);
const objectBounds = this._roomEngine.getRoomObjectBoundingRectangle(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory, RoomPreviewer.PREVIEW_CANVAS_ID);
if(objectBounds && point)
{
objectBounds.x += -(this._currentPreviewCanvasWidth >> 1);
objectBounds.y += -(this._currentPreviewCanvasHeight >> 1);
objectBounds.x += -(point.x);
objectBounds.y += -(point.y);
if(!this._currentPreviewRectangle)
{
this._currentPreviewRectangle = objectBounds;
}
else
{
const bounds = this._currentPreviewRectangle.clone().enlarge(objectBounds);
if(((((bounds.width - this._currentPreviewRectangle.width) > ((this._currentPreviewCanvasWidth - this._currentPreviewRectangle.width) >> 1)) || ((bounds.height - this._currentPreviewRectangle.height) > ((this._currentPreviewCanvasHeight - this._currentPreviewRectangle.height) >> 1))) || (this._currentPreviewRectangle.width < 1)) || (this._currentPreviewRectangle.height < 1)) this._currentPreviewRectangle = bounds;
}
}
}
private validatePreviewSize(point: Point): Point
{
if(((this._currentPreviewRectangle.width < 1) || (this._currentPreviewRectangle.height < 1)))
{
return point;
}
if(this.isRoomEngineReady)
{
const geometry = this._roomEngine.getRoomInstanceGeometry(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID);
if((this._currentPreviewRectangle.width > (this._currentPreviewCanvasWidth * (1 + RoomPreviewer.ALLOWED_IMAGE_CUT))) || (this._currentPreviewRectangle.height > (this._currentPreviewCanvasHeight * (1 + RoomPreviewer.ALLOWED_IMAGE_CUT))))
{
if(RoomPreviewer.ZOOM_ENABLED)
{
if(this._roomEngine.getRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID) !== 0.5)
{
this._roomEngine.setRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, 0.5, null, null);
this._currentPreviewScale = RoomPreviewer.SCALE_SMALL;
this._currentPreviewNeedsZoomOut = true;
point.x = (point.x >> 1);
point.y = (point.y >> 1);
this._currentPreviewRectangle.x = (this._currentPreviewRectangle.x >> 2);
this._currentPreviewRectangle.y = (this._currentPreviewRectangle.y >> 2);
this._currentPreviewRectangle.width = (this._currentPreviewRectangle.width >> 2);
this._currentPreviewRectangle.height = (this._currentPreviewRectangle.height >> 2);
}
}
else
{
if(geometry.isZoomedIn())
{
geometry.performZoomOut();
this._currentPreviewScale = RoomPreviewer.SCALE_SMALL;
this._currentPreviewNeedsZoomOut = true;
}
}
}
else if(!this._currentPreviewNeedsZoomOut)
{
if(RoomPreviewer.ZOOM_ENABLED)
{
if(this._roomEngine.getRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID) !== 1)
{
this._roomEngine.setRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, 1, null, null);
this._currentPreviewScale = RoomPreviewer.SCALE_NORMAL;
}
}
else
{
if(!geometry.isZoomedIn())
{
geometry.performZoomIn();
this._currentPreviewScale = RoomPreviewer.SCALE_NORMAL;
}
}
}
}
return point;
}
public zoomIn(): void
{
if(this.isRoomEngineReady)
{
if(RoomPreviewer.ZOOM_ENABLED)
{
this._roomEngine.setRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, 1);
}
else
{
const geometry = this._roomEngine.getRoomInstanceGeometry(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID);
geometry.performZoomIn();
}
}
this._currentPreviewScale = RoomPreviewer.SCALE_NORMAL;
}
public zoomOut(): void
{
if(this.isRoomEngineReady)
{
if(RoomPreviewer.ZOOM_ENABLED)
{
this._roomEngine.setRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, 0.5);
}
else
{
const geometry = this._roomEngine.getRoomInstanceGeometry(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID);
geometry.performZoomOut();
}
}
this._currentPreviewScale = RoomPreviewer.SCALE_SMALL;
}
public updateAvatarDirection(direction: number, headDirection: number): void
{
if(this.isRoomEngineReady)
{
this._roomEngine.updateRoomObjectUserLocation(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), false, 0, new Vector3d((direction * 45), 0, 0), (headDirection * 45));
}
}
public updateObjectRoom(floorType: string = null, wallType: string = null, landscapeType: string = null, _arg_4: boolean = false): boolean
{
if(this.isRoomEngineReady) return this._roomEngine.updateRoomInstancePlaneType(this._previewRoomId, floorType, wallType, landscapeType, _arg_4);
return false;
}
public updateRoomWallsAndFloorVisibility(wallsVisible: boolean, floorsVisible: boolean = true): void
{
if(this.isRoomEngineReady) this._roomEngine.updateRoomInstancePlaneVisibility(this._previewRoomId, wallsVisible, floorsVisible);
}
private getCanvasOffset(point: Point): Point
{
if(((this._currentPreviewRectangle.width < 1) || (this._currentPreviewRectangle.height < 1))) return point;
let x = (-(this._currentPreviewRectangle.left + this._currentPreviewRectangle.right) >> 1);
let y = (-(this._currentPreviewRectangle.top + this._currentPreviewRectangle.bottom) >> 1);
const height = ((this._currentPreviewCanvasHeight - this._currentPreviewRectangle.height) >> 1);
if(height > 10)
{
y = (y + Math.min(15, (height - 10)));
}
else
{
if(this._currentPreviewObjectCategory !== RoomObjectCategory.UNIT)
{
y = (y + (5 - Math.max(0, (height / 2))));
}
else
{
y = (y - (5 - Math.min(0, (height / 2))));
}
}
y = (y + this._addViewOffset.y);
x = (x + this._addViewOffset.x);
const offsetX = (x - point.x);
const offsetY = (y - point.y);
if((offsetX !== 0) || (offsetY !== 0))
{
const _local_7 = Math.sqrt(((offsetX * offsetX) + (offsetY * offsetY)));
if(_local_7 > 10)
{
x = (point.x + ((offsetX * 10) / _local_7));
y = (point.y + ((offsetY * 10) / _local_7));
}
return new Point(x, y);
}
return null;
}
public updatePreviewRoomView(k: boolean = false): void
{
if(this._disableUpdate && !k) return;
this.checkAutomaticRoomObjectStateChange();
if(this.isRoomEngineReady)
{
let offset = this._roomEngine.getRoomInstanceRenderingCanvasOffset(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID);
if(offset)
{
this.updatePreviewObjectBoundingRectangle(offset);
if(this._currentPreviewRectangle)
{
const scale = this._currentPreviewScale;
offset = this.validatePreviewSize(offset);
const canvasOffset = this.getCanvasOffset(offset);
if(canvasOffset)
{
this._roomEngine.setRoomInstanceRenderingCanvasOffset(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, canvasOffset);
}
if(this._currentPreviewScale !== scale) this._currentPreviewRectangle = null;
}
}
}
}
private onRoomInitializedonRoomInitialized(event: RoomEngineEvent): void
{
if(!event) return;
switch(event.type)
{
case RoomEngineEvent.INITIALIZED:
if((event.roomId === this._previewRoomId) && this.isRoomEngineReady)
{
this._roomEngine.updateRoomInstancePlaneType(this._previewRoomId, '110', '99999');
}
return;
}
}
private onRoomObjectAdded(event: RoomEngineObjectEvent): void
{
if((event.roomId === this._previewRoomId) && (event.objectId === RoomPreviewer.PREVIEW_OBJECT_ID) && (event.category === this._currentPreviewObjectCategory))
{
this._currentPreviewRectangle = null;
this._currentPreviewNeedsZoomOut = false;
const roomObject = this._roomEngine.getRoomObject(event.roomId, event.objectId, event.category);
if(roomObject && roomObject.model && (event.category === RoomObjectCategory.WALL))
{
const sizeZ = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_SIZE_Z);
const centerZ = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_CENTER_Z);
if((sizeZ !== null) || (centerZ !== null))
{
this._roomEngine.updateRoomObjectWallLocation(event.roomId, event.objectId, new Vector3d(0.5, 2.3, (((3.6 - sizeZ) / 2) + centerZ)));
}
}
}
}
public getRenderingCanvas(): IRoomRenderingCanvas
{
const renderingCanvas = this._roomEngine.getRoomInstanceRenderingCanvas(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID);
if(!renderingCanvas) return null;
return renderingCanvas;
}
public getGenericRoomObjectImage(type: string, value: string, direction: IVector3D, scale: number, listener: IGetImageListener, bgColor: number = 0, extras: string = null, objectData: IObjectData = null, state: number = -1, frame: number = -1, posture: string = null): IImageResult
{
if(this.isRoomEngineReady)
{
return this._roomEngine.getGenericRoomObjectImage(type, value, direction, scale, listener, bgColor, extras, objectData, state, frame, posture);
}
return null;
}
public getRoomObjectImage(direction: IVector3D, scale: number, listener: IGetImageListener, bgColor: number = 0): IImageResult
{
if(this.isRoomEngineReady)
{
return this._roomEngine.getRoomObjectImage(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory, direction, scale, listener, bgColor);
}
return null;
}
public getRoomObjectCurrentImage(): Texture
{
if(this.isRoomEngineReady)
{
const roomObject = this._roomEngine.getRoomObject(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory);
if(roomObject && roomObject.visualization) return roomObject.visualization.getImage();
}
return null;
}
public getRoomPreviewObject(): IRoomObjectController
{
if(this.isRoomEngineReady)
{
const roomObject = this._roomEngine.getRoomObject(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory);
if(roomObject) return roomObject;
}
return null;
}
public getRoomPreviewOwnRoomObject(): IRoomObjectController
{
if(this.isRoomEngineReady)
{
const roomObject = this._roomEngine.getRoomObject(this._previewRoomId, RoomEngine.ROOM_OBJECT_ID, RoomObjectCategory.ROOM);
if(roomObject) return roomObject;
}
return null;
}
public get isRoomEngineReady(): boolean
{
return true;
}
public get roomId(): number
{
return this._previewRoomId;
}
public get backgroundColor(): number
{
return this._backgroundColor;
}
public set backgroundColor(color: number)
{
this._backgroundColor = color;
}
public get width(): number
{
return this._currentPreviewCanvasWidth;
}
public get height(): number
{
return this._currentPreviewCanvasHeight;
}
}
+11
View File
@@ -0,0 +1,11 @@
export class RoomVariableEnum
{
public static ROOM_MIN_X: string = 'room_min_x';
public static ROOM_MAX_X: string = 'room_max_x';
public static ROOM_MIN_Y: string = 'room_min_y';
public static ROOM_MAX_Y: string = 'room_max_y';
public static ROOM_IS_PUBLIC: string = 'room_is_public';
public static ROOM_Z_SCALE: string = 'room_z_scale';
public static AD_DISPLAY_DELAY: string = 'ad_display_delay';
public static IS_PLAYING_GAME: string = 'is_playing_game';
}
+36
View File
@@ -0,0 +1,36 @@
export * from './GetRoomContentLoader';
export * from './GetRoomEngine';
export * from './GetRoomManager';
export * from './GetRoomMessageHandler';
export * from './GetRoomObjectLogicFactory';
export * from './GetRoomObjectVisualizationFactory';
export * from './ImageResult';
export * from './PetColorResult';
export * from './RoomContentLoader';
export * from './RoomEngine';
export * from './RoomInstance';
export * from './RoomManager';
export * from './RoomMessageHandler';
export * from './RoomObjectEventHandler';
export * from './RoomObjectLogicFactory';
export * from './RoomObjectManager';
export * from './RoomObjectVisualizationFactory';
export * from './RoomPreviewer';
export * from './RoomVariableEnum';
export * from './messages';
export * from './object';
export * from './object/logic';
export * from './object/logic/furniture';
export * from './object/visualization';
export * from './object/visualization/avatar';
export * from './object/visualization/avatar/additions';
export * from './object/visualization/data';
export * from './object/visualization/furniture';
export * from './object/visualization/pet';
export * from './object/visualization/room';
export * from './object/visualization/room/mask';
export * from './object/visualization/room/utils';
export * from './renderer';
export * from './renderer/cache';
export * from './renderer/utils';
export * from './utils';
@@ -0,0 +1,21 @@
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectAdUpdateMessage extends RoomObjectUpdateMessage
{
public static IMAGE_LOADED: string = 'ROAUM_IMAGE_LOADED';
public static IMAGE_LOADING_FAILED: string = 'ROAUM_IMAGE_FAILED';
private _type: string;
constructor(type: string)
{
super(null, null);
this._type = type;
}
public get type(): string
{
return this._type;
}
}
@@ -0,0 +1,25 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarCarryObjectUpdateMessage extends ObjectStateUpdateMessage
{
private _itemType: number;
private _itemName: string;
constructor(itemType: number, itemName: string)
{
super();
this._itemType = itemType;
this._itemName = itemName;
}
public get itemType(): number
{
return this._itemType;
}
public get itemName(): string
{
return this._itemName;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarChatUpdateMessage extends ObjectStateUpdateMessage
{
private _numberOfWords: number;
constructor(numberOfWords: number = 0)
{
super();
this._numberOfWords = numberOfWords;
}
public get numberOfWords(): number
{
return this._numberOfWords;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarDanceUpdateMessage extends ObjectStateUpdateMessage
{
private _danceStyle: number;
constructor(danceStyle: number = 0)
{
super();
this._danceStyle = danceStyle;
}
public get danceStyle(): number
{
return this._danceStyle;
}
}
@@ -0,0 +1,25 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarEffectUpdateMessage extends ObjectStateUpdateMessage
{
private _effect: number;
private _delayMilliseconds: number;
constructor(effect: number, delayMilliseconds: number = 0)
{
super();
this._effect = effect;
this._delayMilliseconds = delayMilliseconds;
}
public get effect(): number
{
return this._effect;
}
public get delayMilliseconds(): number
{
return this._delayMilliseconds;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarExperienceUpdateMessage extends ObjectStateUpdateMessage
{
private _gainedExperience: number;
constructor(amount: number)
{
super();
this._gainedExperience = amount;
}
public get gainedExperience(): number
{
return this._gainedExperience;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarExpressionUpdateMessage extends ObjectStateUpdateMessage
{
private _expressionType: number;
constructor(expressionType: number = 0)
{
super();
this._expressionType = expressionType;
}
public get expressionType(): number
{
return this._expressionType;
}
}
@@ -0,0 +1,39 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarFigureUpdateMessage extends ObjectStateUpdateMessage
{
private _figure: string;
private _gender: string;
private _subType: string;
private _isRiding: boolean;
constructor(figure: string, gender: string = null, subType: string = null, isRiding: boolean = false)
{
super();
this._figure = figure;
this._gender = gender;
this._subType = subType;
this._isRiding = isRiding;
}
public get figure(): string
{
return this._figure;
}
public get gender(): string
{
return this._gender;
}
public get subType(): string
{
return this._subType;
}
public get isRiding(): boolean
{
return this._isRiding;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarFlatControlUpdateMessage extends ObjectStateUpdateMessage
{
private _level: number;
constructor(level: number = 0)
{
super();
this._level = level;
}
public get level(): number
{
return this._level;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarGestureUpdateMessage extends ObjectStateUpdateMessage
{
private _gesture: number;
constructor(gesture: number = 0)
{
super();
this._gesture = gesture;
}
public get gesture(): number
{
return this._gesture;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarGuideStatusUpdateMessage extends ObjectStateUpdateMessage
{
private _guideStatus: number;
constructor(value: number)
{
super();
this._guideStatus = value;
}
public get guideStatus(): number
{
return this._guideStatus;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarMutedUpdateMessage extends ObjectStateUpdateMessage
{
private _isMuted: boolean;
constructor(isMuted: boolean = false)
{
super();
this._isMuted = isMuted;
}
public get isMuted(): boolean
{
return this._isMuted;
}
}
@@ -0,0 +1,4 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarOwnMessage extends ObjectStateUpdateMessage
{}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarPetGestureUpdateMessage extends ObjectStateUpdateMessage
{
private _gesture: string;
constructor(gesture: string)
{
super();
this._gesture = gesture;
}
public get gesture(): string
{
return this._gesture;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarPlayerValueUpdateMessage extends ObjectStateUpdateMessage
{
private _value: number;
constructor(value: number)
{
super();
this._value = value;
}
public get value(): number
{
return this._value;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarPlayingGameUpdateMessage extends ObjectStateUpdateMessage
{
private _isPlayingGame: boolean;
constructor(flag: boolean)
{
super();
this._isPlayingGame = flag;
}
public get isPlayingGame(): boolean
{
return this._isPlayingGame;
}
}
@@ -0,0 +1,25 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarPostureUpdateMessage extends ObjectStateUpdateMessage
{
private _postureType: string;
private _parameter: string;
constructor(postureType: string, parameter: string = '')
{
super();
this._postureType = postureType;
this._parameter = parameter;
}
public get postureType(): string
{
return this._postureType;
}
public get parameter(): string
{
return this._parameter;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarSelectedMessage extends ObjectStateUpdateMessage
{
private _selected: boolean;
constructor(selected: boolean)
{
super();
this._selected = selected;
}
public get selected(): boolean
{
return this._selected;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarSignUpdateMessage extends ObjectStateUpdateMessage
{
private _signType: number;
constructor(signType: number = 0)
{
super();
this._signType = signType;
}
public get signType(): number
{
return this._signType;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarSleepUpdateMessage extends ObjectStateUpdateMessage
{
private _isSleeping: boolean;
constructor(isSleeping: boolean = false)
{
super();
this._isSleeping = isSleeping;
}
public get isSleeping(): boolean
{
return this._isSleeping;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarTypingUpdateMessage extends ObjectStateUpdateMessage
{
private _isTyping: boolean;
constructor(isTyping: boolean = false)
{
super();
this._isTyping = isTyping;
}
public get isTyping(): boolean
{
return this._isTyping;
}
}
@@ -0,0 +1,33 @@
import { IVector3D } from '@nitrots/api';
import { ObjectMoveUpdateMessage } from './ObjectMoveUpdateMessage';
export class ObjectAvatarUpdateMessage extends ObjectMoveUpdateMessage
{
private _headDirection: number;
private _canStandUp: boolean;
private _baseY: number;
constructor(location: IVector3D, targetLocation: IVector3D, direction: IVector3D, headDirection: number, canStandUp: boolean, baseY: number)
{
super(location, targetLocation, direction);
this._headDirection = headDirection;
this._canStandUp = canStandUp;
this._baseY = baseY;
}
public get headDirection(): number
{
return this._headDirection;
}
public get canStandUp(): boolean
{
return this._canStandUp;
}
public get baseY(): number
{
return this._baseY;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectAvatarUseObjectUpdateMessage extends ObjectStateUpdateMessage
{
private _itemType: number;
constructor(itemType: number)
{
super();
this._itemType = itemType;
}
public get itemType(): number
{
return this._itemType;
}
}
@@ -0,0 +1,33 @@
import { IObjectData } from '@nitrots/api';
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectDataUpdateMessage extends RoomObjectUpdateMessage
{
private _state: number;
private _data: IObjectData;
private _extra: number;
constructor(state: number, data: IObjectData, extra: number = null)
{
super(null, null);
this._state = state;
this._data = data;
this._extra = extra;
}
public get state(): number
{
return this._state;
}
public get data(): IObjectData
{
return this._data;
}
public get extra(): number
{
return this._extra;
}
}
@@ -0,0 +1,27 @@
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectGroupBadgeUpdateMessage extends RoomObjectUpdateMessage
{
public static BADGE_LOADED: string = 'ROGBUM_BADGE_LOADED';
private _badgeId: string;
private _assetName: string;
constructor(badgeId: string, assetName: string)
{
super(null, null);
this._badgeId = badgeId;
this._assetName = assetName;
}
public get badgeId(): string
{
return this._badgeId;
}
public get assetName(): string
{
return this._assetName;
}
}
@@ -0,0 +1,19 @@
import { IVector3D } from '@nitrots/api';
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectHeightUpdateMessage extends RoomObjectUpdateMessage
{
private _height: number;
constructor(location: IVector3D, direction: IVector3D, height: number)
{
super(location, direction);
this._height = height;
}
public get height(): number
{
return this._height;
}
}
@@ -0,0 +1,18 @@
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectItemDataUpdateMessage extends RoomObjectUpdateMessage
{
private _data: string;
constructor(data: string)
{
super(null, null);
this._data = data;
}
public get data(): string
{
return this._data;
}
}
@@ -0,0 +1,25 @@
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectModelDataUpdateMessage extends RoomObjectUpdateMessage
{
private _numberKey: string;
private _numberValue: number;
constructor(numberKey: string, numberValue: number)
{
super(null, null);
this._numberKey = numberKey;
this._numberValue = numberValue;
}
public get numberKey(): string
{
return this._numberKey;
}
public get numberValue(): number
{
return this._numberValue;
}
}
@@ -0,0 +1,28 @@
import { IVector3D } from '@nitrots/api';
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectMoveUpdateMessage extends RoomObjectUpdateMessage
{
private _targetLocation: IVector3D;
private _isSlide: boolean;
constructor(location: IVector3D, targetLocation: IVector3D, direction: IVector3D, isSlide: boolean = false)
{
super(location, direction);
this._targetLocation = targetLocation;
this._isSlide = isSlide;
}
public get targetLocation(): IVector3D
{
if(!this._targetLocation) return this.location;
return this._targetLocation;
}
public get isSlide(): boolean
{
return this._isSlide;
}
}
@@ -0,0 +1,41 @@
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectRoomColorUpdateMessage extends RoomObjectUpdateMessage
{
public static BACKGROUND_COLOR: string = 'RORCUM_BACKGROUND_COLOR';
private _type: string;
private _color: number;
private _light: number;
private _backgroundOnly: boolean;
constructor(type: string, color: number, light: number, backgroundOnly: boolean)
{
super(null, null);
this._type = type;
this._color = color;
this._light = light;
this._backgroundOnly = backgroundOnly;
}
public get type(): string
{
return this._type;
}
public get color(): number
{
return this._color;
}
public get light(): number
{
return this._light;
}
public get backgroundOnly(): boolean
{
return this._backgroundOnly;
}
}
@@ -0,0 +1,56 @@
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectRoomFloorHoleUpdateMessage extends RoomObjectUpdateMessage
{
public static ADD: string = 'ORPFHUM_ADD';
public static REMOVE: string = 'ORPFHUM_REMOVE';
private _type: string;
private _id: number;
private _x: number;
private _y: number;
private _width: number;
private _height: number;
constructor(type: string, id: number, x: number = 0, y: number = 0, width: number = 0, height: number = 0)
{
super(null, null);
this._type = type;
this._id = id;
this._x = x;
this._y = y;
this._width = width;
this._height = height;
}
public get type(): string
{
return this._type;
}
public get id(): number
{
return this._id;
}
public get x(): number
{
return this._x;
}
public get y(): number
{
return this._y;
}
public get width(): number
{
return this._width;
}
public get height(): number
{
return this._height;
}
}
@@ -0,0 +1,28 @@
import { RoomMapData } from '../object';
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectRoomMapUpdateMessage extends RoomObjectUpdateMessage
{
public static UPDATE_MAP: string = 'RORMUM_UPDATE_MAP';
private _type: string;
private _mapData: RoomMapData;
constructor(mapData: RoomMapData)
{
super(null, null);
this._type = ObjectRoomMapUpdateMessage.UPDATE_MAP;
this._mapData = mapData;
}
public get type(): string
{
return this._type;
}
public get mapData(): RoomMapData
{
return this._mapData;
}
}
@@ -0,0 +1,54 @@
import { IVector3D } from '@nitrots/api';
import { Vector3d } from '@nitrots/utils';
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectRoomMaskUpdateMessage extends RoomObjectUpdateMessage
{
public static ADD_MASK: string = 'RORMUM_ADD_MASK';
public static REMOVE_MASK: string = 'RORMUM_ADD_MASK';
public static DOOR: string = 'door';
public static WINDOW: string = 'window';
public static HOLE: string = 'hole';
private _type: string;
private _maskId: string;
private _maskType: string;
private _maskLocation: IVector3D;
private _maskCategory: string;
constructor(type: string, maskId: string, maskType: string = null, maskLocation: IVector3D = null, maskCategory: string = 'window')
{
super(null, null);
this._type = type;
this._maskId = maskId;
this._maskType = maskType;
this._maskLocation = maskLocation ? new Vector3d(maskLocation.x, maskLocation.y, maskLocation.z) : null;
this._maskCategory = maskCategory;
}
public get type(): string
{
return this._type;
}
public get maskId(): string
{
return this._maskId;
}
public get maskType(): string
{
return this._maskType;
}
public get maskLocation(): IVector3D
{
return this._maskLocation;
}
public get maskCategory(): string
{
return this._maskCategory;
}
}
@@ -0,0 +1,28 @@
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectRoomPlanePropertyUpdateMessage extends RoomObjectUpdateMessage
{
public static WALL_THICKNESS: string = 'RORPPUM_WALL_THICKNESS';
public static FLOOR_THICKNESS: string = 'RORPVUM_FLOOR_THICKNESS';
private _type: string;
private _value: number;
constructor(type: string, value: number)
{
super(null, null);
this._type = type;
this._value = value;
}
public get type(): string
{
return this._type;
}
public get value(): number
{
return this._value;
}
}
@@ -0,0 +1,28 @@
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectRoomPlaneVisibilityUpdateMessage extends RoomObjectUpdateMessage
{
public static WALL_VISIBILITY: string = 'RORPVUM_WALL_VISIBILITY';
public static FLOOR_VISIBILITY: string = 'RORPVUM_FLOOR_VISIBILITY';
private _type: string;
private _visible: boolean;
constructor(type: string, visible: boolean)
{
super(null, null);
this._type = type;
this._visible = visible;
}
public get type(): string
{
return this._type;
}
public get visible(): boolean
{
return this._visible;
}
}
@@ -0,0 +1,29 @@
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectRoomUpdateMessage extends RoomObjectUpdateMessage
{
public static ROOM_WALL_UPDATE: string = 'RORUM_ROOM_WALL_UPDATE';
public static ROOM_FLOOR_UPDATE: string = 'RORUM_ROOM_FLOOR_UPDATE';
public static ROOM_LANDSCAPE_UPDATE: string = 'RORUM_ROOM_LANDSCAPE_UPDATE';
private _type: string;
private _value: string;
constructor(type: string, value: string)
{
super(null, null);
this._type = type;
this._value = value;
}
public get type(): string
{
return this._type;
}
public get value(): string
{
return this._value;
}
}
@@ -0,0 +1,18 @@
import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage';
export class ObjectSelectedMessage extends ObjectStateUpdateMessage
{
private _selected: boolean;
constructor(selected: boolean)
{
super();
this._selected = selected;
}
public get selected(): boolean
{
return this._selected;
}
}
@@ -0,0 +1,9 @@
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectStateUpdateMessage extends RoomObjectUpdateMessage
{
constructor()
{
super(null, null);
}
}
@@ -0,0 +1,40 @@
import { IVector3D } from '@nitrots/api';
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectTileCursorUpdateMessage extends RoomObjectUpdateMessage
{
private _height: number;
private _sourceEventId: string;
private _visible: boolean;
private _toggleVisibility: boolean;
constructor(k: IVector3D, height: number, visible: boolean, sourceEventId: string, toggleVisibility: boolean = false)
{
super(k, null);
this._height = height;
this._visible = visible;
this._sourceEventId = sourceEventId;
this._toggleVisibility = toggleVisibility;
}
public get height(): number
{
return this._height;
}
public get visible(): boolean
{
return this._visible;
}
public get sourceEventId(): string
{
return this._sourceEventId;
}
public get toggleVisibility(): boolean
{
return this._toggleVisibility;
}
}
@@ -0,0 +1,21 @@
import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
export class ObjectVisibilityUpdateMessage extends RoomObjectUpdateMessage
{
public static ENABLED: string = 'ROVUM_ENABLED';
public static DISABLED: string = 'ROVUM_DISABLED';
private _type: string;
constructor(type: string)
{
super(null, null);
this._type = type;
}
public get type(): string
{
return this._type;
}
}
@@ -0,0 +1,23 @@
import { IVector3D } from '@nitrots/api';
export class RoomObjectUpdateMessage
{
private _location: IVector3D;
private _direction: IVector3D;
constructor(location: IVector3D, direction: IVector3D)
{
this._location = location;
this._direction = direction;
}
public get location(): IVector3D
{
return this._location;
}
public get direction(): IVector3D
{
return this._direction;
}
}
+41
View File
@@ -0,0 +1,41 @@
export * from './ObjectAdUpdateMessage';
export * from './ObjectAvatarCarryObjectUpdateMessage';
export * from './ObjectAvatarChatUpdateMessage';
export * from './ObjectAvatarDanceUpdateMessage';
export * from './ObjectAvatarEffectUpdateMessage';
export * from './ObjectAvatarExperienceUpdateMessage';
export * from './ObjectAvatarExpressionUpdateMessage';
export * from './ObjectAvatarFigureUpdateMessage';
export * from './ObjectAvatarFlatControlUpdateMessage';
export * from './ObjectAvatarGestureUpdateMessage';
export * from './ObjectAvatarGuideStatusUpdateMessage';
export * from './ObjectAvatarMutedUpdateMessage';
export * from './ObjectAvatarOwnMessage';
export * from './ObjectAvatarPetGestureUpdateMessage';
export * from './ObjectAvatarPlayerValueUpdateMessage';
export * from './ObjectAvatarPlayingGameUpdateMessage';
export * from './ObjectAvatarPostureUpdateMessage';
export * from './ObjectAvatarSelectedMessage';
export * from './ObjectAvatarSignUpdateMessage';
export * from './ObjectAvatarSleepUpdateMessage';
export * from './ObjectAvatarTypingUpdateMessage';
export * from './ObjectAvatarUpdateMessage';
export * from './ObjectAvatarUseObjectUpdateMessage';
export * from './ObjectDataUpdateMessage';
export * from './ObjectGroupBadgeUpdateMessage';
export * from './ObjectHeightUpdateMessage';
export * from './ObjectItemDataUpdateMessage';
export * from './ObjectModelDataUpdateMessage';
export * from './ObjectMoveUpdateMessage';
export * from './ObjectRoomColorUpdateMessage';
export * from './ObjectRoomFloorHoleUpdateMessage';
export * from './ObjectRoomMapUpdateMessage';
export * from './ObjectRoomMaskUpdateMessage';
export * from './ObjectRoomPlanePropertyUpdateMessage';
export * from './ObjectRoomPlaneVisibilityUpdateMessage';
export * from './ObjectRoomUpdateMessage';
export * from './ObjectSelectedMessage';
export * from './ObjectStateUpdateMessage';
export * from './ObjectTileCursorUpdateMessage';
export * from './ObjectVisibilityUpdateMessage';
export * from './RoomObjectUpdateMessage';
+35
View File
@@ -0,0 +1,35 @@
export class RoomFloorHole
{
private _x: number;
private _y: number;
private _width: number;
private _height: number;
constructor(x: number, y: number, width: number, height: number)
{
this._x = x;
this._y = y;
this._width = width;
this._height = height;
}
public get x(): number
{
return this._x;
}
public get y(): number
{
return this._y;
}
public get width(): number
{
return this._width;
}
public get height(): number
{
return this._height;
}
}
+90
View File
@@ -0,0 +1,90 @@
import { IRoomMapData } from '@nitrots/api';
export class RoomMapData implements IRoomMapData
{
private _width: number;
private _height: number;
private _wallHeight: number;
private _fixedWallsHeight: number;
private _tileMap: { height: number }[][];
private _holeMap: { id: number, x: number, y: number, width: number, height: number }[];
private _doors: { x: number, y: number, z: number, dir: number }[];
private _dimensions: { minX: number, maxX: number, minY: number, maxY: number };
constructor()
{
this._width = 0;
this._height = 0;
this._wallHeight = 0;
this._fixedWallsHeight = 0;
this._tileMap = [];
this._holeMap = [];
this._doors = [];
this._dimensions = {
minX: 0,
maxX: 0,
minY: 0,
maxY: 0
};
}
public get width(): number
{
return this._width;
}
public set width(width: number)
{
this._width = width;
}
public get height(): number
{
return this._height;
}
public set height(height: number)
{
this._height = height;
}
public get wallHeight(): number
{
return this._wallHeight;
}
public set wallHeight(wallHeight: number)
{
this._wallHeight = wallHeight;
}
public get fixedWallsHeight(): number
{
return this._fixedWallsHeight;
}
public set fixedWallsHeight(fixedWallsHeight: number)
{
this._fixedWallsHeight = fixedWallsHeight;
}
public get tileMap(): { height: number }[][]
{
return this._tileMap;
}
public get holeMap(): { id: number, x: number, y: number, width: number, height: number }[]
{
return this._holeMap;
}
public get doors(): { x: number, y: number, z: number, dir: number }[]
{
return this._doors;
}
public get dimensions(): { minX: number, maxX: number, minY: number, maxY: number }
{
return this._dimensions;
}
}
@@ -0,0 +1,16 @@
import { IVector3D } from '@nitrots/api';
export class RoomMapMaskData
{
private _masks: { id: string, type: string, category: string, locations: IVector3D[] }[];
constructor()
{
this._masks = [];
}
public get masks(): { id: string, type: string, category: string, locations: IVector3D[] }[]
{
return this._masks;
}
}
+229
View File
@@ -0,0 +1,229 @@
import { IRoomObjectController, IRoomObjectEventHandler, IRoomObjectModel, IRoomObjectMouseHandler, IRoomObjectUpdateMessage, IRoomObjectVisualization, IVector3D } from '@nitrots/api';
import { Vector3d } from '@nitrots/utils';
import { RoomObjectModel } from './RoomObjectModel';
export class RoomObject implements IRoomObjectController
{
private static OBJECT_COUNTER: number = 0;
private _id: number;
private _instanceId: number;
private _type: string;
private _model: IRoomObjectModel = new RoomObjectModel();
private _location: IVector3D = new Vector3d();
private _direction: IVector3D = new Vector3d();
private _states: number[] = [];
private _visualization: IRoomObjectVisualization = null;
private _logic: IRoomObjectEventHandler = null;
private _pendingLogicMessages: IRoomObjectUpdateMessage[] = [];
private _updateCounter: number = 0;
private _isReady: boolean = false;
constructor(id: number, stateCount: number, type: string)
{
this._id = id;
this._instanceId = RoomObject.OBJECT_COUNTER++;
this._type = type;
let i = (stateCount - 1);
while(i >= 0)
{
this._states[i] = 0;
i--;
}
}
public dispose(): void
{
this._pendingLogicMessages = [];
this.setVisualization(null);
this.setLogic(null);
if(this._model) this._model.dispose();
}
public getLocation(): IVector3D
{
return this._location;
}
public setLocation(vector: IVector3D): void
{
if(!vector) return;
if((vector.x === this._location.x) && (vector.y === this._location.y) && (vector.z === this._location.z)) return;
this._location.x = vector.x;
this._location.y = vector.y;
this._location.z = vector.z;
this._updateCounter++;
}
public getDirection(): IVector3D
{
return this._direction;
}
public setDirection(vector: IVector3D): void
{
if(!vector) return;
if((vector.x === this._direction.x) && (vector.y === this._direction.y) && (vector.z === this._direction.z)) return;
this._direction.x = (((vector.x % 360) + 360) % 360);
this._direction.y = (((vector.y % 360) + 360) % 360);
this._direction.z = (((vector.z % 360) + 360) % 360);
this._updateCounter++;
}
public getState(index: number = 0): number
{
if((index >= 0) && (index < this._states.length))
{
return this._states[index];
}
return -1;
}
public setState(state: number, index: number = 0): boolean
{
if((index >= 0) && (index < this._states.length))
{
if(this._states[index] !== state)
{
this._states[index] = state;
this._updateCounter++;
}
return true;
}
return false;
}
public setVisualization(visualization: IRoomObjectVisualization): void
{
if(this._visualization === visualization) return;
if(this._visualization) this._visualization.dispose();
this._visualization = visualization;
if(this._visualization) this._visualization.object = this;
}
public setLogic(logic: IRoomObjectEventHandler): void
{
if(this._logic === logic) return;
const eventHandler = this._logic;
if(eventHandler)
{
this._logic = null;
eventHandler.setObject(null);
}
this._logic = logic;
if(this._logic)
{
this._logic.setObject(this);
while(this._pendingLogicMessages.length)
{
const message = this._pendingLogicMessages.shift();
this._logic.processUpdateMessage(message);
}
}
}
public processUpdateMessage(message: IRoomObjectUpdateMessage): void
{
if(this._logic) return this._logic.processUpdateMessage(message);
this._pendingLogicMessages.push(message);
}
public tearDown(): void
{
if(this._logic) this._logic.tearDown();
}
public get id(): number
{
return this._id;
}
public get instanceId(): number
{
return this._instanceId;
}
public get type(): string
{
return this._type;
}
public get model(): IRoomObjectModel
{
return this._model;
}
public get visualization(): IRoomObjectVisualization
{
return this._visualization;
}
public get mouseHandler(): IRoomObjectMouseHandler
{
return this._logic as IRoomObjectMouseHandler;
}
public get logic(): IRoomObjectEventHandler
{
return this._logic;
}
public get location(): IVector3D
{
return this._location;
}
public get direction(): IVector3D
{
return this._direction;
}
public get updateCounter(): number
{
return this._updateCounter;
}
public set updateCounter(count: number)
{
this._updateCounter = count;
}
public get isReady(): boolean
{
return this._isReady;
}
public set isReady(flag: boolean)
{
this._isReady = flag;
}
}
@@ -0,0 +1,47 @@
import { IRoomObjectModel } from '@nitrots/api';
export class RoomObjectModel implements IRoomObjectModel
{
private _map: Map<string, unknown> = new Map();
private _updateCounter: number = 0;
public dispose(): void
{
this._map.clear();
this._updateCounter = 0;
}
public getValue<T>(key: string): T
{
const existing = this._map.get(key);
return (existing as T);
}
public setValue<T>(key: string, value: T): void
{
if(this._map.has(key))
{
if(this._map.get(key) === value) return;
}
this._map.set(key, (value as T));
this._updateCounter++;
}
public removeKey(key: string): void
{
if(!key) return;
this._map.delete(key);
this._updateCounter++;
}
public get updateCounter(): number
{
return this._updateCounter;
}
}
@@ -0,0 +1,56 @@
import { IVector3D } from '@nitrots/api';
import { Vector3d } from '@nitrots/utils';
export class RoomPlaneBitmapMaskData
{
public static WINDOW: string = 'window';
public static HOLE: string = 'hole';
private _loc: Vector3d;
private _type: string;
private _category: string;
constructor(type: string, loc: IVector3D, category: string)
{
this.type = type;
this.loc = loc;
this.category = category;
}
public get loc(): IVector3D
{
return this._loc;
}
public set loc(k: IVector3D)
{
if(!this._loc) this._loc = new Vector3d();
this._loc.assign(k);
}
public get type(): string
{
return this._type;
}
public set type(type: string)
{
this._type = type;
}
public get category(): string
{
return this._category;
}
public set category(category: string)
{
this._category = category;
}
public dispose(): void
{
this._loc = null;
}
}
@@ -0,0 +1,147 @@
import { IVector3D } from '@nitrots/api';
import { RoomMapMaskData } from './RoomMapMaskData';
import { RoomPlaneBitmapMaskData } from './RoomPlaneBitmapMaskData';
export class RoomPlaneBitmapMaskParser
{
private _masks: Map<string, RoomPlaneBitmapMaskData>;
constructor()
{
this._masks = new Map();
}
public get maskCount(): number
{
return this._masks.size;
}
public dispose(): void
{
if(this._masks)
{
this.reset();
this._masks = null;
}
}
public initialize(k: RoomMapMaskData): boolean
{
if(!k) return false;
this._masks.clear();
if(k.masks.length)
{
for(const mask of k.masks)
{
if(!mask) continue;
const location = mask.locations.length ? mask.locations[0] : null;
if(!location) continue;
this._masks.set(mask.id, new RoomPlaneBitmapMaskData(mask.type, location, mask.category));
}
}
return true;
}
public reset(): void
{
for(const mask of this._masks.values())
{
if(!mask) continue;
mask.dispose();
}
this._masks.clear();
}
public addMask(k: string, _arg_2: string, _arg_3: IVector3D, _arg_4: string): void
{
const mask = new RoomPlaneBitmapMaskData(_arg_2, _arg_3, _arg_4);
this._masks.delete(k);
this._masks.set(k, mask);
}
public removeMask(k: string): boolean
{
const existing = this._masks.get(k);
if(existing)
{
this._masks.delete(k);
existing.dispose();
return true;
}
return false;
}
public getXML(): RoomMapMaskData
{
const data = new RoomMapMaskData();
for(const [key, mask] of this._masks.entries())
{
if(!mask) continue;
const type = this.getMaskType(mask);
const category = this.getMaskCategory(mask);
const location = this.getMaskLocation(mask);
if(type && category && location)
{
const newMask: any = {
id: key,
type: type,
category: category,
locations: [
{
x: location.x,
y: location.y,
z: location.z
}
]
};
data.masks.push(newMask);
}
}
return data;
}
public getMaskLocation(mask: RoomPlaneBitmapMaskData): IVector3D
{
if(!mask) return null;
return mask.loc;
}
public getMaskType(mask: RoomPlaneBitmapMaskData): string
{
if(!mask) return null;
return mask.type;
}
public getMaskCategory(mask: RoomPlaneBitmapMaskData): string
{
if(!mask) return null;
return mask.category;
}
public get masks(): Map<string, RoomPlaneBitmapMaskData>
{
return this._masks;
}
}
+202
View File
@@ -0,0 +1,202 @@
import { IVector3D } from '@nitrots/api';
import { Vector3d } from '@nitrots/utils';
import { RoomPlaneMaskData } from './RoomPlaneMaskData';
export class RoomPlaneData
{
public static PLANE_UNDEFINED: number = 0;
public static PLANE_FLOOR: number = 1;
public static PLANE_WALL: number = 2;
public static PLANE_LANDSCAPE: number = 3;
public static PLANE_BILLBOARD: number = 4;
private _type: number = 0;
private _loc: Vector3d = null;
private _leftSide: Vector3d = null;
private _rightSide: Vector3d = null;
private _normal: Vector3d = null;
private _normalDirection: Vector3d = null;
private _secondaryNormals: Vector3d[];
private _masks: RoomPlaneMaskData[];
constructor(k: number, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D, _arg_5: IVector3D[])
{
let _local_6: number;
let _local_7: number;
let _local_8: number;
let _local_9: number;
let _local_10: number;
let _local_11: number;
let _local_12: IVector3D;
let _local_13: Vector3d;
this._secondaryNormals = [];
this._masks = [];
this._loc = new Vector3d();
this._loc.assign(_arg_2);
this._leftSide = new Vector3d();
this._leftSide.assign(_arg_3);
this._rightSide = new Vector3d();
this._rightSide.assign(_arg_4);
this._type = k;
if(((!(_arg_3 == null)) && (!(_arg_4 == null))))
{
this._normal = Vector3d.crossProduct(_arg_3, _arg_4);
_local_6 = 0;
_local_7 = 0;
_local_8 = 0;
_local_9 = 0;
_local_10 = 0;
if(((!(this.normal.x == 0)) || (!(this.normal.y == 0))))
{
_local_9 = this.normal.x;
_local_10 = this.normal.y;
_local_6 = (360 + ((Math.atan2(_local_10, _local_9) / Math.PI) * 180));
if(_local_6 >= 360)
{
_local_6 = (_local_6 - 360);
}
_local_9 = Math.sqrt(((this.normal.x * this.normal.x) + (this.normal.y * this.normal.y)));
_local_10 = this.normal.z;
_local_7 = (360 + ((Math.atan2(_local_10, _local_9) / Math.PI) * 180));
if(_local_7 >= 360)
{
_local_7 = (_local_7 - 360);
}
}
else
{
if(this.normal.z < 0)
{
_local_7 = 90;
}
else
{
_local_7 = 270;
}
}
this._normalDirection = new Vector3d(_local_6, _local_7, _local_8);
}
if(((!(_arg_5 == null)) && (_arg_5.length > 0)))
{
_local_11 = 0;
while(_local_11 < _arg_5.length)
{
_local_12 = _arg_5[_local_11];
if(((!(_local_12 == null)) && (_local_12.length > 0)))
{
_local_13 = new Vector3d();
_local_13.assign(_local_12);
_local_13.multiply((1 / _local_13.length));
this._secondaryNormals.push(_local_13);
}
_local_11++;
}
}
}
public get type(): number
{
return this._type;
}
public get loc(): IVector3D
{
return this._loc;
}
public get leftSide(): IVector3D
{
return this._leftSide;
}
public get rightSide(): IVector3D
{
return this._rightSide;
}
public get normal(): IVector3D
{
return this._normal;
}
public get normalDirection(): IVector3D
{
return this._normalDirection;
}
public get secondaryNormalCount(): number
{
return this._secondaryNormals.length;
}
public get maskCount(): number
{
return this._masks.length;
}
public getSecondaryNormal(k: number): IVector3D
{
if(((k < 0) || (k >= this.secondaryNormalCount)))
{
return null;
}
const _local_2: Vector3d = new Vector3d();
_local_2.assign((this._secondaryNormals[k] as IVector3D));
return _local_2;
}
public addMask(k: number, _arg_2: number, _arg_3: number, _arg_4: number): void
{
const _local_5: RoomPlaneMaskData = new RoomPlaneMaskData(k, _arg_2, _arg_3, _arg_4);
this._masks.push(_local_5);
}
private getMask(k: number): RoomPlaneMaskData
{
if(((k < 0) || (k >= this.maskCount)))
{
return null;
}
return this._masks[k];
}
public getMaskLeftSideLoc(k: number): number
{
const _local_2: RoomPlaneMaskData = this.getMask(k);
if(_local_2 != null)
{
return _local_2.leftSideLoc;
}
return -1;
}
public getMaskRightSideLoc(k: number): number
{
const _local_2: RoomPlaneMaskData = this.getMask(k);
if(_local_2 != null)
{
return _local_2.rightSideLoc;
}
return -1;
}
public getMaskLeftSideLength(k: number): number
{
const _local_2: RoomPlaneMaskData = this.getMask(k);
if(_local_2 != null)
{
return _local_2.leftSideLength;
}
return -1;
}
public getMaskRightSideLength(k: number): number
{
const _local_2: RoomPlaneMaskData = this.getMask(k);
if(_local_2 != null)
{
return _local_2.rightSideLength;
}
return -1;
}
}
@@ -0,0 +1,35 @@
export class RoomPlaneMaskData
{
private _leftSideLoc: number = 0;
private _rightSideLoc: number = 0;
private _leftSideLength: number = 0;
private _rightSideLength: number = 0;
constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number)
{
this._leftSideLoc = k;
this._rightSideLoc = _arg_2;
this._leftSideLength = _arg_3;
this._rightSideLength = _arg_4;
}
public get leftSideLoc(): number
{
return this._leftSideLoc;
}
public get rightSideLoc(): number
{
return this._rightSideLoc;
}
public get leftSideLength(): number
{
return this._leftSideLength;
}
public get rightSideLength(): number
{
return this._rightSideLength;
}
}
File diff suppressed because it is too large Load Diff
+182
View File
@@ -0,0 +1,182 @@
import { IVector3D } from '@nitrots/api';
import { Vector3d } from '@nitrots/utils';
import { Point } from 'pixi.js';
export class RoomWallData
{
public static WALL_DIRECTION_VECTORS: Vector3d[] = [
new Vector3d(1, 0, 0),
new Vector3d(0, 1, 0),
new Vector3d(-1, 0, 0),
new Vector3d(0, -1, 0)
];
public static WALL_NORMAL_VECTORS: Vector3d[] = [
new Vector3d(0, 1, 0),
new Vector3d(-1, 0, 0),
new Vector3d(0, -1, 0),
new Vector3d(1, 0, 0)
];
private _corners: Point[];
private _endPoints: Point[];
private _directions: number[];
private _lengths: number[];
private _leftTurns: boolean[];
private _borders: boolean[];
private _hideWalls: boolean[];
private _manuallyLeftCut: boolean[];
private _manuallyRightCut: boolean[];
private _addDuplicates: boolean;
private _count: number;
constructor()
{
this._corners = [];
this._endPoints = [];
this._directions = [];
this._lengths = [];
this._leftTurns = [];
this._borders = [];
this._hideWalls = [];
this._manuallyLeftCut = [];
this._manuallyRightCut = [];
this._addDuplicates = false;
this._count = 0;
}
public addWall(k: Point, _arg_2: number, _arg_3: number, _arg_4: boolean, _arg_5: boolean): void
{
if(((this._addDuplicates) || (this.checkIsNotDuplicate(k, _arg_2, _arg_3, _arg_4, _arg_5))))
{
this._corners.push(k);
this._directions.push(_arg_2);
this._lengths.push(_arg_3);
this._borders.push(_arg_4);
this._leftTurns.push(_arg_5);
this._hideWalls.push(false);
this._manuallyLeftCut.push(false);
this._manuallyRightCut.push(false);
this._count++;
}
}
private checkIsNotDuplicate(k: Point, _arg_2: number, _arg_3: number, _arg_4: boolean, _arg_5: boolean): boolean
{
let _local_6 = 0;
while(_local_6 < this._count)
{
if(((((((this._corners[_local_6].x == k.x) && (this._corners[_local_6].y == k.y)) && (this._directions[_local_6] == _arg_2)) && (this._lengths[_local_6] == _arg_3)) && (this._borders[_local_6] == _arg_4)) && (this._leftTurns[_local_6] == _arg_5)))
{
return false;
}
_local_6++;
}
return true;
}
public get count(): number
{
return this._count;
}
public getCorner(k: number): Point
{
return this._corners[k];
}
public getEndPoint(k: number): Point
{
this.calculateWallEndPoints();
return this._endPoints[k];
}
public getLength(k: number): number
{
return this._lengths[k];
}
public getDirection(k: number): number
{
return this._directions[k];
}
public getBorder(k: number): boolean
{
return this._borders[k];
}
public getHideWall(k: number): boolean
{
return this._hideWalls[k];
}
public getLeftTurn(k: number): boolean
{
return this._leftTurns[k];
}
public getManuallyLeftCut(k: number): boolean
{
return this._manuallyLeftCut[k];
}
public getManuallyRightCut(k: number): boolean
{
return this._manuallyRightCut[k];
}
public setHideWall(k: number, _arg_2: boolean): void
{
this._hideWalls[k] = _arg_2;
}
public setLength(k: number, _arg_2: number): void
{
if(_arg_2 < this._lengths[k])
{
this._lengths[k] = _arg_2;
this._manuallyRightCut[k] = true;
}
}
public moveCorner(k: number, _arg_2: number): void
{
let _local_3: IVector3D;
if(((_arg_2 > 0) && (_arg_2 < this._lengths[k])))
{
const corner = this._corners[k];
_local_3 = RoomWallData.WALL_DIRECTION_VECTORS[this.getDirection(k)];
this._corners[k] = new Point((corner.x + (_arg_2 * _local_3.x)), (corner.y + (_arg_2 * _local_3.y)));
this._lengths[k] = (this._lengths[k] - _arg_2);
this._manuallyLeftCut[k] = true;
}
}
private calculateWallEndPoints(): void
{
let k: number;
let _local_2: Point;
let _local_3: Point;
let _local_4: IVector3D;
let _local_5: number;
if(this._endPoints.length != this.count)
{
this._endPoints = [];
k = 0;
while(k < this.count)
{
_local_2 = this.getCorner(k);
_local_3 = new Point(_local_2.x, _local_2.y);
_local_4 = RoomWallData.WALL_DIRECTION_VECTORS[this.getDirection(k)];
_local_5 = this.getLength(k);
_local_3.x = (_local_3.x + (_local_4.x * _local_5));
_local_3.y = (_local_3.y + (_local_4.y * _local_5));
this._endPoints.push(_local_3);
k++;
}
}
}
}
+22
View File
@@ -0,0 +1,22 @@
export * from './RoomFloorHole';
export * from './RoomMapData';
export * from './RoomMapMaskData';
export * from './RoomObject';
export * from './RoomObjectModel';
export * from './RoomPlaneBitmapMaskData';
export * from './RoomPlaneBitmapMaskParser';
export * from './RoomPlaneData';
export * from './RoomPlaneMaskData';
export * from './RoomPlaneParser';
export * from './RoomWallData';
export * from './logic';
export * from './logic/furniture';
export * from './visualization';
export * from './visualization/avatar';
export * from './visualization/avatar/additions';
export * from './visualization/data';
export * from './visualization/furniture';
export * from './visualization/pet';
export * from './visualization/room';
export * from './visualization/room/mask';
export * from './visualization/room/utils';
@@ -0,0 +1,504 @@
import { AvatarAction, IRoomGeometry, IRoomObjectModel, IVector3D, MouseEventType, RoomObjectVariable } from '@nitrots/api';
import { RoomObjectFurnitureActionEvent, RoomObjectMouseEvent, RoomObjectMoveEvent, RoomSpriteMouseEvent } from '@nitrots/events';
import { GetTickerTime, Vector3d } from '@nitrots/utils';
import { ObjectAvatarCarryObjectUpdateMessage, ObjectAvatarChatUpdateMessage, ObjectAvatarDanceUpdateMessage, ObjectAvatarEffectUpdateMessage, ObjectAvatarExpressionUpdateMessage, ObjectAvatarFigureUpdateMessage, ObjectAvatarFlatControlUpdateMessage, ObjectAvatarGestureUpdateMessage, ObjectAvatarMutedUpdateMessage, ObjectAvatarOwnMessage, ObjectAvatarPlayerValueUpdateMessage, ObjectAvatarPlayingGameUpdateMessage, ObjectAvatarPostureUpdateMessage, ObjectAvatarSelectedMessage, ObjectAvatarSignUpdateMessage, ObjectAvatarSleepUpdateMessage, ObjectAvatarTypingUpdateMessage, ObjectAvatarUpdateMessage, ObjectAvatarUseObjectUpdateMessage, RoomObjectUpdateMessage } from '../../messages';
import { MovingObjectLogic } from './MovingObjectLogic';
export class AvatarLogic extends MovingObjectLogic
{
private static MAX_HAND_ID: number = 999999999;
private static MAX_HAND_USE_ID: number = 999;
private static EFFECT_TYPE_SPLASH: number = 28;
private static EFFECT_SPLASH_LENGTH: number = 500;
private static EFFECT_TYPE_SWIM: number = 29;
private static EFFECT_TYPE_SPLASH_DARK: number = 184;
private static EFFECT_TYPE_SWIM_DARK: number = 185;
private _selected: boolean;
private _reportedLocation: IVector3D;
private _effectChangeTimeStamp: number;
private _newEffect: number;
private _blinkingStartTimestamp: number;
private _blinkingEndTimestamp: number;
private _talkingEndTimestamp: number;
private _talkingPauseStartTimestamp: number;
private _talkingPauseEndTimestamp: number;
private _carryObjectStartTimestamp: number;
private _carryObjectEndTimestamp: number;
private _allowUseCarryObject: boolean;
private _animationEndTimestamp: number;
private _signEndTimestamp: number;
private _gestureEndTimestamp: number;
private _numberValueEndTimestamp: number;
constructor()
{
super();
this._selected = false;
this._reportedLocation = null;
this._effectChangeTimeStamp = 0;
this._newEffect = 0;
this._blinkingStartTimestamp = GetTickerTime() + this.randomBlinkStartTimestamp();
this._blinkingEndTimestamp = 0;
this._talkingEndTimestamp = 0;
this._talkingPauseStartTimestamp = 0;
this._talkingPauseEndTimestamp = 0;
this._carryObjectStartTimestamp = 0;
this._carryObjectEndTimestamp = 0;
this._allowUseCarryObject = false;
this._animationEndTimestamp = 0;
this._signEndTimestamp = 0;
this._gestureEndTimestamp = 0;
this._numberValueEndTimestamp = 0;
}
public getEventTypes(): string[]
{
const types = [RoomObjectMouseEvent.CLICK, RoomObjectMouseEvent.DOUBLE_CLICK, RoomObjectMoveEvent.POSITION_CHANGED, RoomObjectMouseEvent.MOUSE_ENTER, RoomObjectMouseEvent.MOUSE_LEAVE, RoomObjectFurnitureActionEvent.MOUSE_BUTTON, RoomObjectFurnitureActionEvent.MOUSE_ARROW];
return this.mergeTypes(super.getEventTypes(), types);
}
public dispose(): void
{
if(this._selected && this.object)
{
if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMoveEvent(RoomObjectMoveEvent.OBJECT_REMOVED, this.object));
}
super.dispose();
this._reportedLocation = null;
}
public update(time: number): void
{
super.update(time);
if(this._selected && this.object)
{
if(this.eventDispatcher)
{
const location = this.object.getLocation();
if(((!this._reportedLocation || (this._reportedLocation.x !== location.x)) || (this._reportedLocation.y !== location.y)) || (this._reportedLocation.z !== location.z))
{
if(!this._reportedLocation) this._reportedLocation = new Vector3d();
this._reportedLocation.assign(location);
this.eventDispatcher.dispatchEvent(new RoomObjectMoveEvent(RoomObjectMoveEvent.POSITION_CHANGED, this.object));
}
}
}
const model = this.object && this.object.model;
if(model) this.updateModel(this.time, model);
}
private updateModel(time: number, model: IRoomObjectModel): void
{
if(this._talkingEndTimestamp > 0)
{
if(time > this._talkingEndTimestamp)
{
model.setValue(RoomObjectVariable.FIGURE_TALK, 0);
this._talkingEndTimestamp = 0;
this._talkingPauseStartTimestamp = 0;
this._talkingPauseEndTimestamp = 0;
}
else
{
if(!this._talkingPauseEndTimestamp && !this._talkingPauseStartTimestamp)
{
this._talkingPauseStartTimestamp = time + this.randomTalkingPauseStartTimestamp();
this._talkingPauseEndTimestamp = this._talkingPauseStartTimestamp + this.randomTalkingPauseEndTimestamp();
}
else
{
if((this._talkingPauseStartTimestamp > 0) && (time > this._talkingPauseStartTimestamp))
{
model.setValue(RoomObjectVariable.FIGURE_TALK, 0);
this._talkingPauseStartTimestamp = 0;
}
else
{
if((this._talkingPauseEndTimestamp > 0) && (time > this._talkingPauseEndTimestamp))
{
model.setValue(RoomObjectVariable.FIGURE_TALK, 1);
this._talkingPauseEndTimestamp = 0;
}
}
}
}
}
if((this._animationEndTimestamp > 0) && (time > this._animationEndTimestamp))
{
model.setValue(RoomObjectVariable.FIGURE_EXPRESSION, 0);
this._animationEndTimestamp = 0;
}
if((this._gestureEndTimestamp > 0) && (time > this._gestureEndTimestamp))
{
model.setValue(RoomObjectVariable.FIGURE_GESTURE, 0);
this._gestureEndTimestamp = 0;
}
if((this._signEndTimestamp > 0) && (time > this._signEndTimestamp))
{
model.setValue(RoomObjectVariable.FIGURE_SIGN, -1);
this._signEndTimestamp = 0;
}
if(this._carryObjectEndTimestamp > 0)
{
if(time > this._carryObjectEndTimestamp)
{
model.setValue(RoomObjectVariable.FIGURE_CARRY_OBJECT, 0);
model.setValue(RoomObjectVariable.FIGURE_USE_OBJECT, 0);
this._carryObjectStartTimestamp = 0;
this._carryObjectEndTimestamp = 0;
this._allowUseCarryObject = false;
}
}
if(this._allowUseCarryObject)
{
if((time - this._carryObjectStartTimestamp) > 5000)
{
if(((time - this._carryObjectStartTimestamp) % 10000) < 1000)
{
model.setValue(RoomObjectVariable.FIGURE_USE_OBJECT, 1);
}
else
{
model.setValue(RoomObjectVariable.FIGURE_USE_OBJECT, 0);
}
}
}
if((this._blinkingStartTimestamp > -1) && (time > this._blinkingStartTimestamp))
{
model.setValue(RoomObjectVariable.FIGURE_BLINK, 1);
this._blinkingStartTimestamp = time + this.randomBlinkStartTimestamp();
this._blinkingEndTimestamp = time + this.randomBlinkEndTimestamp();
}
if((this._blinkingEndTimestamp > 0) && (time > this._blinkingEndTimestamp))
{
model.setValue(RoomObjectVariable.FIGURE_BLINK, 0);
this._blinkingEndTimestamp = 0;
}
if((this._effectChangeTimeStamp > 0) && (time > this._effectChangeTimeStamp))
{
model.setValue(RoomObjectVariable.FIGURE_EFFECT, this._newEffect);
this._effectChangeTimeStamp = 0;
}
if((this._numberValueEndTimestamp > 0) && (time > this._numberValueEndTimestamp))
{
model.setValue(RoomObjectVariable.FIGURE_NUMBER_VALUE, 0);
this._numberValueEndTimestamp = 0;
}
}
public processUpdateMessage(message: RoomObjectUpdateMessage): void
{
if(!message || !this.object) return;
super.processUpdateMessage(message);
const model = this.object && this.object.model;
if(!model) return;
if(message instanceof ObjectAvatarPostureUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_POSTURE, message.postureType);
model.setValue(RoomObjectVariable.FIGURE_POSTURE_PARAMETER, message.parameter);
return;
}
if(message instanceof ObjectAvatarChatUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_TALK, 1);
this._talkingEndTimestamp = (this.time + (message.numberOfWords * 1000));
return;
}
if(message instanceof ObjectAvatarTypingUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_IS_TYPING, message.isTyping ? 1 : 0);
return;
}
if(message instanceof ObjectAvatarMutedUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_IS_MUTED, (message.isMuted ? 1 : 0));
return;
}
if(message instanceof ObjectAvatarPlayingGameUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_IS_PLAYING_GAME, (message.isPlayingGame ? 1 : 0));
return;
}
if(message instanceof ObjectAvatarUpdateMessage)
{
model.setValue(RoomObjectVariable.HEAD_DIRECTION, message.headDirection);
model.setValue(RoomObjectVariable.FIGURE_CAN_STAND_UP, message.canStandUp);
model.setValue(RoomObjectVariable.FIGURE_VERTICAL_OFFSET, message.baseY);
return;
}
if(message instanceof ObjectAvatarGestureUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_GESTURE, message.gesture);
this._gestureEndTimestamp = (this.time + 3000);
return;
}
if(message instanceof ObjectAvatarExpressionUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_EXPRESSION, message.expressionType);
this._animationEndTimestamp = AvatarAction.getExpressionTimeout(model.getValue<number>(RoomObjectVariable.FIGURE_EXPRESSION));
if(this._animationEndTimestamp > -1) this._animationEndTimestamp += this.time;
return;
}
if(message instanceof ObjectAvatarDanceUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_DANCE, message.danceStyle);
return;
}
if(message instanceof ObjectAvatarSleepUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_SLEEP, message.isSleeping ? 1 : 0);
if(message.isSleeping) this._blinkingStartTimestamp = -1;
else this._blinkingStartTimestamp = (this.time + this.randomBlinkStartTimestamp());
return;
}
if(message instanceof ObjectAvatarPlayerValueUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_NUMBER_VALUE, message.value);
this._numberValueEndTimestamp = (this.time + 3000);
return;
}
if(message instanceof ObjectAvatarEffectUpdateMessage)
{
this.updateAvatarEffect(message.effect, message.delayMilliseconds, model);
return;
}
if(message instanceof ObjectAvatarCarryObjectUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_CARRY_OBJECT, message.itemType);
model.setValue(RoomObjectVariable.FIGURE_USE_OBJECT, 0);
if(message.itemType === 0)
{
this._carryObjectStartTimestamp = 0;
this._carryObjectEndTimestamp = 0;
this._allowUseCarryObject = false;
}
else
{
this._carryObjectStartTimestamp = this.time;
if(message.itemType < AvatarLogic.MAX_HAND_ID)
{
this._carryObjectEndTimestamp = 0;
this._allowUseCarryObject = message.itemType <= AvatarLogic.MAX_HAND_USE_ID;
}
else
{
this._carryObjectEndTimestamp = this._carryObjectStartTimestamp + 1500;
this._allowUseCarryObject = false;
}
}
return;
}
if(message instanceof ObjectAvatarUseObjectUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_USE_OBJECT, message.itemType);
return;
}
if(message instanceof ObjectAvatarSignUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_SIGN, message.signType);
this._signEndTimestamp = (this.time + 5000);
return;
}
if(message instanceof ObjectAvatarFlatControlUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_FLAT_CONTROL, message.level);
return;
}
if(message instanceof ObjectAvatarFigureUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE, message.figure);
model.setValue(RoomObjectVariable.GENDER, message.gender);
return;
}
if(message instanceof ObjectAvatarSelectedMessage)
{
this._selected = message.selected;
this._reportedLocation = null;
return;
}
if(message instanceof ObjectAvatarOwnMessage)
{
model.setValue(RoomObjectVariable.OWN_USER, 1);
return;
}
}
private updateAvatarEffect(effect: number, delay: number, model: IRoomObjectModel): void
{
if(effect === AvatarLogic.EFFECT_TYPE_SPLASH)
{
this._effectChangeTimeStamp = (GetTickerTime() + AvatarLogic.EFFECT_SPLASH_LENGTH);
this._newEffect = AvatarLogic.EFFECT_TYPE_SWIM;
}
else if(effect === AvatarLogic.EFFECT_TYPE_SPLASH_DARK)
{
this._effectChangeTimeStamp = (GetTickerTime() + AvatarLogic.EFFECT_SPLASH_LENGTH);
this._newEffect = AvatarLogic.EFFECT_TYPE_SWIM_DARK;
}
else if(model.getValue<number>(RoomObjectVariable.FIGURE_EFFECT) === AvatarLogic.EFFECT_TYPE_SWIM)
{
this._effectChangeTimeStamp = (GetTickerTime() + AvatarLogic.EFFECT_SPLASH_LENGTH);
this._newEffect = effect;
effect = AvatarLogic.EFFECT_TYPE_SPLASH;
}
else if(model.getValue<number>(RoomObjectVariable.FIGURE_EFFECT) === AvatarLogic.EFFECT_TYPE_SWIM_DARK)
{
this._effectChangeTimeStamp = (GetTickerTime() + AvatarLogic.EFFECT_SPLASH_LENGTH);
this._newEffect = effect;
effect = AvatarLogic.EFFECT_TYPE_SPLASH_DARK;
}
else if(delay === 0)
{
this._effectChangeTimeStamp = 0;
}
else
{
this._effectChangeTimeStamp = (GetTickerTime() + delay);
this._newEffect = effect;
return;
}
model.setValue(RoomObjectVariable.FIGURE_EFFECT, effect);
}
public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void
{
let eventType: string = null;
switch(event.type)
{
case MouseEventType.MOUSE_CLICK:
eventType = RoomObjectMouseEvent.CLICK;
break;
case MouseEventType.DOUBLE_CLICK:
eventType = RoomObjectMouseEvent.DOUBLE_CLICK;
break;
case MouseEventType.ROLL_OVER:
eventType = RoomObjectMouseEvent.MOUSE_ENTER;
if(this.object.model) this.object.model.setValue(RoomObjectVariable.FIGURE_HIGHLIGHT, 1);
if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.MOUSE_BUTTON, this.object));
break;
case MouseEventType.ROLL_OUT:
eventType = RoomObjectMouseEvent.MOUSE_LEAVE;
if(this.object.model) this.object.model.setValue(RoomObjectVariable.FIGURE_HIGHLIGHT, 0);
if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.MOUSE_ARROW, this.object));
break;
}
if(eventType && this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMouseEvent(eventType, this.object, event.eventId, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown));
}
private randomTalkingPauseStartTimestamp(): number
{
return 100 + (Math.random() * 200);
}
private randomTalkingPauseEndTimestamp(): number
{
return 75 + (Math.random() * 75);
}
private randomBlinkStartTimestamp(): number
{
return 4500 + (Math.random() * 1000);
}
private randomBlinkEndTimestamp(): number
{
return 50 + (Math.random() * 200);
}
}
@@ -0,0 +1,148 @@
import { IRoomObjectController, IRoomObjectUpdateMessage, IVector3D, RoomObjectVariable } from '@nitrots/api';
import { Vector3d } from '@nitrots/utils';
import { ObjectMoveUpdateMessage } from '../../messages';
import { RoomObjectLogicBase } from './RoomObjectLogicBase';
export class MovingObjectLogic extends RoomObjectLogicBase
{
public static DEFAULT_UPDATE_INTERVAL: number = 500;
private static TEMP_VECTOR: Vector3d = new Vector3d();
private _liftAmount: number;
private _location: Vector3d;
private _locationDelta: Vector3d;
private _lastUpdateTime: number;
private _changeTime: number;
private _updateInterval: number;
constructor()
{
super();
this._liftAmount = 0;
this._location = new Vector3d();
this._locationDelta = new Vector3d();
this._lastUpdateTime = 0;
this._changeTime = 0;
this._updateInterval = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL;
}
public dispose(): void
{
this._liftAmount = 0;
super.dispose();
}
public update(time: number): void
{
super.update(time);
const locationOffset = this.getLocationOffset();
const model = this.object && this.object.model;
if(model)
{
if(locationOffset)
{
if(this._liftAmount !== locationOffset.z)
{
this._liftAmount = locationOffset.z;
model.setValue(RoomObjectVariable.FURNITURE_LIFT_AMOUNT, this._liftAmount);
}
}
else
{
if(this._liftAmount !== 0)
{
this._liftAmount = 0;
model.setValue(RoomObjectVariable.FURNITURE_LIFT_AMOUNT, this._liftAmount);
}
}
}
if((this._locationDelta.length > 0) || locationOffset)
{
const vector = MovingObjectLogic.TEMP_VECTOR;
let difference = (this.time - this._changeTime);
if(difference === (this._updateInterval >> 1)) difference++;
if(difference > this._updateInterval) difference = this._updateInterval;
if(this._locationDelta.length > 0)
{
vector.assign(this._locationDelta);
vector.multiply((difference / this._updateInterval));
vector.add(this._location);
}
else
{
vector.assign(this._location);
}
if(locationOffset) vector.add(locationOffset);
this.object.setLocation(vector);
if(difference === this._updateInterval)
{
this._locationDelta.x = 0;
this._locationDelta.y = 0;
this._locationDelta.z = 0;
}
}
this._lastUpdateTime = this.time;
}
public setObject(object: IRoomObjectController): void
{
super.setObject(object);
if(object) this._location.assign(object.getLocation());
}
public processUpdateMessage(message: IRoomObjectUpdateMessage): void
{
if(!message) return;
super.processUpdateMessage(message);
if(message.location) this._location.assign(message.location);
if(message instanceof ObjectMoveUpdateMessage) return this.processMoveMessage(message);
}
private processMoveMessage(message: ObjectMoveUpdateMessage): void
{
if(!message || !this.object || !message.location) return;
this._changeTime = this._lastUpdateTime;
this._locationDelta.assign(message.targetLocation);
this._locationDelta.subtract(this._location);
}
protected getLocationOffset(): IVector3D
{
return null;
}
protected get lastUpdateTime(): number
{
return this._lastUpdateTime;
}
protected set updateInterval(interval: number)
{
if(interval <= 0) interval = 1;
this._updateInterval = interval;
}
}
+238
View File
@@ -0,0 +1,238 @@
import { IAssetData, IRoomGeometry, IRoomObjectModel, IVector3D, MouseEventType, PetFigureData, PetType, RoomObjectVariable } from '@nitrots/api';
import { RoomObjectMouseEvent, RoomObjectMoveEvent, RoomSpriteMouseEvent } from '@nitrots/events';
import { Vector3d } from '@nitrots/utils';
import { ObjectAvatarChatUpdateMessage, ObjectAvatarExperienceUpdateMessage, ObjectAvatarFigureUpdateMessage, ObjectAvatarPetGestureUpdateMessage, ObjectAvatarPostureUpdateMessage, ObjectAvatarSelectedMessage, ObjectAvatarSleepUpdateMessage, ObjectAvatarUpdateMessage, RoomObjectUpdateMessage } from '../../messages';
import { MovingObjectLogic } from './MovingObjectLogic';
export class PetLogic extends MovingObjectLogic
{
private _selected: boolean;
private _reportedLocation: IVector3D;
private _postureIndex: number;
private _gestureIndex: number;
private _headDirectionDelta: number;
private _directions: number[];
private _talkingEndTimestamp: number;
private _gestureEndTimestamp: number;
private _expressionEndTimestamp: number;
constructor()
{
super();
this._selected = false;
this._reportedLocation = null;
this._postureIndex = 0;
this._gestureIndex = 0;
this._headDirectionDelta = 0;
this._directions = [];
this._talkingEndTimestamp = 0;
this._gestureEndTimestamp = 0;
this._expressionEndTimestamp = 0;
}
public getEventTypes(): string[]
{
const types = [RoomObjectMouseEvent.CLICK, RoomObjectMoveEvent.POSITION_CHANGED];
return this.mergeTypes(super.getEventTypes(), types);
}
public initialize(asset: IAssetData): void
{
if(!asset) return;
const model = this.object && this.object.model;
if(!model) return;
if(asset.logic)
{
if(asset.logic.model)
{
const directions = asset.logic.model.directions;
if(directions && directions.length)
{
for(const direction of directions) this._directions.push(direction);
this._directions.sort();
}
}
}
model.setValue(RoomObjectVariable.PET_ALLOWED_DIRECTIONS, this._directions);
}
public dispose(): void
{
if(this._selected && this.object)
{
if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMoveEvent(RoomObjectMoveEvent.OBJECT_REMOVED, this.object));
}
this._directions = null;
this._reportedLocation = null;
}
public update(totalTimeRunning: number): void
{
super.update(totalTimeRunning);
if(this._selected && this.object)
{
if(this.eventDispatcher)
{
const location = this.object.getLocation();
if(((!this._reportedLocation || (this._reportedLocation.x !== location.x)) || (this._reportedLocation.y !== location.y)) || (this._reportedLocation.z !== location.z))
{
if(!this._reportedLocation) this._reportedLocation = new Vector3d();
this._reportedLocation.assign(location);
this.eventDispatcher.dispatchEvent(new RoomObjectMoveEvent(RoomObjectMoveEvent.POSITION_CHANGED, this.object));
}
}
}
if(this.object && this.object.model) this.updateModel(totalTimeRunning, this.object.model);
}
private updateModel(time: number, model: IRoomObjectModel): void
{
if((this._gestureEndTimestamp > 0) && (time > this._gestureEndTimestamp))
{
model.setValue(RoomObjectVariable.FIGURE_GESTURE, null);
this._gestureEndTimestamp = 0;
}
if(this._talkingEndTimestamp > 0)
{
if(time > this._talkingEndTimestamp)
{
model.setValue(RoomObjectVariable.FIGURE_TALK, 0);
this._talkingEndTimestamp = 0;
}
}
if((this._expressionEndTimestamp > 0) && (time > this._expressionEndTimestamp))
{
model.setValue(RoomObjectVariable.FIGURE_EXPRESSION, 0);
this._expressionEndTimestamp = 0;
}
}
public processUpdateMessage(message: RoomObjectUpdateMessage): void
{
if(!message || !this.object) return;
super.processUpdateMessage(message);
const model = this.object && this.object.model;
if(!model) return;
if(message instanceof ObjectAvatarUpdateMessage)
{
model.setValue(RoomObjectVariable.HEAD_DIRECTION, message.headDirection);
return;
}
if(message instanceof ObjectAvatarFigureUpdateMessage)
{
const petFigureData = new PetFigureData(message.figure);
model.setValue(RoomObjectVariable.FIGURE, message.figure);
model.setValue(RoomObjectVariable.RACE, message.subType);
model.setValue(RoomObjectVariable.PET_PALETTE_INDEX, petFigureData.paletteId);
model.setValue(RoomObjectVariable.PET_COLOR, petFigureData.color);
model.setValue(RoomObjectVariable.PET_TYPE, petFigureData.typeId);
model.setValue(RoomObjectVariable.PET_CUSTOM_LAYER_IDS, petFigureData.customLayerIds);
model.setValue(RoomObjectVariable.PET_CUSTOM_PARTS_IDS, petFigureData.customPartIds);
model.setValue(RoomObjectVariable.PET_CUSTOM_PALETTE_IDS, petFigureData.customPaletteIds);
model.setValue(RoomObjectVariable.PET_IS_RIDING, (message.isRiding ? 1 : 0));
return;
}
if(message instanceof ObjectAvatarPostureUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_POSTURE, message.postureType);
return;
}
if(message instanceof ObjectAvatarChatUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_TALK, 1);
this._talkingEndTimestamp = this.time + (message.numberOfWords * 1000);
return;
}
if(message instanceof ObjectAvatarSleepUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_SLEEP, message.isSleeping ? 1 : 0);
return;
}
if(message instanceof ObjectAvatarPetGestureUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_GESTURE, message.gesture);
this._gestureEndTimestamp = this.time + 3000;
return;
}
if(message instanceof ObjectAvatarSelectedMessage)
{
this._selected = message.selected;
this._reportedLocation = null;
return;
}
if(message instanceof ObjectAvatarExperienceUpdateMessage)
{
model.setValue(RoomObjectVariable.FIGURE_EXPERIENCE_TIMESTAMP, this.time);
model.setValue(RoomObjectVariable.FIGURE_GAINED_EXPERIENCE, message.gainedExperience);
return;
}
}
public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void
{
let eventType: string = null;
switch(event.type)
{
case MouseEventType.MOUSE_CLICK:
eventType = RoomObjectMouseEvent.CLICK;
break;
case MouseEventType.DOUBLE_CLICK:
break;
case MouseEventType.MOUSE_DOWN: {
const petType = this.object.model.getValue<number>(RoomObjectVariable.PET_TYPE);
if(petType === PetType.MONSTERPLANT)
{
if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMouseEvent(RoomObjectMouseEvent.MOUSE_DOWN, this.object, event.eventId, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown));
}
break;
}
}
if(eventType && this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMouseEvent(eventType, this.object, event.eventId, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown));
}
}
+453
View File
@@ -0,0 +1,453 @@
import { IRoomGeometry, IRoomObjectModel, MouseEventType, RoomObjectVariable } from '@nitrots/api';
import { GetConfiguration } from '@nitrots/configuration';
import { RoomObjectEvent, RoomObjectMouseEvent, RoomObjectTileMouseEvent, RoomObjectWallMouseEvent, RoomSpriteMouseEvent } from '@nitrots/events';
import { ColorConverter, Vector3d } from '@nitrots/utils';
import { Point } from 'pixi.js';
import { ObjectRoomColorUpdateMessage, ObjectRoomFloorHoleUpdateMessage, ObjectRoomMapUpdateMessage, ObjectRoomMaskUpdateMessage, ObjectRoomPlanePropertyUpdateMessage, ObjectRoomPlaneVisibilityUpdateMessage, ObjectRoomUpdateMessage, RoomObjectUpdateMessage } from '../../messages';
import { RoomMapData } from '../RoomMapData';
import { RoomPlaneBitmapMaskData } from '../RoomPlaneBitmapMaskData';
import { RoomPlaneBitmapMaskParser } from '../RoomPlaneBitmapMaskParser';
import { RoomPlaneData } from '../RoomPlaneData';
import { RoomPlaneParser } from '../RoomPlaneParser';
import { RoomObjectLogicBase } from './RoomObjectLogicBase';
export class RoomLogic extends RoomObjectLogicBase
{
private _planeParser: RoomPlaneParser;
private _planeBitmapMaskParser: RoomPlaneBitmapMaskParser;
private _color: number;
private _light: number;
private _originalColor: number;
private _originalLight: number;
private _targetColor: number;
private _targetLight: number;
private _colorChangedTime: number;
private _colorTransitionLength: number;
private _lastHoleUpdate: number;
private _needsMapUpdate: boolean;
private _skipColorTransition: boolean;
constructor()
{
super();
this._planeParser = new RoomPlaneParser();
this._planeBitmapMaskParser = new RoomPlaneBitmapMaskParser();
this._color = 0xFFFFFF;
this._light = 0xFF;
this._originalColor = 0xFFFFFF;
this._originalLight = 0xFF;
this._targetColor = 0xFFFFFF;
this._targetLight = 0xFF;
this._colorChangedTime = 0;
this._colorTransitionLength = 1500;
this._lastHoleUpdate = 0;
this._needsMapUpdate = false;
this._skipColorTransition = false;
}
public getEventTypes(): string[]
{
const types = [RoomObjectMouseEvent.MOUSE_MOVE, RoomObjectMouseEvent.CLICK];
return this.mergeTypes(super.getEventTypes(), types);
}
public dispose(): void
{
super.dispose();
if(this._planeParser)
{
this._planeParser.dispose();
this._planeParser = null;
}
if(this._planeBitmapMaskParser)
{
this._planeBitmapMaskParser.dispose();
this._planeBitmapMaskParser = null;
}
}
public initialize(roomMap: RoomMapData): void
{
if(!roomMap || !this.object) return;
if(!(roomMap instanceof RoomMapData)) return;
if(!this._planeParser.initializeFromMapData(roomMap)) return;
this.object.model.setValue(RoomObjectVariable.ROOM_MAP_DATA, roomMap);
this.object.model.setValue(RoomObjectVariable.ROOM_BACKGROUND_COLOR, 0xFFFFFF);
this.object.model.setValue(RoomObjectVariable.ROOM_FLOOR_VISIBILITY, 1);
this.object.model.setValue(RoomObjectVariable.ROOM_WALL_VISIBILITY, 1);
this.object.model.setValue(RoomObjectVariable.ROOM_LANDSCAPE_VISIBILITY, 1);
this._skipColorTransition = (GetConfiguration().getValue<boolean>('room.color.skip.transition') === true);
}
public update(time: number): void
{
super.update(time);
this.updateBackgroundColor(time);
if(this._needsMapUpdate)
{
if(this._lastHoleUpdate && (time - this._lastHoleUpdate) < 5) return;
const model = this.object && this.object.model;
if(model)
{
const mapData = this._planeParser.getMapData();
model.setValue(RoomObjectVariable.ROOM_MAP_DATA, mapData);
model.setValue(RoomObjectVariable.ROOM_FLOOR_HOLE_UPDATE_TIME, time);
this._planeParser.initializeFromMapData(mapData);
}
this._lastHoleUpdate = 0;
this._needsMapUpdate = false;
}
}
private updateBackgroundColor(k: number): void
{
if(!this.object || !this._colorChangedTime) return;
let color = this._color;
let newColor = this._light;
if((k - this._colorChangedTime) >= this._colorTransitionLength)
{
color = this._targetColor;
newColor = this._targetLight;
this._colorChangedTime = 0;
}
else
{
let _local_7 = ((this._originalColor >> 16) & 0xFF);
let _local_8 = ((this._originalColor >> 8) & 0xFF);
let _local_9 = (this._originalColor & 0xFF);
const _local_10 = ((this._targetColor >> 16) & 0xFF);
const _local_11 = ((this._targetColor >> 8) & 0xFF);
const _local_12 = (this._targetColor & 0xFF);
const _local_13 = ((k - this._colorChangedTime) / this._colorTransitionLength);
_local_7 = (_local_7 + ((_local_10 - _local_7) * _local_13));
_local_8 = (_local_8 + ((_local_11 - _local_8) * _local_13));
_local_9 = (_local_9 + ((_local_12 - _local_9) * _local_13));
color = (((_local_7 << 16) + (_local_8 << 8)) + _local_9);
newColor = (this._originalLight + ((this._targetLight - this._originalLight) * _local_13));
this._color = color;
this._light = newColor;
}
let _local_5 = ColorConverter.rgbToHSL(color);
_local_5 = ((_local_5 & 0xFFFF00) + newColor);
color = ColorConverter.hslToRGB(_local_5);
if(this.object.model) this.object.model.setValue(RoomObjectVariable.ROOM_BACKGROUND_COLOR, color);
}
public processUpdateMessage(message: RoomObjectUpdateMessage): void
{
if(!message || !this.object) return;
const model = this.object.model;
if(!model) return;
if(message instanceof ObjectRoomUpdateMessage)
{
this.onObjectRoomUpdateMessage(message, model);
return;
}
if(message instanceof ObjectRoomMaskUpdateMessage)
{
this.onObjectRoomMaskUpdateMessage(message, model);
return;
}
if(message instanceof ObjectRoomPlaneVisibilityUpdateMessage)
{
this.onObjectRoomPlaneVisibilityUpdateMessage(message, model);
return;
}
if(message instanceof ObjectRoomPlanePropertyUpdateMessage)
{
this.onObjectRoomPlanePropertyUpdateMessage(message, model);
return;
}
if(message instanceof ObjectRoomFloorHoleUpdateMessage)
{
this.onObjectRoomFloorHoleUpdateMessage(message, model);
return;
}
if(message instanceof ObjectRoomColorUpdateMessage)
{
this.onObjectRoomColorUpdateMessage(message, model);
return;
}
if(message instanceof ObjectRoomMapUpdateMessage)
{
this.onObjectRoomMapUpdateMessage(message);
}
}
private onObjectRoomUpdateMessage(message: ObjectRoomUpdateMessage, model: IRoomObjectModel): void
{
switch(message.type)
{
case ObjectRoomUpdateMessage.ROOM_FLOOR_UPDATE:
model.setValue(RoomObjectVariable.ROOM_FLOOR_TYPE, message.value);
return;
case ObjectRoomUpdateMessage.ROOM_WALL_UPDATE:
model.setValue(RoomObjectVariable.ROOM_WALL_TYPE, message.value);
return;
case ObjectRoomUpdateMessage.ROOM_LANDSCAPE_UPDATE:
model.setValue(RoomObjectVariable.ROOM_LANDSCAPE_TYPE, message.value);
return;
}
}
private onObjectRoomMaskUpdateMessage(message: ObjectRoomMaskUpdateMessage, _arg_2: IRoomObjectModel): void
{
let maskType: string = null;
let update = false;
switch(message.type)
{
case ObjectRoomMaskUpdateMessage.ADD_MASK:
maskType = RoomPlaneBitmapMaskData.WINDOW;
if(message.maskCategory === ObjectRoomMaskUpdateMessage.HOLE) maskType = RoomPlaneBitmapMaskData.HOLE;
this._planeBitmapMaskParser.addMask(message.maskId, message.maskType, message.maskLocation, maskType);
update = true;
break;
case ObjectRoomMaskUpdateMessage.REMOVE_MASK:
update = this._planeBitmapMaskParser.removeMask(message.maskId);
break;
}
if(update) _arg_2.setValue(RoomObjectVariable.ROOM_PLANE_MASK_XML, this._planeBitmapMaskParser.getXML());
}
private onObjectRoomPlaneVisibilityUpdateMessage(message: ObjectRoomPlaneVisibilityUpdateMessage, model: IRoomObjectModel): void
{
let visible = 0;
if(message.visible) visible = 1;
switch(message.type)
{
case ObjectRoomPlaneVisibilityUpdateMessage.FLOOR_VISIBILITY:
model.setValue(RoomObjectVariable.ROOM_FLOOR_VISIBILITY, visible);
return;
case ObjectRoomPlaneVisibilityUpdateMessage.WALL_VISIBILITY:
model.setValue(RoomObjectVariable.ROOM_WALL_VISIBILITY, visible);
model.setValue(RoomObjectVariable.ROOM_LANDSCAPE_VISIBILITY, visible);
return;
}
}
private onObjectRoomPlanePropertyUpdateMessage(message: ObjectRoomPlanePropertyUpdateMessage, model: IRoomObjectModel): void
{
switch(message.type)
{
case ObjectRoomPlanePropertyUpdateMessage.FLOOR_THICKNESS:
model.setValue(RoomObjectVariable.ROOM_FLOOR_THICKNESS, message.value);
return;
case ObjectRoomPlanePropertyUpdateMessage.WALL_THICKNESS:
model.setValue(RoomObjectVariable.ROOM_WALL_THICKNESS, message.value);
return;
}
}
private onObjectRoomFloorHoleUpdateMessage(message: ObjectRoomFloorHoleUpdateMessage, model: IRoomObjectModel): void
{
switch(message.type)
{
case ObjectRoomFloorHoleUpdateMessage.ADD:
this._planeParser.addFloorHole(message.id, message.x, message.y, message.width, message.height);
this._needsMapUpdate = true;
return;
case ObjectRoomFloorHoleUpdateMessage.REMOVE:
this._planeParser.removeFloorHole(message.id);
this._needsMapUpdate = true;
return;
}
this._lastHoleUpdate = this.time;
}
private onObjectRoomColorUpdateMessage(message: ObjectRoomColorUpdateMessage, model: IRoomObjectModel): void
{
if(!message || !model) return;
this._originalColor = this._color;
this._originalLight = this._light;
this._targetColor = message.color;
this._targetLight = message.light;
this._colorChangedTime = this.time;
if(this._skipColorTransition)
this._colorTransitionLength = 0;
else
this._colorTransitionLength = 1500;
model.setValue(RoomObjectVariable.ROOM_COLORIZE_BG_ONLY, message.backgroundOnly);
}
private onObjectRoomMapUpdateMessage(message: ObjectRoomMapUpdateMessage): void
{
if(!message || !message.mapData) return;
this.object.model.setValue(RoomObjectVariable.ROOM_MAP_DATA, message.mapData);
this.object.model.setValue(RoomObjectVariable.ROOM_FLOOR_HOLE_UPDATE_TIME, this.time);
this._planeParser.initializeFromMapData(message.mapData);
}
public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void
{
if(!event || !geometry || !this.object || !this.object.model) return;
const tag = event.spriteTag;
let planeId = 0;
if(tag && (tag.indexOf('@') >= 0))
{
planeId = parseInt(tag.substr(tag.indexOf('@') + 1));
}
if((planeId < 1) || (planeId > this._planeParser.planeCount))
{
if(event.type === MouseEventType.ROLL_OUT)
{
this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_PLANE, 0);
}
return;
}
planeId--;
let planePosition: Point = null;
const planeLocation = this._planeParser.getPlaneLocation(planeId);
const planeLeftSide = this._planeParser.getPlaneLeftSide(planeId);
const planeRightSide = this._planeParser.getPlaneRightSide(planeId);
const planeNormalDirection = this._planeParser.getPlaneNormalDirection(planeId);
const planeType = this._planeParser.getPlaneType(planeId);
if(((((planeLocation == null) || (planeLeftSide == null)) || (planeRightSide == null)) || (planeNormalDirection == null))) return;
const leftSideLength = planeLeftSide.length;
const rightSideLength = planeRightSide.length;
if(((leftSideLength == 0) || (rightSideLength == 0))) return;
const screenX = event.screenX;
const screenY = event.screenY;
const screenPoint = new Point(screenX, screenY);
planePosition = geometry.getPlanePosition(screenPoint, planeLocation, planeLeftSide, planeRightSide);
if(!planePosition)
{
this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_PLANE, 0);
return;
}
const _local_18 = Vector3d.product(planeLeftSide, (planePosition.x / leftSideLength));
_local_18.add(Vector3d.product(planeRightSide, (planePosition.y / rightSideLength)));
_local_18.add(planeLocation);
const tileX = _local_18.x;
const tileY = _local_18.y;
const tileZ = _local_18.z;
if(((((planePosition.x >= 0) && (planePosition.x < leftSideLength)) && (planePosition.y >= 0)) && (planePosition.y < rightSideLength)))
{
this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_X, tileX);
this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_Y, tileY);
this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_Z, tileZ);
this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_PLANE, (planeId + 1));
}
else
{
this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_PLANE, 0);
return;
}
let eventType: string = null;
if((event.type === MouseEventType.MOUSE_MOVE) || (event.type === MouseEventType.ROLL_OVER)) eventType = RoomObjectMouseEvent.MOUSE_MOVE;
else if((event.type === MouseEventType.MOUSE_CLICK)) eventType = RoomObjectMouseEvent.CLICK;
switch(event.type)
{
case MouseEventType.MOUSE_MOVE:
case MouseEventType.ROLL_OVER:
case MouseEventType.MOUSE_CLICK: {
let newEvent: RoomObjectEvent = null;
if(planeType === RoomPlaneData.PLANE_FLOOR)
{
newEvent = new RoomObjectTileMouseEvent(eventType, this.object, event.eventId, tileX, tileY, tileZ, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown);
}
else if((planeType === RoomPlaneData.PLANE_WALL) || (planeType === RoomPlaneData.PLANE_LANDSCAPE))
{
let direction = 90;
if(planeNormalDirection)
{
direction = (planeNormalDirection.x + 90);
if(direction > 360) direction -= 360;
}
const _local_27 = ((planeLeftSide.length * planePosition.x) / leftSideLength);
const _local_28 = ((planeRightSide.length * planePosition.y) / rightSideLength);
newEvent = new RoomObjectWallMouseEvent(eventType, this.object, event.eventId, planeLocation, planeLeftSide, planeRightSide, _local_27, _local_28, direction, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown);
}
if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(newEvent);
return;
}
}
}
}
@@ -0,0 +1,120 @@
import { IEventDispatcher, IRoomGeometry, IRoomObjectController, IRoomObjectEventHandler, IRoomObjectUpdateMessage } from '@nitrots/api';
import { RoomSpriteMouseEvent } from '@nitrots/events';
export class RoomObjectLogicBase implements IRoomObjectEventHandler
{
private _events: IEventDispatcher = null;
private _object: IRoomObjectController = null;
private _time: number = 0;
public initialize(data: unknown): void
{
return;
}
public dispose(): void
{
this._object = null;
}
public update(time: number): void
{
this._time = time;
return;
}
public processUpdateMessage(message: IRoomObjectUpdateMessage): void
{
if(!message || !this._object) return;
this._object.setLocation(message.location);
this._object.setDirection(message.direction);
}
public getEventTypes(): string[]
{
return [];
}
protected mergeTypes(k: string[], _arg_2: string[]): string[]
{
const types = k.concat();
for(const type of _arg_2)
{
if(!type || (types.indexOf(type) >= 0)) continue;
types.push(type);
}
return types;
}
public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void
{
return;
}
public useObject(): void
{
return;
}
public setObject(object: IRoomObjectController): void
{
if(this._object === object) return;
if(this._object)
{
this._object.setLogic(null);
}
if(!object)
{
this.dispose();
this._object = null;
return;
}
this._object = object;
this._object.setLogic(this);
}
public tearDown(): void
{
return;
}
public get object(): IRoomObjectController
{
return this._object;
}
public get eventDispatcher(): IEventDispatcher
{
return this._events;
}
public set eventDispatcher(events: IEventDispatcher)
{
this._events = events;
}
public get widget(): string
{
return null;
}
public get contextMenu(): string
{
return null;
}
public get time(): number
{
return this._time;
}
}
@@ -0,0 +1,35 @@
import { IAssetData, RoomObjectVariable } from '@nitrots/api';
import { ObjectVisibilityUpdateMessage, RoomObjectUpdateMessage } from '../../messages';
import { RoomObjectLogicBase } from './RoomObjectLogicBase';
export class SelectionArrowLogic extends RoomObjectLogicBase
{
public initialize(data: IAssetData): void
{
if(!this.object) return;
this.object.model.setValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER, 1);
this.object.setState(1, 0);
}
public processUpdateMessage(message: RoomObjectUpdateMessage): void
{
super.processUpdateMessage(message);
if(!(message instanceof ObjectVisibilityUpdateMessage)) return;
if(this.object)
{
switch(message.type)
{
case ObjectVisibilityUpdateMessage.ENABLED:
this.object.setState(0, 0);
return;
case ObjectVisibilityUpdateMessage.DISABLED:
this.object.setState(1, 0);
return;
}
}
}
}
@@ -0,0 +1,64 @@
import { IAssetData, RoomObjectVariable } from '@nitrots/api';
import { ObjectTileCursorUpdateMessage, RoomObjectUpdateMessage } from '../../messages';
import { RoomObjectLogicBase } from './RoomObjectLogicBase';
export class TileCursorLogic extends RoomObjectLogicBase
{
private static CURSOR_VISIBLE_STATE: number = 0;
private static CURSOR_HIDDEN_STATE: number = 1;
private static CURSOR_HEIGHT_STATE: number = 6;
private _lastEventId: string;
private _isHidden: boolean;
constructor()
{
super();
this._lastEventId = null;
this._isHidden = false;
}
public initialize(data: IAssetData): void
{
if(!this.object) return;
this.object.model.setValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER, 1);
this.object.setState(TileCursorLogic.CURSOR_HIDDEN_STATE, 0);
}
public processUpdateMessage(message: RoomObjectUpdateMessage): void
{
if(!(message instanceof ObjectTileCursorUpdateMessage)) return;
if(this._lastEventId && (this._lastEventId === message.sourceEventId)) return;
if(message.toggleVisibility) this._isHidden = !this._isHidden;
super.processUpdateMessage(message);
if(this.object)
{
if(this._isHidden)
{
this.object.setState(TileCursorLogic.CURSOR_HIDDEN_STATE, 0);
}
else
{
if(!message.visible)
{
this.object.setState(TileCursorLogic.CURSOR_HIDDEN_STATE, 0);
}
else
{
this.object.model.setValue(RoomObjectVariable.TILE_CURSOR_HEIGHT, message.height);
this.object.setState((message.height > 0.8) ? TileCursorLogic.CURSOR_HEIGHT_STATE : TileCursorLogic.CURSOR_VISIBLE_STATE);
}
}
}
this._lastEventId = message.sourceEventId;
}
}
@@ -0,0 +1,71 @@
import { RoomObjectVariable } from '@nitrots/api';
import { RoomObjectBadgeAssetEvent, RoomObjectEvent, RoomObjectWidgetRequestEvent } from '@nitrots/events';
import { ObjectGroupBadgeUpdateMessage, ObjectSelectedMessage, RoomObjectUpdateMessage } from '../../../messages';
import { FurnitureBadgeDisplayLogic } from './FurnitureBadgeDisplayLogic';
export class FurnitureAchievementResolutionLogic extends FurnitureBadgeDisplayLogic
{
public static STATE_RESOLUTION_NOT_STARTED: number = 0;
public static STATE_RESOLUTION_IN_PROGRESS: number = 1;
public static STATE_RESOLUTION_ACHIEVED: number = 2;
public static STATE_RESOLUTION_FAILED: number = 3;
private static ACH_NOT_SET: string = 'ach_0';
private static BADGE_VISIBLE_IN_STATE: number = 2;
public getEventTypes(): string[]
{
const types = [RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_OPEN, RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_ENGRAVING, RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_FAILED, RoomObjectBadgeAssetEvent.LOAD_BADGE];
return this.mergeTypes(super.getEventTypes(), types);
}
public processUpdateMessage(message: RoomObjectUpdateMessage): void
{
super.processUpdateMessage(message);
if(message instanceof ObjectGroupBadgeUpdateMessage)
{
if(message.assetName !== 'loading_icon')
{
this.object.model.setValue(RoomObjectVariable.FURNITURE_BADGE_VISIBLE_IN_STATE, FurnitureAchievementResolutionLogic.BADGE_VISIBLE_IN_STATE);
}
}
if(message instanceof ObjectSelectedMessage)
{
if(!this.eventDispatcher || !this.object) return;
this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.CLOSE_FURNI_CONTEXT_MENU, this.object));
}
}
public useObject(): void
{
if(!this.object || !this.eventDispatcher) return;
let event: RoomObjectEvent = null;
switch(this.object.getState(0))
{
case FurnitureAchievementResolutionLogic.STATE_RESOLUTION_NOT_STARTED:
case FurnitureAchievementResolutionLogic.STATE_RESOLUTION_IN_PROGRESS:
event = new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_OPEN, this.object);
break;
case FurnitureAchievementResolutionLogic.STATE_RESOLUTION_ACHIEVED:
event = new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_ENGRAVING, this.object);
break;
case FurnitureAchievementResolutionLogic.STATE_RESOLUTION_FAILED:
event = new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_FAILED, this.object);
break;
}
if(event) this.eventDispatcher.dispatchEvent(event);
}
protected updateBadge(badgeId: string): void
{
if(badgeId === FurnitureAchievementResolutionLogic.ACH_NOT_SET) return;
super.updateBadge(badgeId);
}
}
@@ -0,0 +1,63 @@
import { RoomObjectVariable, StringDataType } from '@nitrots/api';
import { RoomObjectBadgeAssetEvent, RoomObjectWidgetRequestEvent } from '@nitrots/events';
import { GetTickerTime } from '@nitrots/utils';
import { ObjectDataUpdateMessage, ObjectGroupBadgeUpdateMessage, RoomObjectUpdateMessage } from '../../../messages';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureBadgeDisplayLogic extends FurnitureLogic
{
public getEventTypes(): string[]
{
const types = [RoomObjectWidgetRequestEvent.BADGE_DISPLAY_ENGRAVING, RoomObjectBadgeAssetEvent.LOAD_BADGE];
return this.mergeTypes(super.getEventTypes(), types);
}
public processUpdateMessage(message: RoomObjectUpdateMessage): void
{
super.processUpdateMessage(message);
if(!this.object) return;
if(message instanceof ObjectDataUpdateMessage)
{
const data = message.data;
if(data instanceof StringDataType) this.updateBadge(data.getValue(1));
return;
}
if(message instanceof ObjectGroupBadgeUpdateMessage)
{
if(message.assetName !== 'loading_icon')
{
this.object.model.setValue(RoomObjectVariable.FURNITURE_BADGE_ASSET_NAME, message.assetName);
this.object.model.setValue(RoomObjectVariable.FURNITURE_BADGE_IMAGE_STATUS, 1);
this.update(GetTickerTime());
}
return;
}
}
public useObject(): void
{
if(!this.object || !this.eventDispatcher) return;
this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.BADGE_DISPLAY_ENGRAVING, this.object));
}
protected updateBadge(badgeId: string): void
{
if(badgeId === '') return;
if(this.eventDispatcher)
{
this.object.model.setValue(RoomObjectVariable.FURNITURE_BADGE_IMAGE_STATUS, -1);
this.eventDispatcher.dispatchEvent(new RoomObjectBadgeAssetEvent(RoomObjectBadgeAssetEvent.LOAD_BADGE, this.object, badgeId, false));
}
}
}
@@ -0,0 +1,53 @@
import { IAssetData, RoomObjectVariable } from '@nitrots/api';
import { RoomToObjectOwnAvatarMoveEvent } from '@nitrots/events';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureChangeStateWhenStepOnLogic extends FurnitureLogic
{
constructor()
{
super();
this.onRoomToObjectOwnAvatarMoveEvent = this.onRoomToObjectOwnAvatarMoveEvent.bind(this);
}
public initialize(asset: IAssetData): void
{
super.initialize(asset);
if(this.eventDispatcher) this.eventDispatcher.addEventListener(RoomToObjectOwnAvatarMoveEvent.ROAME_MOVE_TO, this.onRoomToObjectOwnAvatarMoveEvent);
}
public tearDown(): void
{
if(this.eventDispatcher) this.eventDispatcher.removeEventListener(RoomToObjectOwnAvatarMoveEvent.ROAME_MOVE_TO, this.onRoomToObjectOwnAvatarMoveEvent);
super.tearDown();
}
private onRoomToObjectOwnAvatarMoveEvent(event: RoomToObjectOwnAvatarMoveEvent): void
{
if(!event || !this.object) return;
const location = this.object.getLocation();
const targetLocation = event.targetLocation;
if(!targetLocation) return;
let sizeX = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_SIZE_X);
let sizeY = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_SIZE_Y);
const direction = (((Math.floor(this.object.getDirection().x) + 45) % 360) / 90);
if((direction === 1) || (direction === 3)) [sizeX, sizeY] = [sizeY, sizeX];
if(((targetLocation.x >= location.x) && (targetLocation.x < (location.x + sizeX))) && ((targetLocation.y >= location.y) && (targetLocation.y < (location.y + sizeY))))
{
this.object.setState(1, 0);
}
else
{
this.object.setState(0, 0);
}
}
}
@@ -0,0 +1,47 @@
import { IAssetData, RoomObjectVariable } from '@nitrots/api';
import { RoomObjectWidgetRequestEvent } from '@nitrots/events';
import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureClothingChangeLogic extends FurnitureLogic
{
public getEventTypes(): string[]
{
const types = [RoomObjectWidgetRequestEvent.CLOTHING_CHANGE];
return this.mergeTypes(super.getEventTypes(), types);
}
public initialize(asset: IAssetData): void
{
super.initialize(asset);
const furniData = this.object.model.getValue<string>(RoomObjectVariable.FURNITURE_DATA);
this.updateClothingData(furniData);
}
public processUpdateMessage(message: RoomObjectUpdateMessage): void
{
super.processUpdateMessage(message);
if(message instanceof ObjectDataUpdateMessage) message.data && this.updateClothingData(message.data.getLegacyString());
}
private updateClothingData(furnitureData: string): void
{
if(!furnitureData || !furnitureData.length) return;
const [boyClothing, girlClothing] = furnitureData.split(',');
if(boyClothing && boyClothing.length) this.object.model.setValue<string>(RoomObjectVariable.FURNITURE_CLOTHING_BOY, boyClothing);
if(girlClothing && girlClothing.length) this.object.model.setValue<string>(RoomObjectVariable.FURNITURE_CLOTHING_GIRL, girlClothing);
}
public useObject(): void
{
if(!this.object || !this.eventDispatcher) return;
this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.CLOTHING_CHANGE, this.object));
}
}
@@ -0,0 +1,51 @@
import { IRoomGeometry, MouseEventType } from '@nitrots/api';
import { RoomObjectEvent, RoomObjectStateChangedEvent, RoomSpriteMouseEvent } from '@nitrots/events';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureCounterClockLogic extends FurnitureLogic
{
public getEventTypes(): string[]
{
const types = [RoomObjectStateChangedEvent.STATE_CHANGE];
return this.mergeTypes(super.getEventTypes(), types);
}
public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void
{
if(!event || !geometry || !this.object) return;
let objectEvent: RoomObjectEvent = null;
switch(event.type)
{
case MouseEventType.DOUBLE_CLICK:
switch(event.spriteTag)
{
case 'start_stop':
objectEvent = new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 1);
break;
case 'reset':
objectEvent = new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 2);
break;
}
if(this.eventDispatcher && objectEvent)
{
this.eventDispatcher.dispatchEvent(objectEvent);
return;
}
break;
}
super.mouseEvent(event, geometry);
}
public useObject(): void
{
if(!this.object || !this.eventDispatcher) return;
this.eventDispatcher.dispatchEvent(new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 1));
}
}
@@ -0,0 +1,18 @@
import { RoomObjectVariable, RoomWidgetEnumItemExtradataParameter } from '@nitrots/api';
import { RoomObjectUpdateMessage } from '../../../messages';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureCrackableLogic extends FurnitureLogic
{
public processUpdateMessage(message: RoomObjectUpdateMessage): void
{
super.processUpdateMessage(message);
if(!this.object) return;
if(this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT) === 1)
{
this.object.model.setValue(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM, RoomWidgetEnumItemExtradataParameter.CRACKABLE_FURNI);
}
}
}
@@ -0,0 +1,10 @@
import { RoomWidgetEnum } from '@nitrots/api';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureCraftingGizmoLogic extends FurnitureLogic
{
public get widget(): string
{
return RoomWidgetEnum.CRAFTING;
}
}
@@ -0,0 +1,38 @@
import { IAssetData, RoomObjectVariable } from '@nitrots/api';
import { RoomObjectWidgetRequestEvent } from '@nitrots/events';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureCreditLogic extends FurnitureLogic
{
public getEventTypes(): string[]
{
const types = [
RoomObjectWidgetRequestEvent.CREDITFURNI
];
return this.mergeTypes(super.getEventTypes(), types);
}
public initialize(asset: IAssetData): void
{
super.initialize(asset);
let creditValue = 0;
if(asset.logic)
{
if(asset.logic.credits && (asset.logic.credits !== '') && (asset.logic.credits.length > 0)) creditValue = parseInt(asset.logic.credits);
}
this.object.model.setValue(RoomObjectVariable.FURNITURE_CREDIT_VALUE, creditValue);
}
public useObject(): void
{
if(!this.object || !this.eventDispatcher) return;
this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.CREDITFURNI, this.object));
super.useObject();
}
}
@@ -0,0 +1,37 @@
import { RoomObjectPlaySoundIdEvent } from '@nitrots/events';
import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages';
import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic';
export class FurnitureCuckooClockLogic extends FurnitureMultiStateLogic
{
private _state: number = 1;
public getEventTypes(): string[]
{
const types = [RoomObjectPlaySoundIdEvent.PLAY_SOUND_AT_PITCH];
return this.mergeTypes(super.getEventTypes(), types);
}
public processUpdateMessage(message: RoomObjectUpdateMessage): void
{
super.processUpdateMessage(message);
if(message instanceof ObjectDataUpdateMessage)
{
if((this._state !== -1) && (message.state !== this._state))
{
this.dispatchSoundEvent(this.object.location.z);
}
this._state = message.state;
}
}
private dispatchSoundEvent(height: number): void
{
const pitch = Math.pow(2, (height - 1.2));
this.eventDispatcher.dispatchEvent(new RoomObjectPlaySoundIdEvent(RoomObjectPlaySoundIdEvent.PLAY_SOUND_AT_PITCH, this.object, 'FURNITURE_cuckoo_clock', pitch));
}
}
@@ -0,0 +1,31 @@
import { IAssetData, RoomObjectVariable } from '@nitrots/api';
import { RoomObjectWidgetRequestEvent } from '@nitrots/events';
import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic';
export class FurnitureCustomStackHeightLogic extends FurnitureMultiStateLogic
{
public getEventTypes(): string[]
{
const types = [
RoomObjectWidgetRequestEvent.STACK_HEIGHT
];
return this.mergeTypes(super.getEventTypes(), types);
}
public initialize(asset: IAssetData): void
{
super.initialize(asset);
if(this.object && this.object.model) this.object.model.setValue(RoomObjectVariable.FURNITURE_ALWAYS_STACKABLE, 1);
}
public useObject(): void
{
if(!this.object || !this.eventDispatcher) return;
this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.STACK_HEIGHT, this.object));
super.useObject();
}
}
@@ -0,0 +1,69 @@
import { IRoomGeometry, MouseEventType } from '@nitrots/api';
import { RoomObjectEvent, RoomObjectFurnitureActionEvent, RoomSpriteMouseEvent } from '@nitrots/events';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureDiceLogic extends FurnitureLogic
{
private _noTags: boolean;
private _noTagsLastStateActivate: boolean;
constructor()
{
super();
this._noTags = false;
this._noTagsLastStateActivate = false;
}
public getEventTypes(): string[]
{
const types = [RoomObjectFurnitureActionEvent.DICE_ACTIVATE, RoomObjectFurnitureActionEvent.DICE_OFF];
return this.mergeTypes(super.getEventTypes(), types);
}
public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void
{
if(!event || !geometry || !this.object) return;
let objectEvent: RoomObjectEvent = null;
switch(event.type)
{
case MouseEventType.DOUBLE_CLICK:
if(this._noTags)
{
if(((!(this._noTagsLastStateActivate)) || (this.object.getState(0) === 0)) || (this.object.getState(0) === 100))
{
objectEvent = new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.DICE_ACTIVATE, this.object);
this._noTagsLastStateActivate = true;
}
else
{
objectEvent = new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.DICE_OFF, this.object);
this._noTagsLastStateActivate = false;
}
}
else
{
if(((event.spriteTag === 'activate') || (this.object.getState(0) === 0)) || (this.object.getState(0) === 100))
{
objectEvent = new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.DICE_ACTIVATE, this.object);
}
else if(event.spriteTag === 'deactivate')
{
objectEvent = new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.DICE_OFF, this.object);
}
}
if(objectEvent && this.eventDispatcher) this.eventDispatcher.dispatchEvent(objectEvent);
return;
}
super.mouseEvent(event, geometry);
}
}
@@ -0,0 +1,21 @@
import { RoomObjectWidgetRequestEvent } from '@nitrots/events';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureEcotronBoxLogic extends FurnitureLogic
{
public getEventTypes(): string[]
{
const types = [
RoomObjectWidgetRequestEvent.ECOTRONBOX
];
return this.mergeTypes(super.getEventTypes(), types);
}
public useObject(): void
{
if(!this.object || !this.eventDispatcher) return;
this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.ECOTRONBOX, this.object));
}
}
@@ -0,0 +1,82 @@
import { IAssetData, IRoomGeometry, MouseEventType, RoomObjectVariable } from '@nitrots/api';
import { RoomObjectWidgetRequestEvent, RoomSpriteMouseEvent } from '@nitrots/events';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureEditableInternalLinkLogic extends FurnitureLogic
{
private _showStateOnceRendered: boolean;
private _updateCount: number;
constructor()
{
super();
this._showStateOnceRendered = false;
this._updateCount = 0;
}
public getEventTypes(): string[]
{
const types = [RoomObjectWidgetRequestEvent.INERNAL_LINK];
return this.mergeTypes(super.getEventTypes(), types);
}
public initialize(asset: IAssetData): void
{
super.initialize(asset);
if(asset.logic)
{
if(asset.logic.action)
{
if(asset.logic.action.startState === 1) this._showStateOnceRendered = true;
}
}
}
public update(time: number): void
{
super.update(time);
if(!this._showStateOnceRendered) return;
this._updateCount++;
if(this._showStateOnceRendered && (this._updateCount > 20))
{
this.setAutomaticStateIndex(1);
this._showStateOnceRendered = false;
}
}
private setAutomaticStateIndex(state: number): void
{
if(!this.object) return;
if(this.object.model)
{
this.object.model.setValue<number>(RoomObjectVariable.FURNITURE_AUTOMATIC_STATE_INDEX, state);
}
}
public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void
{
if(!event || !geometry) return;
if(event.type === MouseEventType.DOUBLE_CLICK)
{
this.setAutomaticStateIndex(0);
}
super.mouseEvent(event, geometry);
}
public useObject(): void
{
if(!this.object || !this.eventDispatcher) return;
this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.INERNAL_LINK, this.object));
}
}
@@ -0,0 +1,76 @@
import { IAssetData, RoomObjectVariable } from '@nitrots/api';
import { RoomObjectWidgetRequestEvent } from '@nitrots/events';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureEditableRoomLinkLogic extends FurnitureLogic
{
private _timer: any;
public getEventTypes(): string[]
{
const types = [RoomObjectWidgetRequestEvent.ROOM_LINK];
return this.mergeTypes(super.getEventTypes(), types);
}
public initialize(asset: IAssetData): void
{
super.initialize(asset);
if(asset.logic)
{
if(asset.logic.action)
{
if(asset.logic.action.link && (asset.logic.action.link !== '') && (asset.logic.action.link.length > 0))
{
(this.object && this.object.model && this.object.model.setValue<string>(RoomObjectVariable.FURNITURE_INTERNAL_LINK, asset.logic.action.link));
}
}
}
}
public dispose(): void
{
if(this._timer)
{
clearTimeout(this._timer);
this._timer = null;
}
super.dispose();
}
private setAutomaticStateIndex(state: number): void
{
if(!this.object) return;
if(this.object.model)
{
this.object.model.setValue<number>(RoomObjectVariable.FURNITURE_AUTOMATIC_STATE_INDEX, state);
}
}
public useObject(): void
{
this.setAutomaticStateIndex(1);
if(this._timer)
{
clearTimeout(this._timer);
this._timer = null;
}
this._timer = setTimeout(() =>
{
this.setAutomaticStateIndex(0);
this._timer = null;
}, 2500);
if(!this.object || !this.eventDispatcher) return;
this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.ROOM_LINK, this.object));
}
}
@@ -0,0 +1,27 @@
import { ContextMenuEnum } from '@nitrots/api';
import { RoomObjectWidgetRequestEvent } from '@nitrots/events';
import { FurnitureLogic } from './FurnitureLogic';
export class FurnitureEffectBoxLogic extends FurnitureLogic
{
private _timer: any;
public getEventTypes(): string[]
{
const types = [RoomObjectWidgetRequestEvent.EFFECTBOX_OPEN_DIALOG];
return this.mergeTypes(super.getEventTypes(), types);
}
public useObject(): void
{
if(!this.object || !this.eventDispatcher) return;
this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.EFFECTBOX_OPEN_DIALOG, this.object));
}
public get contextMenu(): string
{
return ContextMenuEnum.EFFECT_BOX;
}
}

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