nitro-renderer/src/nitro/avatar/animation/Animation.ts

313 lines
8.5 KiB
TypeScript

import { IAssetAnimation, IAssetAnimationFrame } from '../../../core/asset/interfaces';
import { AvatarStructure } from '../AvatarStructure';
import { AddDataContainer } from './AddDataContainer';
import { AvatarAnimationLayerData } from './AvatarAnimationLayerData';
import { AvatarDataContainer } from './AvatarDataContainer';
import { DirectionDataContainer } from './DirectionDataContainer';
import { IAnimation } from './IAnimation';
import { SpriteDataContainer } from './SpriteDataContainer';
export class Animation implements IAnimation
{
private static EMPTY_ARRAY: any[] = [];
private _id: string;
private _description: string;
private _frames: AvatarAnimationLayerData[][];
private _spriteData: SpriteDataContainer[];
private _avatarData: AvatarDataContainer;
private _directionData: DirectionDataContainer;
private _removeData: string[];
private _addData: AddDataContainer[];
private _overriddenActions: Map<string, string>;
private _overrideFrames: Map<string, AvatarAnimationLayerData[][]>;
private _resetOnToggle: boolean;
constructor(k: AvatarStructure, _arg_2: IAssetAnimation)
{
this._id = _arg_2.name;
this._description = this._id;
this._frames = [];
this._spriteData = null;
this._avatarData = null;
this._directionData = null;
this._removeData = null;
this._addData = null;
this._overriddenActions = null;
this._overrideFrames = null;
this._resetOnToggle = (_arg_2.resetOnToggle || false);
if(_arg_2.sprites && _arg_2.sprites.length)
{
this._spriteData = [];
for(const sprite of _arg_2.sprites) this._spriteData.push(new SpriteDataContainer(this, sprite));
}
if(_arg_2.avatars && _arg_2.avatars.length) this._avatarData = new AvatarDataContainer(_arg_2.avatars[0]);
if(_arg_2.directions && _arg_2.directions.length) this._directionData = new DirectionDataContainer(_arg_2.directions[0]);
if(_arg_2.removes && _arg_2.removes.length)
{
this._removeData = [];
for(const remove of _arg_2.removes) this._removeData.push(remove.id);
}
if(_arg_2.adds && _arg_2.adds.length)
{
this._addData = [];
for(const add of _arg_2.adds) this._addData.push(new AddDataContainer(add));
}
if(_arg_2.overrides && _arg_2.overrides.length)
{
this._overrideFrames = new Map();
this._overriddenActions = new Map();
for(const override of _arg_2.overrides)
{
const name = override.name;
const value = override.override;
this._overriddenActions.set(value, name);
const frames: AvatarAnimationLayerData[][] = [];
this.parseFrames(frames, override.frames, k);
this._overrideFrames.set(name, frames);
}
}
this.parseFrames(this._frames, _arg_2.frames, k);
}
private parseFrames(frames: AvatarAnimationLayerData[][], _arg_2: IAssetAnimationFrame[], _arg_3: AvatarStructure): void
{
if(!_arg_2 || !_arg_2.length) return;
for(const frame of _arg_2)
{
let repeats = 1;
if(frame.repeats && (frame.repeats > 1)) repeats = frame.repeats;
let index = 0;
while(index < repeats)
{
const layers: AvatarAnimationLayerData[] = [];
if(frame.bodyparts && frame.bodyparts.length)
{
for(const bodyPart of frame.bodyparts)
{
const definition = _arg_3.getActionDefinition(bodyPart.action);
const layer = new AvatarAnimationLayerData(bodyPart, AvatarAnimationLayerData.BODYPART, definition);
layers.push(layer);
}
}
if(frame.fxs && frame.fxs.length)
{
for(const fx of frame.fxs)
{
const definition = _arg_3.getActionDefinition(fx.action);
const layer = new AvatarAnimationLayerData(fx, AvatarAnimationLayerData.FX, definition);
layers.push(layer);
}
}
frames.push(layers);
index++;
}
}
}
public frameCount(k: string = null): number
{
if(!k) return this._frames.length;
if(this._overrideFrames)
{
const _local_2 = this._overrideFrames.get(k);
if(_local_2) return _local_2.length;
}
return 0;
}
public hasOverriddenActions(): boolean
{
if(!this._overriddenActions) return false;
return (this._overriddenActions.size > 0);
}
public overriddenActionNames(): string[]
{
if(!this._overriddenActions) return null;
const keys: string[] = [];
for(const key of this._overriddenActions.keys()) keys.push(key);
return keys;
}
public overridingAction(k: string): string
{
if(!this._overriddenActions) return null;
return this._overriddenActions.get(k);
}
private getFrame(frameCount: number, _arg_2: string = null): AvatarAnimationLayerData[]
{
if(frameCount < 0) frameCount = 0;
let layers: AvatarAnimationLayerData[] = [];
if(!_arg_2)
{
if(this._frames.length > 0)
{
layers = this._frames[(frameCount % this._frames.length)];
}
}
else
{
const overrideLayers = this._overrideFrames.get(_arg_2);
if(overrideLayers && (overrideLayers.length > 0))
{
layers = overrideLayers[(frameCount % overrideLayers.length)];
}
}
return layers;
}
public getAnimatedBodyPartIds(k: number, _arg_2: string=null): string[]
{
const _local_3: string[] = [];
for(const layer of this.getFrame(k, _arg_2))
{
if(layer.type === AvatarAnimationLayerData.BODYPART)
{
_local_3.push(layer.id);
}
else if(layer.type === AvatarAnimationLayerData.FX)
{
if(this._addData && this._addData.length)
{
for(const _local_5 of this._addData)
{
if(_local_5.id === layer.id) _local_3.push(_local_5.align);
}
}
}
}
return _local_3;
}
public getLayerData(frameCount: number, spriteId: string, _arg_3: string = null): AvatarAnimationLayerData
{
for(const layer of this.getFrame(frameCount, _arg_3))
{
if(layer.id === spriteId) return layer;
if(layer.type === AvatarAnimationLayerData.FX)
{
if(this._addData && this._addData.length)
{
for(const addData of this._addData)
{
if(((addData.align === spriteId) && (addData.id === layer.id))) return layer;
}
}
}
}
return null;
}
public hasAvatarData(): boolean
{
return this._avatarData !== null;
}
public hasDirectionData(): boolean
{
return this._directionData !== null;
}
public hasAddData(): boolean
{
return this._addData !== null;
}
public getAddData(k: string): AddDataContainer
{
if(this._addData)
{
for(const _local_2 of this._addData)
{
if(_local_2.id === k) return _local_2;
}
}
return null;
}
public get id(): string
{
return this._id;
}
public get spriteData(): SpriteDataContainer[]
{
return this._spriteData || Animation.EMPTY_ARRAY;
}
public get avatarData(): AvatarDataContainer
{
return this._avatarData;
}
public get directionData(): DirectionDataContainer
{
return this._directionData;
}
public get removeData(): string[]
{
return this._removeData || Animation.EMPTY_ARRAY;
}
public get addData(): AddDataContainer[]
{
return this._addData || Animation.EMPTY_ARRAY;
}
public toString(): string
{
return this._description;
}
public get resetOnToggle(): boolean
{
return this._resetOnToggle;
}
}