127 lines
3.4 KiB
TypeScript
127 lines
3.4 KiB
TypeScript
import {IRoomObjectController, IRoomObjectUpdateMessage, IVector3D, RoomObjectVariable, Vector3d} from "../../../../api";
|
|
import {RoomObjectLogicBase} from "../../../../room";
|
|
import {ObjectMoveUpdateMessage} from "../../messages";
|
|
|
|
export class MovingObjectLogic extends RoomObjectLogicBase {
|
|
public static DEFAULT_UPDATE_INTERVAL: number = 500;
|
|
private static TEMP_VECTOR: Vector3d = new Vector3d();
|
|
|
|
private _liftAmount: number;
|
|
|
|
private _location: Vector3d;
|
|
private _locationDelta: Vector3d;
|
|
private _lastUpdateTime: number;
|
|
private _changeTime: number;
|
|
private _updateInterval: number;
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
this._liftAmount = 0;
|
|
|
|
this._location = new Vector3d();
|
|
this._locationDelta = new Vector3d();
|
|
this._lastUpdateTime = 0;
|
|
this._changeTime = 0;
|
|
this._updateInterval = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL;
|
|
}
|
|
|
|
protected override onDispose(): void {
|
|
this._liftAmount = 0;
|
|
|
|
super.onDispose();
|
|
}
|
|
|
|
public override update(time: number): void {
|
|
super.update(time);
|
|
|
|
const locationOffset = this.getLocationOffset();
|
|
const model = this.object && this.object.model;
|
|
|
|
if (model) {
|
|
if (locationOffset) {
|
|
if (this._liftAmount !== locationOffset.z) {
|
|
this._liftAmount = locationOffset.z;
|
|
|
|
model.setValue(RoomObjectVariable.FURNITURE_LIFT_AMOUNT, this._liftAmount);
|
|
}
|
|
} else {
|
|
if (this._liftAmount !== 0) {
|
|
this._liftAmount = 0;
|
|
|
|
model.setValue(RoomObjectVariable.FURNITURE_LIFT_AMOUNT, this._liftAmount);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this._locationDelta.length > 0 || locationOffset) {
|
|
const vector = MovingObjectLogic.TEMP_VECTOR;
|
|
|
|
let difference = this.time - this._changeTime;
|
|
|
|
if (difference === this._updateInterval >> 1) difference++;
|
|
|
|
if (difference > this._updateInterval) difference = this._updateInterval;
|
|
|
|
if (this._locationDelta.length > 0) {
|
|
vector.assign(this._locationDelta);
|
|
vector.multiply(difference / this._updateInterval);
|
|
vector.add(this._location);
|
|
} else {
|
|
vector.assign(this._location);
|
|
}
|
|
|
|
if (locationOffset) vector.add(locationOffset);
|
|
|
|
this.object.setLocation(vector);
|
|
|
|
if (difference === this._updateInterval) {
|
|
this._locationDelta.x = 0;
|
|
this._locationDelta.y = 0;
|
|
this._locationDelta.z = 0;
|
|
}
|
|
}
|
|
|
|
this._lastUpdateTime = this.time;
|
|
}
|
|
|
|
public override setObject(object: IRoomObjectController): void {
|
|
super.setObject(object);
|
|
|
|
if (object) this._location.assign(object.getLocation());
|
|
}
|
|
|
|
public override processUpdateMessage(message: IRoomObjectUpdateMessage): void {
|
|
if (!message) return;
|
|
|
|
super.processUpdateMessage(message);
|
|
|
|
if (message.location) this._location.assign(message.location);
|
|
|
|
if (message instanceof ObjectMoveUpdateMessage) return this.processMoveMessage(message);
|
|
}
|
|
|
|
private processMoveMessage(message: ObjectMoveUpdateMessage): void {
|
|
if (!message || !this.object || !message.location) return;
|
|
|
|
this._changeTime = this._lastUpdateTime;
|
|
|
|
this._locationDelta.assign(message.targetLocation);
|
|
this._locationDelta.subtract(this._location);
|
|
}
|
|
|
|
protected getLocationOffset(): IVector3D {
|
|
return null;
|
|
}
|
|
|
|
protected get lastUpdateTime(): number {
|
|
return this._lastUpdateTime;
|
|
}
|
|
|
|
protected set updateInterval(interval: number) {
|
|
if (interval <= 0) interval = 1;
|
|
|
|
this._updateInterval = interval;
|
|
}
|
|
}
|