🆙 Small Fixes

This commit is contained in:
duckietm
2026-04-14 11:19:53 +02:00
parent 399999f23d
commit ca5e754b28
65 changed files with 1717 additions and 125 deletions
@@ -80,6 +80,8 @@ export class RoomObjectVariable
public static FURNITURE_BADGE_ASSET_NAME: string = 'furniture_badge_asset_name'; public static FURNITURE_BADGE_ASSET_NAME: string = 'furniture_badge_asset_name';
public static FURNITURE_BADGE_VISIBLE_IN_STATE: string = 'furniture_badge_visible_in_state'; public static FURNITURE_BADGE_VISIBLE_IN_STATE: string = 'furniture_badge_visible_in_state';
public static FURNITURE_ALPHA_MULTIPLIER: string = 'furniture_alpha_multiplier'; public static FURNITURE_ALPHA_MULTIPLIER: string = 'furniture_alpha_multiplier';
public static FURNITURE_CONF_INVIS_HIDDEN: string = 'furniture_conf_invis_hidden';
public static FURNITURE_AREA_HIDE_HIDDEN: string = 'furniture_area_hide_hidden';
public static FURNITURE_USAGE_POLICY: string = 'furniture_usage_policy'; public static FURNITURE_USAGE_POLICY: string = 'furniture_usage_policy';
public static FURNITURE_OWNER_ID: string = 'furniture_owner_id'; public static FURNITURE_OWNER_ID: string = 'furniture_owner_id';
public static FURNITURE_OWNER_NAME: string = 'furniture_owner_name'; public static FURNITURE_OWNER_NAME: string = 'furniture_owner_name';
@@ -103,6 +105,7 @@ export class RoomObjectVariable
public static FURNITURE_USES_PLANE_MASK: string = 'furniture_uses_plane_mask'; public static FURNITURE_USES_PLANE_MASK: string = 'furniture_uses_plane_mask';
public static FURNITURE_PLANE_MASK_TYPE: string = 'furniture_plane_mask_type'; public static FURNITURE_PLANE_MASK_TYPE: string = 'furniture_plane_mask_type';
public static FURNITURE_IS_VARIABLE_HEIGHT: string = 'furniture_is_variable_height'; public static FURNITURE_IS_VARIABLE_HEIGHT: string = 'furniture_is_variable_height';
public static FURNITURE_IS_WALK_HEIGHT_HELPER: string = 'furniture_is_walk_height_helper';
public static FURNITURE_VOTE_MAJORITY_RESULT: string = 'furniture_vote_majority_result'; public static FURNITURE_VOTE_MAJORITY_RESULT: string = 'furniture_vote_majority_result';
public static FURNITURE_VOTE_COUNTER_COUNT: string = 'furniture_vote_counter_count'; public static FURNITURE_VOTE_COUNTER_COUNT: string = 'furniture_vote_counter_count';
public static FURNITURE_SOUNDBLOCK_RELATIVE_ANIMATION_SPEED: string = 'furniture_soundblock_relative_animation_speed'; public static FURNITURE_SOUNDBLOCK_RELATIVE_ANIMATION_SPEED: string = 'furniture_soundblock_relative_animation_speed';
-3
View File
@@ -315,9 +315,6 @@ export class AvatarImage implements IAvatarImage, IAvatarEffectListener
const url = canvas.toDataURL('image/png'); const url = canvas.toDataURL('image/png');
canvas.width = 0;
canvas.height = 0;
return url; return url;
} }
-6
View File
@@ -23,12 +23,6 @@ export class ImageData
public dispose(): void public dispose(): void
{ {
if(this._container)
{
this._container.destroy({ children: true });
this._container = null;
}
this._texture = null; this._texture = null;
this._regPoint = null; this._regPoint = null;
this._colorTransform = null; this._colorTransform = null;
@@ -117,12 +117,7 @@ export class RoomCameraWidgetManager implements IRoomCameraWidgetManager
TextureUtils.writeToTexture(container, renderTexture); TextureUtils.writeToTexture(container, renderTexture);
const image = await TextureUtils.generateImage(renderTexture); return await TextureUtils.generateImage(renderTexture);
renderTexture.destroy(true);
container.destroy({ children: true });
return image;
} }
public get effects(): Map<string, IRoomCameraWidgetEffect> public get effects(): Map<string, IRoomCameraWidgetEffect>
File diff suppressed because one or more lines are too long
+3
View File
@@ -66,6 +66,7 @@ export * from './messages/incoming/room/furniture';
export * from './messages/incoming/room/furniture/floor'; export * from './messages/incoming/room/furniture/floor';
export * from './messages/incoming/room/furniture/wall'; export * from './messages/incoming/room/furniture/wall';
export * from './messages/incoming/room/furniture/youtube'; export * from './messages/incoming/room/furniture/youtube';
export * from './messages/incoming/room/youtube';
export * from './messages/incoming/room/mapping'; export * from './messages/incoming/room/mapping';
export * from './messages/incoming/room/pet'; export * from './messages/incoming/room/pet';
export * from './messages/incoming/room/session'; export * from './messages/incoming/room/session';
@@ -142,6 +143,7 @@ export * from './messages/outgoing/room/furniture/presents';
export * from './messages/outgoing/room/furniture/toner'; export * from './messages/outgoing/room/furniture/toner';
export * from './messages/outgoing/room/furniture/wall'; export * from './messages/outgoing/room/furniture/wall';
export * from './messages/outgoing/room/furniture/youtube'; export * from './messages/outgoing/room/furniture/youtube';
export * from './messages/outgoing/room/youtube';
export * from './messages/outgoing/room/layout'; export * from './messages/outgoing/room/layout';
export * from './messages/outgoing/room/pets'; export * from './messages/outgoing/room/pets';
export * from './messages/outgoing/room/session'; export * from './messages/outgoing/room/session';
@@ -223,6 +225,7 @@ export * from './messages/parser/room/furniture';
export * from './messages/parser/room/furniture/floor'; export * from './messages/parser/room/furniture/floor';
export * from './messages/parser/room/furniture/wall'; export * from './messages/parser/room/furniture/wall';
export * from './messages/parser/room/furniture/youtube'; export * from './messages/parser/room/furniture/youtube';
export * from './messages/parser/room/youtube';
export * from './messages/parser/room/mapping'; export * from './messages/parser/room/mapping';
export * from './messages/parser/room/pet'; export * from './messages/parser/room/pet';
export * from './messages/parser/room/session'; export * from './messages/parser/room/session';
@@ -269,6 +269,11 @@ export class IncomingHeader
public static WIRED_ACTION = 1434; public static WIRED_ACTION = 1434;
public static WIRED_CONDITION = 1108; public static WIRED_CONDITION = 1108;
public static WIRED_ERROR = 156; public static WIRED_ERROR = 156;
public static WIRED_MONITOR_DATA = 5101;
public static WIRED_ROOM_SETTINGS_DATA = 5102;
public static WIRED_USER_VARIABLES_DATA = 5103;
public static CONF_INVIS_STATE = 5104;
public static HANDITEM_BLOCK_STATE = 5105;
public static WIRED_OPEN = 1830; public static WIRED_OPEN = 1830;
public static WIRED_REWARD = 178; public static WIRED_REWARD = 178;
public static WIRED_SAVE = 1155; public static WIRED_SAVE = 1155;
@@ -490,8 +495,8 @@ export class IncomingHeader
public static USER_PREFIXES = 7001; public static USER_PREFIXES = 7001;
public static PREFIX_RECEIVED = 7002; public static PREFIX_RECEIVED = 7002;
public static ACTIVE_PREFIX_UPDATED = 7003; public static ACTIVE_PREFIX_UPDATED = 7003;
// YouTube Room Broadcast // YouTube Room Broadcast
public static YOUTUBE_ROOM_BROADCAST = 8001; public static YOUTUBE_ROOM_BROADCAST = 8001;
public static YOUTUBE_ROOM_WATCHERS = 8002; public static YOUTUBE_ROOM_WATCHERS = 8002;
public static YOUTUBE_ROOM_SETTINGS = 8003; public static YOUTUBE_ROOM_SETTINGS = 8003;
@@ -58,6 +58,7 @@ export * from './room/furniture';
export * from './room/furniture/floor'; export * from './room/furniture/floor';
export * from './room/furniture/wall'; export * from './room/furniture/wall';
export * from './room/furniture/youtube'; export * from './room/furniture/youtube';
export * from './room/youtube';
export * from './room/mapping'; export * from './room/mapping';
export * from './room/pet'; export * from './room/pet';
export * from './room/session'; export * from './room/session';
@@ -0,0 +1,16 @@
import { IMessageEvent } from '@nitrots/api';
import { MessageEvent } from '@nitrots/events';
import { ConfInvisStateMessageParser } from '../../../parser';
export class ConfInvisStateMessageEvent extends MessageEvent implements IMessageEvent
{
constructor(callBack: Function)
{
super(callBack, ConfInvisStateMessageParser);
}
public getParser(): ConfInvisStateMessageParser
{
return this.parser as ConfInvisStateMessageParser;
}
}
@@ -0,0 +1,16 @@
import { IMessageEvent } from '@nitrots/api';
import { MessageEvent } from '@nitrots/events';
import { HanditemBlockStateMessageParser } from '../../../parser';
export class HanditemBlockStateMessageEvent extends MessageEvent implements IMessageEvent
{
constructor(callBack: Function)
{
super(callBack, HanditemBlockStateMessageParser);
}
public getParser(): HanditemBlockStateMessageParser
{
return this.parser as HanditemBlockStateMessageParser;
}
}
@@ -1,4 +1,5 @@
export * from './AreaHideMessageEvent'; export * from './AreaHideMessageEvent';
export * from './ConfInvisStateMessageEvent';
export * from './CustomUserNotificationMessageEvent'; export * from './CustomUserNotificationMessageEvent';
export * from './DiceValueMessageEvent'; export * from './DiceValueMessageEvent';
export * from './FurniRentOrBuyoutOfferMessageEvent'; export * from './FurniRentOrBuyoutOfferMessageEvent';
@@ -6,6 +7,7 @@ export * from './FurnitureAliasesEvent';
export * from './FurnitureDataEvent'; export * from './FurnitureDataEvent';
export * from './FurnitureStackHeightEvent'; export * from './FurnitureStackHeightEvent';
export * from './GroupFurniContextMenuInfoMessageEvent'; export * from './GroupFurniContextMenuInfoMessageEvent';
export * from './HanditemBlockStateMessageEvent';
export * from './ItemDataUpdateMessageEvent'; export * from './ItemDataUpdateMessageEvent';
export * from './LoveLockFurniFinishedEvent'; export * from './LoveLockFurniFinishedEvent';
export * from './LoveLockFurniFriendConfirmedEvent'; export * from './LoveLockFurniFriendConfirmedEvent';
@@ -13,4 +13,3 @@ export * from './pet';
export * from './session'; export * from './session';
export * from './unit'; export * from './unit';
export * from './unit/chat'; export * from './unit/chat';
export * from './youtube';
@@ -0,0 +1,16 @@
import { IMessageEvent } from '@nitrots/api';
import { MessageEvent } from '@nitrots/events';
import { WiredMonitorDataParser } from '../../parser';
export class WiredMonitorDataEvent extends MessageEvent implements IMessageEvent
{
constructor(callBack: Function)
{
super(callBack, WiredMonitorDataParser);
}
public getParser(): WiredMonitorDataParser
{
return this.parser as WiredMonitorDataParser;
}
}
@@ -0,0 +1,16 @@
import { IMessageEvent } from '@nitrots/api';
import { MessageEvent } from '@nitrots/events';
import { WiredRoomSettingsDataParser } from '../../parser';
export class WiredRoomSettingsDataEvent extends MessageEvent implements IMessageEvent
{
constructor(callBack: Function)
{
super(callBack, WiredRoomSettingsDataParser);
}
public getParser(): WiredRoomSettingsDataParser
{
return this.parser as WiredRoomSettingsDataParser;
}
}
@@ -0,0 +1,16 @@
import { IMessageEvent } from '@nitrots/api';
import { MessageEvent } from '@nitrots/events';
import { WiredUserVariablesDataParser } from '../../parser';
export class WiredUserVariablesDataEvent extends MessageEvent implements IMessageEvent
{
constructor(callBack: Function)
{
super(callBack, WiredUserVariablesDataParser);
}
public getParser(): WiredUserVariablesDataParser
{
return this.parser as WiredUserVariablesDataParser;
}
}
@@ -1,7 +1,10 @@
export * from './WiredFurniActionEvent'; export * from './WiredFurniActionEvent';
export * from './WiredFurniConditionEvent'; export * from './WiredFurniConditionEvent';
export * from './WiredFurniTriggerEvent'; export * from './WiredFurniTriggerEvent';
export * from './WiredMonitorDataEvent';
export * from './WiredOpenEvent'; export * from './WiredOpenEvent';
export * from './WiredRoomSettingsDataEvent';
export * from './WiredRewardResultMessageEvent'; export * from './WiredRewardResultMessageEvent';
export * from './WiredSaveSuccessEvent'; export * from './WiredSaveSuccessEvent';
export * from './WiredUserVariablesDataEvent';
export * from './WiredValidationErrorEvent'; export * from './WiredValidationErrorEvent';
@@ -271,6 +271,13 @@ export class OutgoingHeader
public static WIRED_ACTION_SAVE = 2281; public static WIRED_ACTION_SAVE = 2281;
public static WIRED_APPLY_SNAPSHOT = 3373; public static WIRED_APPLY_SNAPSHOT = 3373;
public static WIRED_CONDITION_SAVE = 3203; public static WIRED_CONDITION_SAVE = 3203;
public static WIRED_MONITOR_REQUEST = 10021;
public static WIRED_ROOM_SETTINGS_REQUEST = 10022;
public static WIRED_ROOM_SETTINGS_SAVE = 10023;
public static WIRED_USER_VARIABLES_REQUEST = 10024;
public static WIRED_USER_VARIABLE_UPDATE = 10025;
public static WIRED_USER_VARIABLE_MANAGE = 10026;
public static WIRED_USER_INSPECT_MOVE = 10027;
public static WIRED_OPEN = 768; public static WIRED_OPEN = 768;
public static WIRED_TRIGGER_SAVE = 1520; public static WIRED_TRIGGER_SAVE = 1520;
public static GET_ITEM_DATA = 3964; public static GET_ITEM_DATA = 3964;
@@ -503,9 +510,4 @@ export class OutgoingHeader
public static SET_ACTIVE_PREFIX = 7012; public static SET_ACTIVE_PREFIX = 7012;
public static DELETE_PREFIX = 7013; public static DELETE_PREFIX = 7013;
public static PURCHASE_PREFIX = 7014; public static PURCHASE_PREFIX = 7014;
// YouTube Room Broadcast
public static YOUTUBE_ROOM_PLAY = 8001;
public static YOUTUBE_ROOM_WATCHING = 8002;
public static YOUTUBE_ROOM_SETTINGS = 8003;
} }
@@ -4,9 +4,9 @@ export class CatalogAdminCreateOfferComposer implements IMessageComposer<Constru
{ {
private _data: ConstructorParameters<typeof CatalogAdminCreateOfferComposer>; private _data: ConstructorParameters<typeof CatalogAdminCreateOfferComposer>;
constructor(pageId: number, itemId: number, catalogName: string, costCredits: number, costPoints: number, pointsType: number, amount: number, clubOnly: number, extradata: string, haveOffer: boolean, offerIdGroup: number, limitedStack: number, orderNumber: number) constructor(pageId: number, itemId: number, catalogName: string, costCredits: number, costPoints: number, pointsType: number, amount: number, clubOnly: number, extradata: string, haveOffer: boolean, offerIdGroup: number, limitedStack: number, orderNumber: number, catalogMode: string = 'NORMAL')
{ {
this._data = [ pageId, itemId, catalogName, costCredits, costPoints, pointsType, amount, clubOnly, extradata, haveOffer, offerIdGroup, limitedStack, orderNumber ]; this._data = [ pageId, itemId, catalogName, costCredits, costPoints, pointsType, amount, clubOnly, extradata, haveOffer, offerIdGroup, limitedStack, orderNumber, catalogMode ];
} }
dispose(): void dispose(): void
@@ -4,9 +4,9 @@ export class CatalogAdminCreatePageComposer implements IMessageComposer<Construc
{ {
private _data: ConstructorParameters<typeof CatalogAdminCreatePageComposer>; private _data: ConstructorParameters<typeof CatalogAdminCreatePageComposer>;
constructor(caption: string, caption2: string, layout: string, iconType: number, minRank: number, visible: boolean, enabled: boolean, orderNum: number, parentId: number) constructor(caption: string, caption2: string, layout: string, iconType: number, minRank: number, visible: boolean, enabled: boolean, orderNum: number, parentId: number, targetCatalogType: string, catalogMode: string = 'NORMAL')
{ {
this._data = [ caption, caption2, layout, iconType, minRank, visible, enabled, orderNum, parentId ]; this._data = [ caption, caption2, layout, iconType, minRank, visible, enabled, orderNum, parentId, targetCatalogType, catalogMode ];
} }
dispose(): void dispose(): void
@@ -4,9 +4,9 @@ export class CatalogAdminDeleteOfferComposer implements IMessageComposer<Constru
{ {
private _data: ConstructorParameters<typeof CatalogAdminDeleteOfferComposer>; private _data: ConstructorParameters<typeof CatalogAdminDeleteOfferComposer>;
constructor(offerId: number) constructor(offerId: number, catalogMode: string = 'NORMAL')
{ {
this._data = [ offerId ]; this._data = [ offerId, catalogMode ];
} }
dispose(): void dispose(): void
@@ -4,9 +4,9 @@ export class CatalogAdminDeletePageComposer implements IMessageComposer<Construc
{ {
private _data: ConstructorParameters<typeof CatalogAdminDeletePageComposer>; private _data: ConstructorParameters<typeof CatalogAdminDeletePageComposer>;
constructor(pageId: number) constructor(pageId: number, catalogMode: string = 'NORMAL')
{ {
this._data = [ pageId ]; this._data = [ pageId, catalogMode ];
} }
dispose(): void dispose(): void
@@ -4,9 +4,9 @@ export class CatalogAdminMoveOfferComposer implements IMessageComposer<Construct
{ {
private _data: ConstructorParameters<typeof CatalogAdminMoveOfferComposer>; private _data: ConstructorParameters<typeof CatalogAdminMoveOfferComposer>;
constructor(offerId: number, orderNumber: number) constructor(offerId: number, orderNumber: number, catalogMode: string = 'NORMAL')
{ {
this._data = [ offerId, orderNumber ]; this._data = [ offerId, orderNumber, catalogMode ];
} }
dispose(): void dispose(): void
@@ -4,9 +4,9 @@ export class CatalogAdminMovePageComposer implements IMessageComposer<Constructo
{ {
private _data: ConstructorParameters<typeof CatalogAdminMovePageComposer>; private _data: ConstructorParameters<typeof CatalogAdminMovePageComposer>;
constructor(pageId: number, newParentId: number, newIndex: number) constructor(pageId: number, newParentId: number, newIndex: number, catalogMode: string = 'NORMAL')
{ {
this._data = [ pageId, newParentId, newIndex ]; this._data = [ pageId, newParentId, newIndex, catalogMode ];
} }
dispose(): void dispose(): void
@@ -4,9 +4,9 @@ export class CatalogAdminSaveOfferComposer implements IMessageComposer<Construct
{ {
private _data: ConstructorParameters<typeof CatalogAdminSaveOfferComposer>; private _data: ConstructorParameters<typeof CatalogAdminSaveOfferComposer>;
constructor(offerId: number, pageId: number, itemId: number, catalogName: string, costCredits: number, costPoints: number, pointsType: number, amount: number, clubOnly: number, extradata: string, haveOffer: boolean, offerIdGroup: number, limitedStack: number, orderNumber: number) constructor(offerId: number, pageId: number, itemId: number, catalogName: string, costCredits: number, costPoints: number, pointsType: number, amount: number, clubOnly: number, extradata: string, haveOffer: boolean, offerIdGroup: number, limitedStack: number, orderNumber: number, catalogMode: string = 'NORMAL')
{ {
this._data = [ offerId, pageId, itemId, catalogName, costCredits, costPoints, pointsType, amount, clubOnly, extradata, haveOffer, offerIdGroup, limitedStack, orderNumber ]; this._data = [ offerId, pageId, itemId, catalogName, costCredits, costPoints, pointsType, amount, clubOnly, extradata, haveOffer, offerIdGroup, limitedStack, orderNumber, catalogMode ];
} }
dispose(): void dispose(): void
@@ -4,9 +4,9 @@ export class CatalogAdminSavePageComposer implements IMessageComposer<Constructo
{ {
private _data: ConstructorParameters<typeof CatalogAdminSavePageComposer>; private _data: ConstructorParameters<typeof CatalogAdminSavePageComposer>;
constructor(pageId: number, caption: string, caption2: string, layout: string, iconType: number, minRank: number, visible: boolean, enabled: boolean, orderNum: number, parentId: number, headline: string, teaser: string, textDetails: string) constructor(pageId: number, caption: string, caption2: string, layout: string, iconType: number, minRank: number, visible: boolean, enabled: boolean, orderNum: number, parentId: number, headline: string, teaser: string, textDetails: string, targetCatalogType: string, catalogMode: string = 'NORMAL')
{ {
this._data = [ pageId, caption, caption2, layout, iconType, minRank, visible, enabled, orderNum, parentId, headline, teaser, textDetails ]; this._data = [ pageId, caption, caption2, layout, iconType, minRank, visible, enabled, orderNum, parentId, headline, teaser, textDetails, targetCatalogType, catalogMode ];
} }
dispose(): void dispose(): void
@@ -55,6 +55,7 @@ export * from './room/furniture/presents';
export * from './room/furniture/toner'; export * from './room/furniture/toner';
export * from './room/furniture/wall'; export * from './room/furniture/wall';
export * from './room/furniture/youtube'; export * from './room/furniture/youtube';
export * from './room/youtube';
export * from './room/layout'; export * from './room/layout';
export * from './room/pets'; export * from './room/pets';
export * from './room/session'; export * from './room/session';
@@ -17,4 +17,3 @@ export * from './RedeemItemClothingComposer';
export * from './session'; export * from './session';
export * from './unit'; export * from './unit';
export * from './unit/chat'; export * from './unit/chat';
export * from './youtube';
@@ -6,8 +6,6 @@ export class YouTubeRoomWatchingComposer implements IMessageComposer<any[]>
constructor(watching: boolean) constructor(watching: boolean)
{ {
// Send as int (0/1) instead of bare boolean to avoid
// serialization ambiguity in the Nitro wire protocol.
this._data = [watching ? 1 : 0]; this._data = [watching ? 1 : 0];
} }
@@ -0,0 +1,21 @@
import { IMessageComposer } from '@nitrots/api';
export class WiredMonitorRequestComposer implements IMessageComposer<ConstructorParameters<typeof WiredMonitorRequestComposer>>
{
private _data: ConstructorParameters<typeof WiredMonitorRequestComposer>;
constructor(action: number = 0)
{
this._data = [ action ];
}
public getMessageArray()
{
return this._data;
}
public dispose(): void
{
return;
}
}
@@ -0,0 +1,14 @@
import { IMessageComposer } from '@nitrots/api';
export class WiredRoomSettingsRequestComposer implements IMessageComposer<ConstructorParameters<typeof WiredRoomSettingsRequestComposer>>
{
public getMessageArray()
{
return [];
}
public dispose(): void
{
return;
}
}
@@ -0,0 +1,21 @@
import { IMessageComposer } from '@nitrots/api';
export class WiredRoomSettingsSaveComposer implements IMessageComposer<ConstructorParameters<typeof WiredRoomSettingsSaveComposer>>
{
private _data: ConstructorParameters<typeof WiredRoomSettingsSaveComposer>;
constructor(inspectMask: number, modifyMask: number)
{
this._data = [ inspectMask, modifyMask ];
}
public getMessageArray()
{
return this._data;
}
public dispose(): void
{
return;
}
}
@@ -0,0 +1,21 @@
import { IMessageComposer } from '@nitrots/api';
export class WiredUserInspectMoveComposer implements IMessageComposer<ConstructorParameters<typeof WiredUserInspectMoveComposer>>
{
private _data: ConstructorParameters<typeof WiredUserInspectMoveComposer>;
constructor(roomUnitId: number, x: number, y: number, direction: number)
{
this._data = [ roomUnitId, x, y, direction ];
}
public getMessageArray()
{
return this._data;
}
public dispose(): void
{
return;
}
}
@@ -0,0 +1,21 @@
import { IMessageComposer } from '@nitrots/api';
export class WiredUserVariableManageComposer implements IMessageComposer<ConstructorParameters<typeof WiredUserVariableManageComposer>>
{
private _data: ConstructorParameters<typeof WiredUserVariableManageComposer>;
constructor(action: number, targetType: number, targetId: number, variableItemId: number, value: number)
{
this._data = [ action, targetType, targetId, variableItemId, value ];
}
public getMessageArray()
{
return this._data;
}
public dispose(): void
{
return;
}
}
@@ -0,0 +1,21 @@
import { IMessageComposer } from '@nitrots/api';
export class WiredUserVariableUpdateComposer implements IMessageComposer<ConstructorParameters<typeof WiredUserVariableUpdateComposer>>
{
private _data: ConstructorParameters<typeof WiredUserVariableUpdateComposer>;
constructor(targetType: number, targetId: number, variableItemId: number, value: number)
{
this._data = [ targetType, targetId, variableItemId, value ];
}
public getMessageArray()
{
return this._data;
}
public dispose(): void
{
return;
}
}
@@ -0,0 +1,14 @@
import { IMessageComposer } from '@nitrots/api';
export class WiredUserVariablesRequestComposer implements IMessageComposer<ConstructorParameters<typeof WiredUserVariablesRequestComposer>>
{
public getMessageArray()
{
return [];
}
public dispose(): void
{
return;
}
}
@@ -4,3 +4,10 @@ export * from './RoomMuteComposer';
export * from './UpdateActionMessageComposer'; export * from './UpdateActionMessageComposer';
export * from './UpdateConditionMessageComposer'; export * from './UpdateConditionMessageComposer';
export * from './UpdateTriggerMessageComposer'; export * from './UpdateTriggerMessageComposer';
export * from './WiredMonitorRequestComposer';
export * from './WiredRoomSettingsRequestComposer';
export * from './WiredRoomSettingsSaveComposer';
export * from './WiredUserInspectMoveComposer';
export * from './WiredUserVariableManageComposer';
export * from './WiredUserVariablesRequestComposer';
export * from './WiredUserVariableUpdateComposer';
@@ -6,6 +6,8 @@ export class BuildersClubSubscriptionStatusMessageParser implements IMessagePars
private _furniLimit: number; private _furniLimit: number;
private _maxFurniLimit: number; private _maxFurniLimit: number;
private _secondsLeftWithGrace: number; private _secondsLeftWithGrace: number;
private _placementBlockedByVisitors: boolean;
private _placementAllowedInCurrentRoom: boolean;
public flush(): boolean public flush(): boolean
{ {
@@ -13,6 +15,8 @@ export class BuildersClubSubscriptionStatusMessageParser implements IMessagePars
this._furniLimit = 0; this._furniLimit = 0;
this._maxFurniLimit = 0; this._maxFurniLimit = 0;
this._secondsLeftWithGrace = 0; this._secondsLeftWithGrace = 0;
this._placementBlockedByVisitors = false;
this._placementAllowedInCurrentRoom = false;
return true; return true;
} }
@@ -28,6 +32,12 @@ export class BuildersClubSubscriptionStatusMessageParser implements IMessagePars
if(wrapper.bytesAvailable) this._secondsLeftWithGrace = wrapper.readInt(); if(wrapper.bytesAvailable) this._secondsLeftWithGrace = wrapper.readInt();
else this._secondsLeftWithGrace = this._secondsLeft; else this._secondsLeftWithGrace = this._secondsLeft;
if(wrapper.bytesAvailable) this._placementBlockedByVisitors = wrapper.readBoolean();
else this._placementBlockedByVisitors = false;
if(wrapper.bytesAvailable) this._placementAllowedInCurrentRoom = wrapper.readBoolean();
else this._placementAllowedInCurrentRoom = false;
return true; return true;
} }
@@ -50,4 +60,14 @@ export class BuildersClubSubscriptionStatusMessageParser implements IMessagePars
{ {
return this._secondsLeftWithGrace; return this._secondsLeftWithGrace;
} }
public get placementBlockedByVisitors(): boolean
{
return this._placementBlockedByVisitors;
}
public get placementAllowedInCurrentRoom(): boolean
{
return this._placementAllowedInCurrentRoom;
}
} }
@@ -4,10 +4,12 @@ import { ClubOfferData } from './ClubOfferData';
export class HabboClubOffersMessageParser implements IMessageParser export class HabboClubOffersMessageParser implements IMessageParser
{ {
private _offers: ClubOfferData[]; private _offers: ClubOfferData[];
private _windowId = 1;
public flush(): boolean public flush(): boolean
{ {
this._offers = []; this._offers = [];
this._windowId = 1;
return true; return true;
} }
@@ -25,6 +27,8 @@ export class HabboClubOffersMessageParser implements IMessageParser
totalOffers--; totalOffers--;
} }
if(wrapper.bytesAvailable) this._windowId = wrapper.readInt();
return true; return true;
} }
@@ -32,4 +36,9 @@ export class HabboClubOffersMessageParser implements IMessageParser
{ {
return this._offers; return this._offers;
} }
public get windowId(): number
{
return this._windowId;
}
} }
@@ -59,6 +59,7 @@ export * from './room/furniture';
export * from './room/furniture/floor'; export * from './room/furniture/floor';
export * from './room/furniture/wall'; export * from './room/furniture/wall';
export * from './room/furniture/youtube'; export * from './room/furniture/youtube';
export * from './room/youtube';
export * from './room/mapping'; export * from './room/mapping';
export * from './room/pet'; export * from './room/pet';
export * from './room/session'; export * from './room/session';
@@ -1,16 +1,14 @@
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
export class BadgeReceivedParser implements IMessageParser export class BadgeReceivedParser implements IMessageParser
{ {
private _badgeId: number; private _badgeId: number;
private _badgeCode: string; private _badgeCode: string;
private _senderName: string;
public flush(): boolean public flush(): boolean
{ {
this._badgeId = 0; this._badgeId = 0;
this._badgeCode = null; this._badgeCode = null;
this._senderName = '';
return true; return true;
} }
@@ -21,10 +19,6 @@ export class BadgeReceivedParser implements IMessageParser
this._badgeId = wrapper.readInt(); this._badgeId = wrapper.readInt();
this._badgeCode = wrapper.readString(); this._badgeCode = wrapper.readString();
// Extra field appended by the Arcturus-Nitro fork: sender username for
// badges awarded by a staff member via the `:badge` command. Read
// defensively so older servers that don't send it still parse cleanly.
this._senderName = wrapper.bytesAvailable ? wrapper.readString() : '';
return true; return true;
} }
@@ -38,9 +32,4 @@ export class BadgeReceivedParser implements IMessageParser
{ {
return this._badgeCode; return this._badgeCode;
} }
public get senderName(): string
{
return this._senderName;
}
} }
@@ -9,6 +9,8 @@ export class AreaHideMessageData
private _width: number; private _width: number;
private _length: number; private _length: number;
private _invert: boolean; private _invert: boolean;
private _wallItems: boolean;
private _invisibility: boolean;
constructor(wrapper: IMessageDataWrapper) constructor(wrapper: IMessageDataWrapper)
{ {
@@ -19,6 +21,8 @@ export class AreaHideMessageData
this._width = wrapper.readInt(); this._width = wrapper.readInt();
this._length = wrapper.readInt(); this._length = wrapper.readInt();
this._invert = wrapper.readBoolean(); this._invert = wrapper.readBoolean();
this._wallItems = wrapper.readBoolean();
this._invisibility = wrapper.readBoolean();
} }
public get furniId(): number public get furniId(): number
@@ -55,4 +59,14 @@ export class AreaHideMessageData
{ {
return this._invert; return this._invert;
} }
public get wallItems(): boolean
{
return this._wallItems;
}
public get invisibility(): boolean
{
return this._invisibility;
}
} }
@@ -0,0 +1,38 @@
import { IMessageDataWrapper } from '@nitrots/api';
export class ConfInvisStateMessageData
{
private _roomId: number;
private _active: boolean;
private _hiddenItemIds: number[];
constructor(wrapper: IMessageDataWrapper)
{
this._roomId = wrapper.readInt();
this._active = wrapper.readBoolean();
const totalHiddenItems = wrapper.readInt();
this._hiddenItemIds = [];
for(let index = 0; index < totalHiddenItems; index++)
{
this._hiddenItemIds.push(wrapper.readInt());
}
}
public get roomId(): number
{
return this._roomId;
}
public get hiddenItemIds(): number[]
{
return this._hiddenItemIds;
}
public get active(): boolean
{
return this._active;
}
}
@@ -0,0 +1,23 @@
import { IMessageDataWrapper } from '@nitrots/api';
export class HanditemBlockStateMessageData
{
private _roomId: number;
private _blocked: boolean;
constructor(wrapper: IMessageDataWrapper)
{
this._roomId = wrapper.readInt();
this._blocked = wrapper.readBoolean();
}
public get roomId(): number
{
return this._roomId;
}
public get blocked(): boolean
{
return this._blocked;
}
}
@@ -1,4 +1,6 @@
export * from './AreaHideMessageData'; export * from './AreaHideMessageData';
export * from './ConfInvisStateMessageData';
export * from './HanditemBlockStateMessageData';
export * from './FavoriteMembershipUpdateMessageParser'; export * from './FavoriteMembershipUpdateMessageParser';
export * from './ObjectData'; export * from './ObjectData';
export * from './ObjectsDataUpdateParser'; export * from './ObjectsDataUpdateParser';
@@ -0,0 +1,28 @@
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
import { ConfInvisStateMessageData } from '../engine';
export class ConfInvisStateMessageParser implements IMessageParser
{
private _stateData: ConfInvisStateMessageData;
public flush(): boolean
{
this._stateData = null;
return true;
}
public parse(wrapper: IMessageDataWrapper): boolean
{
if(!wrapper) return false;
this._stateData = new ConfInvisStateMessageData(wrapper);
return true;
}
public get stateData(): ConfInvisStateMessageData
{
return this._stateData;
}
}
@@ -0,0 +1,28 @@
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
import { HanditemBlockStateMessageData } from '../engine';
export class HanditemBlockStateMessageParser implements IMessageParser
{
private _stateData: HanditemBlockStateMessageData;
public flush(): boolean
{
this._stateData = null;
return true;
}
public parse(wrapper: IMessageDataWrapper): boolean
{
if(!wrapper) return false;
this._stateData = new HanditemBlockStateMessageData(wrapper);
return true;
}
public get stateData(): HanditemBlockStateMessageData
{
return this._stateData;
}
}
@@ -1,4 +1,5 @@
export * from './AreaHideMessageParser'; export * from './AreaHideMessageParser';
export * from './ConfInvisStateMessageParser';
export * from './CustomUserNotificationMessageParser'; export * from './CustomUserNotificationMessageParser';
export * from './DiceValueMessageParser'; export * from './DiceValueMessageParser';
export * from './FurniRentOrBuyoutOfferMessageParser'; export * from './FurniRentOrBuyoutOfferMessageParser';
@@ -6,6 +7,7 @@ export * from './FurnitureAliasesParser';
export * from './FurnitureDataParser'; export * from './FurnitureDataParser';
export * from './FurnitureStackHeightParser'; export * from './FurnitureStackHeightParser';
export * from './GroupFurniContextMenuInfoMessageParser'; export * from './GroupFurniContextMenuInfoMessageParser';
export * from './HanditemBlockStateMessageParser';
export * from './ItemDataUpdateMessageParser'; export * from './ItemDataUpdateMessageParser';
export * from './LoveLockFurniFinishedParser'; export * from './LoveLockFurniFinishedParser';
export * from './LoveLockFurniFriendConfirmedParser'; export * from './LoveLockFurniFriendConfirmedParser';
@@ -13,4 +13,3 @@ export * from './pet';
export * from './session'; export * from './session';
export * from './unit'; export * from './unit';
export * from './unit/chat'; export * from './unit/chat';
export * from './youtube';
@@ -0,0 +1,222 @@
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
export interface IWiredMonitorLogData
{
amount: number;
latestOccurrenceSeconds: number;
latestReason: string;
latestSourceId: number;
latestSourceLabel: string;
severity: string;
type: string;
}
export interface IWiredMonitorHistoryData
{
occurredAtSeconds: number;
reason: string;
sourceId: number;
sourceLabel: string;
severity: string;
type: string;
}
export class WiredMonitorDataParser implements IMessageParser
{
private _usageCurrentWindow: number;
private _usageLimitPerWindow: number;
private _isHeavy: boolean;
private _delayedEventsPending: number;
private _delayedEventsLimit: number;
private _averageExecutionMs: number;
private _peakExecutionMs: number;
private _recursionDepthCurrent: number;
private _recursionDepthLimit: number;
private _killedRemainingSeconds: number;
private _usageWindowMs: number;
private _overloadAverageThresholdMs: number;
private _overloadPeakThresholdMs: number;
private _heavyUsageThresholdPercent: number;
private _heavyConsecutiveWindowsThreshold: number;
private _overloadConsecutiveWindowsThreshold: number;
private _heavyDelayedThresholdPercent: number;
private _logs: IWiredMonitorLogData[];
private _history: IWiredMonitorHistoryData[];
public flush(): boolean
{
this._usageCurrentWindow = 0;
this._usageLimitPerWindow = 0;
this._isHeavy = false;
this._delayedEventsPending = 0;
this._delayedEventsLimit = 0;
this._averageExecutionMs = 0;
this._peakExecutionMs = 0;
this._recursionDepthCurrent = 0;
this._recursionDepthLimit = 0;
this._killedRemainingSeconds = 0;
this._usageWindowMs = 0;
this._overloadAverageThresholdMs = 0;
this._overloadPeakThresholdMs = 0;
this._heavyUsageThresholdPercent = 0;
this._heavyConsecutiveWindowsThreshold = 0;
this._overloadConsecutiveWindowsThreshold = 0;
this._heavyDelayedThresholdPercent = 0;
this._logs = [];
this._history = [];
return true;
}
public parse(wrapper: IMessageDataWrapper): boolean
{
if(!wrapper) return false;
this._usageCurrentWindow = wrapper.readInt();
this._usageLimitPerWindow = wrapper.readInt();
this._isHeavy = wrapper.readBoolean();
this._delayedEventsPending = wrapper.readInt();
this._delayedEventsLimit = wrapper.readInt();
this._averageExecutionMs = wrapper.readInt();
this._peakExecutionMs = wrapper.readInt();
this._recursionDepthCurrent = wrapper.readInt();
this._recursionDepthLimit = wrapper.readInt();
this._killedRemainingSeconds = wrapper.readInt();
this._usageWindowMs = wrapper.readInt();
this._overloadAverageThresholdMs = wrapper.readInt();
this._overloadPeakThresholdMs = wrapper.readInt();
this._heavyUsageThresholdPercent = wrapper.readInt();
this._heavyConsecutiveWindowsThreshold = wrapper.readInt();
this._overloadConsecutiveWindowsThreshold = wrapper.readInt();
this._heavyDelayedThresholdPercent = wrapper.readInt();
const totalLogs = wrapper.readInt();
this._logs = [];
this._history = [];
for(let i = 0; i < totalLogs; i++)
{
this._logs.push({
type: wrapper.readString(),
severity: wrapper.readString(),
amount: wrapper.readInt(),
latestOccurrenceSeconds: wrapper.readInt(),
latestReason: wrapper.readString(),
latestSourceLabel: wrapper.readString(),
latestSourceId: wrapper.readInt()
});
}
const totalHistory = wrapper.readInt();
for(let i = 0; i < totalHistory; i++)
{
this._history.push({
type: wrapper.readString(),
severity: wrapper.readString(),
occurredAtSeconds: wrapper.readInt(),
reason: wrapper.readString(),
sourceLabel: wrapper.readString(),
sourceId: wrapper.readInt()
});
}
return true;
}
public get usageCurrentWindow(): number
{
return this._usageCurrentWindow;
}
public get usageLimitPerWindow(): number
{
return this._usageLimitPerWindow;
}
public get isHeavy(): boolean
{
return this._isHeavy;
}
public get delayedEventsPending(): number
{
return this._delayedEventsPending;
}
public get delayedEventsLimit(): number
{
return this._delayedEventsLimit;
}
public get averageExecutionMs(): number
{
return this._averageExecutionMs;
}
public get peakExecutionMs(): number
{
return this._peakExecutionMs;
}
public get recursionDepthCurrent(): number
{
return this._recursionDepthCurrent;
}
public get recursionDepthLimit(): number
{
return this._recursionDepthLimit;
}
public get killedRemainingSeconds(): number
{
return this._killedRemainingSeconds;
}
public get usageWindowMs(): number
{
return this._usageWindowMs;
}
public get overloadAverageThresholdMs(): number
{
return this._overloadAverageThresholdMs;
}
public get overloadPeakThresholdMs(): number
{
return this._overloadPeakThresholdMs;
}
public get heavyUsageThresholdPercent(): number
{
return this._heavyUsageThresholdPercent;
}
public get heavyConsecutiveWindowsThreshold(): number
{
return this._heavyConsecutiveWindowsThreshold;
}
public get overloadConsecutiveWindowsThreshold(): number
{
return this._overloadConsecutiveWindowsThreshold;
}
public get heavyDelayedThresholdPercent(): number
{
return this._heavyDelayedThresholdPercent;
}
public get logs(): IWiredMonitorLogData[]
{
return this._logs;
}
public get history(): IWiredMonitorHistoryData[]
{
return this._history;
}
}
@@ -0,0 +1,67 @@
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
export class WiredRoomSettingsDataParser implements IMessageParser
{
private _roomId: number;
private _inspectMask: number;
private _modifyMask: number;
private _canInspect: boolean;
private _canModify: boolean;
private _canManageSettings: boolean;
public flush(): boolean
{
this._roomId = 0;
this._inspectMask = 0;
this._modifyMask = 0;
this._canInspect = false;
this._canModify = false;
this._canManageSettings = false;
return true;
}
public parse(wrapper: IMessageDataWrapper): boolean
{
if(!wrapper) return false;
this._roomId = wrapper.readInt();
this._inspectMask = wrapper.readInt();
this._modifyMask = wrapper.readInt();
this._canInspect = wrapper.readBoolean();
this._canModify = wrapper.readBoolean();
this._canManageSettings = wrapper.readBoolean();
return true;
}
public get roomId(): number
{
return this._roomId;
}
public get inspectMask(): number
{
return this._inspectMask;
}
public get modifyMask(): number
{
return this._modifyMask;
}
public get canInspect(): boolean
{
return this._canInspect;
}
public get canModify(): boolean
{
return this._canModify;
}
public get canManageSettings(): boolean
{
return this._canManageSettings;
}
}
@@ -0,0 +1,301 @@
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
export interface IWiredUserVariableDefinitionData
{
availability: number;
hasValue: boolean;
isReadOnly: boolean;
isTextConnected: boolean;
itemId: number;
name: string;
}
export interface IWiredUserVariableAssignmentData
{
createdAt: number;
hasValue: boolean;
updatedAt: number;
value: number | null;
variableItemId: number;
}
export interface IWiredUserVariablesUserData
{
assignments: IWiredUserVariableAssignmentData[];
userId: number;
}
export interface IWiredFurniVariableDefinitionData
{
availability: number;
hasValue: boolean;
isReadOnly: boolean;
isTextConnected: boolean;
itemId: number;
name: string;
}
export interface IWiredUserVariablesFurniData
{
assignments: IWiredUserVariableAssignmentData[];
furniId: number;
}
export interface IWiredRoomVariableDefinitionData
{
availability: number;
hasValue: boolean;
isReadOnly: boolean;
isTextConnected: boolean;
itemId: number;
name: string;
}
export interface IWiredRoomVariableAssignmentData
{
createdAt: number;
hasValue: boolean;
updatedAt: number;
value: number | null;
variableItemId: number;
}
export interface IWiredContextVariableDefinitionData
{
availability: number;
hasValue: boolean;
isReadOnly: boolean;
isTextConnected: boolean;
itemId: number;
name: string;
}
export class WiredUserVariablesDataParser implements IMessageParser
{
private _roomId: number;
private _definitions: IWiredUserVariableDefinitionData[];
private _users: IWiredUserVariablesUserData[];
private _furniDefinitions: IWiredFurniVariableDefinitionData[];
private _furnis: IWiredUserVariablesFurniData[];
private _roomDefinitions: IWiredRoomVariableDefinitionData[];
private _roomAssignments: IWiredRoomVariableAssignmentData[];
private _contextDefinitions: IWiredContextVariableDefinitionData[];
public flush(): boolean
{
this._roomId = 0;
this._definitions = [];
this._users = [];
this._furniDefinitions = [];
this._furnis = [];
this._roomDefinitions = [];
this._roomAssignments = [];
this._contextDefinitions = [];
return true;
}
public parse(wrapper: IMessageDataWrapper): boolean
{
if(!wrapper) return false;
this._roomId = wrapper.readInt();
let totalDefinitions = wrapper.readInt();
this._definitions = [];
this._users = [];
this._furniDefinitions = [];
this._furnis = [];
this._roomDefinitions = [];
this._roomAssignments = [];
this._contextDefinitions = [];
while(totalDefinitions > 0)
{
this._definitions.push({
itemId: wrapper.readInt(),
name: wrapper.readString(),
hasValue: wrapper.readBoolean(),
availability: wrapper.readInt(),
isTextConnected: wrapper.readBoolean(),
isReadOnly: wrapper.readBoolean()
});
totalDefinitions--;
}
let totalUsers = wrapper.readInt();
while(totalUsers > 0)
{
const userId = wrapper.readInt();
let totalAssignments = wrapper.readInt();
const assignments: IWiredUserVariableAssignmentData[] = [];
while(totalAssignments > 0)
{
const variableItemId = wrapper.readInt();
const hasValue = wrapper.readBoolean();
const rawValue = wrapper.readInt();
const createdAt = wrapper.readInt();
const updatedAt = wrapper.readInt();
assignments.push({
variableItemId,
hasValue,
value: (hasValue ? rawValue : null),
createdAt,
updatedAt
});
totalAssignments--;
}
this._users.push({ userId, assignments });
totalUsers--;
}
let totalFurniDefinitions = wrapper.readInt();
while(totalFurniDefinitions > 0)
{
this._furniDefinitions.push({
itemId: wrapper.readInt(),
name: wrapper.readString(),
hasValue: wrapper.readBoolean(),
availability: wrapper.readInt(),
isTextConnected: wrapper.readBoolean(),
isReadOnly: wrapper.readBoolean()
});
totalFurniDefinitions--;
}
let totalFurnis = wrapper.readInt();
while(totalFurnis > 0)
{
const furniId = wrapper.readInt();
let totalAssignments = wrapper.readInt();
const assignments: IWiredUserVariableAssignmentData[] = [];
while(totalAssignments > 0)
{
const variableItemId = wrapper.readInt();
const hasValue = wrapper.readBoolean();
const rawValue = wrapper.readInt();
const createdAt = wrapper.readInt();
const updatedAt = wrapper.readInt();
assignments.push({
variableItemId,
hasValue,
value: (hasValue ? rawValue : null),
createdAt,
updatedAt
});
totalAssignments--;
}
this._furnis.push({ furniId, assignments });
totalFurnis--;
}
let totalRoomDefinitions = wrapper.readInt();
while(totalRoomDefinitions > 0)
{
this._roomDefinitions.push({
itemId: wrapper.readInt(),
name: wrapper.readString(),
hasValue: wrapper.readBoolean(),
availability: wrapper.readInt(),
isTextConnected: wrapper.readBoolean(),
isReadOnly: wrapper.readBoolean()
});
totalRoomDefinitions--;
}
let totalRoomAssignments = wrapper.readInt();
while(totalRoomAssignments > 0)
{
const variableItemId = wrapper.readInt();
const hasValue = wrapper.readBoolean();
const rawValue = wrapper.readInt();
const createdAt = wrapper.readInt();
const updatedAt = wrapper.readInt();
this._roomAssignments.push({
variableItemId,
hasValue,
value: (hasValue ? rawValue : null),
createdAt,
updatedAt
});
totalRoomAssignments--;
}
let totalContextDefinitions = wrapper.readInt();
while(totalContextDefinitions > 0)
{
this._contextDefinitions.push({
itemId: wrapper.readInt(),
name: wrapper.readString(),
hasValue: wrapper.readBoolean(),
availability: wrapper.readInt(),
isTextConnected: wrapper.readBoolean(),
isReadOnly: wrapper.readBoolean()
});
totalContextDefinitions--;
}
return true;
}
public get roomId(): number
{
return this._roomId;
}
public get definitions(): IWiredUserVariableDefinitionData[]
{
return this._definitions;
}
public get users(): IWiredUserVariablesUserData[]
{
return this._users;
}
public get furniDefinitions(): IWiredFurniVariableDefinitionData[]
{
return this._furniDefinitions;
}
public get furnis(): IWiredUserVariablesFurniData[]
{
return this._furnis;
}
public get roomDefinitions(): IWiredRoomVariableDefinitionData[]
{
return this._roomDefinitions;
}
public get roomAssignments(): IWiredRoomVariableAssignmentData[]
{
return this._roomAssignments;
}
public get contextDefinitions(): IWiredContextVariableDefinitionData[]
{
return this._contextDefinitions;
}
}
@@ -5,7 +5,10 @@ export * from './WiredActionDefinition';
export * from './WiredFurniActionParser'; export * from './WiredFurniActionParser';
export * from './WiredFurniConditionParser'; export * from './WiredFurniConditionParser';
export * from './WiredFurniTriggerParser'; export * from './WiredFurniTriggerParser';
export * from './WiredMonitorDataParser';
export * from './WiredRoomSettingsDataParser';
export * from './WiredOpenParser'; export * from './WiredOpenParser';
export * from './WiredRewardResultMessageParser'; export * from './WiredRewardResultMessageParser';
export * from './WiredSaveSuccessParser'; export * from './WiredSaveSuccessParser';
export * from './WiredUserVariablesDataParser';
export * from './WiredValidationErrorParser'; export * from './WiredValidationErrorParser';
+106 -2
View File
@@ -22,6 +22,7 @@ export class RoomEngine implements IRoomEngine, IRoomCreator, IRoomEngineService
{ {
public static ROOM_OBJECT_ID: number = -1; public static ROOM_OBJECT_ID: number = -1;
public static ROOM_OBJECT_TYPE: string = 'room'; public static ROOM_OBJECT_TYPE: string = 'room';
private _areaHideHoleCounts = new Map<string, number>();
public static CURSOR_OBJECT_ID: number = -2; public static CURSOR_OBJECT_ID: number = -2;
public static CURSOR_OBJECT_TYPE: string = 'tile_cursor'; public static CURSOR_OBJECT_TYPE: string = 'tile_cursor';
@@ -170,6 +171,11 @@ export class RoomEngine implements IRoomEngine, IRoomCreator, IRoomEngineService
existing.dispose(); existing.dispose();
} }
for(const key of Array.from(this._areaHideHoleCounts.keys()))
{
if(key.startsWith(roomId + ':')) this._areaHideHoleCounts.delete(key);
}
GetEventDispatcher().dispatchEvent(new RoomEngineEvent(RoomEngineEvent.DISPOSED, roomId)); GetEventDispatcher().dispatchEvent(new RoomEngineEvent(RoomEngineEvent.DISPOSED, roomId));
} }
@@ -585,14 +591,106 @@ export class RoomEngine implements IRoomEngine, IRoomCreator, IRoomEngineService
GetEventDispatcher().dispatchEvent(new RoomEngineAreaHideStateEvent(roomId, furniId, RoomObjectCategory.FLOOR, on)); GetEventDispatcher().dispatchEvent(new RoomEngineAreaHideStateEvent(roomId, furniId, RoomObjectCategory.FLOOR, on));
this.removeAreaHideFloorHoles(roomObject, roomId, furniId);
if(on) if(on)
{ {
roomObject.logic.processUpdateMessage(new ObjectRoomFloorHoleUpdateMessage(ObjectRoomFloorHoleUpdateMessage.ADD, furniId, rootX, rootY, width, length, invert)); const rectangles = this.getAreaHideHoleRectangles(roomObject, rootX, rootY, width, length, invert);
for(let index = 0; index < rectangles.length; index++)
{
const rectangle = rectangles[index];
roomObject.logic.processUpdateMessage(new ObjectRoomFloorHoleUpdateMessage(ObjectRoomFloorHoleUpdateMessage.ADD, this.getAreaHideHoleId(furniId, index), rectangle.x, rectangle.y, rectangle.width, rectangle.length, false));
}
this._areaHideHoleCounts.set(this.getAreaHideHoleKey(roomId, furniId), rectangles.length);
} }
else else
{ {
roomObject.logic.processUpdateMessage(new ObjectRoomFloorHoleUpdateMessage(ObjectRoomFloorHoleUpdateMessage.REMOVE, furniId)); this._areaHideHoleCounts.delete(this.getAreaHideHoleKey(roomId, furniId));
} }
return true;
}
private removeAreaHideFloorHoles(roomObject: IRoomObjectController, roomId: number, furniId: number): void
{
if(!roomObject?.logic) return;
roomObject.logic.processUpdateMessage(new ObjectRoomFloorHoleUpdateMessage(ObjectRoomFloorHoleUpdateMessage.REMOVE, furniId));
const count = this._areaHideHoleCounts.get(this.getAreaHideHoleKey(roomId, furniId)) ?? 0;
for(let index = 0; index < Math.max(count, 4); index++)
{
roomObject.logic.processUpdateMessage(new ObjectRoomFloorHoleUpdateMessage(ObjectRoomFloorHoleUpdateMessage.REMOVE, this.getAreaHideHoleId(furniId, index)));
}
}
private getAreaHideHoleKey(roomId: number, furniId: number): string
{
return roomId + ':' + furniId;
}
private getAreaHideHoleId(furniId: number, index: number): number
{
return -((furniId * 10000) + index + 1);
}
private getAreaHideHoleRectangles(roomObject: IRoomObjectController, rootX: number, rootY: number, width: number, length: number, invert: boolean): { x: number, y: number, width: number, length: number }[]
{
const rectangles: { x: number, y: number, width: number, length: number }[] = [];
if(width <= 0 || length <= 0) return rectangles;
const roomMap = roomObject?.model?.getValue<RoomMapData>(RoomObjectVariable.ROOM_MAP_DATA);
const tileMap = roomMap?.tileMap;
if(!tileMap?.length) return rectangles;
const areaMinX = rootX;
const areaMinY = rootY;
const areaMaxX = (rootX + width);
const areaMaxY = (rootY + length);
const pushRectangle = (x: number, y: number, rectWidth: number) =>
{
if(rectWidth <= 0) return;
rectangles.push({ x, y, width: rectWidth, length: 1 });
};
for(let y = 0; y < tileMap.length; y++)
{
const row = tileMap[y];
if(!row?.length) continue;
let segmentStart = -1;
for(let x = 0; x <= row.length; x++)
{
const tileHeight = (x < row.length) ? row[x]?.height : Number.NEGATIVE_INFINITY;
const validTile = (tileHeight >= 0);
const inSelection = (x >= areaMinX) && (x < areaMaxX) && (y >= areaMinY) && (y < areaMaxY);
const shouldHide = validTile && (invert ? !inSelection : inSelection);
if(shouldHide)
{
if(segmentStart === -1) segmentStart = x;
continue;
}
if(segmentStart !== -1)
{
pushRectangle(segmentStart, y, (x - segmentStart));
segmentStart = -1;
}
}
}
return rectangles;
} }
public updateObjectRoomColor(roomId: number, color: number, light: number, backgroundOnly: boolean): boolean public updateObjectRoomColor(roomId: number, color: number, light: number, backgroundOnly: boolean): boolean
@@ -1733,6 +1831,12 @@ export class RoomEngine implements IRoomEngine, IRoomCreator, IRoomEngineService
object.processUpdateMessage(new RoomObjectUpdateMessage(location, direction)); object.processUpdateMessage(new RoomObjectUpdateMessage(location, direction));
object.processUpdateMessage(new ObjectDataUpdateMessage(state, data, extra)); object.processUpdateMessage(new ObjectDataUpdateMessage(state, data, extra));
if(object.model && (extra === 2147483001))
{
object.model.setValue(RoomObjectVariable.FURNITURE_IS_VARIABLE_HEIGHT, 1);
object.model.setValue(RoomObjectVariable.FURNITURE_IS_WALK_HEIGHT_HELPER, 1);
}
return true; return true;
} }
+424 -23
View File
@@ -1,5 +1,5 @@
import { AvatarGuideStatus, IConnection, IMessageEvent, IRoomCreator, IRoomObjectController, IVector3D, LegacyDataType, ObjectRolling, PetType, RoomObjectType, RoomObjectUserType, RoomObjectVariable } from '@nitrots/api'; import { AvatarGuideStatus, IConnection, IMessageEvent, IRoomCreator, IRoomObjectController, IRoomObject, IVector3D, LegacyDataType, ObjectRolling, PetType, RoomObjectCategory, RoomObjectType, RoomObjectUserType, RoomObjectVariable } from '@nitrots/api';
import { AreaHideMessageEvent, DiceValueMessageEvent, FloorHeightMapEvent, FurnitureAliasesComposer, FurnitureAliasesEvent, FurnitureDataEvent, FurnitureFloorAddEvent, FurnitureFloorDataParser, FurnitureFloorEvent, FurnitureFloorRemoveEvent, FurnitureFloorUpdateEvent, FurnitureWallAddEvent, FurnitureWallDataParser, FurnitureWallEvent, FurnitureWallRemoveEvent, FurnitureWallUpdateEvent, GetCommunication, GetRoomEntryDataMessageComposer, GuideSessionEndedMessageEvent, GuideSessionErrorMessageEvent, GuideSessionStartedMessageEvent, IgnoreResultEvent, ItemDataUpdateMessageEvent, ObjectsDataUpdateEvent, ObjectsRollingEvent, OneWayDoorStatusMessageEvent, PetExperienceEvent, PetFigureUpdateEvent, RoomEntryTileMessageEvent, RoomEntryTileMessageParser, RoomHeightMapEvent, RoomHeightMapUpdateEvent, RoomPaintEvent, RoomReadyMessageEvent, RoomUnitChatEvent, RoomUnitChatShoutEvent, RoomUnitChatWhisperEvent, RoomUnitDanceEvent, RoomUnitEffectEvent, RoomUnitEvent, RoomUnitExpressionEvent, RoomUnitHandItemEvent, RoomUnitIdleEvent, RoomUnitInfoEvent, RoomUnitNumberEvent, RoomUnitRemoveEvent, RoomUnitStatusEvent, RoomUnitStatusMessage, RoomUnitTypingEvent, RoomVisualizationSettingsEvent, UserInfoEvent, WiredFurniMovementData, WiredMovementsEvent, WiredUserDirectionUpdateData, WiredUserMovementData, YouArePlayingGameEvent } from '@nitrots/communication'; import { AreaHideMessageEvent, ConfInvisStateMessageEvent, DiceValueMessageEvent, FloorHeightMapEvent, FurnitureAliasesComposer, FurnitureAliasesEvent, FurnitureDataEvent, FurnitureFloorAddEvent, FurnitureFloorDataParser, FurnitureFloorEvent, FurnitureFloorRemoveEvent, FurnitureFloorUpdateEvent, FurnitureWallAddEvent, FurnitureWallDataParser, FurnitureWallEvent, FurnitureWallRemoveEvent, FurnitureWallUpdateEvent, GetCommunication, GetRoomEntryDataMessageComposer, GuideSessionEndedMessageEvent, GuideSessionErrorMessageEvent, GuideSessionStartedMessageEvent, IgnoreResultEvent, ItemDataUpdateMessageEvent, ObjectsDataUpdateEvent, ObjectsRollingEvent, OneWayDoorStatusMessageEvent, PetExperienceEvent, PetFigureUpdateEvent, RoomEntryTileMessageEvent, RoomEntryTileMessageParser, RoomHeightMapEvent, RoomHeightMapUpdateEvent, RoomPaintEvent, RoomReadyMessageEvent, RoomUnitChatEvent, RoomUnitChatShoutEvent, RoomUnitChatWhisperEvent, RoomUnitDanceEvent, RoomUnitEffectEvent, RoomUnitEvent, RoomUnitExpressionEvent, RoomUnitHandItemEvent, RoomUnitIdleEvent, RoomUnitInfoEvent, RoomUnitNumberEvent, RoomUnitRemoveEvent, RoomUnitStatusEvent, RoomUnitStatusMessage, RoomUnitTypingEvent, RoomVisualizationSettingsEvent, UserInfoEvent, WiredFurniMovementData, WiredMovementsEvent, WiredUserDirectionUpdateData, WiredUserMovementData, YouArePlayingGameEvent } from '@nitrots/communication';
import { GetRoomSessionManager, GetSessionDataManager } from '@nitrots/session'; import { GetRoomSessionManager, GetSessionDataManager } from '@nitrots/session';
import { Vector3d } from '@nitrots/utils'; import { Vector3d } from '@nitrots/utils';
import { GetRoomEngine } from './GetRoomEngine'; import { GetRoomEngine } from './GetRoomEngine';
@@ -7,6 +7,16 @@ import { RoomVariableEnum } from './RoomVariableEnum';
import { RoomPlaneParser } from './object/RoomPlaneParser'; import { RoomPlaneParser } from './object/RoomPlaneParser';
import { FurnitureStackingHeightMap, LegacyWallGeometry } from './utils'; import { FurnitureStackingHeightMap, LegacyWallGeometry } from './utils';
type AreaHideControllerState = {
rootX: number;
rootY: number;
width: number;
length: number;
invert: boolean;
wallItems: boolean;
invisibility: boolean;
};
export class RoomMessageHandler export class RoomMessageHandler
{ {
private static WIRED_FURNI_ANCHOR_NONE = 0; private static WIRED_FURNI_ANCHOR_NONE = 0;
@@ -21,8 +31,13 @@ export class RoomMessageHandler
private _planeParser = new RoomPlaneParser(); private _planeParser = new RoomPlaneParser();
private _latestEntryTileEvent: RoomEntryTileMessageEvent = null; private _latestEntryTileEvent: RoomEntryTileMessageEvent = null;
private _messageEvents: IMessageEvent[] = []; private _messageEvents: IMessageEvent[] = [];
private _activeWiredUserMovements = new Map<number, { expiresAt: number, targetX: number, targetY: number, targetZ: number }>(); private _activeWiredUserMovements = new Map<number, { expiresAt: number, sourceX: number, sourceY: number, sourceZ: number, targetX: number, targetY: number, targetZ: number }>();
private _activeRoomUserWalks = new Map<number, { startedAt: number, targetX: number, targetY: number, targetZ: number, duration: number }>(); private _activeRoomUserWalks = new Map<number, { startedAt: number, targetX: number, targetY: number, targetZ: number, duration: number }>();
private _activeConfInvisHiddenItemIds = new Set<number>();
private _confInvisReapplyTimeouts: ReturnType<typeof setTimeout>[] = [];
private _activeAreaHideControllers = new Map<number, AreaHideControllerState>();
private _areaHideReapplyTimeouts: ReturnType<typeof setTimeout>[] = [];
private _isConfInvisControlActive = false;
private _currentRoomId: number = 0; private _currentRoomId: number = 0;
private _ownUserId: number = 0; private _ownUserId: number = 0;
@@ -62,6 +77,7 @@ export class RoomMessageHandler
new ItemDataUpdateMessageEvent(this.onItemDataUpdateMessageEvent.bind(this)), new ItemDataUpdateMessageEvent(this.onItemDataUpdateMessageEvent.bind(this)),
new OneWayDoorStatusMessageEvent(this.onOneWayDoorStatusMessageEvent.bind(this)), new OneWayDoorStatusMessageEvent(this.onOneWayDoorStatusMessageEvent.bind(this)),
new AreaHideMessageEvent(this.onAreaHideMessageEvent.bind(this)), new AreaHideMessageEvent(this.onAreaHideMessageEvent.bind(this)),
new ConfInvisStateMessageEvent(this.onConfInvisStateMessageEvent.bind(this)),
new RoomUnitDanceEvent(this.onRoomUnitDanceEvent.bind(this)), new RoomUnitDanceEvent(this.onRoomUnitDanceEvent.bind(this)),
new RoomUnitEffectEvent(this.onRoomUnitEffectEvent.bind(this)), new RoomUnitEffectEvent(this.onRoomUnitEffectEvent.bind(this)),
new RoomUnitEvent(this.onRoomUnitEvent.bind(this)), new RoomUnitEvent(this.onRoomUnitEvent.bind(this)),
@@ -110,12 +126,16 @@ export class RoomMessageHandler
this._latestEntryTileEvent = null; this._latestEntryTileEvent = null;
this._activeWiredUserMovements.clear(); this._activeWiredUserMovements.clear();
this._activeRoomUserWalks.clear(); this._activeRoomUserWalks.clear();
if(this._planeParser) if(this._planeParser)
{ {
this._planeParser.dispose(); this._planeParser.dispose();
this._planeParser = null; this._planeParser = null;
} }
this._activeConfInvisHiddenItemIds.clear();
this.clearConfInvisReapplyTimeouts();
this._activeAreaHideControllers.clear();
this.clearAreaHideReapplyTimeouts();
this._isConfInvisControlActive = false;
} }
public setRoomId(id: number): void public setRoomId(id: number): void
@@ -129,6 +149,11 @@ export class RoomMessageHandler
this._latestEntryTileEvent = null; this._latestEntryTileEvent = null;
this._activeWiredUserMovements.clear(); this._activeWiredUserMovements.clear();
this._activeRoomUserWalks.clear(); this._activeRoomUserWalks.clear();
this._activeConfInvisHiddenItemIds.clear();
this.clearConfInvisReapplyTimeouts();
this._activeAreaHideControllers.clear();
this.clearAreaHideReapplyTimeouts();
this._isConfInvisControlActive = false;
} }
public clearRoomId(): void public clearRoomId(): void
@@ -137,6 +162,11 @@ export class RoomMessageHandler
this._latestEntryTileEvent = null; this._latestEntryTileEvent = null;
this._activeWiredUserMovements.clear(); this._activeWiredUserMovements.clear();
this._activeRoomUserWalks.clear(); this._activeRoomUserWalks.clear();
this._activeConfInvisHiddenItemIds.clear();
this.clearConfInvisReapplyTimeouts();
this._activeAreaHideControllers.clear();
this.clearAreaHideReapplyTimeouts();
this._isConfInvisControlActive = false;
} }
private onUserInfoEvent(event: UserInfoEvent): void private onUserInfoEvent(event: UserInfoEvent): void
@@ -383,6 +413,8 @@ export class RoomMessageHandler
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.rollerId, null, null, 1, null); this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.rollerId, null, null, 1, null);
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.rollerId, null, null, 2, null); this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.rollerId, null, null, 2, null);
this.applyConfInvisStateToFloorObjects([ parser.rollerId ]);
this.applyAreaHideStateToFloorObjects([ parser.rollerId ]);
const furnitureRolling = parser.itemsRolling; const furnitureRolling = parser.itemsRolling;
@@ -394,6 +426,8 @@ export class RoomMessageHandler
this._roomEngine.rollRoomObjectFloor(this._currentRoomId, rollData.id, rollData.location, rollData.targetLocation); this._roomEngine.rollRoomObjectFloor(this._currentRoomId, rollData.id, rollData.location, rollData.targetLocation);
} }
this.scheduleAreaHideReapply(this._currentRoomId);
} }
const unitRollData = parser.unitRolling; const unitRollData = parser.unitRolling;
@@ -584,6 +618,9 @@ export class RoomMessageHandler
{ {
this._activeWiredUserMovements.set(movement.id, { this._activeWiredUserMovements.set(movement.id, {
expiresAt: Date.now() + Math.max(movement.duration, 1) + RoomMessageHandler.WIRED_MOVEMENT_STATUS_GRACE, expiresAt: Date.now() + Math.max(movement.duration, 1) + RoomMessageHandler.WIRED_MOVEMENT_STATUS_GRACE,
sourceX: movement.location.x,
sourceY: movement.location.y,
sourceZ: movement.location.z,
targetX: movement.targetLocation.x, targetX: movement.targetLocation.x,
targetY: movement.targetLocation.y, targetY: movement.targetLocation.y,
targetZ: movement.targetLocation.z targetZ: movement.targetLocation.z
@@ -603,7 +640,8 @@ export class RoomMessageHandler
return false; return false;
} }
if(this.shouldReleaseWiredStatusLocation(status, activeMovement)) if(this.shouldDiscardWiredStatusLocation(status, activeMovement)
|| !!this.getMatchedWiredStatusTargetLocation(status, activeMovement))
{ {
this._activeWiredUserMovements.delete(status.id); this._activeWiredUserMovements.delete(status.id);
@@ -613,37 +651,82 @@ export class RoomMessageHandler
return true; return true;
} }
private shouldReleaseWiredStatusLocation(status: RoomUnitStatusMessage, activeMovement: { expiresAt: number, targetX: number, targetY: number, targetZ: number }): boolean private getReleasedWiredStatusLocation(status: RoomUnitStatusMessage): IVector3D
{
const activeMovement = this._activeWiredUserMovements.get(status.id);
if(!activeMovement) return null;
if(activeMovement.expiresAt <= Date.now()) return null;
if(this.shouldDiscardWiredStatusLocation(status, activeMovement)) return null;
return this.getMatchedWiredStatusTargetLocation(status, activeMovement);
}
private getMatchedWiredStatusTargetLocation(status: RoomUnitStatusMessage, activeMovement: { expiresAt: number, sourceX: number, sourceY: number, sourceZ: number, targetX: number, targetY: number, targetZ: number }): IVector3D
{
if(this.matchesWiredMovementTarget(status.x, status.y, (status.z + status.height), activeMovement))
{
return new Vector3d(activeMovement.targetX, activeMovement.targetY, activeMovement.targetZ);
}
if(status.didMove && this.matchesWiredMovementTarget(status.targetX, status.targetY, status.targetZ, activeMovement))
{
return new Vector3d(activeMovement.targetX, activeMovement.targetY, activeMovement.targetZ);
}
return null;
}
private shouldDiscardWiredStatusLocation(status: RoomUnitStatusMessage, activeMovement: { expiresAt: number, sourceX: number, sourceY: number, sourceZ: number, targetX: number, targetY: number, targetZ: number }): boolean
{ {
if(!status.didMove) if(!status.didMove)
{ {
return this.matchesWiredMovementTarget(status.x, status.y, (status.z + status.height), activeMovement); return !this.matchesWiredMovementSource(status.x, status.y, (status.z + status.height), activeMovement)
&& !this.matchesWiredMovementTarget(status.x, status.y, (status.z + status.height), activeMovement);
} }
return !this.matchesWiredMovementTarget(status.targetX, status.targetY, status.targetZ, activeMovement); return !this.matchesWiredMovementSource(status.x, status.y, (status.z + status.height), activeMovement)
&& !this.matchesWiredMovementTarget(status.x, status.y, (status.z + status.height), activeMovement)
&& !this.matchesWiredMovementSource(status.targetX, status.targetY, status.targetZ, activeMovement)
&& !this.matchesWiredMovementTarget(status.targetX, status.targetY, status.targetZ, activeMovement);
} }
private matchesWiredMovementTarget(x: number, y: number, z: number, activeMovement: { expiresAt: number, targetX: number, targetY: number, targetZ: number }): boolean private matchesWiredMovementSource(x: number, y: number, z: number, activeMovement: { expiresAt: number, sourceX: number, sourceY: number, sourceZ: number, targetX: number, targetY: number, targetZ: number }): boolean
{ {
if(!activeMovement) return false; if(!activeMovement) return false;
return ((x === activeMovement.targetX) return this.matchesWiredMovementLocation(x, y, z, activeMovement.sourceX, activeMovement.sourceY, activeMovement.sourceZ);
&& (y === activeMovement.targetY) }
&& (Math.abs(z - activeMovement.targetZ) <= RoomMessageHandler.WIRED_MOVEMENT_Z_EPSILON));
private matchesWiredMovementTarget(x: number, y: number, z: number, activeMovement: { expiresAt: number, sourceX: number, sourceY: number, sourceZ: number, targetX: number, targetY: number, targetZ: number }): boolean
{
if(!activeMovement) return false;
return this.matchesWiredMovementLocation(x, y, z, activeMovement.targetX, activeMovement.targetY, activeMovement.targetZ);
}
private matchesWiredMovementLocation(x: number, y: number, z: number, movementX: number, movementY: number, movementZ: number): boolean
{
return ((x === movementX)
&& (y === movementY)
&& (Math.abs(z - movementZ) <= RoomMessageHandler.WIRED_MOVEMENT_Z_EPSILON));
} }
private applyWiredUserDirectionUpdate(update: WiredUserDirectionUpdateData): void private applyWiredUserDirectionUpdate(update: WiredUserDirectionUpdateData): void
{ {
this._roomEngine.updateRoomObjectUserLocation( const userObject = this._roomEngine.getRoomObjectUser(this._currentRoomId, update.id);
this._currentRoomId,
update.id, if(!userObject) return;
null,
null, userObject.setDirection(new Vector3d(update.bodyDirection));
false,
0, const model = userObject.model;
new Vector3d(update.bodyDirection),
update.headDirection, if(!model) return;
true);
model.setValue(RoomObjectVariable.HEAD_DIRECTION, update.headDirection);
} }
private onObjectsDataUpdateEvent(event: ObjectsDataUpdateEvent): void private onObjectsDataUpdateEvent(event: ObjectsDataUpdateEvent): void
@@ -658,6 +741,9 @@ export class RoomMessageHandler
{ {
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, object.id, null, null, object.state, object.data); this._roomEngine.updateRoomObjectFloor(this._currentRoomId, object.id, null, null, object.state, object.data);
} }
this.applyConfInvisStateToFloorObjects();
this.applyAreaHideStateToFloorObjects();
} }
private onFurnitureAliasesEvent(event: FurnitureAliasesEvent): void private onFurnitureAliasesEvent(event: FurnitureAliasesEvent): void
@@ -678,6 +764,8 @@ export class RoomMessageHandler
if(!item) return; if(!item) return;
this.addRoomObjectFurnitureFloor(this._currentRoomId, item); this.addRoomObjectFurnitureFloor(this._currentRoomId, item);
this.applyConfInvisStateToFloorObjects([ item.itemId ]);
this.applyAreaHideStateToFloorObjects([ item.itemId ]);
} }
private onFurnitureFloorEvent(event: FurnitureFloorEvent): void private onFurnitureFloorEvent(event: FurnitureFloorEvent): void
@@ -700,6 +788,10 @@ export class RoomMessageHandler
iterator++; iterator++;
} }
this.applyConfInvisStateToFloorObjects();
this.applyAreaHideStateToFloorObjects();
this.scheduleAreaHideReapply(this._currentRoomId);
} }
private onFurnitureFloorRemoveEvent(event: FurnitureFloorRemoveEvent): void private onFurnitureFloorRemoveEvent(event: FurnitureFloorRemoveEvent): void
@@ -714,12 +806,18 @@ export class RoomMessageHandler
{ {
setTimeout(() => setTimeout(() =>
{ {
this._activeConfInvisHiddenItemIds.delete(parser.itemId);
this._activeAreaHideControllers.delete(parser.itemId);
this._roomEngine.removeRoomObjectFloor(this._currentRoomId, parser.itemId, (parser.isExpired) ? -1 : parser.userId, true); this._roomEngine.removeRoomObjectFloor(this._currentRoomId, parser.itemId, (parser.isExpired) ? -1 : parser.userId, true);
this.applyAreaHideStateToRoomObjects();
}, parser.delay); }, parser.delay);
} }
else else
{ {
this._activeConfInvisHiddenItemIds.delete(parser.itemId);
this._activeAreaHideControllers.delete(parser.itemId);
this._roomEngine.removeRoomObjectFloor(this._currentRoomId, parser.itemId, (parser.isExpired) ? -1 : parser.userId, true); this._roomEngine.removeRoomObjectFloor(this._currentRoomId, parser.itemId, (parser.isExpired) ? -1 : parser.userId, true);
this.applyAreaHideStateToRoomObjects();
} }
} }
@@ -737,6 +835,73 @@ export class RoomMessageHandler
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, item.itemId, location, direction, item.data.state, item.data, item.extra); this._roomEngine.updateRoomObjectFloor(this._currentRoomId, item.itemId, location, direction, item.data.state, item.data, item.extra);
this._roomEngine.updateRoomObjectFloorHeight(this._currentRoomId, item.itemId, item.stackHeight); this._roomEngine.updateRoomObjectFloorHeight(this._currentRoomId, item.itemId, item.stackHeight);
this._roomEngine.updateRoomObjectFloorExpiration(this._currentRoomId, item.itemId, item.expires); this._roomEngine.updateRoomObjectFloorExpiration(this._currentRoomId, item.itemId, item.expires);
this.applyConfInvisStateToFloorObjects([ item.itemId ]);
this.applyAreaHideStateToFloorObjects([ item.itemId ]);
}
private onConfInvisStateMessageEvent(event: ConfInvisStateMessageEvent): void
{
if(!(event instanceof ConfInvisStateMessageEvent) || !event.connection || !this._roomEngine) return;
const parser = event.getParser();
if(!parser?.stateData) return;
if(parser.stateData.roomId !== this._currentRoomId) return;
this._isConfInvisControlActive = parser.stateData.active;
this._activeConfInvisHiddenItemIds = new Set<number>(parser.stateData.hiddenItemIds);
this.applyConfInvisStateToFloorObjects();
this.applyAreaHideStateToRoomObjects();
this.scheduleConfInvisReapply(parser.stateData.roomId);
this.scheduleAreaHideReapply(parser.stateData.roomId);
}
private applyConfInvisStateToFloorObjects(itemIds?: number[]): void
{
const floorObjects = ((this._roomEngine as any)?.getRoomObjects?.(this._currentRoomId, RoomObjectCategory.FLOOR) as IRoomObject[]) ?? [];
if(!floorObjects?.length) return;
const scopedIds = itemIds?.length ? new Set<number>(itemIds) : null;
for(const roomObject of floorObjects)
{
if(!roomObject?.model) continue;
if(scopedIds && !scopedIds.has(roomObject.id)) continue;
roomObject.model.setValue(RoomObjectVariable.FURNITURE_CONF_INVIS_HIDDEN, this._activeConfInvisHiddenItemIds.has(roomObject.id) ? 1 : 0);
}
}
private scheduleConfInvisReapply(roomId: number): void
{
this.clearConfInvisReapplyTimeouts();
const retryDelays = [ 0, 50, 150, 300, 600, 1000 ];
for(const delay of retryDelays)
{
const timeout = setTimeout(() =>
{
if(roomId !== this._currentRoomId) return;
this.applyConfInvisStateToFloorObjects();
}, delay);
this._confInvisReapplyTimeouts.push(timeout);
}
}
private clearConfInvisReapplyTimeouts(): void
{
if(!this._confInvisReapplyTimeouts.length) return;
for(const timeout of this._confInvisReapplyTimeouts)
{
clearTimeout(timeout);
}
this._confInvisReapplyTimeouts = [];
} }
private onFurnitureWallAddEvent(event: FurnitureWallAddEvent): void private onFurnitureWallAddEvent(event: FurnitureWallAddEvent): void
@@ -748,6 +913,7 @@ export class RoomMessageHandler
if(!data) return; if(!data) return;
this.addRoomObjectFurnitureWall(this._currentRoomId, data); this.addRoomObjectFurnitureWall(this._currentRoomId, data);
this.applyAreaHideStateToWallObjects([ data.itemId ]);
} }
private onFurnitureWallEvent(event: FurnitureWallEvent): void private onFurnitureWallEvent(event: FurnitureWallEvent): void
@@ -770,6 +936,9 @@ export class RoomMessageHandler
iterator++; iterator++;
} }
this.applyAreaHideStateToWallObjects();
this.scheduleAreaHideReapply(this._currentRoomId);
} }
private onFurnitureWallRemoveEvent(event: FurnitureWallRemoveEvent): void private onFurnitureWallRemoveEvent(event: FurnitureWallRemoveEvent): void
@@ -781,6 +950,7 @@ export class RoomMessageHandler
if(!parser) return; if(!parser) return;
this._roomEngine.removeRoomObjectWall(this._currentRoomId, parser.itemId, parser.userId); this._roomEngine.removeRoomObjectWall(this._currentRoomId, parser.itemId, parser.userId);
this.applyAreaHideStateToWallObjects();
} }
private onFurnitureWallUpdateEvent(event: FurnitureWallUpdateEvent): void private onFurnitureWallUpdateEvent(event: FurnitureWallUpdateEvent): void
@@ -800,6 +970,7 @@ export class RoomMessageHandler
this._roomEngine.updateRoomObjectWall(this._currentRoomId, item.itemId, location, direction, item.state, item.stuffData); this._roomEngine.updateRoomObjectWall(this._currentRoomId, item.itemId, location, direction, item.state, item.stuffData);
this._roomEngine.updateRoomObjectWallExpiration(this._currentRoomId, item.itemId, item.secondsToExpiration); this._roomEngine.updateRoomObjectWallExpiration(this._currentRoomId, item.itemId, item.secondsToExpiration);
this.applyAreaHideStateToWallObjects([ item.itemId ]);
} }
private onFurnitureDataEvent(event: FurnitureDataEvent): void private onFurnitureDataEvent(event: FurnitureDataEvent): void
@@ -809,6 +980,8 @@ export class RoomMessageHandler
const parser = event.getParser(); const parser = event.getParser();
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.furnitureId, null, null, parser.objectData.state, parser.objectData); this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.furnitureId, null, null, parser.objectData.state, parser.objectData);
this.applyConfInvisStateToFloorObjects([ parser.furnitureId ]);
this.applyAreaHideStateToFloorObjects([ parser.furnitureId ]);
} }
private onItemDataUpdateMessageEvent(event: ItemDataUpdateMessageEvent): void private onItemDataUpdateMessageEvent(event: ItemDataUpdateMessageEvent): void
@@ -818,6 +991,7 @@ export class RoomMessageHandler
const parser = event.getParser(); const parser = event.getParser();
this._roomEngine.updateRoomObjectWallItemData(this._currentRoomId, parser.furnitureId, parser.data); this._roomEngine.updateRoomObjectWallItemData(this._currentRoomId, parser.furnitureId, parser.data);
this.applyAreaHideStateToWallObjects([ parser.furnitureId ]);
} }
private onOneWayDoorStatusMessageEvent(event: OneWayDoorStatusMessageEvent): void private onOneWayDoorStatusMessageEvent(event: OneWayDoorStatusMessageEvent): void
@@ -827,6 +1001,8 @@ export class RoomMessageHandler
const parser = event.getParser(); const parser = event.getParser();
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.itemId, null, null, parser.state, new LegacyDataType()); this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.itemId, null, null, parser.state, new LegacyDataType());
this.applyConfInvisStateToFloorObjects([ parser.itemId ]);
this.applyAreaHideStateToFloorObjects([ parser.itemId ]);
} }
private onAreaHideMessageEvent(event: AreaHideMessageEvent): void private onAreaHideMessageEvent(event: AreaHideMessageEvent): void
@@ -837,6 +1013,26 @@ export class RoomMessageHandler
const areaData = parser.areaData; const areaData = parser.areaData;
this._roomEngine.updateAreaHide(this._currentRoomId, areaData.furniId, areaData.on, areaData.rootX, areaData.rootY, areaData.width, areaData.length, areaData.invert); this._roomEngine.updateAreaHide(this._currentRoomId, areaData.furniId, areaData.on, areaData.rootX, areaData.rootY, areaData.width, areaData.length, areaData.invert);
if(areaData.on)
{
this._activeAreaHideControllers.set(areaData.furniId, {
rootX: areaData.rootX,
rootY: areaData.rootY,
width: areaData.width,
length: areaData.length,
invert: areaData.invert,
wallItems: areaData.wallItems,
invisibility: areaData.invisibility
});
}
else
{
this._activeAreaHideControllers.delete(areaData.furniId);
}
this.applyAreaHideStateToRoomObjects();
this.scheduleAreaHideReapply(this._currentRoomId);
} }
private onDiceValueMessageEvent(event: DiceValueMessageEvent): void private onDiceValueMessageEvent(event: DiceValueMessageEvent): void
@@ -846,6 +1042,210 @@ export class RoomMessageHandler
const parser = event.getParser(); const parser = event.getParser();
this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.itemId, null, null, parser.value, new LegacyDataType()); this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.itemId, null, null, parser.value, new LegacyDataType());
this.applyConfInvisStateToFloorObjects([ parser.itemId ]);
this.applyAreaHideStateToFloorObjects([ parser.itemId ]);
}
private applyAreaHideStateToRoomObjects(floorItemIds?: number[], wallItemIds?: number[]): void
{
this.applyAreaHideStateToFloorObjects(floorItemIds);
this.applyAreaHideStateToWallObjects(wallItemIds);
}
private applyAreaHideStateToFloorObjects(itemIds?: number[]): void
{
const floorObjects = ((this._roomEngine as any)?.getRoomObjects?.(this._currentRoomId, RoomObjectCategory.FLOOR) as IRoomObject[]) ?? [];
if(!floorObjects?.length) return;
const scopedIds = itemIds?.length ? new Set<number>(itemIds) : null;
for(const roomObject of floorObjects)
{
if(!roomObject?.model) continue;
if(scopedIds && !scopedIds.has(roomObject.id)) continue;
roomObject.model.setValue(RoomObjectVariable.FURNITURE_AREA_HIDE_HIDDEN, this.shouldHideRoomObjectByAreaHide(roomObject, RoomObjectCategory.FLOOR) ? 1 : 0);
}
}
private applyAreaHideStateToWallObjects(itemIds?: number[]): void
{
const wallObjects = ((this._roomEngine as any)?.getRoomObjects?.(this._currentRoomId, RoomObjectCategory.WALL) as IRoomObject[]) ?? [];
if(!wallObjects?.length) return;
const scopedIds = itemIds?.length ? new Set<number>(itemIds) : null;
for(const roomObject of wallObjects)
{
if(!roomObject?.model) continue;
if(scopedIds && !scopedIds.has(roomObject.id)) continue;
roomObject.model.setValue(RoomObjectVariable.FURNITURE_AREA_HIDE_HIDDEN, this.shouldHideRoomObjectByAreaHide(roomObject, RoomObjectCategory.WALL) ? 1 : 0);
}
}
private shouldHideRoomObjectByAreaHide(roomObject: IRoomObject, category: number): boolean
{
if(!roomObject?.model) return false;
const controllerState = this.getAreaHideControllerStateFromObject(roomObject, category);
if(controllerState)
{
return (controllerState.invisibility && this._isConfInvisControlActive);
}
if(!this._activeAreaHideControllers.size) return false;
for(const activeState of this._activeAreaHideControllers.values())
{
if((activeState.width <= 0) || (activeState.length <= 0)) continue;
if((category === RoomObjectCategory.WALL) && !activeState.wallItems) continue;
const intersectsArea = (category === RoomObjectCategory.WALL)
? this.isWallObjectInsideArea(roomObject, activeState)
: this.doesFloorObjectIntersectArea(roomObject, activeState);
const shouldHide = (activeState.invert ? !intersectsArea : intersectsArea);
if(shouldHide) return true;
}
return false;
}
private doesFloorObjectIntersectArea(roomObject: IRoomObject, areaState: AreaHideControllerState): boolean
{
if(!roomObject?.model) return false;
const location = roomObject.getLocation();
if(!location) return false;
let sizeX = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_SIZE_X);
let sizeY = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_SIZE_Y);
if(!sizeX || (sizeX < 1)) sizeX = 1;
if(!sizeY || (sizeY < 1)) sizeY = 1;
const direction = roomObject.getDirection();
const directionQuarterTurns = (((Math.trunc(((direction?.x ?? 0) + 45)) % 360) + 360) % 360) / 90;
if((directionQuarterTurns === 1) || (directionQuarterTurns === 3))
{
[ sizeX, sizeY ] = [ sizeY, sizeX ];
}
const objectMinX = location.x;
const objectMinY = location.y;
const objectMaxX = objectMinX + sizeX;
const objectMaxY = objectMinY + sizeY;
const areaMinX = areaState.rootX;
const areaMinY = areaState.rootY;
const areaMaxX = areaMinX + areaState.width;
const areaMaxY = areaMinY + areaState.length;
return (objectMinX < areaMaxX)
&& (objectMaxX > areaMinX)
&& (objectMinY < areaMaxY)
&& (objectMaxY > areaMinY);
}
private isWallObjectInsideArea(roomObject: IRoomObject, areaState: AreaHideControllerState): boolean
{
const location = roomObject?.getLocation();
if(!location) return false;
const xCandidates = Array.from(new Set([ Math.floor(location.x), Math.ceil(location.x), Math.round(location.x) ]));
const yCandidates = Array.from(new Set([ Math.floor(location.y), Math.ceil(location.y), Math.round(location.y) ]));
for(const x of xCandidates)
{
for(const y of yCandidates)
{
if((x >= areaState.rootX)
&& (x < (areaState.rootX + areaState.width))
&& (y >= areaState.rootY)
&& (y < (areaState.rootY + areaState.length)))
{
return true;
}
}
}
return false;
}
private getAreaHideControllerStateFromObject(roomObject: IRoomObject, category: number): AreaHideControllerState
{
if(!roomObject?.model || (category !== RoomObjectCategory.FLOOR)) return null;
if(this._activeAreaHideControllers.has(roomObject.id))
{
return this._activeAreaHideControllers.get(roomObject.id);
}
if(!this.isAreaHideControllerObject(roomObject)) return null;
return {
rootX: (roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_ROOT_X) ?? 0),
rootY: (roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_ROOT_Y) ?? 0),
width: (roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_WIDTH) ?? 0),
length: (roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_LENGTH) ?? 0),
invert: (roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_INVERT) === 1),
wallItems: (roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_WALL_ITEMS) === 1),
invisibility: (roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_INVISIBILITY) === 1)
};
}
private isAreaHideControllerObject(roomObject: IRoomObject): boolean
{
if(!roomObject?.model) return false;
const furniData = GetSessionDataManager().getFloorItemDataByName(roomObject.type);
const customParams = (furniData?.customParams || '').toLowerCase();
if(customParams.includes('area_hide_control') || customParams.includes('wf_conf_area_hide') || customParams.includes('conf_area_hide'))
{
return true;
}
const stuffData = roomObject.model.getValue<number[]>(RoomObjectVariable.FURNITURE_DATA);
return Array.isArray(stuffData) && (stuffData.length >= 8);
}
private scheduleAreaHideReapply(roomId: number): void
{
this.clearAreaHideReapplyTimeouts();
const retryDelays = [ 0, 50, 150, 300, 600, 1000 ];
for(const delay of retryDelays)
{
const timeout = setTimeout(() =>
{
if(roomId !== this._currentRoomId) return;
this.applyAreaHideStateToRoomObjects();
}, delay);
this._areaHideReapplyTimeouts.push(timeout);
}
}
private clearAreaHideReapplyTimeouts(): void
{
if(!this._areaHideReapplyTimeouts.length) return;
for(const timeout of this._areaHideReapplyTimeouts)
{
clearTimeout(timeout);
}
this._areaHideReapplyTimeouts = [];
} }
private onRoomUnitDanceEvent(event: RoomUnitDanceEvent): void private onRoomUnitDanceEvent(event: RoomUnitDanceEvent): void
@@ -973,7 +1373,8 @@ export class RoomMessageHandler
if(height) height = (height / zScale); if(height) height = (height / zScale);
const location = new Vector3d(status.x, status.y, (status.z + height)); const releasedWiredLocation = this.getReleasedWiredStatusLocation(status);
const location = (releasedWiredLocation || new Vector3d(status.x, status.y, (status.z + height)));
const direction = new Vector3d(status.direction); const direction = new Vector3d(status.direction);
let goal: IVector3D = null; let goal: IVector3D = null;
@@ -87,6 +87,18 @@ export class RoomObjectEventHandler implements IRoomCanvasMouseListener, IRoomOb
} }
} }
if((event.type === MouseEventType.DOUBLE_CLICK) && (category === RoomObjectCategory.FLOOR) && object.model && (object.model.getValue<number>(RoomObjectVariable.FURNITURE_IS_VARIABLE_HEIGHT) > 0))
{
const roomIdString = object.model.getValue<string>(RoomObjectVariable.OBJECT_ROOM_ID);
const roomId = ((roomIdString && (parseInt(roomIdString.split('_')[0]) || 0)) || -1);
if((roomId >= 0) && GetEventDispatcher())
{
GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_STACK_HEIGHT, roomId, object.id, category));
return;
}
}
if(object.mouseHandler) object.mouseHandler.mouseEvent(event, geometry); if(object.mouseHandler) object.mouseHandler.mouseEvent(event, geometry);
} }
-2
View File
@@ -239,8 +239,6 @@ export class RoomPreviewer
if(this.isRoomEngineReady) if(this.isRoomEngineReady)
{ {
if((this._currentPreviewObjectCategory === RoomObjectCategory.FLOOR) && (this._currentPreviewObjectType === classId) && (this._currentPreviewObjectData === (extra || ''))) return RoomPreviewer.PREVIEW_OBJECT_ID;
this.reset(false); this.reset(false);
this._currentPreviewObjectType = classId; this._currentPreviewObjectType = classId;
+11 -1
View File
@@ -623,7 +623,17 @@ export class RoomPlaneParser
} }
_local_3++; _local_3++;
} }
const _local_4: Point = RoomPlaneParser.findEntranceTile(this._tileMatrix); const _local_4: Point = (() =>
{
const matrixWithFloorHoles = this._tileMatrix.map((row, rowIndex) =>
{
const floorHoleRow = this._floorHoleMatrix[rowIndex] || [];
return row.map((value, columnIndex) => (floorHoleRow[columnIndex] ? RoomPlaneParser.TILE_HOLE : value));
});
return RoomPlaneParser.findEntranceTile(matrixWithFloorHoles);
})();
_local_3 = 0; _local_3 = 0;
while(_local_3 < this._height) while(_local_3 < this._height)
@@ -6,6 +6,7 @@ import { RoomObjectLogicBase } from './RoomObjectLogicBase';
export class MovingObjectLogic extends RoomObjectLogicBase export class MovingObjectLogic extends RoomObjectLogicBase
{ {
public static DEFAULT_UPDATE_INTERVAL: number = 500; public static DEFAULT_UPDATE_INTERVAL: number = 500;
private static LOCATION_EPSILON: number = 0.01;
private static TEMP_VECTOR: Vector3d = new Vector3d(); private static TEMP_VECTOR: Vector3d = new Vector3d();
private _liftAmount: number; private _liftAmount: number;
@@ -17,6 +18,7 @@ export class MovingObjectLogic extends RoomObjectLogicBase
private _lastUpdateTime: number; private _lastUpdateTime: number;
private _changeTime: number; private _changeTime: number;
private _updateInterval: number; private _updateInterval: number;
private _queuedMoveMessages: ObjectMoveUpdateMessage[];
constructor() constructor()
{ {
@@ -31,11 +33,13 @@ export class MovingObjectLogic extends RoomObjectLogicBase
this._lastUpdateTime = 0; this._lastUpdateTime = 0;
this._changeTime = 0; this._changeTime = 0;
this._updateInterval = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL; this._updateInterval = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL;
this._queuedMoveMessages = [];
} }
public dispose(): void public dispose(): void
{ {
this._liftAmount = 0; this._liftAmount = 0;
this._queuedMoveMessages = [];
super.dispose(); super.dispose();
} }
@@ -46,6 +50,7 @@ export class MovingObjectLogic extends RoomObjectLogicBase
const locationOffset = this.getLocationOffset(); const locationOffset = this.getLocationOffset();
const model = this.object && this.object.model; const model = this.object && this.object.model;
let completedInterpolation = false;
if(model) if(model)
{ {
@@ -111,10 +116,13 @@ export class MovingObjectLogic extends RoomObjectLogicBase
this._locationDelta.x = 0; this._locationDelta.x = 0;
this._locationDelta.y = 0; this._locationDelta.y = 0;
this._locationDelta.z = 0; this._locationDelta.z = 0;
completedInterpolation = true;
} }
} }
this._lastUpdateTime = this.time; this._lastUpdateTime = this.time;
if(completedInterpolation) this.processQueuedMoveMessage();
} }
public setObject(object: IRoomObjectController): void public setObject(object: IRoomObjectController): void
@@ -130,6 +138,17 @@ export class MovingObjectLogic extends RoomObjectLogicBase
if(message instanceof ObjectMoveUpdateMessage) if(message instanceof ObjectMoveUpdateMessage)
{ {
if(this.shouldApplyInstantMoveMessage(message))
{
super.processUpdateMessage(message);
if(message.location) this._location.assign(message.location);
this.resetInterpolationState();
return;
}
const requiresCustomMoveHandling = !!message.anchorObject || (message.elapsed > 0); const requiresCustomMoveHandling = !!message.anchorObject || (message.elapsed > 0);
if(requiresCustomMoveHandling) if(requiresCustomMoveHandling)
@@ -147,15 +166,30 @@ export class MovingObjectLogic extends RoomObjectLogicBase
if(message instanceof ObjectMoveUpdateMessage) return this.processMoveMessage(message); if(message instanceof ObjectMoveUpdateMessage) return this.processMoveMessage(message);
} }
private shouldApplyInstantMoveMessage(message: ObjectMoveUpdateMessage): boolean
{
if(!message || !message.location || message.isSlide || !!message.anchorObject || (message.elapsed > 0)) return false;
return this.matchesLocation(message.location, message.targetLocation);
}
private processMoveMessage(message: ObjectMoveUpdateMessage): void private processMoveMessage(message: ObjectMoveUpdateMessage): void
{ {
if(!message || !this.object || !message.location) return; if(!message || !this.object || !message.location) return;
if(this.shouldQueueMoveMessage(message))
{
this.queueMoveMessage(message);
return;
}
const hadActiveInterpolation = this.isInterpolating(); const hadActiveInterpolation = this.isInterpolating();
const duration = ((message.duration > 0) ? message.duration : ObjectMoveUpdateMessage.DEFAULT_DURATION);
const startLocation = hadActiveInterpolation const startLocation = hadActiveInterpolation
? this.object.getLocation() ? this.object.getLocation()
: message.location; : message.location;
const elapsed = Math.max(0, Math.min(message.duration, message.elapsed)); const elapsed = Math.max(0, Math.min(duration, message.elapsed));
this._location.assign(startLocation); this._location.assign(startLocation);
this.object.setLocation(this._location); this.object.setLocation(this._location);
@@ -165,7 +199,7 @@ export class MovingObjectLogic extends RoomObjectLogicBase
else this._followOffset.assign(new Vector3d()); else this._followOffset.assign(new Vector3d());
this._changeTime = (this._lastUpdateTime - elapsed); this._changeTime = (this._lastUpdateTime - elapsed);
this.updateInterval = message.duration; this.updateInterval = duration;
this._locationDelta.assign(message.targetLocation); this._locationDelta.assign(message.targetLocation);
this._locationDelta.subtract(this._location); this._locationDelta.subtract(this._location);
@@ -203,11 +237,86 @@ export class MovingObjectLogic extends RoomObjectLogicBase
} }
} }
private resetInterpolationState(): void
{
this._locationDelta.x = 0;
this._locationDelta.y = 0;
this._locationDelta.z = 0;
this._followObject = null;
this._followOffset.assign(new Vector3d());
this._queuedMoveMessages = [];
this._changeTime = this._lastUpdateTime;
}
private isInterpolating(): boolean private isInterpolating(): boolean
{ {
return (this._locationDelta.length > 0) && ((this.time - this._changeTime) < this._updateInterval); return (this._locationDelta.length > 0) && ((this.time - this._changeTime) < this._updateInterval);
} }
private shouldQueueMoveMessage(message: ObjectMoveUpdateMessage): boolean
{
if(!message.isSlide || !!message.anchorObject || !this.isInterpolating() || !message.location || !message.targetLocation) return false;
const expectedStartLocation = this.getQueuedMovementTailLocation();
if(!expectedStartLocation) return false;
return this.matchesLocation(message.location, expectedStartLocation)
&& !this.matchesLocation(message.targetLocation, expectedStartLocation);
}
private queueMoveMessage(message: ObjectMoveUpdateMessage): void
{
this._queuedMoveMessages.push(new ObjectMoveUpdateMessage(
message.location,
message.targetLocation,
message.direction,
message.isSlide,
message.duration,
message.elapsed,
message.anchorObject,
message.anchorOffset));
}
private processQueuedMoveMessage(): void
{
if(!this._queuedMoveMessages.length) return;
const nextMoveMessage = this._queuedMoveMessages.shift();
if(!nextMoveMessage) return;
this.processMoveMessage(nextMoveMessage);
}
private getQueuedMovementTailLocation(): IVector3D
{
if(this._queuedMoveMessages.length)
{
const queuedMoveMessage = this._queuedMoveMessages[this._queuedMoveMessages.length - 1];
if(queuedMoveMessage?.targetLocation) return queuedMoveMessage.targetLocation;
}
if(this._locationDelta.length <= 0) return null;
const targetLocation = new Vector3d();
targetLocation.assign(this._location);
targetLocation.add(this._locationDelta);
return targetLocation;
}
private matchesLocation(first: IVector3D, second: IVector3D): boolean
{
if(!first || !second) return false;
return (Math.abs(first.x - second.x) <= MovingObjectLogic.LOCATION_EPSILON)
&& (Math.abs(first.y - second.y) <= MovingObjectLogic.LOCATION_EPSILON)
&& (Math.abs(first.z - second.z) <= MovingObjectLogic.LOCATION_EPSILON);
}
protected getLocationOffset(): IVector3D protected getLocationOffset(): IVector3D
{ {
return null; return null;
+1 -1
View File
@@ -294,7 +294,7 @@ export class RoomLogic extends RoomObjectLogicBase
switch(message.type) switch(message.type)
{ {
case ObjectRoomFloorHoleUpdateMessage.ADD: case ObjectRoomFloorHoleUpdateMessage.ADD:
this._planeParser.addFloorHole(message.id, message.x, message.y, message.width, message.height); this._planeParser.addFloorHole(message.id, message.x, message.y, message.width, message.height, message.invert);
this._needsMapUpdate = true; this._needsMapUpdate = true;
return; return;
case ObjectRoomFloorHoleUpdateMessage.REMOVE: case ObjectRoomFloorHoleUpdateMessage.REMOVE:
@@ -25,7 +25,5 @@ export class FurnitureCustomStackHeightLogic extends FurnitureMultiStateLogic
if(!this.object || !this.eventDispatcher) return; if(!this.object || !this.eventDispatcher) return;
this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.STACK_HEIGHT, this.object)); this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.STACK_HEIGHT, this.object));
super.useObject();
} }
} }
@@ -398,6 +398,13 @@ export class FurnitureLogic extends MovingObjectLogic
{ {
if(!this.object || !this.eventDispatcher) return; if(!this.object || !this.eventDispatcher) return;
if(this.object.model && (this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_IS_VARIABLE_HEIGHT) > 0))
{
this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.STACK_HEIGHT, this.object));
return;
}
const clickUrl = this.getAdClickUrl(this.object.model); const clickUrl = this.getAdClickUrl(this.object.model);
if(clickUrl && clickUrl.length) if(clickUrl && clickUrl.length)
@@ -164,18 +164,6 @@ export class AvatarVisualization extends RoomObjectSpriteVisualization implement
if(this._avatarImage) this._avatarImage.dispose(); if(this._avatarImage) this._avatarImage.dispose();
if(this._cachedAvatars)
{
for(const avatar of this._cachedAvatars.getValues()) avatar && avatar.dispose();
this._cachedAvatars.reset();
}
if(this._cachedAvatarEffects)
{
for(const avatar of this._cachedAvatarEffects.getValues()) avatar && avatar.dispose();
this._cachedAvatarEffects.reset();
}
if(this._reflectionOppositeTexture) if(this._reflectionOppositeTexture)
{ {
this._reflectionOppositeTexture.destroy(true); this._reflectionOppositeTexture.destroy(true);
@@ -237,8 +237,11 @@ export class FurnitureVisualization extends RoomObjectSpriteVisualization
this._furnitureLift = (model.getValue<number>(RoomObjectVariable.FURNITURE_LIFT_AMOUNT) || 0); this._furnitureLift = (model.getValue<number>(RoomObjectVariable.FURNITURE_LIFT_AMOUNT) || 0);
let alphaMultiplier = model.getValue<number>(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER); let alphaMultiplier = model.getValue<number>(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER);
const hiddenByConfInvisControl = (model.getValue<number>(RoomObjectVariable.FURNITURE_CONF_INVIS_HIDDEN) === 1);
const hiddenByAreaHideControl = (model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_HIDDEN) === 1);
if(isNaN(alphaMultiplier)) alphaMultiplier = 1; if(isNaN(alphaMultiplier)) alphaMultiplier = 1;
if(hiddenByConfInvisControl || hiddenByAreaHideControl) alphaMultiplier = 0;
if(this._alphaMultiplier !== alphaMultiplier) if(this._alphaMultiplier !== alphaMultiplier)
{ {
@@ -27,17 +27,6 @@ export class IsometricImageFurniVisualization extends FurnitureAnimatedVisualiza
this._photoUrl = null; this._photoUrl = null;
} }
public dispose(): void {
if (this._thumbnailTexture instanceof RenderTexture) {
this._thumbnailTexture.destroy(true);
}
this._thumbnailTexture = null;
this._thumbnailImageNormal = null;
super.dispose();
}
public get hasThumbnailImage(): boolean { public get hasThumbnailImage(): boolean {
return !(this._thumbnailImageNormal == null); return !(this._thumbnailImageNormal == null);
} }
@@ -158,16 +158,6 @@ export class RoomPlane implements IRoomPlane
this._animationLayers = []; this._animationLayers = [];
} }
this._windowReflectionLastVisible.clear();
this._windowReflectionFadeOut.clear();
this._windowReflectionFirstSeenAt.clear();
if(this._maskFilter)
{
this._maskFilter.destroy();
this._maskFilter = null;
}
this._disposed = true; this._disposed = true;
} }