Merge branch 'main' into dev

This commit is contained in:
Bill 2022-03-02 20:49:21 -05:00
commit 4e8e65ec28
607 changed files with 11990 additions and 8120 deletions

View File

@ -24,6 +24,9 @@
"SwitchCase": 1
}
],
"no-multi-spaces": [
"error"
],
"no-trailing-spaces": [
"error",
{

View File

@ -1,2 +1,17 @@
# Nitro Renderer
nitro-renderer is a Javascript library for rendering Nitro in the browser using PixiJS
## Installation
npm
```
npm install @nitrots/nitro-renderer
```
yarn
```
yarn add @nitrots/nitro-renderer
```

3072
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +1,39 @@
{
"name": "@nitrots/nitro-renderer",
"version": "1.0.0",
"description": "Javascript library for rendering Nitro in the browser using PixiJS",
"version": "1.1.5",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://git.krews.org/nitro/nitro-renderer"
"url": "https://git.krews.org/nitro/nitro-renderer.git"
},
"main": "./index.ts",
"license": "GPL-3.0",
"bugs": {
"url": "https://git.krews.org/nitro/nitro-renderer/issues"
},
"homepage": "https://git.krews.org/nitro/nitro-renderer",
"type": "module",
"scripts": {
"compile": "tsc --project ./tsconfig.json",
"eslint": "eslint ./src --fix"
"eslint": "eslint ./src --fix",
"postinstall": "node ./post-install.js"
},
"private": true,
"dependencies": {
"@pixi/canvas-renderer": "^6.1.3",
"@pixi/extract": "^6.1.3",
"@pixi/canvas-renderer": "^6.2.2",
"@pixi/extract": "^6.2.2",
"@pixi/filter-adjustment": "^4.1.3",
"@pixi/tilemap": "^3.2.2",
"pako": "^2.0.4",
"pixi.js": "^6.1.3",
"tslib": "^2.3.1"
"pixi.js": "^6.2.2"
},
"devDependencies": {
"@types/pako": "^1.0.2",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"eslint": "^7.32.0",
"typescript": "^4.4.4"
"@types/pako": "^1.0.3",
"@typescript-eslint/eslint-plugin": "^5.13.0",
"@typescript-eslint/parser": "^5.13.0",
"eslint": "^8.10.0",
"tslib": "^2.3.1",
"typescript": "~4.4.4"
}
}

34
post-install.js Normal file
View File

@ -0,0 +1,34 @@
import { request as httpsRequest } from 'https';
function install()
{
try
{
const params = {};
params['packageName'] = process.env.npm_package_name;
params['packageVersion'] = process.env.npm_package_version;
const data = JSON.stringify(params);
const request = httpsRequest({
hostname: 'install.nitrots.co',
port: 443,
path: '/collect',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
});
request.write(data);
request.end();
}
catch (e)
{
//
}
}
install();

View File

@ -6,7 +6,7 @@ import { ICommunicationManager } from './communication/ICommunicationManager';
import { ConfigurationManager } from './configuration/ConfigurationManager';
import { IConfigurationManager } from './configuration/IConfigurationManager';
import { INitroCore } from './INitroCore';
import { NitroVersion } from './NitroVersion';
import { SayHello } from './utils/SayHello';
export class NitroCore extends Disposable implements INitroCore
{
@ -18,9 +18,7 @@ export class NitroCore extends Disposable implements INitroCore
{
super();
window.console.log.apply(console, [
`\n%c _ ___ __ \n / | / (_) /__________ \n / |/ / / __/ ___/ __ \\ \n / /| / / /_/ / / /_/ / \n /_/ |_/_/\\__/_/ \\____/ \n \n Thanks for using Nitro \n To report bugs or issues \n join us on Discord \n https://nitrots.co/discord \n \n Renderer: v${ NitroVersion.RENDERER_VERSION } \n UI: v${ NitroVersion.UI_VERSION } \n \n`,
'color: #FFFFFF; background: #000000; padding:0px 0;' ]);
SayHello();
this._configuration = new ConfigurationManager();
this._communication = new CommunicationManager();

View File

@ -1,5 +1,5 @@
export class NitroVersion
{
public static RENDERER_VERSION: string = '1.1.0';
public static RENDERER_VERSION: string = '1.1.5';
public static UI_VERSION: string = '';
}

View File

@ -1,4 +1,4 @@
import { BaseTexture, Resource, Texture } from '@pixi/core';
import { Resource, Texture } from '@pixi/core';
import { Loader, LoaderResource } from '@pixi/loaders';
import { Spritesheet } from '@pixi/spritesheet';
import { IGraphicAsset } from '../../room';
@ -170,7 +170,7 @@ export class AssetManager extends Disposable implements IAssetManager
const nitroBundle = new NitroBundle(resource.data);
const assetData = (nitroBundle.jsonFile as IAssetData);
if(!assetData || !assetData.type)
if(!assetData)
{
onDownloaded(loader, resource, false);
@ -231,77 +231,7 @@ export class AssetManager extends Disposable implements IAssetManager
onDownloaded(loader, resource, true);
}
else if(resource.type === LoaderResource.TYPE.JSON)
{
const assetData = (resource.data as IAssetData);
if(!assetData || !assetData.type)
{
onDownloaded(loader, resource, false);
return;
}
if(assetData.spritesheet && Object.keys(assetData.spritesheet).length)
{
const imageName = (assetData.spritesheet.meta && assetData.spritesheet.meta.image);
if(!imageName || !imageName.length)
{
onDownloaded(loader, resource, false);
return;
}
const imageUrl = (resource.url.substring(0, (resource.url.lastIndexOf('/') + 1)) + imageName);
const baseTexture = BaseTexture.from(imageUrl);
if(baseTexture.valid)
{
const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet);
spritesheet.parse(() =>
{
this.createCollection(assetData, spritesheet);
onDownloaded(loader, resource, true);
});
}
else
{
baseTexture.once('loaded', () =>
{
baseTexture.removeAllListeners();
const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet);
spritesheet.parse(() =>
{
this.createCollection(assetData, spritesheet);
onDownloaded(loader, resource, true);
});
});
baseTexture.once('error', () =>
{
baseTexture.removeAllListeners();
onDownloaded(loader, resource, false);
});
}
return;
}
this.createCollection(assetData, null);
onDownloaded(loader, resource, true);
return;
}
if(resource.type === LoaderResource.TYPE.IMAGE)
else if(resource.type === LoaderResource.TYPE.IMAGE)
{
if(resource.texture.valid)
{

View File

@ -39,7 +39,7 @@ export class NitroLogger implements INitroLogger
public static log(message: string, name: string = 'Nitro', modus: string = null): void
{
const logString = `[Nitro] ${ new Date().toDateString() } [${ name }] ${ message } ${ this.getTimestamp() }`;
const logString = `[Nitro] [${ name }] ${ message } ${ this.getTimestamp() }`;
switch(modus)
{

View File

@ -7,7 +7,7 @@ import { ICommunicationManager } from './ICommunicationManager';
export class CommunicationManager extends Disposable implements ICommunicationManager, IUpdateReceiver
{
private _connections: IConnection[]
private _connections: IConnection[];
constructor()
{

View File

@ -301,9 +301,12 @@ export class SocketConnection extends EventDispatcher implements IConnection
try
{
const parser = events[0].parser;
//@ts-ignore
const parser = new events[0].parserClass();
if(!parser || !parser.flush() || !parser.parse(wrapper)) return null;
for(const event of events) (event.parser = parser);
}
catch (e)

View File

@ -67,13 +67,6 @@ export class MessageClassManager
existing = [];
this._messageInstancesById.set(header, existing);
//@ts-ignore
event.parser = new event.parserClass();
}
else
{
event.parser = existing[0].parser;
}
existing.push(event);

View File

@ -1,44 +1,29 @@
import { NitroManager } from '../common/NitroManager';
import { AdvancedMap } from '../utils/AdvancedMap';
import { ConfigurationEvent } from './ConfigurationEvent';
import { IConfigurationManager } from './IConfigurationManager';
export class ConfigurationManager extends NitroManager implements IConfigurationManager
{
private _definitions: AdvancedMap<string, unknown>;
private _definitions: Map<string, unknown>;
private _pendingUrls: string[];
private _missingKeys: string[];
constructor()
{
super();
this._definitions = new AdvancedMap();
this._definitions = new Map();
this._pendingUrls = [];
this._missingKeys = [];
this.onConfigurationLoaded = this.onConfigurationLoaded.bind(this);
}
protected onInit(): void
{
//@ts-ignore
let urls: string[] = NitroConfig.configurationUrls;
this.parseConfiguration(this.getDefaultConfig(), true);
if(!urls || !urls.length)
{
//@ts-ignore
const url: string = NitroConfig.configurationUrl;
if(url && url.length) urls = [ url ];
}
if(!urls || !urls.length)
{
this.dispatchConfigurationEvent(ConfigurationEvent.FAILED);
return;
}
this._pendingUrls = urls;
this._pendingUrls = this.getValue<string[]>('config.urls').slice();
this.loadNextConfiguration();
}
@ -98,7 +83,7 @@ export class ConfigurationManager extends NitroManager implements IConfiguration
this.events && this.events.dispatchEvent(new ConfigurationEvent(type));
}
private parseConfiguration(data: { [index: string]: any }): boolean
private parseConfiguration(data: { [index: string]: any }, overrides: boolean = false): boolean
{
if(!data) return false;
@ -110,12 +95,16 @@ export class ConfigurationManager extends NitroManager implements IConfiguration
{
let value = data[key];
if(typeof value === 'string')
{
value = this.interpolate((value as string), regex);
}
if(typeof value === 'string') value = this.interpolate((value as string), regex);
this._definitions.add(key, value);
if(this._definitions.has(key))
{
if(overrides) this.setValue(key, value);
}
else
{
this.setValue(key, value);
}
}
return true;
@ -139,7 +128,7 @@ export class ConfigurationManager extends NitroManager implements IConfiguration
{
for(const piece of pieces)
{
const existing = (this._definitions.getValue(this.removeInterpolateKey(piece)) as string);
const existing = (this._definitions.get(this.removeInterpolateKey(piece)) as string);
if(existing) (value = value.replace(piece, existing));
}
@ -155,10 +144,13 @@ export class ConfigurationManager extends NitroManager implements IConfiguration
public getValue<T>(key: string, value: T = null): T
{
let existing = this._definitions.getValue(key);
let existing = this._definitions.get(key);
if(existing === undefined)
{
if(this._missingKeys.indexOf(key) >= 0) return value;
this._missingKeys.push(key);
this.logger.warn(`Missing configuration key: ${ key }`);
existing = value;
@ -169,6 +161,12 @@ export class ConfigurationManager extends NitroManager implements IConfiguration
public setValue(key: string, value: string): void
{
this._definitions.add(key, value);
this._definitions.set(key, value);
}
public getDefaultConfig(): { [index: string]: any }
{
//@ts-ignore
return NitroConfig as { [index: string]: any };
}
}

View File

@ -0,0 +1,93 @@
import { NitroBaseTexture, NitroFilter } from './proxy';
const vertex = `
attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat3 projectionMatrix;
varying vec2 vTextureCoord;
void main(void)
{
gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
vTextureCoord = aTextureCoord;
}`;
const fragment = `
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
uniform sampler2D lut;
uniform int channel;
void main(void) {
vec4 currentColor = texture2D(uSampler, vTextureCoord);
vec4 adjusted = currentColor;
if(currentColor.a > 0.0)
{
if(channel == 0)
{
adjusted = texture2D(lut, vec2((currentColor.r * 255.0 + 0.5) / 256.0, 0.5));
} else if(channel == 1) {
adjusted = texture2D(lut, vec2((currentColor.g * 255.0 + 0.5) / 256.0, 0.5));
} else if(channel == 2) {
adjusted = texture2D(lut, vec2((currentColor.b * 255.0 + 0.5) / 256.0, 0.5));
} else if(channel == 3) {
adjusted = texture2D(lut, vec2((currentColor.a * 255.0 + 0.5) / 256.0, 0.5));
}
}
gl_FragColor = vec4(adjusted.r, adjusted.g, adjusted.b, currentColor.a);
}`;
export class PaletteMapFilter extends NitroFilter
{
public static readonly CHANNEL_RED = 0;
public static readonly CHANNEL_GREEN = 1;
public static readonly CHANNEL_BLUE = 2;
public static readonly CHANNEL_ALPHA = 3;
private _lut: NitroBaseTexture;
private _channel: number;
constructor(palette: number[], channel = PaletteMapFilter.CHANNEL_RED)
{
super(vertex, fragment);
this._channel = channel;
let lut: number[] = [];
lut = this.getLutForPalette(palette);
this._lut = NitroBaseTexture.fromBuffer(Uint8Array.from(lut), lut.length / 4, 1, { mipmap: 0, scaleMode: 0 });
this.uniforms.lut = this._lut;
this.uniforms.channel = this._channel;
}
private getLutForPalette(data: number[]): number[]
{
const lut = [];
for(let i = 0; i < data.length; i++)
{
// R
lut[(i * 4) + PaletteMapFilter.CHANNEL_RED] = ((data[i] >> 16) & 0xFF);
// G
lut[(i * 4) + PaletteMapFilter.CHANNEL_GREEN] = ((data[i] >> 8) & 0xFF);
// B
lut[(i * 4) + PaletteMapFilter.CHANNEL_BLUE] = (data[i] & 0xFF);
// A
lut[(i * 4) + PaletteMapFilter.CHANNEL_ALPHA] = ((data[i] >> 24) & 0xFF);
}
return lut;
}
public get lut(): NitroBaseTexture
{
return this._lut;
}
public get channel(): number
{
return this._channel;
}
}

View File

@ -0,0 +1,26 @@
import { NitroVersion } from '..';
export const SayHello = () =>
{
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1)
{
const args = [
`\n %c %c %c Nitro ${ NitroVersion.UI_VERSION } - Renderer ${ NitroVersion.RENDERER_VERSION } %c %c %c https://nitrots.co/discord %c %c \n\n`,
'background: #ffffff; padding:5px 0;',
'background: #ffffff; padding:5px 0;',
'color: #ffffff; background: #000000; padding:5px 0;',
'background: #ffffff; padding:5px 0;',
'background: #ffffff; padding:5px 0;',
'background: #000000; padding:5px 0;',
'background: #ffffff; padding:5px 0;',
'background: #ffffff; padding:5px 0;'
];
self.console.log(...args);
}
else if(self.console)
{
self.console.log(`Nitro ${ NitroVersion.UI_VERSION } - Renderer ${ NitroVersion.RENDERER_VERSION } `);
}
};

View File

@ -0,0 +1,4 @@
import { Polygon } from '@pixi/math';
export class NitroPolygon extends Polygon
{}

View File

@ -5,6 +5,7 @@ export * from './NitroBaseTexture';
export * from './NitroContainer';
export * from './NitroFilter';
export * from './NitroPoint';
export * from './NitroPolygon';
export * from './NitroRectangle';
export * from './NitroRenderTexture';
export * from './NitroSprite';

View File

@ -124,11 +124,6 @@ export class Nitro extends Application implements INitro
});
canvas.addEventListener('webglcontextlost', () => instance.events.dispatchEvent(new NitroEvent(Nitro.WEBGL_CONTEXT_LOST)));
//@ts-ignore
const sso = (NitroConfig.sso as string);
instance.communication.demo.setSSO(sso);
}
public init(): void

View File

@ -5,6 +5,7 @@ import { Rectangle } from '@pixi/math';
import { Sprite } from '@pixi/sprite';
import { NitroContainer, NitroSprite } from '../../core';
import { AdvancedMap } from '../../core/utils/AdvancedMap';
import { PaletteMapFilter } from '../../core/utils/PaletteMapFilter';
import { IGraphicAsset } from '../../room/object/visualization/utils/IGraphicAsset';
import { TextureUtils } from '../../room/utils/TextureUtils';
import { Nitro } from '../Nitro';
@ -391,7 +392,19 @@ export class AvatarImage implements IAvatarImage, IAvatarEffectListener
partCount--;
}
if(this._avatarSpriteData && this._avatarSpriteData.paletteIsGrayscale) this.convertToGrayscale(container);
if(this._avatarSpriteData)
{
if(!container.filters) container.filters = [];
if(this._avatarSpriteData.colorTransform) container.filters.push(this._avatarSpriteData.colorTransform);
if(this._avatarSpriteData.paletteIsGrayscale)
{
this.convertToGrayscale(container);
container.filters.push(new PaletteMapFilter(this._avatarSpriteData.reds, PaletteMapFilter.CHANNEL_RED));
}
}
if(!cache)
{
@ -412,10 +425,15 @@ export class AvatarImage implements IAvatarImage, IAvatarEffectListener
if(!this._reusableTexture) return null;
if(this._avatarSpriteData && this._avatarSpriteData.paletteIsGrayscale)
/*
if(this._avatarSpriteData)
{
//this._reusableTexture = this.applyPalette(this._reusableTexture, this._avatarSpriteData.reds);
if(this._avatarSpriteData.paletteIsGrayscale)
{
this._reusableTexture = this.applyPalette(this._reusableTexture, this._avatarSpriteData.reds, [], []);
}
}
*/
this._image = this._reusableTexture;
this._changes = false;
@ -423,28 +441,56 @@ export class AvatarImage implements IAvatarImage, IAvatarEffectListener
return this._image;
}
// public applyPalette(texture: RenderTexture, reds: number[] = [], greens: number[] = [], blues: number[] = []): RenderTexture
// {
// const textureCanvas = Nitro.instance.renderer.extract.canvas(texture);
// const textureCtx = textureCanvas.getContext('2d');
// const textureImageData = textureCtx.getImageData(0, 0, textureCanvas.width, textureCanvas.height);
// const data = textureImageData.data;
public applyPalette(texture: RenderTexture, reds: number[] = [], greens: number[] = [], blues: number[] = []): RenderTexture
{
const textureCanvas = TextureUtils.generateCanvas(texture);
const textureCtx = textureCanvas.getContext('2d');
const textureImageData = textureCtx.getImageData(0, 0, textureCanvas.width, textureCanvas.height);
const data = textureImageData.data;
// for(const i = 0; i < data.length; i += 4)
// {
// let paletteColor = this._palette[data[ i + 1 ]];
for(let i = 0; i < data.length; i += 4)
{
if(reds.length == 256)
{
let paletteColor = reds[ data[i] ];
if(paletteColor === undefined) paletteColor = 0;
// if(paletteColor === undefined) paletteColor = [ 0, 0, 0 ];
data[ i ] = ((paletteColor >> 16) & 0xFF);
data[ i + 1] = ((paletteColor >> 8) & 0xFF);
data[ i + 2] = (paletteColor & 0xFF);
}
// data[ i ] = paletteColor[0];
// data[ i + 1 ] = paletteColor[1];
// data[ i + 2 ] = paletteColor[2];
// }
if(greens.length == 256)
{
let paletteColor = greens[ data[i + 1] ];
if(paletteColor === undefined) paletteColor = 0;
// textureCtx.putImageData(textureImageData, 0, 0);
data[ i ] = ((paletteColor >> 16) & 0xFF);
data[ i + 1] = ((paletteColor >> 8) & 0xFF);
data[ i + 2] = (paletteColor & 0xFF);
}
if(blues.length == 256)
{
let paletteColor = greens[ data[i + 2] ];
if(paletteColor === undefined) paletteColor = 0;
// return Texture.from(textureCanvas);
// }
data[ i ] = ((paletteColor >> 16) & 0xFF);
data[ i + 1] = ((paletteColor >> 8) & 0xFF);
data[ i + 2] = (paletteColor & 0xFF);
}
}
textureCtx.putImageData(textureImageData, 0, 0);
const newTexture = new Sprite(Texture.from(textureCanvas));
Nitro.instance.renderer.render(newTexture, {
renderTexture: texture,
clear: true
});
return texture;
}
public getImageAsSprite(setType: string, scale: number = 1): Sprite
{
@ -1019,7 +1065,7 @@ export class AvatarImage implements IAvatarImage, IAvatarEffectListener
colorFilter.matrix = [_local_3, _local_4, _local_5, 0, 0, _local_3, _local_4, _local_5, 0, 0, _local_3, _local_4, _local_5, 0, 0, 0, 0, 0, 1, 0];
container.filters = [ colorFilter ];
container.filters.push(colorFilter);
return container;
}

View File

@ -48,6 +48,7 @@ export class AvatarDataContainer implements IAvatarDataContainer
this._paletteIsGrayscale = false;
}
this._colorTransform = new AdjustmentFilter({ red: (this._r / 255), green: (this._g / 255), blue: (this._b / 255), alpha: this._alphaMultiplier });
this._colorMap = this.generatePaletteMapForGrayscale(this._backGround, this._foreGround);
}
@ -86,45 +87,44 @@ export class AvatarDataContainer implements IAvatarDataContainer
return this._paletteIsGrayscale;
}
private generatePaletteMapForGrayscale(k: number, _arg_2: number): Map<string, number[]>
private generatePaletteMapForGrayscale(background: number, foreground: number): Map<string, number[]>
{
const _local_3 = ((k >> 24) & 0xFF);
const _local_4 = ((k >> 16) & 0xFF);
const _local_5 = ((k >> 8) & 0xFF);
const _local_6 = ((k >> 0) & 0xFF);
const _local_7 = ((_arg_2 >> 24) & 0xFF);
const _local_8 = ((_arg_2 >> 16) & 0xFF);
const _local_9 = ((_arg_2 >> 8) & 0xFF);
const _local_10 = ((_arg_2 >> 0) & 0xFF);
const _local_11 = ((_local_7 - _local_3) / 0xFF);
const _local_12 = ((_local_8 - _local_4) / 0xFF);
const _local_13 = ((_local_9 - _local_5) / 0xFF);
const _local_14 = ((_local_10 - _local_6) / 0xFF);
const alphaBackground = ((background >> 24) & 0xFF);
const redBackground = ((background >> 16) & 0xFF);
const greenBackground = ((background >> 8) & 0xFF);
const blueBackground = ((background >> 0) & 0xFF);
const alphaForeground = ((foreground >> 24) & 0xFF);
const redForeground = ((foreground >> 16) & 0xFF);
const greenForeground = ((foreground >> 8) & 0xFF);
const blueForeground = ((foreground >> 0) & 0xFF);
const alphaDifference = ((alphaForeground - alphaBackground) / 0xFF);
const redDifference = ((redForeground - redBackground) / 0xFF);
const greenDifference = ((greenForeground - greenBackground) / 0xFF);
const blueDifference = ((blueForeground - blueBackground) / 0xFF);
const _local_15: Map<string, number[]> = new Map();
const _local_16: number[] = [];
const _local_17: number[] = [];
const _local_18: number[] = [];
const _local_19: number[] = [];
let _local_20 = _local_3;
let _local_21 = _local_4;
let _local_22 = _local_5;
let _local_23 = _local_6;
let _local_24 = 0;
while(_local_24 < 0x0100)
let _local_20 = alphaBackground;
let _local_21 = redBackground;
let _local_22 = greenBackground;
let _local_23 = blueBackground;
for(let i = 0; i < 256; i++)
{
if((((_local_21 == _local_4) && (_local_22 == _local_5)) && (_local_23 == _local_6)))
if((((_local_21 == redBackground) && (_local_22 == greenBackground)) && (_local_23 == blueBackground)))
{
_local_20 = 0;
}
_local_20 = (_local_20 + _local_11);
_local_21 = (_local_21 + _local_12);
_local_22 = (_local_22 + _local_13);
_local_23 = (_local_23 + _local_14);
_local_20 = (_local_20 + alphaDifference);
_local_21 = (_local_21 + redDifference);
_local_22 = (_local_22 + greenDifference);
_local_23 = (_local_23 + blueDifference);
_local_19.push((_local_20 << 24));
_local_16.push(((((_local_20 << 24) | (_local_21 << 16)) | (_local_22 << 8)) | _local_23));
_local_17.push(((((_local_20 << 24) | (_local_21 << 16)) | (_local_22 << 8)) | _local_23));
_local_18.push(((((_local_20 << 24) | (_local_21 << 16)) | (_local_22 << 8)) | _local_23));
_local_24++;
}
_local_15.set('alphas', _local_16);

File diff suppressed because one or more lines are too long

View File

@ -16,7 +16,6 @@ export class NitroCommunicationDemo extends NitroManager
{
private _communication: INitroCommunicationManager;
private _sso: string;
private _handShaking: boolean;
private _didConnect: boolean;
@ -28,7 +27,6 @@ export class NitroCommunicationDemo extends NitroManager
this._communication = communication;
this._sso = null;
this._handShaking = false;
this._didConnect = false;
@ -66,7 +64,6 @@ export class NitroCommunicationDemo extends NitroManager
connection.removeEventListener(SocketConnectionEvent.CONNECTION_ERROR, this.onConnectionErrorEvent);
}
this._sso = null;
this._handShaking = false;
this.stopPonging();
@ -117,9 +114,9 @@ export class NitroCommunicationDemo extends NitroManager
private tryAuthentication(connection: IConnection): void
{
if(!connection || !this._sso)
if(!connection || !this.getSSO())
{
if(!this._sso)
if(!this.getSSO())
{
NitroLogger.log('Login without an SSO ticket is not supported');
}
@ -129,7 +126,7 @@ export class NitroCommunicationDemo extends NitroManager
return;
}
connection.send(new SSOTicketMessageComposer(this._sso, Nitro.instance.time));
connection.send(new SSOTicketMessageComposer(this.getSSO(), Nitro.instance.time));
}
private onClientPingEvent(event: ClientPingEvent): void
@ -147,18 +144,9 @@ export class NitroCommunicationDemo extends NitroManager
this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED, event.connection);
//event.connection.send(new UserHomeRoomComposer(555));
event.connection.send(new InfoRetrieveMessageComposer());
}
public setSSO(sso: string): void
{
if(!sso || (sso === '') || this._sso) return;
this._sso = sso;
}
private startHandshake(connection: IConnection): void
{
this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_HANDSHAKING, connection);
@ -202,4 +190,9 @@ export class NitroCommunicationDemo extends NitroManager
{
Nitro.instance.events.dispatchEvent(new NitroCommunicationDemoEvent(type, connection));
}
private getSSO(): string
{
return Nitro.instance.getConfiguration('sso.ticket', null);
}
}

View File

@ -363,4 +363,6 @@ export class IncomingHeader
public static CHAT_REVIEW_SESSION_STARTED = 143;
public static CHAT_REVIEW_SESSION_VOTING_STATUS = 1829;
public static SCR_SEND_KICKBACK_INFO = 3277;
public static PET_STATUS = 1907;
public static GROUP_DEACTIVATE = 3129;
}

View File

@ -0,0 +1,4 @@
export * from './CraftableProductsEvent';
export * from './CraftingRecipeEvent';
export * from './CraftingRecipesAvailableEvent';
export * from './CraftingResultEvent';

View File

@ -0,0 +1,16 @@
import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent';
import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent';
import { HabboGroupDeactivatedMessageParser } from '../../parser/group/HabboGroupDeactivatedMessageParser';
export class HabboGroupDeactivatedMessageEvent extends MessageEvent implements IMessageEvent
{
constructor(callBack: Function)
{
super(callBack, HabboGroupDeactivatedMessageParser);
}
public getParser(): HabboGroupDeactivatedMessageParser
{
return this.parser as HabboGroupDeactivatedMessageParser;
}
}

View File

@ -6,3 +6,4 @@ export * from './GroupInformationEvent';
export * from './GroupMembersEvent';
export * from './GroupPurchasedEvent';
export * from './GroupSettingsEvent';
export * from './HabboGroupDeactivatedMessageEvent';

View File

@ -7,6 +7,7 @@ export * from './camera';
export * from './campaign';
export * from './catalog';
export * from './client';
export * from './crafting';
export * from './desktop';
export * from './friendlist';
export * from './game';

View File

@ -7,7 +7,7 @@ export class CfhChatlogData
private _callerUserId: number;
private _reportedUserId: number;
private _chatRecordId: number;
private _chatRecord: ChatRecordData
private _chatRecord: ChatRecordData;
constructor(k:IMessageDataWrapper)
{

View File

@ -0,0 +1,16 @@
import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent';
import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent';
import { PetStatusUpdateParser } from '../../../parser/room/pet/PetStatusUpdateParser';
export class PetStatusUpdateEvent extends MessageEvent implements IMessageEvent
{
constructor(callBack: Function)
{
super(callBack, PetStatusUpdateParser);
}
public getParser(): PetStatusUpdateParser
{
return this.parser as PetStatusUpdateParser;
}
}

View File

@ -186,6 +186,7 @@ export class OutgoingHeader
public static USER_IGNORED = 3878;
public static USER_PETS = 3095;
public static USER_PROFILE = 3265;
public static USER_PROFILE_BY_NAME = 2249;
public static USER_RESPECT = 2694;
public static GET_SOUND_SETTINGS = 2388;
public static USER_SETTINGS_CAMERA = 1461;
@ -366,7 +367,7 @@ export class OutgoingHeader
public static GUIDE_SESSION_GUIDE_DECIDES = 1424;
public static GUIDE_SESSION_INVITE_REQUESTER = 234;
public static GUIDE_SESSION_IS_TYPING = 519;
public static GUIDE_SESSION_MESSAGE = 3899
public static GUIDE_SESSION_MESSAGE = 3899;
public static GUIDE_SESSION_ON_DUTY_UPDATE = 1922;
public static GUIDE_SESSION_REPORT = 3969;
public static GUIDE_SESSION_REQUESTER_CANCELS = 291;
@ -378,4 +379,6 @@ export class OutgoingHeader
public static POLL_START = 109;
public static DISCONNECT = 2445;
public static SCR_GET_KICKBACK_INFO = 869;
public static COMPOST_PLANT = 3835;
public static HARVEST_PET = 1521;
}

View File

@ -4,7 +4,7 @@ export class GetCraftableProductsComposer implements IMessageComposer<Constructo
{
private _data: ConstructorParameters<typeof GetCraftableProductsComposer>;
constructor(k: string)
constructor(k: number)
{
this._data = [k];
}

View File

@ -4,7 +4,7 @@ export class GetCraftingRecipeComposer implements IMessageComposer<ConstructorPa
{
private _data: ConstructorParameters<typeof GetCraftingRecipeComposer>;
constructor(k: number)
constructor(k: string)
{
this._data = [k];
}

View File

@ -0,0 +1,5 @@
export * from './CraftComposer';
export * from './CraftSecretComposer';
export * from './GetCraftableProductsComposer';
export * from './GetCraftingRecipeComposer';
export * from './GetCraftingRecipesAvailableComposer';

View File

@ -4,6 +4,7 @@ export * from './camera';
export * from './campaign';
export * from './catalog';
export * from './competition';
export * from './crafting';
export * from './desktop';
export * from './friendfurni';
export * from './friendlist';

View File

@ -0,0 +1,9 @@
import { PetMessageComposer } from './PetMessageComposer';
export class CompostPlantMessageComposer extends PetMessageComposer
{
constructor(id: number)
{
super(id);
}
}

View File

@ -0,0 +1,9 @@
import { PetMessageComposer } from './PetMessageComposer';
export class HarvestPetMessageComposer extends PetMessageComposer
{
constructor(id: number)
{
super(id);
}
}

View File

@ -0,0 +1,21 @@
import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer';
export class PetMessageComposer implements IMessageComposer<ConstructorParameters<typeof PetMessageComposer>>
{
private _data: ConstructorParameters<typeof PetMessageComposer>;
constructor(id: number)
{
this._data = [ id ];
}
public getMessageArray()
{
return this._data;
}
public dispose(): void
{
return;
}
}

View File

@ -1,7 +1,10 @@
export * from './BotPlaceComposer';
export * from './BotRemoveComposer';
export * from './BotSkillSaveComposer';
export * from './CompostPlantMessageComposer';
export * from './GetItemDataComposer';
export * from './HarvestPetMessageComposer';
export * from './PetMessageComposer';
export * from './PetMoveComposer';
export * from './PetPlaceComposer';
export * from './PetRemoveComposer';

View File

@ -0,0 +1,21 @@
import { IMessageComposer } from '../../../../../../core';
export class GetExtendedProfileByNameMessageComposer implements IMessageComposer<ConstructorParameters<typeof GetExtendedProfileByNameMessageComposer>>
{
private _data: ConstructorParameters<typeof GetExtendedProfileByNameMessageComposer>;
constructor(username: string)
{
this._data = [ username ];
}
public getMessageArray()
{
return this._data;
}
public dispose(): void
{
return;
}
}

View File

@ -1,3 +1,4 @@
export * from './GetExtendedProfileByNameMessageComposer';
export * from './GetIgnoredUsersComposer';
export * from './IgnoreUserComposer';
export * from './IgnoreUserIdComposer';

View File

@ -0,0 +1,6 @@
export * from './CraftableProductsMessageParser';
export * from './CraftingRecipeIngredientParser';
export * from './CraftingRecipeMessageParser';
export * from './CraftingRecipesAvailableMessageParser';
export * from './CraftingResultMessageParser';
export * from './CraftingResultObjectParser';

View File

@ -0,0 +1,24 @@
import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper';
import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser';
export class HabboGroupDeactivatedMessageParser implements IMessageParser
{
private _groupId: number;
public flush():boolean
{
return true;
}
public parse(wrapper: IMessageDataWrapper):boolean
{
this._groupId = wrapper.readInt();
return true;
}
public get groupId(): number
{
return this._groupId;
}
}

View File

@ -6,4 +6,5 @@ export * from './GroupInformationParser';
export * from './GroupMembersParser';
export * from './GroupPurchasedParser';
export * from './GroupSettingsParser';
export * from './HabboGroupDeactivatedMessageParser';
export * from './utils';

View File

@ -1,91 +0,0 @@
import { IMessageDataWrapper } from '../../../../../../core';
export class GroupDataParser
{
private _id: number;
private _title: string;
private _badge: string;
private _colorA: string;
private _colorB: string;
private _ownerOrFavorite: boolean;
private _ownerId: number;
private _hasForum: boolean;
constructor(wrapper: IMessageDataWrapper)
{
if(!wrapper) throw new Error('invalid_wrapper');
this.flush();
this.parse(wrapper);
}
public flush(): boolean
{
this._id = 0;
this._title = null;
this._badge = null;
this._colorA = null;
this._colorB = null;
this._ownerOrFavorite = null;
this._ownerId = 0;
this._hasForum = false;
return true;
}
public parse(wrapper: IMessageDataWrapper): boolean
{
if(!wrapper) return false;
this._id = wrapper.readInt();
this._title = wrapper.readString();
this._badge = wrapper.readString();
this._colorA = wrapper.readString();
this._colorB = wrapper.readString();
this._ownerOrFavorite = wrapper.readBoolean();
this._ownerId = wrapper.readInt();
this._hasForum = wrapper.readBoolean();
return true;
}
public get id(): number
{
return this._id;
}
public get title(): string
{
return this._title;
}
public get badge(): string
{
return this._badge;
}
public get colorA(): string
{
return this._colorA;
}
public get colorB(): string
{
return this._colorB;
}
public get ownerOrFavorite(): boolean
{
return this._ownerOrFavorite;
}
public get ownerId(): number
{
return this._ownerId;
}
public get hasForum(): boolean
{
return this._hasForum;
}
}

View File

@ -1,3 +1,2 @@
export * from './GroupDataBadgePart';
export * from './GroupDataParser';
export * from './GroupMemberParser';

View File

@ -3,11 +3,12 @@ import { IMessageDataWrapper, IMessageParser } from '../../../../../core';
export class IssueCloseNotificationMessageParser implements IMessageParser
{
private _closeReason: number;
private _messageText: string;
public flush(): boolean
{
this._closeReason = 0;
this._messageText = '';
return true;
}
@ -16,6 +17,7 @@ export class IssueCloseNotificationMessageParser implements IMessageParser
if(!wrapper) return false;
this._closeReason = wrapper.readInt();
this._messageText = wrapper.readString();
return true;
}
@ -24,4 +26,9 @@ export class IssueCloseNotificationMessageParser implements IMessageParser
{
return this._closeReason;
}
public get messageText(): string
{
return this._messageText;
}
}

View File

@ -8,6 +8,7 @@ export * from './campaign';
export * from './catalog';
export * from './client';
export * from './competition';
export * from './crafting';
export * from './desktop';
export * from './friendlist';
export * from './game';

View File

@ -3,7 +3,7 @@
export class FigureSetIdsMessageParser implements IMessageParser
{
private _figureSetIds: number[];
private _boundFurnitureNames: string[]
private _boundFurnitureNames: string[];
public flush(): boolean
{

View File

@ -2,7 +2,7 @@ import { IMessageDataWrapper, IMessageParser } from '../../../../../core';
export class MOTDNotificationParser implements IMessageParser
{
private _messages: string[]
private _messages: string[];
public flush(): boolean
{

View File

@ -10,7 +10,7 @@ export class PollContentsParser implements IMessageParser
private _endMessage = '';
private _numQuestions = 0;
private _questionArray:PollQuestion[] = [];
private _npsPoll = false
private _npsPoll = false;
flush(): boolean
{

View File

@ -0,0 +1,67 @@
import { IMessageDataWrapper, IMessageParser } from '../../../../../../core';
export class PetStatusUpdateParser implements IMessageParser
{
private _roomIndex: number;
private _petId: number;
private _canBreed: boolean;
private _canHarvest: boolean;
private _canRevive: boolean;
private _hasBreedingPermission: boolean;
public flush(): boolean
{
this._roomIndex = -1;
this._petId = -1;
this._canBreed = false;
this._canHarvest = false;
this._canRevive = false;
this._hasBreedingPermission = false;
return true;
}
public parse(wrapper: IMessageDataWrapper): boolean
{
if(!wrapper) return false;
this._roomIndex = wrapper.readInt();
this._petId = wrapper.readInt();
this._canBreed = wrapper.readBoolean();
this._canHarvest = wrapper.readBoolean();
this._canRevive = wrapper.readBoolean();
this._hasBreedingPermission = wrapper.readBoolean();
return true;
}
public get roomIndex(): number
{
return this._roomIndex;
}
public get petId(): number
{
return this._petId;
}
public get canBreed(): boolean
{
return this._canBreed;
}
public get canHarvest(): boolean
{
return this._canHarvest;
}
public get canRevive(): boolean
{
return this._canRevive;
}
public get hasBreedingPermission(): boolean
{
return this._hasBreedingPermission;
}
}

View File

@ -1,3 +1,4 @@
export * from './PetExperienceParser';
export * from './PetFigureUpdateParser';
export * from './PetInfoParser';
export * from './PetStatusUpdateParser';

View File

@ -61,53 +61,99 @@ export class RoomUnitStatusParser implements IMessageParser
if(actions)
{
const actionParts = actions.split('/');
const totalActions = actionParts.length;
const statusActions: RoomUnitStatusAction[] = [];
if(totalActions)
for(const action of actionParts)
{
for(let i = 0; i < totalActions; i++)
const parts = action.split(' ');
if(parts[0] === '') continue;
if(parts.length >= 2)
{
const action = actionParts[i];
if(!action) continue;
const [ key, value, extra ] = action.split(' ');
if(!key || !value) continue;
switch(key)
switch(parts[0])
{
case 'mv':
[ targetX, targetY, targetZ ] = value.split(',').map(a => parseFloat(a));
case 'mv': {
const values = parts[1].split(',');
if(values.length >= 3)
{
targetX = parseInt(values[0]);
targetY = parseInt(values[1]);
targetZ = parseFloat(values[2]);
didMove = true;
}
break;
}
case 'sit': {
const sitHeight = parseFloat(value);
const sitHeight = parseFloat(parts[1]);
if(extra !== undefined) canStandUp = value === '1';
if(parts.length >= 3) canStandUp = (parts[2] === '1');
height = sitHeight;
break;
}
case 'lay': {
const layHeight = parseFloat(value);
const layHeight = parseFloat(parts[1]);
height = layHeight;
height = Math.abs(layHeight);
break;
}
}
statusActions.push(new RoomUnitStatusAction(key, value));
statusActions.push(new RoomUnitStatusAction(parts[0], parts[1]));
}
}
// const totalActions = actionParts.length;
// if(totalActions)
// {
// for(let i = 0; i < totalActions; i++)
// {
// const action = actionParts[i];
// if(!action) continue;
// console.log(action);
// const [ key, value, extra ] = action.split(' ');
// if(!key || !value) continue;
// switch(key)
// {
// case 'mv':
// [ targetX, targetY, targetZ ] = value.split(',').map(a => parseFloat(a));
// didMove = true;
// break;
// case 'sit': {
// const sitHeight = parseFloat(value);
// if(extra !== undefined) canStandUp = value === '1';
// height = sitHeight;
// break;
// }
// case 'lay': {
// const layHeight = parseFloat(value);
// height = layHeight;
// break;
// }
// }
// statusActions.push(new RoomUnitStatusAction(key, value));
// }
// }
this._statuses.push(new RoomUnitStatusMessage(unitId, x, y, z, height, headDirection, direction, targetX, targetY, targetZ, didMove, canStandUp, statusActions));
}
}

View File

@ -5,7 +5,7 @@ export class TalentTrackLevel
{
private _level: number;
private _state: number;
private _tasks: TalentTrackTask[]
private _tasks: TalentTrackTask[];
private _rewardPerks: string[];
private _rewardProducts: TalentTrackRewardProduct[];

View File

@ -1,5 +1,5 @@
import { IMessageDataWrapper, IMessageParser } from '../../../../../../core';
import { GroupDataParser } from '../../group/utils/GroupDataParser';
import { HabboGroupEntryData } from '../HabboGroupEntryData';
export class UserProfileParser implements IMessageParser
{
@ -13,7 +13,7 @@ export class UserProfileParser implements IMessageParser
private _isMyFriend: boolean;
private _requestSent: boolean;
private _isOnline: boolean;
private _groups: GroupDataParser[];
private _groups: HabboGroupEntryData[];
private _secondsSinceLastVisit: number;
private _openProfileWindow: boolean;
@ -54,7 +54,7 @@ export class UserProfileParser implements IMessageParser
for(let i = 0; i < groupsCount; i++)
{
this._groups.push(new GroupDataParser(wrapper));
this._groups.push(new HabboGroupEntryData(wrapper));
}
this._secondsSinceLastVisit = wrapper.readInt();
@ -113,7 +113,7 @@ export class UserProfileParser implements IMessageParser
return this._isOnline;
}
public get groups(): GroupDataParser[]
public get groups(): HabboGroupEntryData[]
{
return this._groups;
}

View File

@ -39,8 +39,35 @@ declare global
export class LegacyExternalInterface
{
private static readonly MESSAGE_KEY = 'Nitro_LegacyExternalInterface';
private static _isListeningForPostMessages = false;
public static get available(): boolean
{
if(!this._isListeningForPostMessages)
{
this._isListeningForPostMessages = true;
window.addEventListener('message', (ev) =>
{
if(typeof ev.data !== 'string') return;
if(ev.data.startsWith(LegacyExternalInterface.MESSAGE_KEY))
{
const { method, params } = JSON.parse(
ev.data.substr(LegacyExternalInterface.MESSAGE_KEY.length)
);
const fn = (window as any)[method];
if(!fn) return;
fn(...params);
return;
}
});
}
return true;
}
@ -51,7 +78,7 @@ export class LegacyExternalInterface
{
if(window.top !== window)
{
window.top.postMessage('Nitro_LegacyExternalInterface' + JSON.stringify({
window.top.postMessage(LegacyExternalInterface.MESSAGE_KEY + JSON.stringify({
method,
params
}), '*');

View File

@ -117,6 +117,8 @@ export class NitroLocalizationManager extends NitroManager implements INitroLoca
public getValue(key: string, doParams: boolean = true): string
{
if(!key || !key.length) return null;
if(key.startsWith('${')) key = key.substr(2, (key.length - 3));
let value = (this._definitions.get(key) || null);

View File

@ -1,4 +1,4 @@
import { BaseTexture, Resource, Texture } from '@pixi/core';
import { Resource, Texture } from '@pixi/core';
import { Loader, LoaderResource } from '@pixi/loaders';
import { Spritesheet } from '@pixi/spritesheet';
import { IAssetData } from '../../core/asset/interfaces';
@ -559,7 +559,7 @@ export class RoomContentLoader implements IFurnitureDataListener
const nitroBundle = new NitroBundle(resource.data);
const assetData = (nitroBundle.jsonFile as IAssetData);
if(!assetData || !assetData.type)
if(!assetData)
{
onDownloaded(loader, resource, false);
@ -619,74 +619,6 @@ export class RoomContentLoader implements IFurnitureDataListener
onDownloaded(loader, resource, true);
}
else if(resource.type === LoaderResource.TYPE.JSON)
{
const assetData = (resource.data as IAssetData);
if(!assetData.type)
{
onDownloaded(loader, resource, false);
return;
}
if(assetData.spritesheet && Object.keys(assetData.spritesheet).length)
{
const imageName = (assetData.spritesheet.meta && assetData.spritesheet.meta.image);
if(!imageName || !imageName.length)
{
onDownloaded(loader, resource, false);
return;
}
const imageUrl = (resource.url.substring(0, (resource.url.lastIndexOf('/') + 1)) + imageName);
const baseTexture = BaseTexture.from(imageUrl);
if(baseTexture.valid)
{
const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet);
spritesheet.parse(() =>
{
this.createCollection(assetData, spritesheet);
onDownloaded(loader, resource, true);
});
}
else
{
baseTexture.once('loaded', () =>
{
baseTexture.removeAllListeners();
const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet);
spritesheet.parse(() =>
{
this.createCollection(assetData, spritesheet);
onDownloaded(loader, resource, true);
});
});
baseTexture.once('error', () =>
{
baseTexture.removeAllListeners();
onDownloaded(loader, resource, false);
});
}
return;
}
this.createCollection(assetData, null);
onDownloaded(loader, resource, true);
}
else
{
onDownloaded(loader, resource, false);

View File

@ -2,8 +2,12 @@ import { Disposable } from '../../core/common/disposable/Disposable';
import { IConnection } from '../../core/communication/connections/IConnection';
import { IVector3D } from '../../room/utils/IVector3D';
import { Vector3d } from '../../room/utils/Vector3d';
import { AvatarGuideStatus } from '../avatar/enum/AvatarGuideStatus';
import { PetType } from '../avatar/pets/PetType';
import { ObjectsDataUpdateEvent, PetExperienceEvent } from '../communication';
import { GuideSessionEndedMessageEvent } from '../communication/messages/incoming/help/GuideSessionEndedMessageEvent';
import { GuideSessionErrorMessageEvent } from '../communication/messages/incoming/help/GuideSessionErrorMessageEvent';
import { GuideSessionStartedMessageEvent } from '../communication/messages/incoming/help/GuideSessionStartedMessageEvent';
import { ObjectsRollingEvent } from '../communication/messages/incoming/room/engine/ObjectsRollingEvent';
import { DiceValueMessageEvent } from '../communication/messages/incoming/room/furniture/DiceValueMessageEvent';
import { FurnitureFloorAddEvent } from '../communication/messages/incoming/room/furniture/floor/FurnitureFloorAddEvent';
@ -48,6 +52,7 @@ import { GetRoomEntryDataMessageComposer } from '../communication/messages/outgo
import { FurnitureFloorDataParser } from '../communication/messages/parser/room/furniture/floor/FurnitureFloorDataParser';
import { FurnitureWallDataParser } from '../communication/messages/parser/room/furniture/wall/FurnitureWallDataParser';
import { RoomEntryTileMessageParser } from '../communication/messages/parser/room/mapping/RoomEntryTileMessageParser';
import { RoomObjectType } from '../room/object/RoomObjectType';
import { IRoomCreator } from './IRoomCreator';
import { LegacyDataType } from './object/data/type/LegacyDataType';
import { RoomObjectUserType } from './object/RoomObjectUserType';
@ -68,6 +73,8 @@ export class RoomMessageHandler extends Disposable
private _currentRoomId: number;
private _ownUserId: number;
private _initialConnection: boolean;
private _guideId: number;
private _requesterId: number;
constructor(roomCreator: IRoomCreator)
{
@ -81,6 +88,8 @@ export class RoomMessageHandler extends Disposable
this._currentRoomId = 0;
this._ownUserId = 0;
this._initialConnection = true;
this._guideId = -1;
this._requesterId = -1;
}
protected onDispose(): void
@ -146,6 +155,9 @@ export class RoomMessageHandler extends Disposable
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
@ -703,6 +715,8 @@ export class RoomMessageHandler extends Disposable
this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, user.roomIndex, RoomObjectVariable.FIGURE_IS_MUTED, (this._roomCreator.sessionDataManager.isUserIgnored(user.name) ? 1 : 0));
}
this.updateGuideMarker();
}
private onRoomUnitExpressionEvent(event: RoomUnitExpressionEvent): void
@ -749,6 +763,8 @@ export class RoomMessageHandler extends Disposable
if(!(event instanceof RoomUnitRemoveEvent) || !event.connection || !this._roomCreator) return;
this._roomCreator.removeRoomObjectUser(this._currentRoomId, event.getParser().unitId);
this.updateGuideMarker();
}
private onRoomUnitStatusEvent(event: RoomUnitStatusEvent): void
@ -828,6 +844,8 @@ export class RoomMessageHandler extends Disposable
if(postureUpdate) this._roomCreator.updateRoomObjectUserPosture(this._currentRoomId, status.id, postureType, parameter);
else if(isPosture) this._roomCreator.updateRoomObjectUserPosture(this._currentRoomId, status.id, RoomObjectVariable.STD, '');
}
this.updateGuideMarker();
}
private onRoomUnitChatEvent(event: RoomUnitChatEvent): void
@ -949,6 +967,58 @@ export class RoomMessageHandler extends Disposable
}
}
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 = this._roomCreator.sessionDataManager.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
{
if(!this._roomCreator || !this._roomCreator.roomSessionManager) return;
const roomSession = this._roomCreator.roomSessionManager.getSession(this._currentRoomId);
if(!roomSession) return;
const userData = roomSession.userDataManager.getDataByType(userId, RoomObjectType.USER);
if(!userData) return;
this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, userData.roomIndex, RoomObjectVariable.FIGURE_GUIDE_STATUS, status);
}
// public _SafeStr_10580(event:_SafeStr_2242): void
// {
// var arrayIndex: number;

View File

@ -1550,6 +1550,8 @@ export class RoomObjectEventHandler extends Disposable implements IRoomCanvasMou
private handleMoveTargetFurni(k: number, _arg_2: RoomObjectMouseEvent): boolean
{
if((_arg_2.objectType === RoomObjectUserType.USER) || (_arg_2.objectType === RoomObjectUserType.PET) || (_arg_2.objectType === RoomObjectUserType.BOT) || (_arg_2.objectType === RoomObjectUserType.RENTABLE_BOT) || (_arg_2.objectType === RoomObjectUserType.MONSTER_PLANT)) return;
const _local_3 = this._roomEngine.getRoomObject(k, _arg_2.objectId, RoomObjectCategory.FLOOR);
const _local_4 = this.getActiveSurfaceLocation(_local_3, _arg_2);

View File

@ -34,7 +34,7 @@ export class RoomEngineTriggerWidgetEvent extends RoomEngineObjectEvent
public static REQUEST_INTERNAL_LINK: string = 'RETWE_REQUEST_INTERNAL_LINK';
public static REQUEST_ROOM_LINK: string = 'RETWE_REQUEST_ROOM_LINK';
private _widget: string
private _widget: string;
constructor(type: string, roomId: number, objectId: number, category: number, widget: string = null)
{

View File

@ -407,15 +407,15 @@ export class RoomLogic extends RoomObjectLogicBase
_local_18.add(Vector3d.product(planeRightSide, (planePosition.y / rightSideLength)));
_local_18.add(planeLocation);
const _local_19 = _local_18.x;
const _local_20 = _local_18.y;
const _local_21 = _local_18.z;
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, _local_19);
this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_Y, _local_20);
this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_Z, _local_21);
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
@ -439,7 +439,7 @@ export class RoomLogic extends RoomObjectLogicBase
if(planeType === RoomPlaneData.PLANE_FLOOR)
{
newEvent = new RoomObjectTileMouseEvent(eventType, this.object, event.eventId, _local_19, _local_20, _local_21, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown);
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))

View File

@ -10,14 +10,16 @@ import { RoomObjectSpriteVisualization } from '../../../../../room/object/visual
import { IGraphicAsset } from '../../../../../room/object/visualization/utils/IGraphicAsset';
import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry';
import { AvatarAction } from '../../../../avatar/enum/AvatarAction';
import { AvatarGuideStatus } from '../../../../avatar/enum/AvatarGuideStatus';
import { AvatarSetType } from '../../../../avatar/enum/AvatarSetType';
import { IAvatarEffectListener } from '../../../../avatar/IAvatarEffectListener';
import { IAvatarImage } from '../../../../avatar/IAvatarImage';
import { IAvatarImageListener } from '../../../../avatar/IAvatarImageListener';
import { Nitro } from '../../../../Nitro';
import { RoomObjectVariable } from '../../RoomObjectVariable';
import { ExpressionAdditionFactory } from './additions/ExpressionAdditionFactory';
import { FloatingIdleZAddition } from './additions/FloatingIdleZAddition';
import { GameClickTargetAddition } from './additions/GameClickTargetAddition';
import { GuideStatusBubbleAddition } from './additions/GuideStatusBubbleAddition';
import { IAvatarAddition } from './additions/IAvatarAddition';
import { MutedBubbleAddition } from './additions/MutedBubbleAddition';
import { NumberBubbleAddition } from './additions/NumberBubbleAddition';
@ -31,7 +33,9 @@ export class AvatarVisualization extends RoomObjectSpriteVisualization implement
private static TYPING_BUBBLE_ID: number = 2;
private static EXPRESSION_ID: number = 3;
private static NUMBER_BUBBLE_ID: number = 4;
private static GAME_CLICK_TARGET_ID: number = 5;
private static MUTED_BUBBLE_ID: number = 6;
private static GUIDE_BUBBLE_ID: number = 7;
private static OWN_USER_ID: number = 4;
private static UPDATE_TIME_INCREASER: number = 41;
private static AVATAR_LAYER_ID: number = 0;
@ -767,6 +771,40 @@ export class AvatarVisualization extends RoomObjectSpriteVisualization implement
}
}
const guideStatusValue = (model.getValue<number>(RoomObjectVariable.FIGURE_GUIDE_STATUS) || 0);
if(guideStatusValue !== AvatarGuideStatus.NONE)
{
this.removeAddition(AvatarVisualization.GUIDE_BUBBLE_ID);
this.addAddition(new GuideStatusBubbleAddition(AvatarVisualization.GUIDE_BUBBLE_ID, this, guideStatusValue));
needsUpdate = true;
}
else
{
if(this.getAddition(AvatarVisualization.GUIDE_BUBBLE_ID))
{
this.removeAddition(AvatarVisualization.GUIDE_BUBBLE_ID);
needsUpdate = true;
}
}
const isPlayingGame = (model.getValue<number>(RoomObjectVariable.FIGURE_IS_PLAYING_GAME) > 0);
let gameClickAddition = this.getAddition(AvatarVisualization.GAME_CLICK_TARGET_ID);
if(isPlayingGame)
{
if(!gameClickAddition) gameClickAddition = this.addAddition(new GameClickTargetAddition(AvatarVisualization.GAME_CLICK_TARGET_ID));
needsUpdate = true;
}
else
{
if(gameClickAddition) this.removeAddition(AvatarVisualization.GAME_CLICK_TARGET_ID);
}
const numberValue = model.getValue<number>(RoomObjectVariable.FIGURE_NUMBER_VALUE);
let numberAddition = this.getAddition(AvatarVisualization.NUMBER_BUBBLE_ID);
@ -1093,9 +1131,7 @@ export class AvatarVisualization extends RoomObjectSpriteVisualization implement
public getAvatarRenderAsset(name: string): Texture<Resource>
{
const url = (Nitro.instance.getConfiguration<string>('images.url') + '/additions/' + name + '.png');
return this._data ? this._data.getAvatarRendererAsset(url) : null;
return this._data ? this._data.getAvatarRendererAsset(name) : null;
}
public get direction(): number

View File

@ -1,5 +1,6 @@
import { Resource, Texture } from '@pixi/core';
import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite';
import { AvatarAction } from '../../../../../avatar/enum/AvatarAction';
import { Nitro } from '../../../../../Nitro';
import { AvatarVisualization } from '../AvatarVisualization';
import { ExpressionAddition } from './ExpressionAddition';
@ -42,7 +43,7 @@ export class FloatingHeartAddition extends ExpressionAddition
if(scale < 48)
{
this._asset = this.visualization.getAvatarRenderAsset('user_blowkiss_small');
this._asset = this.visualization.getAvatarRenderAsset('avatar_addition_user_blowkiss_small');
if((this.visualization.angle === 90) || (this.visualization.angle === 270))
{
@ -62,7 +63,7 @@ export class FloatingHeartAddition extends ExpressionAddition
}
else
{
this._asset = this.visualization.getAvatarRenderAsset('user_blowkiss');
this._asset = this.visualization.getAvatarRenderAsset('avatar_addition_user_blowkiss');
if((this.visualization.angle === 90) || (this.visualization.angle === 270))
{
@ -79,12 +80,12 @@ export class FloatingHeartAddition extends ExpressionAddition
this._offsetY = -70;
}
if(this.visualization.posture === 'sit')
if(this.visualization.posture === AvatarAction.POSTURE_SIT)
{
this._offsetY += (additionScale / 2);
}
else if(this.visualization.posture === 'lay')
else if(this.visualization.posture === AvatarAction.POSTURE_LAY)
{
this._offsetY += additionScale;
}

View File

@ -1,5 +1,6 @@
import { Resource, Texture } from '@pixi/core';
import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite';
import { AvatarAction } from '../../../../../avatar/enum/AvatarAction';
import { Nitro } from '../../../../../Nitro';
import { AvatarVisualization } from '../AvatarVisualization';
import { IAvatarAddition } from './IAvatarAddition';
@ -43,7 +44,7 @@ export class FloatingIdleZAddition implements IAvatarAddition
if((this._visualization.angle === 135) || (this._visualization.angle === 180) || (this._visualization.angle === 225) || (this._visualization.angle === 270)) side = 'right';
return ('user_idle_' + side + '_' + state + ((this._scale < 48) ? '_small' : ''));
return ('avatar_addition_user_idle_' + side + '_' + state + ((this._scale < 48) ? '_small' : ''));
}
public update(sprite: IRoomObjectSprite, scale: number): void
@ -85,12 +86,12 @@ export class FloatingIdleZAddition implements IAvatarAddition
this._offsetY = -70;
}
if(this._visualization.posture === 'sit')
if(this._visualization.posture === AvatarAction.POSTURE_SIT)
{
this._offsetY += (additionScale / 2);
}
else if(this._visualization.posture === 'lay')
else if(this._visualization.posture === AvatarAction.POSTURE_LAY)
{
this._offsetY += (additionScale - (0.3 * additionScale));
}

View File

@ -0,0 +1,61 @@
import { Resource, Texture } from '@pixi/core';
import { Sprite } from '@pixi/sprite';
import { AlphaTolerance, TextureUtils } from '../../../../../..';
import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite';
import { IAvatarAddition } from './IAvatarAddition';
export class GameClickTargetAddition implements IAvatarAddition
{
private static WIDTH: number = 46;
private static HEIGHT: number = 60;
private static OFFSET_X: number = -23;
private static OFFSET_Y: number = -48;
private _id: number;
private _asset: Texture<Resource>;
private _disposed: boolean;
constructor(id: number)
{
this._id = id;
this._asset = null;
this._disposed = false;
}
public dispose(): void
{
this._asset = null;
}
public update(sprite: IRoomObjectSprite, scale: number): void
{
if(!sprite) return;
if(!this._asset)
{
const newSprite = new Sprite(Texture.WHITE);
newSprite.alpha = 0;
newSprite.width = GameClickTargetAddition.WIDTH;
newSprite.height = GameClickTargetAddition.HEIGHT;
this._asset = TextureUtils.generateTexture(newSprite);
}
sprite.visible = true;
sprite.texture = this._asset;
sprite.offsetX = GameClickTargetAddition.OFFSET_X;
sprite.offsetY = GameClickTargetAddition.OFFSET_Y;
sprite.alphaTolerance = AlphaTolerance.MATCH_ALL_PIXELS;
}
public animate(sprite: IRoomObjectSprite): boolean
{
return false;
}
public get id(): number
{
return this._id;
}
}

View File

@ -0,0 +1,100 @@
import { Resource, Texture } from '@pixi/core';
import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite';
import { AvatarAction } from '../../../../../avatar/enum/AvatarAction';
import { AvatarGuideStatus } from '../../../../../avatar/enum/AvatarGuideStatus';
import { AvatarVisualization } from '../AvatarVisualization';
import { IAvatarAddition } from './IAvatarAddition';
export class GuideStatusBubbleAddition implements IAvatarAddition
{
private _id: number;
private _visualization: AvatarVisualization;
private _asset: Texture<Resource>;
private _relativeDepth: number;
private _status: number;
constructor(id: number, visualization: AvatarVisualization, status: number)
{
this._id = id;
this._visualization = visualization;
this._asset = null;
this._relativeDepth = 0;
this._status = status;
}
public dispose(): void
{
this._visualization = null;
this._asset = null;
}
public update(sprite: IRoomObjectSprite, scale: number): void
{
if(!sprite) return;
sprite.visible = true;
sprite.relativeDepth = this._relativeDepth;
sprite.alpha = 255;
let additionScale = 64;
let offsetX = 0;
let offsetY = 0;
this._asset = this._visualization.getAvatarRenderAsset((this._status === AvatarGuideStatus.GUIDE) ? 'avatar_addition_user_guide_bubble' : 'avatar_addition_user_guide_requester_bubble');
if(scale < 48)
{
offsetX = -19;
offsetY = -80;
additionScale = 32;
}
else
{
offsetX = -19;
offsetY = -120;
}
if(this._visualization.posture === AvatarAction.POSTURE_SIT)
{
offsetY += (additionScale / 2);
}
else if(this._visualization.posture === AvatarAction.POSTURE_LAY)
{
offsetY += scale;
}
if(this._asset)
{
sprite.texture = this._asset;
sprite.offsetX = offsetX;
sprite.offsetY = offsetY;
sprite.relativeDepth = (-0.02 + 0);
}
}
public animate(sprite: IRoomObjectSprite): boolean
{
if(this._asset && sprite)
{
sprite.texture = this._asset;
}
return false;
}
public get id(): number
{
return this._id;
}
public get relativeDepth(): number
{
return this._relativeDepth;
}
public set relativeDepth(depth: number)
{
this._relativeDepth = depth;
}
}

View File

@ -1,5 +1,6 @@
import { Resource, Texture } from '@pixi/core';
import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite';
import { AvatarAction } from '../../../../../avatar/enum/AvatarAction';
import { AvatarVisualization } from '../AvatarVisualization';
import { IAvatarAddition } from './IAvatarAddition';
@ -32,7 +33,7 @@ export class MutedBubbleAddition implements IAvatarAddition
if(scale < 48)
{
this._asset = this._visualization.getAvatarRenderAsset('user_muted_small');
this._asset = this._visualization.getAvatarRenderAsset('avatar_addition_user_muted_small');
additionScale = 32;
offsetX = -12;
@ -40,14 +41,14 @@ export class MutedBubbleAddition implements IAvatarAddition
}
else
{
this._asset = this._visualization.getAvatarRenderAsset('user_muted');
this._asset = this._visualization.getAvatarRenderAsset('avatar_addition_user_muted');
offsetX = -15;
offsetY = -110;
}
if(this._visualization.posture === 'sit') offsetY += (additionScale / 2);
else if(this._visualization.posture === 'lay') offsetY += scale;
if(this._visualization.posture === AvatarAction.POSTURE_SIT) offsetY += (additionScale / 2);
else if(this._visualization.posture === AvatarAction.POSTURE_LAY) offsetY += scale;
if(this._asset)
{

View File

@ -1,5 +1,6 @@
import { Resource, Texture } from '@pixi/core';
import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite';
import { AvatarAction } from '../../../../../avatar/enum/AvatarAction';
import { AvatarVisualization } from '../AvatarVisualization';
import { IAvatarAddition } from './IAvatarAddition';
@ -46,7 +47,7 @@ export class NumberBubbleAddition implements IAvatarAddition
{
if(scale < 48)
{
this._asset = this._visualization.getAvatarRenderAsset('number_' + this._number + '_small');
this._asset = this._visualization.getAvatarRenderAsset('avatar_addition_number_' + this._number + '_small');
additionScale = 32;
offsetX = -6;
@ -54,18 +55,18 @@ export class NumberBubbleAddition implements IAvatarAddition
}
else
{
this._asset = this._visualization.getAvatarRenderAsset('number_' + this._number);
this._asset = this._visualization.getAvatarRenderAsset('avatar_addition_number_' + this._number);
offsetX = -8;
offsetY = -105;
}
if(this._visualization.posture === 'sit')
if(this._visualization.posture === AvatarAction.POSTURE_SIT)
{
offsetY += (additionScale / 2);
}
else if(this._visualization.posture === 'lay')
else if(this._visualization.posture === AvatarAction.POSTURE_LAY)
{
offsetY += scale;
}

View File

@ -1,5 +1,6 @@
import { Resource, Texture } from '@pixi/core';
import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite';
import { AvatarAction } from '../../../../../avatar/enum/AvatarAction';
import { AvatarVisualization } from '../AvatarVisualization';
import { IAvatarAddition } from './IAvatarAddition';
@ -38,7 +39,7 @@ export class TypingBubbleAddition implements IAvatarAddition
if(scale < 48)
{
this._asset = this._visualization.getAvatarRenderAsset('user_typing_small');
this._asset = this._visualization.getAvatarRenderAsset('avatar_addition_user_typing_small');
offsetX = 3;
offsetY = -42;
@ -47,18 +48,18 @@ export class TypingBubbleAddition implements IAvatarAddition
}
else
{
this._asset = this._visualization.getAvatarRenderAsset('user_typing');
this._asset = this._visualization.getAvatarRenderAsset('avatar_addition_user_typing');
offsetX = 14;
offsetY = -83;
}
if(this._visualization.posture === 'sit')
if(this._visualization.posture === AvatarAction.POSTURE_SIT)
{
offsetY += (additionScale / 2);
}
else if(this._visualization.posture === 'lay')
else if(this._visualization.posture === AvatarAction.POSTURE_LAY)
{
offsetY += scale;
}

View File

@ -2,6 +2,8 @@ export * from './ExpressionAddition';
export * from './ExpressionAdditionFactory';
export * from './FloatingHeartAddition';
export * from './FloatingIdleZAddition';
export * from './GameClickTargetAddition';
export * from './GuideStatusBubbleAddition';
export * from './IAvatarAddition';
export * from './IExpressionAddition';
export * from './MutedBubbleAddition';

View File

@ -42,7 +42,7 @@ export class AnimationSizeData extends SizeData
if(!animation) return false;
let animationId = parseInt(key);
let animationId = parseInt(key.split('_')[0]);
let isTransition = false;
const transitionTo = animation.transitionTo;

View File

@ -12,10 +12,6 @@ export class LayerData
public static DEFAULT_YOFFSET: number = 0;
public static DEFAULT_ZOFFSET: number = 0;
public static ADD_INK: number = BLEND_MODES.ADD;
public static SUBTRACT_INK: number = BLEND_MODES.NORMAL;
public static DARKEN_INK: number = BLEND_MODES.NORMAL;
private _tag: string;
private _ink: number;
private _alpha: number;

View File

@ -506,7 +506,7 @@ export class FurnitureVisualization extends RoomObjectSpriteVisualization
protected getLayerYOffset(scale: number, direction: number, layerId: number): number
{
if(layerId === this._shadowLayerIndex) return Math.ceil((this._furnitureLift * (64 / 2)));
if(layerId === this._shadowLayerIndex) return Math.ceil((this._furnitureLift * (scale / 2)));
const existing = this._spriteYOffsets[layerId];

View File

@ -9,8 +9,10 @@ export class FurnitureYoutubeVisualization extends FurnitureDynamicThumbnailVisu
{
if(!this.object) return null;
const url = this.object.model.getValue<string>(RoomObjectVariable.SESSION_URL_PREFIX);
const furnitureData = this.object.model.getValue<{ [index: string]: string }>(RoomObjectVariable.FURNITURE_DATA);
return (url + FurnitureYoutubeVisualization.THUMBNAIL);
if(furnitureData) return (furnitureData[FurnitureYoutubeVisualization.THUMBNAIL_URL] || null);
return null;
}
}

View File

@ -23,7 +23,7 @@ export class PetVisualization extends FurnitureAnimatedVisualization
private static HAIR: string = 'hair';
private static ADDITIONAL_SPRITE_COUNT: number = 1;
private static EXPERIENCE_BUBBLE_VISIBLE_IN_MS: number = 1000;
private static PET_EXPERIENCE_BUBBLE: string = 'pet_experience_bubble';
private static PET_EXPERIENCE_BUBBLE: string = 'avatar_addition_pet_experience_bubble';
private static POSTURE_ANIMATION_INDEX: number = 0;
private static GESTURE_ANIMATION_INDEX: number = 1;
private static ANIMATION_INDEX_COUNT: number = 2;
@ -600,8 +600,6 @@ export class PetVisualization extends FurnitureAnimatedVisualization
public getPetAdditionAsset(name: string): Texture<Resource>
{
const url = (Nitro.instance.getConfiguration<string>('images.url') + '/additions/' + name + '.png');
return Nitro.instance.core.asset.getTexture(url);
return Nitro.instance.core.asset.getTexture(name);
}
}

View File

@ -89,10 +89,12 @@ export class RoomPlane implements IRoomPlane
this._rightSide = new Vector3d();
this._rightSide.assign(rightSide);
this._normal = Vector3d.crossProduct(this._leftSide, this._rightSide);
if(this._normal.length > 0)
{
this._normal.multiply((1 / this._normal.length));
}
if(secondaryNormals != null)
{
for(const entry of secondaryNormals)

View File

@ -258,8 +258,6 @@ export class RoomPreviewer
if(this.isRoomEngineReady)
{
if((this._currentPreviewObjectCategory === RoomObjectCategory.FLOOR) && (this._currentPreviewObjectType === classId)) return RoomPreviewer.PREVIEW_OBJECT_ID;
this.reset(false);
this._currentPreviewObjectType = classId;
@ -512,7 +510,7 @@ export class RoomPreviewer
return this._addViewOffset;
}
private updatePreviewObjectBoundingRectangle(point: Point): void
public updatePreviewObjectBoundingRectangle(point: Point): void
{
const objectBounds = this._roomEngine.getRoomObjectBoundingRectangle(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory, RoomPreviewer.PREVIEW_CANVAS_ID);

View File

@ -2,7 +2,7 @@ export class FurnitureStackingHeightMap
{
private _width: number;
private _height: number;
private _heights: number[]
private _heights: number[];
private _isNotStackable: boolean[];
private _isRoomTile: boolean[];

View File

@ -43,6 +43,8 @@ export interface IRoomSession extends IDisposable
togglePetBreeding(id: number): void;
togglePetRiding(id: number): void;
useMultistateItem(id: number): void;
harvestPet(id: number): void;
compostPlant(id: number): void;
connection: IConnection;
userDataManager: UserDataManager;
roomId: number;

View File

@ -1,6 +1,6 @@
import { Disposable } from '../../core/common/disposable/Disposable';
import { IConnection } from '../../core/communication/connections/IConnection';
import { FurnitureMultiStateComposer, PetMountComposer, PollAnswerComposer, PollRejectComposer, PollStartComposer, RemovePetSaddleComposer, TogglePetBreedingComposer, TogglePetRidingComposer, UsePetProductComposer } from '../communication';
import { CompostPlantMessageComposer, FurnitureMultiStateComposer, HarvestPetMessageComposer, PetMountComposer, PollAnswerComposer, PollRejectComposer, PollStartComposer, RemovePetSaddleComposer, TogglePetBreedingComposer, TogglePetRidingComposer, UsePetProductComposer } from '../communication';
import { RoomDoorbellAccessComposer } from '../communication/messages/outgoing/room/access/RoomDoorbellAccessComposer';
import { RoomEnterComposer } from '../communication/messages/outgoing/room/access/RoomEnterComposer';
import { RoomAmbassadorAlertComposer } from '../communication/messages/outgoing/room/action/RoomAmbassadorAlertComposer';
@ -314,6 +314,16 @@ export class RoomSession extends Disposable implements IRoomSession
this._connection.send(new FurnitureMultiStateComposer(id));
}
public harvestPet(id: number): void
{
this._connection.send(new HarvestPetMessageComposer(id));
}
public compostPlant(id: number): void
{
this._connection.send(new CompostPlantMessageComposer(id));
}
public get connection(): IConnection
{
return this._connection;

View File

@ -174,6 +174,34 @@ export class UserDataManager extends Disposable
userData.custom = custom;
}
public updateAchievementScore(roomIndex: number, score: number): void
{
const userData = this.getUserDataByIndex(roomIndex);
if(!userData) return;
userData.activityPoints = score;
}
public updatePetLevel(roomIndex: number, level: number): void
{
const userData = this.getUserDataByIndex(roomIndex);
if(userData) userData.petLevel = level;
}
public updatePetBreedingStatus(roomIndex: number, canBreed: boolean, canHarvest: boolean, canRevive: boolean, hasBreedingPermission: boolean): void
{
const userData = this.getUserDataByIndex(roomIndex);
if(!userData) return;
userData.canBreed = canBreed;
userData.canHarvest = canHarvest;
userData.canRevive = canRevive;
userData.hasBreedingPermission = hasBreedingPermission;
}
public requestPetInfo(id: number): void
{
if(!this._connection) return;

View File

@ -1,4 +1,5 @@
import { Resource, Texture } from '@pixi/core';
import { NitroContainer, NitroTexture } from '../../..';
import { IAssetManager } from '../../../core/asset/IAssetManager';
import { IMessageEvent } from '../../../core/communication/messages/IMessageEvent';
import { NitroSprite } from '../../../core/utils/proxy/NitroSprite';
@ -100,18 +101,18 @@ export class BadgeImageManager implements IDisposable
{
const url = this.getBadgeUrl(badgeName, type);
if(!url || !url.length) return null;
const existing = this._assets.getTexture(url);
if(existing) return existing.clone();
if(this._requestedBadges.get(badgeName)) return null;
if(url)
{
this._requestedBadges.set(badgeName, true);
if(type === BadgeImageManager.NORMAL_BADGE)
{
if(this._requestedBadges.get(badgeName)) return null;
this._requestedBadges.set(badgeName, true);
this._assets.downloadAsset(url, (flag: boolean) =>
{
if(flag)
@ -124,17 +125,14 @@ export class BadgeImageManager implements IDisposable
}
});
}
else
else if(type === BadgeImageManager.GROUP_BADGE)
{
if(!this._readyToGenerateGroupBadges)
{
if(!this._groupBadgesQueue.get(badgeName)) this._groupBadgesQueue.set(badgeName, true);
}
else
{
this.loadGroupBadge(badgeName);
}
}
if(this._groupBadgesQueue.get(badgeName)) return;
this._groupBadgesQueue.set(badgeName, true);
if(this._readyToGenerateGroupBadges) this.loadGroupBadge(badgeName);
}
return null;
@ -160,7 +158,6 @@ export class BadgeImageManager implements IDisposable
url = (Nitro.instance.getConfiguration<string>('badge.asset.url')).replace('%badgename%', badge);
break;
case BadgeImageManager.GROUP_BADGE:
//url = (Nitro.instance.getConfiguration<string>('badge.asset.group.url')).replace('%badgedata%', badge);
url = badge;
break;
}
@ -171,80 +168,65 @@ export class BadgeImageManager implements IDisposable
private loadGroupBadge(badgeCode: string): void
{
const groupBadge = new GroupBadge(badgeCode);
const imagePath = Nitro.instance.getConfiguration<string>('badge.asset.grouparts.url');
const urlsToLoad: string[] = [];
const partMatches = [...badgeCode.matchAll(/[b|s][0-9]{5,6}/g)];
for(const partMatch of partMatches)
{
const partCode = partMatch[0];
const shortMethod = (partCode.length === 6);
const partType = partCode[0];
const partId = parseInt(partCode.slice(1, shortMethod ? 3 : 4));
const partColor = parseInt(partCode.slice(shortMethod ? 3 : 4, shortMethod ? 5 : 6));
const partPosition = parseInt(partCode.slice(shortMethod ? 5 : 6, shortMethod ? 6 : 7));
const part = new GroupBadgePart(partType, partId, partColor, partPosition);
groupBadge.parts.push(part);
const isBase = (partType === 'b');
const requiredAssets = isBase ? this._groupBases.get(partId) : this._groupSymbols.get(partId);
if(!requiredAssets) continue;
for(const requiredAsset of requiredAssets)
{
if(requiredAsset.length > 0)
{
const url = imagePath.replace('%part%', requiredAsset);
part.urls.push(url);
if(!this._assets.getAsset(requiredAsset)) urlsToLoad.push(url);
}
}
}
if(urlsToLoad.length === 0) return this.renderGroupBadge(groupBadge);
this._assets.downloadAssets(urlsToLoad, (flag: boolean) =>
{
this.renderGroupBadge(groupBadge);
});
}
private renderGroupBadge(groupBadge: GroupBadge): void
{
const container = new NitroContainer();
const tempSprite = new NitroSprite(NitroTexture.EMPTY);
tempSprite.width = GroupBadgePart.IMAGE_WIDTH;
tempSprite.height = GroupBadgePart.IMAGE_HEIGHT;
container.addChild(tempSprite);
for(const part of groupBadge.parts)
{
let isFirst = true;
for(const partUrl of part.urls)
const partNames = ((part.type === 'b') ? this._groupBases.get(part.key) : this._groupSymbols.get(part.key));
for(const partName of partNames)
{
const texture = this._assets.getTexture(partUrl);
if(!partName || !partName.length) continue;
if(!texture) continue; //Generate with what we got
const texture = this._assets.getTexture(`badgepart_${ partName }`);
const pos = part.calculatePosition(texture);
if(!texture) continue;
const { x, y } = part.calculatePosition(texture);
const sprite = new NitroSprite(texture);
sprite.x = pos.x;
sprite.y = pos.y;
sprite.position.set(x, y);
if(isFirst) sprite.tint = parseInt(this._groupPartColors.get(part.color), 16);
isFirst = false;
groupBadge.container.addChild(sprite);
container.addChild(sprite);
}
}
this._requestedBadges.delete(groupBadge.code);
this._groupBadgesQueue.delete(groupBadge.code);
const texture = TextureUtils.generateTexture(groupBadge.container);
const texture = TextureUtils.generateTexture(container);
this._assets.setTexture(groupBadge.code, texture);
if(this._sessionDataManager) this._sessionDataManager.events.dispatchEvent(new BadgeImageReadyEvent(groupBadge.code, texture));
@ -258,23 +240,14 @@ export class BadgeImageManager implements IDisposable
if(!data) return;
data.bases.forEach( (names, id) =>
{
this._groupBases.set(id, names.map( val => val.replace('.png', '').replace('.gif', '')));
});
data.bases.forEach((names, id) => this._groupBases.set(id, names.map( val => val.replace('.png', '').replace('.gif', ''))));
data.symbols.forEach( (names, id) =>
{
this._groupSymbols.set(id, names.map( val => val.replace('.png', '').replace('.gif', '')));
});
data.symbols.forEach( (names, id) => this._groupSymbols.set(id, names.map( val => val.replace('.png', '').replace('.gif', ''))));
this._groupPartColors = data.partColors;
this._readyToGenerateGroupBadges = true;
this._groupBadgesQueue.forEach((_, badgeCode) =>
{
this.loadGroupBadge(badgeCode);
});
for(const badgeCode of this._groupBadgesQueue.keys()) this.loadGroupBadge(badgeCode);
}
public get disposed(): boolean

View File

@ -1,17 +1,14 @@
import { NitroContainer } from '../../..';
import { GroupBadgePart } from './GroupBadgePart';
export class GroupBadge
{
private _code: string;
private _parts: GroupBadgePart[];
private _container: NitroContainer;
constructor(code: string)
{
this._code = code;
this._parts = [];
this._container = new NitroContainer();
}
public get code(): string
@ -23,9 +20,4 @@ export class GroupBadge
{
return this._parts;
}
public get container(): NitroContainer
{
return this._container;
}
}

View File

@ -5,7 +5,6 @@ export class GroupBadgePart
public static BASE: string = 'b';
public static SYMBOL: string = 's';
public static SYMBOL_ALT: string = 't';
public static BASE_PART: number = 0;
public static LAYER_PART: number = 1;
public static IMAGE_WIDTH: number = 39;
@ -17,15 +16,13 @@ export class GroupBadgePart
public key: number;
public color: number;
public position: number;
public urls: string[];
constructor(type: string, key?: number, color?: number, position?: number)
constructor(type: string, key: number = 0, color: number = 0, position: number = 0)
{
this.type = type;
this.key = key ? key : 0;
this.color = color ? color : 0;
this.position = position ? position : 4;
this.urls = [];
this.key = key;
this.color = color;
this.position = position;
}
public get code(): string

View File

@ -11,15 +11,15 @@ export class RoomSessionPetStatusUpdateEvent extends RoomSessionEvent
private _canRevive: boolean;
private _hasBreedingPermission: boolean;
constructor(k: IRoomSession, _arg_2: number, _arg_3: boolean, _arg_4: boolean, _arg_5: boolean, _arg_6: boolean)
constructor(roomSession: IRoomSession, petId: number, canBreed: boolean, canHarvest: boolean, canRevive: boolean, hasBreedingPermission: boolean)
{
super(RoomSessionPetStatusUpdateEvent.PET_STATUS_UPDATE, k);
super(RoomSessionPetStatusUpdateEvent.PET_STATUS_UPDATE, roomSession);
this._petId = _arg_2;
this._canBreed = _arg_3;
this._canHarvest = _arg_4;
this._canRevive = _arg_5;
this._hasBreedingPermission = _arg_6;
this._petId = petId;
this._canBreed = canBreed;
this._canHarvest = canHarvest;
this._canRevive = canRevive;
this._hasBreedingPermission = hasBreedingPermission;
}
public get petId(): number

View File

@ -11,14 +11,15 @@ export class RoomSessionUserFigureUpdateEvent extends RoomSessionEvent
private _customInfo: string = '';
private _achievementScore: number;
constructor(k: IRoomSession, _arg_2: number, _arg_3: string, _arg_4: string, _arg_5: string, _arg_6: number)
constructor(session: IRoomSession, userId: number, figure: string, gender: string, customInfo: string, achievementScore: number)
{
super(RoomSessionUserFigureUpdateEvent.USER_FIGURE, k);
this._userId = _arg_2;
this._figure = _arg_3;
this._gender = _arg_4;
this._customInfo = _arg_5;
this._achievementScore = _arg_6;
super(RoomSessionUserFigureUpdateEvent.USER_FIGURE, session);
this._userId = userId;
this._figure = figure;
this._gender = gender;
this._customInfo = customInfo;
this._achievementScore = achievementScore;
}
public get userId(): number

View File

@ -5,13 +5,14 @@ import { BotErrorEvent } from '../../communication/messages/incoming/notificatio
import { PetPlacingErrorEvent } from '../../communication/messages/incoming/notifications/PetPlacingErrorEvent';
import { RoomDoorbellEvent } from '../../communication/messages/incoming/room/access/doorbell/RoomDoorbellEvent';
import { PetInfoEvent } from '../../communication/messages/incoming/room/pet/PetInfoEvent';
import { PetStatusUpdateEvent } from '../../communication/messages/incoming/room/pet/PetStatusUpdateEvent';
import { RoomUnitDanceEvent } from '../../communication/messages/incoming/room/unit/RoomUnitDanceEvent';
import { RoomUnitEvent } from '../../communication/messages/incoming/room/unit/RoomUnitEvent';
import { RoomUnitInfoEvent } from '../../communication/messages/incoming/room/unit/RoomUnitInfoEvent';
import { RoomUnitRemoveEvent } from '../../communication/messages/incoming/room/unit/RoomUnitRemoveEvent';
import { UserCurrentBadgesEvent } from '../../communication/messages/incoming/user/data/UserCurrentBadgesEvent';
import { UserNameChangeMessageEvent } from '../../communication/messages/incoming/user/data/UserNameChangeMessageEvent';
import { RoomSessionPetFigureUpdateEvent } from '../events';
import { RoomSessionPetFigureUpdateEvent, RoomSessionPetStatusUpdateEvent, RoomSessionUserFigureUpdateEvent } from '../events';
import { RoomSessionDanceEvent } from '../events/RoomSessionDanceEvent';
import { RoomSessionDoorbellEvent } from '../events/RoomSessionDoorbellEvent';
import { RoomSessionErrorMessageEvent } from '../events/RoomSessionErrorMessageEvent';
@ -39,6 +40,7 @@ export class RoomUsersHandler extends BaseHandler
connection.addMessageEvent(new UserNameChangeMessageEvent(this.onUserNameChangeMessageEvent.bind(this)));
connection.addMessageEvent(new NewFriendRequestEvent(this.onNewFriendRequestEvent.bind(this)));
connection.addMessageEvent(new PetInfoEvent(this.onPetInfoEvent.bind(this)));
connection.addMessageEvent(new PetStatusUpdateEvent(this.onPetStatusUpdateEvent.bind(this)));
connection.addMessageEvent(new PetFigureUpdateEvent(this.onPetFigureUpdateEvent.bind(this)));
connection.addMessageEvent(new PetPlacingErrorEvent(this.onPetPlacingError.bind(this)));
connection.addMessageEvent(new BotErrorEvent(this.onBotError.bind(this)));
@ -110,6 +112,10 @@ export class RoomUsersHandler extends BaseHandler
session.userDataManager.updateFigure(parser.unitId, parser.figure, parser.gender, false, false);
session.userDataManager.updateMotto(parser.unitId, parser.motto);
session.userDataManager.updateAchievementScore(parser.unitId, parser.achievementScore);
this.listener.events.dispatchEvent(new RoomSessionUserFigureUpdateEvent(session, parser.unitId, parser.figure, parser.gender, parser.motto, parser.achievementScore));
}
private onRoomUnitRemoveEvent(event: RoomUnitRemoveEvent): void
@ -250,6 +256,23 @@ export class RoomUsersHandler extends BaseHandler
this.listener.events.dispatchEvent(new RoomSessionPetInfoUpdateEvent(session, petData));
}
private onPetStatusUpdateEvent(event: PetStatusUpdateEvent): void
{
if(!this.listener) return;
const parser = event.getParser();
if(!parser) return;
const session = this.listener.getSession(this.roomId);
if(!session) return;
session.userDataManager.updatePetBreedingStatus(parser.roomIndex, parser.canBreed, parser.canHarvest, parser.canRevive, parser.hasBreedingPermission);
this.listener.events.dispatchEvent(new RoomSessionPetStatusUpdateEvent(session, parser.petId, parser.canBreed, parser.canHarvest, parser.canRevive, parser.hasBreedingPermission));
}
private onPetFigureUpdateEvent(event: PetFigureUpdateEvent): void
{
if(!this.listener) return;

View File

@ -21,6 +21,10 @@ export interface IRoomRenderingCanvas
handleMouseEvent(x: number, y: number, type: string, altKey: boolean, ctrlKey: boolean, shiftKey: boolean, buttonDown: boolean): boolean;
getSortableSpriteList(): RoomObjectSpriteData[];
getDisplayAsTexture(): RenderTexture;
moveLeft(): void;
moveRight(): void;
moveUp(): void;
moveDown(): void;
id: number;
geometry: IRoomGeometry;
master: DisplayObject;

View File

@ -12,6 +12,7 @@ import { RoomObjectSpriteType } from '../object/enum/RoomObjectSpriteType';
import { IRoomObject } from '../object/IRoomObject';
import { IRoomObjectSprite } from '../object/visualization/IRoomObjectSprite';
import { IRoomObjectSpriteVisualization } from '../object/visualization/IRoomObjectSpriteVisualization';
import { RoomRotatingEffect, RoomShakingEffect } from '../utils';
import { IRoomGeometry } from '../utils/IRoomGeometry';
import { RoomEnterEffect } from '../utils/RoomEnterEffect';
import { RoomGeometry } from '../utils/RoomGeometry';
@ -63,6 +64,14 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas
private _eventId: number;
private _scale: number;
private _SafeStr_4507: boolean = false;
private _rotation: number = 0;
private _rotationOrigin: Vector3d = null;
private _rotationRodLength: number = 0;
private _effectDirection: Vector3d;
private _effectLocation: Vector3d;
private _SafeStr_795: number = 0;
private _restrictsScaling: boolean;
private _noSpriteVisibilityChecking: boolean;
private _usesExclusionRectangles: boolean;
@ -353,6 +362,8 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas
update = true;
}
this.doMagic();
const frame = Math.round(this._totalTimeRunning / (60 / this._animationFPS));
let updateVisuals = false;
@ -1033,6 +1044,177 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas
return renderTexture;
}
private doMagic(): void
{
const geometry = (this.geometry as RoomGeometry);
if(this._rotation !== 0)
{
let direction = this._effectDirection;
geometry.direction = new Vector3d((direction.x + this._rotation), direction.y, direction.z);
direction = (geometry.direction as Vector3d);
geometry.setDepthVector(new Vector3d(direction.x, direction.y, 5));
const location = new Vector3d();
location.assign(this._rotationOrigin);
location.x = (location.x + ((this._rotationRodLength * Math.cos((((direction.x + 180) / 180) * 3.14159265358979))) * Math.cos(((direction.y / 180) * 3.14159265358979))));
location.y = (location.y + ((this._rotationRodLength * Math.sin((((direction.x + 180) / 180) * 3.14159265358979))) * Math.cos(((direction.y / 180) * 3.14159265358979))));
location.z = (location.z + (this._rotationRodLength * Math.sin(((direction.y / 180) * 3.14159265358979))));
geometry.location = location;
this._effectLocation = new Vector3d();
this._effectLocation.assign(location);
this._effectDirection = new Vector3d();
this._effectDirection.assign(geometry.direction);
}
if(RoomShakingEffect.isVisualizationOn() && !this._SafeStr_4507)
{
this.changeShaking();
}
else
{
if(!RoomShakingEffect.isVisualizationOn() && this._SafeStr_4507) this.changeShaking();
}
if(RoomRotatingEffect.isVisualizationOn()) this.changeRotation();
if(this._SafeStr_4507)
{
this._SafeStr_795++;
const _local_4 = this._effectDirection;
const _local_1 = Vector3d.sum(_local_4, new Vector3d((Math.sin((((this._SafeStr_795 * 5) / 180) * 3.14159265358979)) * 2), (Math.sin(((this._SafeStr_795 / 180) * 3.14159265358979)) * 5), (Math.sin((((this._SafeStr_795 * 10) / 180) * 3.14159265358979)) * 2)));
geometry.direction = _local_1;
}
else
{
this._SafeStr_795 = 0;
geometry.direction = this._effectDirection;
}
}
private changeShaking(): void
{
this._SafeStr_4507 = !this._SafeStr_4507;
if(this._SafeStr_4507)
{
const direction = this.geometry.direction;
this._effectDirection = new Vector3d(direction.x, direction.y, direction.z);
}
}
private changeRotation(): void
{
if(this._SafeStr_4507) return;
const geometry = (this.geometry as RoomGeometry);
if(!geometry) return;
if(this._rotation === 0)
{
const location = geometry.location;
const directionAxis = geometry.directionAxis;
this._effectLocation = new Vector3d();
this._effectLocation.assign(location);
this._effectDirection = new Vector3d();
this._effectDirection.assign(geometry.direction);
const intersection = RoomGeometry.getIntersectionVector(location, directionAxis, new Vector3d(0, 0, 0), new Vector3d(0, 0, 1));
if(intersection !== null)
{
this._rotationOrigin = new Vector3d(intersection.x, intersection.y, intersection.z);
this._rotationRodLength = Vector3d.dif(intersection, location).length;
this._rotation = 1;
}
return;
}
this._rotation = 0;
geometry.location = this._effectLocation;
geometry.direction = this._effectDirection;
geometry.setDepthVector(new Vector3d(this._effectDirection.x, this._effectDirection.y, 5));
}
public moveLeft(): void
{
if(this._rotation !== 0)
{
if(this._rotation === 1)
{
this._rotation = -1;
}
else
{
this._rotation = (this._rotation - 1);
}
return;
}
const geometry = (this.geometry as RoomGeometry);
const direction = (((geometry.direction.x - 90) / 180) * 3.14159265358979);
geometry.location = Vector3d.sum(geometry.location, new Vector3d((Math.cos(direction) * Math.sqrt(2)), (Math.sin(direction) * Math.sqrt(2))));
}
public moveRight(): void
{
if(this._rotation !== 0)
{
if(this._rotation === -1)
{
this._rotation = 1;
}
else
{
this._rotation = (this._rotation + 1);
}
return;
}
const geometry = (this.geometry as RoomGeometry);
const direction = (((geometry.direction.x + 90) / 180) * 3.14159265358979);
geometry.location = Vector3d.sum(geometry.location, new Vector3d((Math.cos(direction) * Math.sqrt(2)), (Math.sin(direction) * Math.sqrt(2))));
}
public moveUp(): void
{
if(this._rotation !== 0) return;
const geometry = (this.geometry as RoomGeometry);
const direction = ((geometry.direction.x / 180) * 3.14159265358979);
geometry.location = Vector3d.sum(geometry.location, new Vector3d((Math.cos(direction) * Math.sqrt(2)), (Math.sin(direction) * Math.sqrt(2))));
}
public moveDown(): void
{
if(this._rotation !== 0) return;
const geometry = (this.geometry as RoomGeometry);
const direction = (((geometry.direction.x + 180) / 180) * 3.14159265358979);
geometry.location = Vector3d.sum(geometry.location, new Vector3d((Math.cos(direction) * Math.sqrt(2)), (Math.sin(direction) * Math.sqrt(2))));
}
public get id(): number
{
return this._id;

View File

@ -0,0 +1,75 @@
import { Nitro } from '../../nitro/Nitro';
export class RoomRotatingEffect
{
public static STATE_NOT_INITIALIZED: number = 0;
public static STATE_START_DELAY: number = 1;
public static STATE_RUNNING: number = 2;
public static STATE_OVER: number = 3;
private static _SafeStr_448: number = 0;
private static _SafeStr_4512: boolean = false;
private static _SafeStr_4513: number = 0;
private static _SafeStr_4514: number = 0;
private static _SafeStr_4515: number = 20000;
private static _SafeStr_4516: number = 5000;
private static _SafeStr_4524: ReturnType<typeof setTimeout>;
public static init(_arg_1: number, _arg_2: number): void
{
this._SafeStr_4513 = 0;
this._SafeStr_4515 = _arg_1;
this._SafeStr_4516 = _arg_2;
this._SafeStr_4514 = Nitro.instance.time;
this._SafeStr_448 = 1;
}
public static turnVisualizationOn(): void
{
if((this._SafeStr_448 === 0) || (this._SafeStr_448 === 3)) return;
if(!this._SafeStr_4524) this._SafeStr_4524 = setTimeout(() => this.turnVisualizationOff(), this._SafeStr_4516);
const _local_1 = (Nitro.instance.time - this._SafeStr_4514);
if(_local_1 > (this._SafeStr_4515 + this._SafeStr_4516))
{
this._SafeStr_448 = 3;
return;
}
this._SafeStr_4512 = true;
if(_local_1 < this._SafeStr_4515)
{
this._SafeStr_448 = 1;
return;
}
this._SafeStr_448 = 2;
this._SafeStr_4513 = ((_local_1 - this._SafeStr_4515) / this._SafeStr_4516);
}
public static turnVisualizationOff():void
{
this._SafeStr_4512 = false;
clearTimeout(this._SafeStr_4524);
this._SafeStr_4524 = null;
}
public static isVisualizationOn(): boolean
{
return (this._SafeStr_4512 && this.isRunning());
}
private static isRunning(): boolean
{
if((this._SafeStr_448 === 1) || (this._SafeStr_448 === 2)) return true;
return false;
}
}

View File

@ -0,0 +1,75 @@
import { Nitro } from '../../nitro/Nitro';
export class RoomShakingEffect
{
public static STATE_NOT_INITIALIZED: number = 0;
public static STATE_START_DELAY: number = 1;
public static STATE_RUNNING: number = 2;
public static STATE_OVER: number = 3;
private static _SafeStr_448: number = 0;
private static _SafeStr_4512: boolean = false;
private static _SafeStr_4513: number;
private static _SafeStr_4514: number = 0;
private static _SafeStr_4515: number = 20000;
private static _SafeStr_4516: number = 5000;
private static _SafeStr_4524: ReturnType<typeof setTimeout>;
public static init(_arg_1: number, _arg_2: number): void
{
this._SafeStr_4513 = 0;
this._SafeStr_4515 = _arg_1;
this._SafeStr_4516 = _arg_2;
this._SafeStr_4514 = Nitro.instance.time;
this._SafeStr_448 = 1;
}
public static turnVisualizationOn(): void
{
if((this._SafeStr_448 === 0) || (this._SafeStr_448 === 3)) return;
if(!this._SafeStr_4524) this._SafeStr_4524 = setTimeout(() => this.turnVisualizationOff(), this._SafeStr_4516);
const _local_1 = (Nitro.instance.time - this._SafeStr_4514);
if(_local_1 > (this._SafeStr_4515 + this._SafeStr_4516))
{
this._SafeStr_448 = 3;
return;
}
this._SafeStr_4512 = true;
if(_local_1 < this._SafeStr_4515)
{
this._SafeStr_448 = 1;
return;
}
this._SafeStr_448 = 2;
this._SafeStr_4513 = ((_local_1 - this._SafeStr_4515) / this._SafeStr_4516);
}
public static turnVisualizationOff():void
{
this._SafeStr_4512 = false;
clearTimeout(this._SafeStr_4524);
this._SafeStr_4524 = null;
}
public static isVisualizationOn(): boolean
{
return (this._SafeStr_4512 && this.isRunning());
}
private static isRunning(): boolean
{
if((this._SafeStr_448 === 1) || (this._SafeStr_448 === 2)) return true;
return false;
}
}

View File

@ -11,6 +11,10 @@ export class SpriteUtilities
{
if(ink == 'ADD' || ink == 33) return BLEND_MODES.ADD;
if(ink == 'SUBTRACT') return BLEND_MODES.SUBTRACT;
if(ink == 'DARKEN') return BLEND_MODES.DARKEN;
return BLEND_MODES.NORMAL;
}
}

View File

@ -121,6 +121,8 @@ export class Vector3d implements IVector3D
public divide(amount: number): void
{
if(!amount) return;
this._x /= amount;
this._y /= amount;
this._z /= amount;

View File

@ -7,6 +7,8 @@ export * from './Rasterizer';
export * from './RoomEnterEffect';
export * from './RoomGeometry';
export * from './RoomId';
export * from './RoomRotatingEffect';
export * from './RoomShakingEffect';
export * from './SpriteUtilities';
export * from './TextureUtils';
export * from './Vector3d';

1139
yarn.lock Normal file

File diff suppressed because it is too large Load Diff