﻿// @Author 空伊伊
// @论坛主页 https://forum.ark.online/home.php?mod=space&uid=113&do=thread&view=me&from=space


@Component
export default class CustomAnim extends Script {
    @Property({ displayName: "待机动画Guid" })
    idleAnimGuid = "281721";

    @Property({ displayName: "跳跃动画Guid" })
    jumpAnimGuid = "280881";

    @Property({ displayName: "下落动画Guid" })
    fallAnimGuid = "281008";

    @Property({ displayName: "落地动画Guid" })
    landedAnimGuid = "285403";

    @Property({ displayName: "行走动画Guid" })
    walkAnimGuid = "285026";

    @Property({ displayName: "奔跑动画Guid" })
    runAnimGuid = "269052";

    @Property({ displayName: "奔跑所需速度" })
    runSpeed: number = 400;

    /** 角色 */
    char: Character;
    /** 动画 */
    idleAnim: Animation;
    jumpAnim: Animation;
    fallAnim: Animation;
    landedAnim: Animation
    walkAnim: Animation;
    runAnim: Animation;


    protected async onStart(): Promise<void> {
        if (SystemUtil.isClient()) {
            await this.loadAssets();

            // 如果想实现多端同步，那么就给每位进入的角色对象，都分别添加CustomAnim脚本，然后loadChar就填入对应的角色对象
            this.loadChar((await Player.asyncGetLocalPlayer()).character)
        }
    }

    public loadChar(char: Character) {
        this.char = char;
        this.loadAnimations();
        this.useUpdate = true;
    }

    private async loadAssets(): Promise<void> {
        const assetGuids = [
            this.idleAnimGuid,
            this.jumpAnimGuid,
            this.fallAnimGuid,
            this.landedAnimGuid,
            this.walkAnimGuid,
            this.runAnimGuid,
        ];
        await Promise.all(assetGuids.map(AssetUtil.asyncDownloadAsset));
    }

    private loadAnimations(): void {
        this.idleAnim = this.char.loadAnimation(this.idleAnimGuid);
        this.jumpAnim = this.char.loadAnimation(this.jumpAnimGuid);
        this.fallAnim = this.char.loadAnimation(this.fallAnimGuid);
        this.landedAnim = this.char.loadAnimation(this.landedAnimGuid);
        this.walkAnim = this.char.loadAnimation(this.walkAnimGuid);
        this.runAnim = this.char.loadAnimation(this.runAnimGuid);

        this.idleAnim.loop = this.walkAnim.loop = this.runAnim.loop = this.fallAnim.loop = 0;

        // 状态变更监听
        this.char.onStateChanged.add(async (prevState: CharacterStateType, curstate: CharacterStateType) => {
            if (prevState == CharacterStateType.Running) {
                if (curstate == CharacterStateType.Jumping) {
                    //console.log("Jump!")
                    this.jumpAnim.play()
                }
            } else if (prevState == CharacterStateType.Jumping) {
                if (curstate == CharacterStateType.Freefall) {
                    //console.log("Fall!")
                    this.fallAnim.play()
                }
            } else if (prevState == CharacterStateType.Freefall) {
                if (curstate == CharacterStateType.Landed) {
                    this.landedAnim.play()
                }
            }
        })
    }

    protected onUpdate(dt: number): void {
        if (this.char.getCurrentState() !== CharacterStateType.Running) {
            this.idleAnim.stop()
            return
        }
        this.updateMovementState();
    }



    private updateMovementState(): void {
        const velocityLength = this.char.velocity.length;
        if (velocityLength > 0) {
            if (velocityLength > this.runSpeed) {
                this.playAnimation(this.runAnim);
            } else {
                this.playAnimation(this.walkAnim);
            }
        } else {
            this.resetMovementAnims();
            // 保证落地动画播放完整
            if (!this.landedAnim.isPlaying) {
                this.playAnimation(this.idleAnim);
            }
        }
    }

    private resetMovementAnims(): void {
        this.runAnim.stop();
        this.walkAnim.stop();
    }

    private playAnimation(anim: Animation): void {
        if (!anim.isPlaying) {
            anim.play();
        }
    }
}