nitro/libs/renderer/src/nitro/room/object/logic/furniture/FurniturePushableLogic.ts

98 lines
3.2 KiB
TypeScript

import {LegacyDataType, Vector3d} from "../../../../../api";
import {RoomObjectUpdateMessage} from "../../../../../room";
import {ObjectDataUpdateMessage, ObjectMoveUpdateMessage} from "../../../messages";
import {MovingObjectLogic} from "../MovingObjectLogic";
import {FurnitureMultiStateLogic} from "./FurnitureMultiStateLogic";
export class FurniturePushableLogic extends FurnitureMultiStateLogic {
private static ANIMATION_NOT_MOVING: number = 0;
private static ANIMATION_MOVING: number = 1;
private static MAX_ANIMATION_COUNT: number = 10;
private _oldLocation: Vector3d;
constructor() {
super();
this.updateInterval = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL;
this._oldLocation = new Vector3d();
}
public override processUpdateMessage(message: RoomObjectUpdateMessage): void {
if (!message) return;
const isMoveMessage = message instanceof ObjectMoveUpdateMessage;
if (this.object && !isMoveMessage && message.location) {
const location = this.object.getLocation();
const difference = Vector3d.dif(message.location, location);
if (difference) {
if (Math.abs(difference.x) < 2 && Math.abs(difference.y) < 2) {
let prevLocation = location;
if (Math.abs(difference.x) > 1 || Math.abs(difference.y) > 1) {
prevLocation = Vector3d.sum(location, Vector3d.product(difference, 0.5));
}
super.processUpdateMessage(new ObjectMoveUpdateMessage(prevLocation, message.location, message.direction));
return;
}
}
}
if (message.location && !isMoveMessage) super.processUpdateMessage(new ObjectMoveUpdateMessage(message.location, message.location, message.direction));
if (message instanceof ObjectDataUpdateMessage) {
if (message.state > 0) {
this.updateInterval = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL / this.getUpdateIntervalValue(message.state);
} else {
this.updateInterval = 1;
}
this.handleDataUpdate(message);
return;
}
if (isMoveMessage && message.isSlide) this.updateInterval = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL;
super.processUpdateMessage(message);
}
protected getUpdateIntervalValue(value: number) {
return value / FurniturePushableLogic.MAX_ANIMATION_COUNT;
}
protected getAnimationValue(value: number) {
return value % FurniturePushableLogic.MAX_ANIMATION_COUNT;
}
private handleDataUpdate(message: ObjectDataUpdateMessage): void {
const animation = this.getAnimationValue(message.state);
if (animation !== message.state) {
const legacyStuff = new LegacyDataType();
legacyStuff.setString(animation.toString());
message = new ObjectDataUpdateMessage(animation, legacyStuff, message.extra);
}
super.processUpdateMessage(message);
}
public override update(time: number): void {
if (!this.object) return;
this._oldLocation.assign(this.object.getLocation());
super.update(time);
if (Vector3d.dif(this.object.getLocation(), this._oldLocation).length !== 0) return;
if (this.object.getState(0) !== FurniturePushableLogic.ANIMATION_NOT_MOVING) this.object.setState(FurniturePushableLogic.ANIMATION_NOT_MOVING, 0);
}
}