/*
文件名:Animation.nut
路径:User/Asset/Character/Animation.nut
创建日期:2024-12-12	16:43
文件用途:
*/
class Character_Animation extends Actor {

    //角色对象
    Parent = null;
    //当前动画组
    CurrentAni = null;

    //等待Ani
    WaitingAni = null;
    //移动Ani
    MoveAni = null;
    //蹲下Ani
    SitAni = null;
    //受伤Ani
    DamageAni1 = null;
    DamageAni2 = null;
    //倒地Ani
    DownAni = null;
    //被击后退Ani
    OverturnAni = null;
    //跳跃Ani
    JumoAni = null;
    //跳跃攻击Ani
    JumpAttackAni = null;
    //站立Ani
    RestAni = null;
    //引导Ani
    ThrowAni1_1 = null;
    ThrowAni1_2 = null;
    ThrowAni2_1 = null;
    ThrowAni2_2 = null;
    ThrowAni3_1 = null;
    ThrowAni3_2 = null;
    ThrowAni4_1 = null;
    ThrowAni4_2 = null;
    //奔跑Ani
    DashAni = null;
    //奔跑攻击Ani
    DashAttackAni = null;
    //拾取Ani
    GetItemAni = null;
    //释放BUFFAni
    BuffAni = null;
    //普通攻击Ani
    AttackAni = null;

    constructor() {
        base.constructor();

    }

    //同步单部位动画
    function SyncAnimationBySlot(Type, AniObj, Src) {

        this[AniObj][Type] <- [];

        //如果有时装就初始化Ani
        //除了皮肤 在没有的情况下初始化0
        if (Type == "skin") {
            local variation = [0, 0];
            //如果存在皮肤就读取variation
            if (Parent[Type] != null) {
                local AvaInfo = Parent[Type];
                local JobInfo = AvaInfo["Animation_Job"]["Ani_" + Parent.Info["job"]];
                variation = JobInfo["variation"];
            }
            local BufInfo = sq_DeepCopy(ScriptData.GetAni(Src));
            local Ao = {
                ImgVariation = variation,
                ImgFormat = function(ImgPath) {
                    if (ImgVariation[0] > 0) {
                        local Pos = ImgPath.find("%04d");
                        ImgPath = ImgPath.slice(0, Pos) + "%02d%02d" + ImgPath.slice(Pos + 4);
                        return format(ImgPath, ImgVariation[0], ImgVariation[1]);
                    } else {
                        return format(ImgPath, ImgVariation[1]);
                    }
                }
            }
            local SkinAni = Animation(BufInfo, Ao);
            //如果是皮肤Ani 绑定状态机 确保唯一性
            SkinAni.BindenvStateMachine(Parent.StateMachine);
            //将Ani类型设置为皮肤
            SkinAni.Type = "skin";
            //加入组
            this[AniObj][Type].append(SkinAni);
        } else {
            //先判断类型
            if (Parent[Type] != null) {
                local AvaInfo = Parent[Type];
                if (AvaInfo) {
                    local JobInfo = AvaInfo["Animation_Job"]["Ani_" + Parent.Info["job"]];
                    foreach(_index, value in JobInfo["layer_variation"]) {
                        local BufInfo = sq_DeepCopy(ScriptData.GetAni(AvaInfo["DirPath"] + value["Path"] + Src.slice(Src.lastfind("/"))));
                        local Ao = {
                            ImgVariation = JobInfo["variation"],
                            ImgFormat = function(ImgPath) {
                                return format(ImgPath, ImgVariation[0], ImgVariation[1]);
                            }
                        }
                        local AniBuf = Animation(BufInfo, Ao);
                        //设置Ani类型
                        AniBuf.Type = Type;
                        AniBuf.SetZOrder(value["Zorder"]);
                        this[AniObj][Type].append(AniBuf);
                    }
                }
            }
        }

        return this[AniObj][Type];
    }

    //读取并设置Ani
    function ReadAndSetAni(AniObj, Src, SlotType) {
        //从父对象 也就是角色对象取得Info
        local Info = Parent.Info;
        //如果有这个标签Ani则初始化 获取ani路径
        if (Info.rawin(Src)) Src = Info[Src];
        else return;

        //如果不存在则构造
        if (this[AniObj] == null) this[AniObj] = {};

        //如果没有传递装备类型就初始化所有
        if (!SlotType) {
            foreach(Type in getconsttable().AvatarType) {
                SyncAnimationBySlot(Type, AniObj, Src);
            }
        }
        //否则只初始化这一件装备的
        else {
            //记录当前皮肤Ani的时间 确保唯一性
            local AniTime = 0;
            if (this.CurrentAni) AniTime = this.CurrentAni["skin"][0].CurrentIndexT;
            //记录当前皮肤Ani的帧 确保唯一性
            local AniFrameIndex = 0;
            if (this.CurrentAni) AniFrameIndex = this.CurrentAni["skin"][0].CurrentFrameIndex;
            //如果当前播放Ani是 构造的Ani 则移除 并清空
            if (this.CurrentAni == this[AniObj]) {
                foreach(AniBuf in this.CurrentAni[SlotType]) {
                    AniBuf.RemoveSelf();
                }
            }
            SyncAnimationBySlot(SlotType, AniObj, Src);
            //如果当前播放Ani是 构造的Ani
            if (this.CurrentAni == this[AniObj]) {
                //添加Ani 并设置为当前皮肤Ani的时间
                foreach(AniBuf in this.CurrentAni[SlotType]) {
                    //一定要先添加 否则会导致动画时间混乱因为被添加时会刷新到0帧
                    Addchild(AniBuf);
                    AniBuf.CurrentIndexT = AniTime;
                    AniBuf.FlushFrame(AniFrameIndex);
                }
            }
        }
    }

    function ReadAndSetAttackAni() {
        local AttackAniArrSrc = Info["attack_motion"];
        AttackAni = array(AttackAniArrSrc.len());
        foreach(_Index, Path in AttackAniArrSrc) {
            local Src = Path;
            AttackAni[_Index] = [];
            foreach(Type in getconsttable().AvatarType) {
                //如果有时装就初始化Ani
                //除了皮肤 在没有的情况下初始化0
                if (Type == "skin") {
                    local SkinAni;
                    if (this[Type] == null) {
                        local BufInfo = sq_DeepCopy(ScriptData.GetAni(Src));
                        local Ao = {
                            ImgVariation = [0, 0],
                            ImgFormat = function(ImgPath) {
                                if (ImgVariation[0] > 0) {
                                    local Pos = ImgPath.find("%04d");
                                    ImgPath = ImgPath.slice(0, Pos) + "%02d%02d" + ImgPath.slice(Pos + 4);
                                    return format(ImgPath, ImgVariation[0], ImgVariation[1]);
                                } else {
                                    return format(ImgPath, ImgVariation[1]);
                                }
                            }
                        }
                        SkinAni = Animation(BufInfo, Ao);
                    } else {
                        local AvaInfo = AssetManager.GetEquipment(this[Type]);
                        local JobInfo = AvaInfo["Ani"]["Ani_" + Info["job"]];
                        local BufInfo = sq_DeepCopy(ScriptData.GetAni(Src));
                        local Ao = {
                            ImgVariation = JobInfo["variation"],
                            ImgFormat = function(ImgPath) {
                                return format(ImgPath, ImgVariation[0], ImgVariation[1]);
                            }
                        }
                        SkinAni = Animation(BufInfo, Ao);
                    }
                    //如果是皮肤Ani 绑定状态机 确保唯一性
                    SkinAni.BindenvStateMachine(StateMachine);
                    //将Ani类型设置为皮肤
                    SkinAni.Type = "skin";
                    //加入组
                    AttackAni[_Index].append(SkinAni);
                } else {
                    if (this[Type] != null) {

                        local AvaInfo = AssetManager.GetEquipment(this[Type]);
                        local JobInfo = AvaInfo["Ani"]["Ani_" + Info["job"]];
                        foreach(_index, value in JobInfo["layer_variation"]) {
                            local BufInfo = sq_DeepCopy(ScriptData.GetAni(AvaInfo["DirPath"] + value["Path"] + Src.slice(Src.lastfind("/"))));
                            local Ao = {
                                ImgVariation = JobInfo["variation"],
                                ImgFormat = function(ImgPath) {
                                    return format(ImgPath, ImgVariation[0], ImgVariation[1]);
                                }
                            }
                            local AniBuf = Animation(BufInfo, Ao);
                            //设置Ani类型
                            AniBuf.Type = Type;
                            AniBuf.SetZOrder(value["Zorder"]);
                            AttackAni[_Index].append(AniBuf);
                        }
                    }
                }
            }
        }
    }

    //初始化
    function Init(...) {
        local SlotType = false;
        if (vargv.len() > 0) SlotType = vargv[0];
        //读取并设置 等待Ani
        ReadAndSetAni("WaitingAni", "waiting motion", SlotType);
        //读取并设置 移动Ani
        ReadAndSetAni("MoveAni", "move motion", SlotType);
        //读取并设置 蹲下Ani
        ReadAndSetAni("SitAni", "sit motion", SlotType);
        //读取并设置 受伤Ani
        ReadAndSetAni("DamageAni1", "damage motion 1", SlotType);
        //读取并设置 受伤Ani
        ReadAndSetAni("DamageAni2", "damage motion 2", SlotType);
        //读取并设置 倒地Ani
        ReadAndSetAni("DownAni", "down motion", SlotType);
        //读取并设置 被击后退Ani
        ReadAndSetAni("OverturnAni", "overturn motion", SlotType);
        //读取并设置 跳跃Ani
        ReadAndSetAni("JumoAni", "jump motion", SlotType);
        //读取并设置 跳跃攻击Ani
        ReadAndSetAni("JumpAttackAni", "jumpattack motion", SlotType);
        //读取并设置 站立Ani
        ReadAndSetAni("RestAni", "rest motion", SlotType);
        //读取并设置 引导Ani
        ReadAndSetAni("ThrowAni1_1", "throw motion 1-1", SlotType);
        ReadAndSetAni("ThrowAni1_2", "throw motion 1-2", SlotType);
        ReadAndSetAni("ThrowAni2_1", "throw motion 2-1", SlotType);
        ReadAndSetAni("ThrowAni2_2", "throw motion 2-2", SlotType);
        ReadAndSetAni("ThrowAni3_1", "throw motion 3-1", SlotType);
        ReadAndSetAni("ThrowAni3_2", "throw motion 3-2", SlotType);
        ReadAndSetAni("ThrowAni4_1", "throw motion 4-1", SlotType);
        ReadAndSetAni("ThrowAni4_2", "throw motion 4-2", SlotType);
        //读取并设置 奔跑Ani
        ReadAndSetAni("DashAni", "dash motion", SlotType);
        //读取并设置 奔跑攻击Ani
        ReadAndSetAni("DashAttackAni", "dashattack motion", SlotType);
        //读取并设置 拾取Ani
        ReadAndSetAni("GetItemAni", "getitem motion", SlotType);
        //读取并设置 释放BUFFAni
        ReadAndSetAni("BuffAni", "buff motion", SlotType);

        //读取并设置 AttackAni
        // ReadAndSetAttackAni();
    }


    //设置Ani
    function SetAnimation(Ani) {
        //因为是Ani组所以要foreach调用
        //如果已经有Ani了
        if (CurrentAni) {
            //动作Ani组
            foreach(AniGroup in CurrentAni) {
                //槽类型动画
                foreach(AniObj in AniGroup) {
                    Removechild(AniObj);
                }
            }
        }
        if (type(Ani) == "integer") {
            //TODO 进阶ANI
        } else {
            CurrentAni = this[Ani];
        }
        //重置Ani 并添加子对象
        foreach(AniGroup in CurrentAni) {
            foreach(AniObj in AniGroup) {
                AniObj.Reset();
                Addchild(AniObj);
            }
        }
    }
}