Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import * as PIXI from 'pixi.js-legacy';
- import { OnClick } from '../../../common/interactions/OnClick';
- import { OnDispose } from '../../../common/interactions/OnDispose';
- import { OnStart } from '../../../common/interactions/OnStart';
- import { Direction } from '../../../common/position/Direction';
- import { SpriteContainer } from '../../../common/SpriteContainer';
- import { Nitro } from '../../../Nitro';
- import { UnitLookComposer } from '../../../packets/outgoing/room/unit/UnitLookComposer';
- import { RoomConfiguration } from '../../room/map/RoomConfiguration';
- import { UnitStatusType } from '../../room/unit/status';
- import { Unit } from '../../room/unit/Unit';
- import { UnitHandItem } from '../../room/unit/UnitHandItem';
- import { AvatarAction } from '../base/AvatarAction';
- import { AvatarBodyPart } from '../base/AvatarBodyPart';
- import { BaseAvatar } from '../base/BaseAvatar';
- import { BaseAvatarPart } from '../base/BaseAvatarPart';
- import { IPartData } from '../interfaces/IPartData';
- export class AvatarBuilder extends SpriteContainer implements OnStart, OnDispose, OnClick
- {
- public static HEAD_PARTS = [ AvatarBodyPart.HEAD, AvatarBodyPart.HEAD_ACCESSORY, AvatarBodyPart.HEAD_ACCESSORY_EXTRA, AvatarBodyPart.HAIR, AvatarBodyPart.HAIR_BIG, AvatarBodyPart.EYES, AvatarBodyPart.EYE_ACCESSORY, AvatarBodyPart.FACE, AvatarBodyPart.FACE_ACCESSORY ];
- public static GESTURE_PARTS = [ AvatarBodyPart.FACE, AvatarBodyPart.EYES ];
- public static LEFT_PARTS = [ AvatarBodyPart.LEFT_HAND, AvatarBodyPart.LEFT_HAND_ITEM, AvatarBodyPart.LEFT_SLEEVE, AvatarBodyPart.LEFT_COAT_SLEEVE ];
- public static RIGHT_PARTS = [ AvatarBodyPart.RIGHT_HAND, AvatarBodyPart.RIGHT_HAND_ITEM, AvatarBodyPart.RIGHT_SLEEVE, AvatarBodyPart.RIGHT_COAT_SLEEVE ];
- public static IGNORES_WALK = [ ...AvatarBuilder.HEAD_PARTS, AvatarBodyPart.CHEST, AvatarBodyPart.CHEST_ACCESSORY, AvatarBodyPart.CHEST_PRINT, AvatarBodyPart.COAT_CHEST, AvatarBodyPart.WAIST_ACCESSORY ];
- public static IGNORES_SIT = AvatarBuilder.IGNORES_WALK;
- public static EXPRESSIONS_LEFT: AvatarAction[] = [ AvatarAction.EXPRESSION_WAVE ];
- public static EXPRESSIONS_RIGHT: AvatarAction[] = [ AvatarAction.CARRY, AvatarAction.EXPRESSION_LAUGH, AvatarAction.EXPRESSION_BLOW ];
- public static ACTIVATES_ANIMATION: AvatarAction[] = [ AvatarAction.POSTURE_WALK, AvatarAction.EXPRESSION_WAVE ];
- private _unit: Unit;
- private _direction: Direction;
- private _headDirection: Direction;
- private _posture: AvatarAction;
- private _gesture: AvatarAction;
- private _expression: AvatarAction;
- private _carryItem: UnitHandItem;
- private _isUsing: boolean;
- private _shadow: PIXI.Sprite;
- private _gestureTimeout: any;
- private _expressionTimeout: any;
- private _blinkInterval: any;
- private _useInterval: any;
- private _isReady: boolean;
- private _didCreateShadow: boolean;
- constructor(unit: Unit)
- {
- super();
- if(!(unit instanceof Unit)) throw new Error('invalid_unit');
- this._unit = unit;
- this._direction = Direction.NORTH;
- this._headDirection = Direction.NORTH;
- this._posture = AvatarAction.POSTURE_STAND;
- this._gesture = null;
- this._expression = null;
- this._carryItem = null;
- this._isUsing = false;
- this._shadow = null;
- this._gestureTimeout = null;
- this._expressionTimeout = null;
- this._blinkInterval = null;
- this._useInterval = null;
- this._isReady = false;
- this._didCreateShadow = false;
- }
- public onStart(): void
- {
- this._unit.room.mapManager.collisionMap.layerMap.addChild(this);
- this.toggleReadyness(null);
- this.updateView();
- }
- public toggleReadyness(flag: boolean): void
- {
- if(flag === null) return this.toggleReadyness(this._unit.figure.isDownloaded);
- if(!flag) this.alpha = 0.80;
- else this.alpha = 1;
- this._isReady = flag;
- }
- public onUpdate(): void
- {
- this.setActions();
- if(!this.needsUpdate && !this.tween) return;
- super.onUpdate();
- const frameCount = Math.round(this.totalTimeRunning / SpriteContainer.FPS_TIME_MS);
- if(this.frameCount === frameCount) return;
- this.frameCount = frameCount;
- this.updateView();
- this.needsUpdate = false;
- }
- public onClick(event: MouseEvent): void
- {
- Nitro.networkManager.processOutgoing(new UnitLookComposer(this._unit.position));
- }
- public onDispose(): void
- {
- if(this._gestureTimeout) clearTimeout(this._gestureTimeout);
- if(this._expressionTimeout) clearTimeout(this._expressionTimeout);
- if(this._blinkInterval) clearInterval(this._blinkInterval);
- if(this._useInterval) clearInterval(this._useInterval);
- this.stopTweening();
- }
- private setActions(): void
- {
- if(!this._unit) return;
- let didSetPosture = false;
- if(this._unit.hasStatus(UnitStatusType.MOVE))
- {
- this.setPosture(AvatarAction.POSTURE_WALK);
- didSetPosture = true;
- }
- if(this._unit.hasStatus(UnitStatusType.SIT))
- {
- this.setPosture(AvatarAction.POSTURE_SIT);
- didSetPosture = true;
- }
- if(this._unit.hasStatus(UnitStatusType.LAY))
- {
- this.setPosture(AvatarAction.POSTURE_LAY);
- didSetPosture = true;
- }
- if(!didSetPosture) this.setPosture(AvatarAction.POSTURE_STAND);
- if(AvatarBuilder.ACTIVATES_ANIMATION.indexOf(this._expression) !== -1) this.needsUpdate = true;
- }
- public updateView(): void
- {
- this.destroyChildren();
- this.destroyTempSprites();
- if(!this._didCreateShadow) this.createShadow();
- if(this._shadow && !this._unit.hasStatus(UnitStatusType.SIT, UnitStatusType.LAY)) this.addChild(this._shadow);
- const x = this._unit.position.screenX;
- const y = this._unit.position.screenY - RoomConfiguration.TILE_HEIGHT - this._unit.position.screenZ;
- const parts = this._unit.figure.parts;
- if(!parts) return;
- const totalParts = parts.length;
- if(!totalParts) return;
- for(let i = 0; i < totalParts; i++)
- {
- const part = parts[i];
- if(!part) continue;
- if(this._unit.figure.partsHidden.indexOf(part.type) !== -1) continue;
- const generated = this.generateBodyPart(part);
- if(!generated) continue;
- if(part.setData.setType.type === AvatarBodyPart.HEAD) this.addTempSelectableForLayer(generated, x, y);
- this.addChild(generated);
- }
- if(this._carryItem)
- {
- const itemid = this._carryItem === 19 ? 5 : this._carryItem;
- const handItem = BaseAvatar.createHandItem(this._isUsing ? AvatarAction.DRINK : AvatarAction.CARRY, AvatarBodyPart.RIGHT_HAND_ITEM, this._direction, itemid);
- if(handItem) this.addChild(handItem);
- }
- }
- private destroyChildren(): void
- {
- const totalChildren = this.children.length;
- if(!totalChildren) return;
- for(let i = 0; i < totalChildren; i++)
- {
- const child = this.children[i];
- if(!child) continue;
- if(child === this._shadow) continue;
- child.destroy();
- }
- this.removeChildren();
- }
- private addTempSelectableForLayer(layer: PIXI.Sprite, x: number, y: number): void
- {
- if(!layer) return;
- const isScaling = layer.scale.x === -1;
- const selectable = this.getSelectable(layer.name, isScaling);
- if(!selectable) return;
- const body = BaseAvatar.getBaseFromPart('hh_human_body');
- if(!body) return;
- const asset = body.partData.assets[layer.name];
- if(!asset) return;
- const position = layer.position.clone();
- if(isScaling)
- {
- position.x = -layer.width + asset.x;
- position.x += 35;
- }
- position.x += x;
- position.y += y;
- const goalPosition = this._unit.room.mapManager.collisionMap.layerMap.toGlobal(position);
- this.tempSelectables.push({ selectable, x: goalPosition.x, y: goalPosition.y });
- }
- private generateBodyPart(part: IPartData): PIXI.Sprite
- {
- if(!part) return null;
- if(this._unit.figure.isPartHidden(part.type)) return null;
- const partType = part.type === AvatarBodyPart.HAIR_BIG ? AvatarBodyPart.HAIR : part.type;
- let library = Nitro.gameManager.avatarManager.findLibrary(part.id, partType);
- if(!library) return null;
- const basePart = BaseAvatar.getPart(library.id);
- if(!basePart) return null;
- const sprite = this.generateSpriteWithActions(basePart, part);
- if(!sprite) return null;
- return sprite;
- }
- private generateSpriteWithActions(basePart: BaseAvatarPart, part: IPartData): PIXI.Sprite
- {
- if(!basePart || !part) return null;
- let action: AvatarAction = AvatarAction.POSTURE_STAND;
- let direction: Direction = this._direction;
- if(AvatarBuilder.HEAD_PARTS.indexOf(part.type) !== -1) direction = this._headDirection;
- if(this._posture === AvatarAction.POSTURE_WALK && AvatarBuilder.IGNORES_WALK.indexOf(part.type) !== -1) action = AvatarAction.POSTURE_STAND;
- else if(this._posture === AvatarAction.POSTURE_SIT && AvatarBuilder.IGNORES_SIT.indexOf(part.type) !== -1) action = AvatarAction.POSTURE_STAND;
- else action = this._posture;
- if(action === AvatarAction.POSTURE_LAY) direction = direction === Direction.NORTH ? Direction.SOUTH : Direction.EAST;
- if(this._gesture && AvatarBuilder.GESTURE_PARTS.indexOf(part.type) !== -1) action = this._gesture;
- if(this._expression)
- {
- if(AvatarBuilder.LEFT_PARTS.indexOf(part.type) !== -1)
- {
- if(AvatarBuilder.EXPRESSIONS_LEFT.indexOf(this._expression) !== -1) action = this._expression;
- }
- if(AvatarBuilder.RIGHT_PARTS.indexOf(part.type) !== -1)
- {
- if(AvatarBuilder.EXPRESSIONS_RIGHT.indexOf(this._expression) !== -1) action = this._expression;
- }
- }
- if(this._carryItem)
- {
- const carryParts: AvatarBodyPart[] = [ AvatarBodyPart.RIGHT_HAND, AvatarBodyPart.RIGHT_SLEEVE, AvatarBodyPart.RIGHT_COAT_SLEEVE ];
- if(carryParts.indexOf(part.type) !== -1)
- {
- action = this._isUsing ? AvatarAction.DRINK : AvatarAction.CARRY;
- }
- }
- const sprite = this.generateSprite(basePart, part, action, direction);
- if(!sprite) return null;
- return sprite;
- }
- private generateSprite(basePart: BaseAvatarPart, part: IPartData, action: AvatarAction, direction: Direction): PIXI.Sprite
- {
- if(!basePart) return null;
- const frameIndex = Math.floor(this.frameCount % (4 * 4) / 4);
- const frameCount = AvatarBuilder.ACTIVATES_ANIMATION.indexOf(action) !== -1 ? frameIndex : 0;
- const sprite = basePart.getSpriteFrom(BaseAvatar.AVATAR_SIZE, action, part.type, direction, frameCount, part.id);
- if(!sprite) return;
- if(direction >= Direction.SOUTH && direction <= Direction.WEST && this._expression)
- {
- if(AvatarBuilder.LEFT_PARTS.indexOf(part.type) !== -1 || AvatarBuilder.RIGHT_PARTS.indexOf(part.type) !== -1) sprite.scale.x = -1;
- }
- if(part.colorable === 1)
- {
- const color = Nitro.gameManager.avatarManager.getPaletteColorFromIndex(part.setData.setType.paletteid, this._unit.figure.getColorIndexForSet(part.setData, part.colorindex));
- if(color) sprite.tint = parseInt(`0x${ color }`);
- }
- if(part.type === AvatarBodyPart.EYES) sprite.tint = 0xFFFFFF;
- return sprite;
- }
- public createShadow(): void
- {
- if(this._shadow) return;
- this.removeShadow();
- const body = BaseAvatar.getPart('hh_human_body');
- if(!body)
- {
- this._didCreateShadow = true;
- return;
- }
- const shadowLayer = body.getSpriteFrom(BaseAvatar.AVATAR_SIZE, AvatarAction.POSTURE_STAND, AvatarBodyPart.SHADOW, Direction.NORTH, 0);
- if(!shadowLayer)
- {
- this._didCreateShadow = true;
- return;
- }
- shadowLayer.x = 0;
- shadowLayer.y = 0;
- shadowLayer.position.y = RoomConfiguration.TILE_REAL_HEIGHT;
- shadowLayer.anchor.set(0.5);
- shadowLayer.alpha = 0.2;
- this._shadow = shadowLayer;
- this._didCreateShadow = true;
- }
- public removeShadow(): void
- {
- if(!this._shadow) return;
- if(this._shadow.parent) this._shadow.parent.removeChild(this._shadow);
- this._shadow.destroy();
- this._shadow = null;
- this._didCreateShadow = false;
- }
- private setPosture(action: AvatarAction): void
- {
- if(!action) return;
- if(this._posture === action) return;
- this._posture = action;
- this.needsUpdate = true;
- }
- public setDirection(direction: Direction): void
- {
- if(this._direction === direction) return;
- this._direction = direction;
- this.needsUpdate = true;
- }
- public setHeadDirection(direction: Direction): void
- {
- if(this._headDirection === direction) return;
- this._headDirection = direction;
- this.needsUpdate = true;
- }
- public gesture(gesture: AvatarAction, timeout: number): void
- {
- if(this._gesture === gesture) return;
- if(this._gestureTimeout) clearTimeout(this._gestureTimeout);
- this._gesture = gesture;
- this.needsUpdate = true;
- this._gestureTimeout = setTimeout(() =>
- {
- this._gesture = null;
- this.needsUpdate = true;
- }, timeout);
- }
- public expression(expression: AvatarAction, timeout: number): void
- {
- if(this._expression === expression) return;
- if(this._expressionTimeout) clearTimeout(this._expressionTimeout);
- this._expression = expression;
- this.needsUpdate = true;
- // this._expressionTimeout = setTimeout(() =>
- // {
- // this._expression = null;
- // this.needsUpdate = true;
- // }, timeout);
- }
- public carry(handItem: UnitHandItem): void
- {
- if(this._carryItem === handItem) return;
- this._carryItem = handItem;
- this.needsUpdate = true;
- this.startUseInterval();
- }
- public startUseInterval(): void
- {
- if(this._useInterval) clearInterval(this._useInterval);
- if(!this._carryItem) return;
- this._useInterval = setInterval(() => this.useItem(), 5000);
- }
- private useItem(): void
- {
- if(this._isUsing) return;
- if(!this._carryItem)
- {
- this._isUsing = false;
- this.needsUpdate = true;
- if(this._useInterval) clearInterval(this._useInterval);
- return;
- }
- this._isUsing = true;
- this.needsUpdate = true;
- setTimeout(() =>
- {
- if(!this._carryItem) return;
- this._isUsing = false;
- this.needsUpdate = true;
- }, 2000);
- }
- public get unit(): Unit
- {
- return this._unit;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement