import { IAssetData, IRoomGeometry, IRoomObjectModel, IVector3D, MouseEventType, PetFigureData, PetType, RoomObjectVariable } from '@nitrots/api'; import { RoomObjectMouseEvent, RoomObjectMoveEvent, RoomSpriteMouseEvent } from '@nitrots/events'; import { Vector3d } from '@nitrots/utils'; import { ObjectAvatarChatUpdateMessage, ObjectAvatarExperienceUpdateMessage, ObjectAvatarFigureUpdateMessage, ObjectAvatarPetGestureUpdateMessage, ObjectAvatarPostureUpdateMessage, ObjectAvatarSelectedMessage, ObjectAvatarSleepUpdateMessage, ObjectAvatarUpdateMessage, RoomObjectUpdateMessage } from '../../messages'; import { MovingObjectLogic } from './MovingObjectLogic'; export class PetLogic extends MovingObjectLogic { private _selected: boolean; private _reportedLocation: IVector3D; private _postureIndex: number; private _gestureIndex: number; private _headDirectionDelta: number; private _directions: number[]; private _talkingEndTimestamp: number; private _gestureEndTimestamp: number; private _expressionEndTimestamp: number; constructor() { super(); this._selected = false; this._reportedLocation = null; this._postureIndex = 0; this._gestureIndex = 0; this._headDirectionDelta = 0; this._directions = []; this._talkingEndTimestamp = 0; this._gestureEndTimestamp = 0; this._expressionEndTimestamp = 0; } public getEventTypes(): string[] { const types = [RoomObjectMouseEvent.CLICK, RoomObjectMoveEvent.POSITION_CHANGED]; return this.mergeTypes(super.getEventTypes(), types); } public initialize(asset: IAssetData): void { if(!asset) return; const model = this.object && this.object.model; if(!model) return; if(asset.logic) { if(asset.logic.model) { const directions = asset.logic.model.directions; if(directions && directions.length) { for(const direction of directions) this._directions.push(direction); this._directions.sort(); } } } model.setValue(RoomObjectVariable.PET_ALLOWED_DIRECTIONS, this._directions); } public dispose(): void { if(this._selected && this.object) { if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMoveEvent(RoomObjectMoveEvent.OBJECT_REMOVED, this.object)); } this._directions = null; this._reportedLocation = null; } public update(totalTimeRunning: number): void { super.update(totalTimeRunning); if(this._selected && this.object) { if(this.eventDispatcher) { const location = this.object.getLocation(); if(((!this._reportedLocation || (this._reportedLocation.x !== location.x)) || (this._reportedLocation.y !== location.y)) || (this._reportedLocation.z !== location.z)) { if(!this._reportedLocation) this._reportedLocation = new Vector3d(); this._reportedLocation.assign(location); this.eventDispatcher.dispatchEvent(new RoomObjectMoveEvent(RoomObjectMoveEvent.POSITION_CHANGED, this.object)); } } } if(this.object && this.object.model) this.updateModel(totalTimeRunning, this.object.model); } private updateModel(time: number, model: IRoomObjectModel): void { if((this._gestureEndTimestamp > 0) && (time > this._gestureEndTimestamp)) { model.setValue(RoomObjectVariable.FIGURE_GESTURE, null); this._gestureEndTimestamp = 0; } if(this._talkingEndTimestamp > 0) { if(time > this._talkingEndTimestamp) { model.setValue(RoomObjectVariable.FIGURE_TALK, 0); this._talkingEndTimestamp = 0; } } if((this._expressionEndTimestamp > 0) && (time > this._expressionEndTimestamp)) { model.setValue(RoomObjectVariable.FIGURE_EXPRESSION, 0); this._expressionEndTimestamp = 0; } } public processUpdateMessage(message: RoomObjectUpdateMessage): void { if(!message || !this.object) return; super.processUpdateMessage(message); const model = this.object && this.object.model; if(!model) return; if(message instanceof ObjectAvatarUpdateMessage) { model.setValue(RoomObjectVariable.HEAD_DIRECTION, message.headDirection); return; } if(message instanceof ObjectAvatarFigureUpdateMessage) { const petFigureData = new PetFigureData(message.figure); model.setValue(RoomObjectVariable.FIGURE, message.figure); model.setValue(RoomObjectVariable.RACE, message.subType); model.setValue(RoomObjectVariable.PET_PALETTE_INDEX, petFigureData.paletteId); model.setValue(RoomObjectVariable.PET_COLOR, petFigureData.color); model.setValue(RoomObjectVariable.PET_TYPE, petFigureData.typeId); model.setValue(RoomObjectVariable.PET_CUSTOM_LAYER_IDS, petFigureData.customLayerIds); model.setValue(RoomObjectVariable.PET_CUSTOM_PARTS_IDS, petFigureData.customPartIds); model.setValue(RoomObjectVariable.PET_CUSTOM_PALETTE_IDS, petFigureData.customPaletteIds); model.setValue(RoomObjectVariable.PET_IS_RIDING, (message.isRiding ? 1 : 0)); return; } if(message instanceof ObjectAvatarPostureUpdateMessage) { model.setValue(RoomObjectVariable.FIGURE_POSTURE, message.postureType); return; } if(message instanceof ObjectAvatarChatUpdateMessage) { model.setValue(RoomObjectVariable.FIGURE_TALK, 1); this._talkingEndTimestamp = this.time + (message.numberOfWords * 1000); return; } if(message instanceof ObjectAvatarSleepUpdateMessage) { model.setValue(RoomObjectVariable.FIGURE_SLEEP, message.isSleeping ? 1 : 0); return; } if(message instanceof ObjectAvatarPetGestureUpdateMessage) { model.setValue(RoomObjectVariable.FIGURE_GESTURE, message.gesture); this._gestureEndTimestamp = this.time + 3000; return; } if(message instanceof ObjectAvatarSelectedMessage) { this._selected = message.selected; this._reportedLocation = null; return; } if(message instanceof ObjectAvatarExperienceUpdateMessage) { model.setValue(RoomObjectVariable.FIGURE_EXPERIENCE_TIMESTAMP, this.time); model.setValue(RoomObjectVariable.FIGURE_GAINED_EXPERIENCE, message.gainedExperience); return; } } public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void { let eventType: string = null; switch(event.type) { case MouseEventType.MOUSE_CLICK: eventType = RoomObjectMouseEvent.CLICK; break; case MouseEventType.DOUBLE_CLICK: break; case MouseEventType.MOUSE_DOWN: { const petType = this.object.model.getValue(RoomObjectVariable.PET_TYPE); if(petType === PetType.MONSTERPLANT) { if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMouseEvent(RoomObjectMouseEvent.MOUSE_DOWN, this.object, event.eventId, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown)); } break; } } if(eventType && this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMouseEvent(eventType, this.object, event.eventId, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown)); } }