You've already forked Nitro_Render_V3
mirror of
https://github.com/duckietm/Nitro_Render_V3.git
synced 2026-06-19 15:06:20 +00:00
feat: support wired movement packets and room sync
This commit is contained in:
@@ -35,9 +35,9 @@ export interface IRoomCreator
|
||||
updateRoomObjectFloorHeight(roomId: number, objectId: number, height: number): boolean;
|
||||
updateRoomObjectFloorExpiration(roomId: number, objectId: number, expires: number): boolean;
|
||||
updateRoomObjectWallExpiration(roomId: number, objectId: number, expires: number): boolean;
|
||||
rollRoomObjectFloor(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D): void;
|
||||
rollRoomObjectFloor(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D, duration?: number, direction?: IVector3D): void;
|
||||
addRoomObjectUser(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, headDirection: number, type: number, figure: string): boolean;
|
||||
updateRoomObjectUserLocation(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D, canStandUp?: boolean, baseY?: number, direction?: IVector3D, headDirection?: number, skipLocationFix?: boolean): boolean;
|
||||
updateRoomObjectUserLocation(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D, canStandUp?: boolean, baseY?: number, direction?: IVector3D, headDirection?: number, skipLocationFix?: boolean, isSlide?: boolean, duration?: number): boolean;
|
||||
updateRoomObjectUserAction(roomId: number, objectId: number, action: string, value: number, parameter?: string): boolean;
|
||||
updateRoomObjectUserFigure(roomId: number, objectId: number, figure: string, gender?: string, subType?: string, isRiding?: boolean): boolean;
|
||||
updateRoomObjectUserFlatControl(roomId: number, objectId: number, level: string): boolean;
|
||||
|
||||
@@ -45,7 +45,7 @@ export interface IRoomEngine
|
||||
getFurnitureWallIcon(typeId: number, listener: IGetImageListener, extras?: string): IImageResult;
|
||||
updateRoomObjectWallLocation(roomId: number, objectId: number, location: IVector3D): boolean;
|
||||
addRoomObjectUser(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, headDirection: number, type: number, figure: string): boolean;
|
||||
updateRoomObjectUserLocation(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D, canStandUp?: boolean, baseY?: number, direction?: IVector3D, headDirection?: number, skipLocationFix?: boolean): boolean;
|
||||
updateRoomObjectUserLocation(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D, canStandUp?: boolean, baseY?: number, direction?: IVector3D, headDirection?: number, skipLocationFix?: boolean, isSlide?: boolean, duration?: number): boolean;
|
||||
addFurnitureFloor(roomId: number, id: number, typeId: number, location: IVector3D, direction: IVector3D, state: number, objectData: IObjectData, extra?: number, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, synchronized?: boolean, realRoomObject?: boolean, sizeZ?: number): boolean;
|
||||
addFurnitureFloorByTypeName(roomId: number, id: number, typeName: string, location: IVector3D, direction: IVector3D, state: number, objectData: IObjectData, extra?: number, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, synchronized?: boolean, realRoomObject?: boolean, sizeZ?: number): boolean;
|
||||
addFurnitureWall(roomId: number, id: number, typeId: number, location: IVector3D, direction: IVector3D, state: number, extra: string, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, realRoomObject?: boolean): boolean;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -181,6 +181,7 @@ export class IncomingHeader
|
||||
public static ROOM_RIGHTS_LIST_REMOVE = 1327;
|
||||
public static ROOM_RIGHTS_OWNER = 339;
|
||||
public static ROOM_ROLLING = 3207;
|
||||
public static WIRED_MOVEMENTS = 3999;
|
||||
public static ROOM_SCORE = 482;
|
||||
public static ROOM_SETTINGS = 1498;
|
||||
public static ROOM_SETTINGS_CHAT = 1191;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { IMessageEvent } from '@nitrots/api';
|
||||
import { MessageEvent } from '@nitrots/events';
|
||||
import { WiredMovementsParser } from '../../../parser';
|
||||
|
||||
export class WiredMovementsEvent extends MessageEvent implements IMessageEvent
|
||||
{
|
||||
constructor(callBack: Function)
|
||||
{
|
||||
super(callBack, WiredMovementsParser);
|
||||
}
|
||||
|
||||
public getParser(): WiredMovementsParser
|
||||
{
|
||||
return this.parser as WiredMovementsParser;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './FavoriteMembershipUpdateMessageEvent';
|
||||
export * from './ObjectsDataUpdateEvent';
|
||||
export * from './ObjectsRollingEvent';
|
||||
export * from './WiredMovementsEvent';
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
import { IMessageDataWrapper, IMessageParser, ObjectRolling } from '@nitrots/api';
|
||||
import { Vector3d } from '@nitrots/utils';
|
||||
|
||||
function parseLocaleFloat(value: string): number
|
||||
{
|
||||
if(!value) return 0;
|
||||
|
||||
return parseFloat(value.replace(',', '.'));
|
||||
}
|
||||
|
||||
function parseDirection(value: number): number
|
||||
{
|
||||
return ((((value % 8) + 8) % 8) * 45);
|
||||
}
|
||||
|
||||
export class WiredUserMovementData extends ObjectRolling
|
||||
{
|
||||
constructor(id: number, location: Vector3d, targetLocation: Vector3d, movementType: string, private _bodyDirection: number, private _headDirection: number, private _duration: number)
|
||||
{
|
||||
super(id, location, targetLocation, movementType);
|
||||
}
|
||||
|
||||
public get bodyDirection(): number
|
||||
{
|
||||
return this._bodyDirection;
|
||||
}
|
||||
|
||||
public get headDirection(): number
|
||||
{
|
||||
return this._headDirection;
|
||||
}
|
||||
|
||||
public get duration(): number
|
||||
{
|
||||
return this._duration;
|
||||
}
|
||||
}
|
||||
|
||||
export class WiredFurniMovementData extends ObjectRolling
|
||||
{
|
||||
constructor(id: number, location: Vector3d, targetLocation: Vector3d, private _rotation: number, private _duration: number)
|
||||
{
|
||||
super(id, location, targetLocation, ObjectRolling.SLIDE);
|
||||
}
|
||||
|
||||
public get rotation(): number
|
||||
{
|
||||
return this._rotation;
|
||||
}
|
||||
|
||||
public get duration(): number
|
||||
{
|
||||
return this._duration;
|
||||
}
|
||||
}
|
||||
|
||||
export class WiredWallItemMovementData
|
||||
{
|
||||
constructor(private _id: number, private _enabled: boolean, private _values: number[])
|
||||
{
|
||||
}
|
||||
|
||||
public get id(): number
|
||||
{
|
||||
return this._id;
|
||||
}
|
||||
|
||||
public get enabled(): boolean
|
||||
{
|
||||
return this._enabled;
|
||||
}
|
||||
|
||||
public get values(): number[]
|
||||
{
|
||||
return this._values;
|
||||
}
|
||||
}
|
||||
|
||||
export class WiredUserDirectionUpdateData
|
||||
{
|
||||
constructor(private _id: number, private _headDirection: number, private _bodyDirection: number)
|
||||
{
|
||||
}
|
||||
|
||||
public get id(): number
|
||||
{
|
||||
return this._id;
|
||||
}
|
||||
|
||||
public get headDirection(): number
|
||||
{
|
||||
return this._headDirection;
|
||||
}
|
||||
|
||||
public get bodyDirection(): number
|
||||
{
|
||||
return this._bodyDirection;
|
||||
}
|
||||
}
|
||||
|
||||
export class WiredMovementsParser implements IMessageParser
|
||||
{
|
||||
private _furniMovements: WiredFurniMovementData[];
|
||||
private _userMovements: WiredUserMovementData[];
|
||||
private _wallItemMovements: WiredWallItemMovementData[];
|
||||
private _userDirectionUpdates: WiredUserDirectionUpdateData[];
|
||||
|
||||
public flush(): boolean
|
||||
{
|
||||
this._furniMovements = [];
|
||||
this._userMovements = [];
|
||||
this._wallItemMovements = [];
|
||||
this._userDirectionUpdates = [];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public parse(wrapper: IMessageDataWrapper): boolean
|
||||
{
|
||||
if(!wrapper) return false;
|
||||
|
||||
let totalMovements = wrapper.readInt();
|
||||
|
||||
while(totalMovements > 0)
|
||||
{
|
||||
const type = wrapper.readInt();
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
const fromX = wrapper.readInt();
|
||||
const fromY = wrapper.readInt();
|
||||
const toX = wrapper.readInt();
|
||||
const toY = wrapper.readInt();
|
||||
const fromZ = parseLocaleFloat(wrapper.readString());
|
||||
const toZ = parseLocaleFloat(wrapper.readString());
|
||||
const id = wrapper.readInt();
|
||||
const animationType = wrapper.readInt();
|
||||
const bodyDirection = parseDirection(wrapper.readInt());
|
||||
const headDirection = parseDirection(wrapper.readInt());
|
||||
const duration = wrapper.readInt();
|
||||
const movementType = (animationType === 0) ? ObjectRolling.MOVE : ObjectRolling.SLIDE;
|
||||
|
||||
this._userMovements.push(new WiredUserMovementData(
|
||||
id,
|
||||
new Vector3d(fromX, fromY, fromZ),
|
||||
new Vector3d(toX, toY, toZ),
|
||||
movementType,
|
||||
bodyDirection,
|
||||
headDirection,
|
||||
duration));
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
const fromX = wrapper.readInt();
|
||||
const fromY = wrapper.readInt();
|
||||
const toX = wrapper.readInt();
|
||||
const toY = wrapper.readInt();
|
||||
const fromZ = parseLocaleFloat(wrapper.readString());
|
||||
const toZ = parseLocaleFloat(wrapper.readString());
|
||||
const id = wrapper.readInt();
|
||||
const rotation = wrapper.readInt();
|
||||
const duration = wrapper.readInt();
|
||||
|
||||
this._furniMovements.push(new WiredFurniMovementData(
|
||||
id,
|
||||
new Vector3d(fromX, fromY, fromZ),
|
||||
new Vector3d(toX, toY, toZ),
|
||||
rotation,
|
||||
duration));
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
const id = wrapper.readInt();
|
||||
const enabled = wrapper.readBoolean();
|
||||
const values: number[] = [];
|
||||
|
||||
let index = 0;
|
||||
|
||||
while(index < 9)
|
||||
{
|
||||
values.push(wrapper.readInt());
|
||||
index++;
|
||||
}
|
||||
|
||||
this._wallItemMovements.push(new WiredWallItemMovementData(id, enabled, values));
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
const id = wrapper.readInt();
|
||||
const headDirection = parseDirection(wrapper.readInt());
|
||||
const bodyDirection = parseDirection(wrapper.readInt());
|
||||
|
||||
this._userDirectionUpdates.push(new WiredUserDirectionUpdateData(id, headDirection, bodyDirection));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
totalMovements--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public get itemMovements(): WiredFurniMovementData[]
|
||||
{
|
||||
return this._furniMovements;
|
||||
}
|
||||
|
||||
public get unitMovements(): WiredUserMovementData[]
|
||||
{
|
||||
return this._userMovements;
|
||||
}
|
||||
|
||||
public get furniMovements(): WiredFurniMovementData[]
|
||||
{
|
||||
return this._furniMovements;
|
||||
}
|
||||
|
||||
public get userMovements(): WiredUserMovementData[]
|
||||
{
|
||||
return this._userMovements;
|
||||
}
|
||||
|
||||
public get wallItemMovements(): WiredWallItemMovementData[]
|
||||
{
|
||||
return this._wallItemMovements;
|
||||
}
|
||||
|
||||
public get userDirectionUpdates(): WiredUserDirectionUpdateData[]
|
||||
{
|
||||
return this._userDirectionUpdates;
|
||||
}
|
||||
}
|
||||
@@ -3,3 +3,4 @@ export * from './FavoriteMembershipUpdateMessageParser';
|
||||
export * from './ObjectData';
|
||||
export * from './ObjectsDataUpdateParser';
|
||||
export * from './ObjectsRollingParser';
|
||||
export * from './WiredMovementsParser';
|
||||
|
||||
@@ -1816,13 +1816,13 @@ export class RoomEngine implements IRoomEngine, IRoomCreator, IRoomEngineService
|
||||
if(roomOwnObject && roomOwnObject.logic && maskUpdate) roomOwnObject.logic.processUpdateMessage(maskUpdate);
|
||||
}
|
||||
|
||||
public rollRoomObjectFloor(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D): void
|
||||
public rollRoomObjectFloor(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D, duration: number = ObjectMoveUpdateMessage.DEFAULT_DURATION, direction: IVector3D = null): void
|
||||
{
|
||||
const object = this.getRoomObjectFloor(roomId, objectId);
|
||||
|
||||
if(!object) return;
|
||||
|
||||
object.processUpdateMessage(new ObjectMoveUpdateMessage(location, targetLocation, null, !!targetLocation));
|
||||
object.processUpdateMessage(new ObjectMoveUpdateMessage(location, targetLocation, direction, !!targetLocation, duration));
|
||||
}
|
||||
|
||||
public updateRoomObjectWallLocation(roomId: number, objectId: number, location: IVector3D): boolean
|
||||
@@ -1884,7 +1884,7 @@ export class RoomEngine implements IRoomEngine, IRoomCreator, IRoomEngineService
|
||||
return true;
|
||||
}
|
||||
|
||||
public updateRoomObjectUserLocation(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D, canStandUp: boolean = false, baseY: number = 0, direction: IVector3D = null, headDirection: number = NaN, skipLocationFix: boolean = false): boolean
|
||||
public updateRoomObjectUserLocation(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D, canStandUp: boolean = false, baseY: number = 0, direction: IVector3D = null, headDirection: number = NaN, skipLocationFix: boolean = false, isSlide: boolean = false, duration: number = ObjectMoveUpdateMessage.DEFAULT_DURATION): boolean
|
||||
{
|
||||
const object = this.getRoomObjectUser(roomId, objectId);
|
||||
|
||||
@@ -1899,11 +1899,11 @@ export class RoomEngine implements IRoomEngine, IRoomCreator, IRoomEngineService
|
||||
const fixedLoc = skipLocationFix ? location : this.fixedUserLocation(roomId, location);
|
||||
const fixedTarget = skipLocationFix ? targetLocation : this.fixedUserLocation(roomId, targetLocation);
|
||||
|
||||
object.processUpdateMessage(new ObjectAvatarUpdateMessage(fixedLoc, fixedTarget, direction, headDirection, canStandUp, baseY));
|
||||
object.processUpdateMessage(new ObjectAvatarUpdateMessage(fixedLoc, fixedTarget, direction, headDirection, canStandUp, baseY, isSlide, duration));
|
||||
|
||||
const roomSession = this._roomSessionManager.getSession(roomId);
|
||||
|
||||
if(roomSession && (roomSession.ownRoomIndex === objectId))
|
||||
if(roomSession && (roomSession.ownRoomIndex === objectId) && targetLocation)
|
||||
{
|
||||
GetEventDispatcher().dispatchEvent(new RoomToObjectOwnAvatarMoveEvent(RoomToObjectOwnAvatarMoveEvent.ROAME_MOVE_TO, targetLocation));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AvatarGuideStatus, IConnection, IMessageEvent, IRoomCreator, IVector3D, LegacyDataType, ObjectRolling, PetType, 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, RoomUnitTypingEvent, RoomVisualizationSettingsEvent, UserInfoEvent, YouArePlayingGameEvent } from '@nitrots/communication';
|
||||
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, WiredMovementsEvent, WiredUserDirectionUpdateData, WiredUserMovementData, YouArePlayingGameEvent } from '@nitrots/communication';
|
||||
import { GetRoomSessionManager, GetSessionDataManager } from '@nitrots/session';
|
||||
import { Vector3d } from '@nitrots/utils';
|
||||
import { GetRoomEngine } from './GetRoomEngine';
|
||||
@@ -9,11 +9,15 @@ import { FurnitureStackingHeightMap, LegacyWallGeometry } from './utils';
|
||||
|
||||
export class RoomMessageHandler
|
||||
{
|
||||
private static WIRED_MOVEMENT_STATUS_GRACE = 250;
|
||||
private static WIRED_MOVEMENT_Z_EPSILON = 0.01;
|
||||
|
||||
private _connection: IConnection = null;
|
||||
private _roomEngine: IRoomCreator = null;
|
||||
private _planeParser = new RoomPlaneParser();
|
||||
private _latestEntryTileEvent: RoomEntryTileMessageEvent = null;
|
||||
private _messageEvents: IMessageEvent[] = [];
|
||||
private _activeWiredUserMovements = new Map<number, { expiresAt: number, targetX: number, targetY: number, targetZ: number }>();
|
||||
|
||||
private _currentRoomId: number = 0;
|
||||
private _ownUserId: number = 0;
|
||||
@@ -38,6 +42,7 @@ export class RoomMessageHandler
|
||||
new RoomVisualizationSettingsEvent(this.onRoomThicknessEvent.bind(this)),
|
||||
new RoomEntryTileMessageEvent(this.onRoomDoorEvent.bind(this)),
|
||||
new ObjectsRollingEvent(this.onRoomRollingEvent.bind(this)),
|
||||
new WiredMovementsEvent(this.onWiredMovementsEvent.bind(this)),
|
||||
new ObjectsDataUpdateEvent(this.onObjectsDataUpdateEvent.bind(this)),
|
||||
new FurnitureAliasesEvent(this.onFurnitureAliasesEvent.bind(this)),
|
||||
new FurnitureFloorAddEvent(this.onFurnitureFloorAddEvent.bind(this)),
|
||||
@@ -98,6 +103,7 @@ export class RoomMessageHandler
|
||||
this._connection = null;
|
||||
this._roomEngine = null;
|
||||
this._latestEntryTileEvent = null;
|
||||
this._activeWiredUserMovements.clear();
|
||||
}
|
||||
|
||||
public setRoomId(id: number): void
|
||||
@@ -109,12 +115,14 @@ export class RoomMessageHandler
|
||||
|
||||
this._currentRoomId = id;
|
||||
this._latestEntryTileEvent = null;
|
||||
this._activeWiredUserMovements.clear();
|
||||
}
|
||||
|
||||
public clearRoomId(): void
|
||||
{
|
||||
this._currentRoomId = 0;
|
||||
this._latestEntryTileEvent = null;
|
||||
this._activeWiredUserMovements.clear();
|
||||
}
|
||||
|
||||
private onUserInfoEvent(event: UserInfoEvent): void
|
||||
@@ -378,27 +386,158 @@ export class RoomMessageHandler
|
||||
|
||||
if(unitRollData)
|
||||
{
|
||||
this._roomEngine.updateRoomObjectUserLocation(this._currentRoomId, unitRollData.id, unitRollData.location, unitRollData.targetLocation, false, 0, null, NaN, true);
|
||||
this.applyRollingUnitMovement(unitRollData);
|
||||
}
|
||||
}
|
||||
|
||||
const object = this._roomEngine.getRoomObjectUser(this._currentRoomId, unitRollData.id);
|
||||
private onWiredMovementsEvent(event: WiredMovementsEvent): void
|
||||
{
|
||||
if(!(event instanceof WiredMovementsEvent) || !event.connection || !this._roomEngine) return;
|
||||
|
||||
const parser = event.getParser();
|
||||
|
||||
if(!parser) return;
|
||||
|
||||
if(parser.furniMovements?.length)
|
||||
{
|
||||
for(const movement of parser.furniMovements)
|
||||
{
|
||||
if(!movement) continue;
|
||||
|
||||
this._roomEngine.rollRoomObjectFloor(
|
||||
this._currentRoomId,
|
||||
movement.id,
|
||||
movement.location,
|
||||
movement.targetLocation,
|
||||
movement.duration,
|
||||
new Vector3d(movement.rotation));
|
||||
}
|
||||
}
|
||||
|
||||
if(parser.userMovements?.length)
|
||||
{
|
||||
for(const movement of parser.userMovements)
|
||||
{
|
||||
if(!movement) continue;
|
||||
|
||||
this.applyWiredUserMovement(movement);
|
||||
}
|
||||
}
|
||||
|
||||
if(parser.userDirectionUpdates?.length)
|
||||
{
|
||||
for(const update of parser.userDirectionUpdates)
|
||||
{
|
||||
if(!update) continue;
|
||||
|
||||
this.applyWiredUserDirectionUpdate(update);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private applyRollingUnitMovement(movement: ObjectRolling): void
|
||||
{
|
||||
this._roomEngine.updateRoomObjectUserLocation(this._currentRoomId, movement.id, movement.location, movement.targetLocation, false, 0, null, NaN, true);
|
||||
|
||||
const object = this._roomEngine.getRoomObjectUser(this._currentRoomId, movement.id);
|
||||
|
||||
if(object && object.type !== RoomObjectUserType.MONSTER_PLANT)
|
||||
{
|
||||
let posture = 'std';
|
||||
const posture = (movement.movementType === ObjectRolling.MOVE) ? 'mv' : 'std';
|
||||
|
||||
switch(unitRollData.movementType)
|
||||
this._roomEngine.updateRoomObjectUserPosture(this._currentRoomId, movement.id, posture);
|
||||
}
|
||||
}
|
||||
|
||||
private applyWiredUserMovement(movement: WiredUserMovementData): void
|
||||
{
|
||||
case ObjectRolling.MOVE:
|
||||
posture = 'mv';
|
||||
break;
|
||||
case ObjectRolling.SLIDE:
|
||||
posture = 'std';
|
||||
break;
|
||||
const isSlide = (movement.movementType === ObjectRolling.SLIDE);
|
||||
this.trackWiredUserMovement(movement);
|
||||
|
||||
this._roomEngine.updateRoomObjectUserLocation(
|
||||
this._currentRoomId,
|
||||
movement.id,
|
||||
movement.location,
|
||||
movement.targetLocation,
|
||||
false,
|
||||
0,
|
||||
new Vector3d(movement.bodyDirection),
|
||||
movement.headDirection,
|
||||
true,
|
||||
isSlide,
|
||||
movement.duration);
|
||||
|
||||
const object = this._roomEngine.getRoomObjectUser(this._currentRoomId, movement.id);
|
||||
|
||||
if(object && object.type !== RoomObjectUserType.MONSTER_PLANT)
|
||||
{
|
||||
const posture = (movement.movementType === ObjectRolling.MOVE) ? 'mv' : 'std';
|
||||
|
||||
this._roomEngine.updateRoomObjectUserPosture(this._currentRoomId, movement.id, posture);
|
||||
}
|
||||
}
|
||||
|
||||
this._roomEngine.updateRoomObjectUserPosture(this._currentRoomId, unitRollData.id, posture);
|
||||
private trackWiredUserMovement(movement: WiredUserMovementData): void
|
||||
{
|
||||
this._activeWiredUserMovements.set(movement.id, {
|
||||
expiresAt: Date.now() + Math.max(movement.duration, 1) + RoomMessageHandler.WIRED_MOVEMENT_STATUS_GRACE,
|
||||
targetX: movement.targetLocation.x,
|
||||
targetY: movement.targetLocation.y,
|
||||
targetZ: movement.targetLocation.z
|
||||
});
|
||||
}
|
||||
|
||||
private shouldSuppressWiredStatusLocation(status: RoomUnitStatusMessage): boolean
|
||||
{
|
||||
const activeMovement = this._activeWiredUserMovements.get(status.id);
|
||||
|
||||
if(!activeMovement) return false;
|
||||
|
||||
if(activeMovement.expiresAt <= Date.now())
|
||||
{
|
||||
this._activeWiredUserMovements.delete(status.id);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(this.shouldReleaseWiredStatusLocation(status, activeMovement))
|
||||
{
|
||||
this._activeWiredUserMovements.delete(status.id);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private shouldReleaseWiredStatusLocation(status: RoomUnitStatusMessage, activeMovement: { expiresAt: number, targetX: number, targetY: number, targetZ: number }): boolean
|
||||
{
|
||||
if(!status.didMove) return false;
|
||||
|
||||
return !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
|
||||
{
|
||||
if(!activeMovement) return false;
|
||||
|
||||
return ((x === activeMovement.targetX)
|
||||
&& (y === activeMovement.targetY)
|
||||
&& (Math.abs(z - activeMovement.targetZ) <= RoomMessageHandler.WIRED_MOVEMENT_Z_EPSILON));
|
||||
}
|
||||
|
||||
private applyWiredUserDirectionUpdate(update: WiredUserDirectionUpdateData): void
|
||||
{
|
||||
this._roomEngine.updateRoomObjectUserLocation(
|
||||
this._currentRoomId,
|
||||
update.id,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
0,
|
||||
new Vector3d(update.bodyDirection),
|
||||
update.headDirection,
|
||||
true);
|
||||
}
|
||||
|
||||
private onObjectsDataUpdateEvent(event: ObjectsDataUpdateEvent): void
|
||||
@@ -734,7 +873,11 @@ export class RoomMessageHandler
|
||||
|
||||
if(status.didMove) goal = new Vector3d(status.targetX, status.targetY, status.targetZ);
|
||||
|
||||
if(!this.shouldSuppressWiredStatusLocation(status))
|
||||
{
|
||||
this._roomEngine.updateRoomObjectUserLocation(this._currentRoomId, status.id, location, goal, status.canStandUp, height, direction, status.headDirection);
|
||||
}
|
||||
|
||||
this._roomEngine.updateRoomObjectUserFlatControl(this._currentRoomId, status.id, null);
|
||||
|
||||
// Save own user's position for reconnection
|
||||
|
||||
@@ -7,9 +7,9 @@ export class ObjectAvatarUpdateMessage extends ObjectMoveUpdateMessage
|
||||
private _canStandUp: boolean;
|
||||
private _baseY: number;
|
||||
|
||||
constructor(location: IVector3D, targetLocation: IVector3D, direction: IVector3D, headDirection: number, canStandUp: boolean, baseY: number)
|
||||
constructor(location: IVector3D, targetLocation: IVector3D, direction: IVector3D, headDirection: number, canStandUp: boolean, baseY: number, isSlide: boolean = false, duration: number = ObjectMoveUpdateMessage.DEFAULT_DURATION)
|
||||
{
|
||||
super(location, targetLocation, direction);
|
||||
super(location, targetLocation, direction, isSlide, duration);
|
||||
|
||||
this._headDirection = headDirection;
|
||||
this._canStandUp = canStandUp;
|
||||
|
||||
@@ -3,15 +3,19 @@ import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage';
|
||||
|
||||
export class ObjectMoveUpdateMessage extends RoomObjectUpdateMessage
|
||||
{
|
||||
public static DEFAULT_DURATION: number = 500;
|
||||
|
||||
private _targetLocation: IVector3D;
|
||||
private _isSlide: boolean;
|
||||
private _duration: number;
|
||||
|
||||
constructor(location: IVector3D, targetLocation: IVector3D, direction: IVector3D, isSlide: boolean = false)
|
||||
constructor(location: IVector3D, targetLocation: IVector3D, direction: IVector3D, isSlide: boolean = false, duration: number = ObjectMoveUpdateMessage.DEFAULT_DURATION)
|
||||
{
|
||||
super(location, direction);
|
||||
|
||||
this._targetLocation = targetLocation;
|
||||
this._isSlide = isSlide;
|
||||
this._duration = duration;
|
||||
}
|
||||
|
||||
public get targetLocation(): IVector3D
|
||||
@@ -25,4 +29,9 @@ export class ObjectMoveUpdateMessage extends RoomObjectUpdateMessage
|
||||
{
|
||||
return this._isSlide;
|
||||
}
|
||||
|
||||
public get duration(): number
|
||||
{
|
||||
return this._duration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,7 @@ export class MovingObjectLogic extends RoomObjectLogicBase
|
||||
if(!message || !this.object || !message.location) return;
|
||||
|
||||
this._changeTime = this._lastUpdateTime;
|
||||
this.updateInterval = message.duration;
|
||||
|
||||
this._locationDelta.assign(message.targetLocation);
|
||||
this._locationDelta.subtract(this._location);
|
||||
|
||||
@@ -67,7 +67,7 @@ export class FurniturePushableLogic extends FurnitureMultiStateLogic
|
||||
return;
|
||||
}
|
||||
|
||||
if(isMoveMessage && message.isSlide) this.updateInterval = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL;
|
||||
if(isMoveMessage && message.isSlide) this.updateInterval = message.duration;
|
||||
|
||||
super.processUpdateMessage(message);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,14 @@ export class RoomAreaSelectionManager implements IRoomAreaSelectionManager
|
||||
private _callback: (rootX: number, rootY: number, width: number, height: number) => void;
|
||||
private _highlightType: string = RoomAreaSelectionManager.HIGHLIGHT_BRIGHTEN;
|
||||
|
||||
private resetHighlightBounds(): void
|
||||
{
|
||||
this._highlightRootX = 0;
|
||||
this._highlightRootY = 0;
|
||||
this._highlightWidth = 0;
|
||||
this._highlightHeight = 0;
|
||||
}
|
||||
|
||||
constructor(roomEngine: IRoomEngine)
|
||||
{
|
||||
this._roomEngine = roomEngine;
|
||||
@@ -191,6 +199,7 @@ export class RoomAreaSelectionManager implements IRoomAreaSelectionManager
|
||||
if(this._state === RoomAreaSelectionManager.NOT_ACTIVE) return;
|
||||
|
||||
this.clearHighlightSilent();
|
||||
this.resetHighlightBounds();
|
||||
|
||||
this._state = RoomAreaSelectionManager.NOT_SELECTING_AREA;
|
||||
|
||||
@@ -233,6 +242,7 @@ export class RoomAreaSelectionManager implements IRoomAreaSelectionManager
|
||||
|
||||
this._callback = callback;
|
||||
this._highlightType = highlightType;
|
||||
this.resetHighlightBounds();
|
||||
|
||||
for(const roomObject of this.getAllFurniture())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user