using System.Collections.Generic; 
 | 
using UnityEngine; 
 | 
using System; 
 | 
using DG.Tweening; 
 | 
using Spine; 
 | 
  
 | 
  
 | 
public class SkillBase 
 | 
{ 
 | 
    protected H0604_tagUseSkillAttack tagUseSkillAttack; 
 | 
  
 | 
    protected SkillConfig skillConfig; 
 | 
  
 | 
    protected bool isFinished = false; 
 | 
  
 | 
    protected BattleField battleField = null; // 战场 
 | 
  
 | 
    protected RectTransform targetNode = null; // 目标节点 
 | 
  
 | 
    protected BattleObject caster = null; // 施法者 
 | 
  
 | 
    protected bool startCounting = false; 
 | 
  
 | 
    protected bool pauseState = false; 
 | 
  
 | 
    protected int curFrame = 0; 
 | 
  
 | 
    protected List<GameNetPackBasic> packList; 
 | 
  
 | 
    protected SkillBase otherSkill; 
 | 
  
 | 
    public SkillBase(BattleObject _caster, SkillConfig _skillCfg, H0604_tagUseSkillAttack vNetData, List<GameNetPackBasic> _packList, BattleField _battleField = null) 
 | 
    { 
 | 
        caster = _caster; 
 | 
        skillConfig = _skillCfg; 
 | 
        tagUseSkillAttack = vNetData; 
 | 
        battleField = _battleField; 
 | 
        packList = _packList; 
 | 
  
 | 
    }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
 | 
  
 | 
    public virtual void Run() 
 | 
    { 
 | 
        if (startCounting) 
 | 
        { 
 | 
            curFrame++; 
 | 
        } 
 | 
    } 
 | 
  
 | 
    protected virtual void OnActiveSkillFrame() 
 | 
    { 
 | 
  
 | 
    } 
 | 
  
 | 
    protected virtual void OnStartSkillFrame() 
 | 
    { 
 | 
  
 | 
    } 
 | 
  
 | 
    protected virtual void OnEndSkillFrame() 
 | 
    { 
 | 
         
 | 
    } 
 | 
  
 | 
    public void Pause() 
 | 
    { 
 | 
        pauseState = startCounting; 
 | 
        startCounting = false; 
 | 
    } 
 | 
  
 | 
    public void Resume() 
 | 
    { 
 | 
        startCounting = pauseState; 
 | 
    } 
 | 
  
 | 
    // 0·移动到距离目标n码,的距离释放(可配置,9999即原地释放,负数则是移动到人物背面,人物要转身) 
 | 
    // 1·移动到距离阵容位置n码的距离(如2号位,5号位)释放(即战场中央此类) 
 | 
    public virtual void Cast() 
 | 
    { 
 | 
        //    高亮所有本次技能相关的目标 
 | 
        HighLightAllTargets(); 
 | 
  
 | 
        //    距离配成负数要转身 TurnBack 
 | 
  
 | 
        switch (skillConfig.castMode) 
 | 
        { 
 | 
            case SkillCastMode.Self: 
 | 
                PlayCastAnimation(() => DoSkillLogic(OnSkillFinished)); 
 | 
                break; 
 | 
            case SkillCastMode.Enemy: 
 | 
                MoveToTarget(caster.GetEnemyCamp(), skillConfig.CastIndexNum, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); })))); 
 | 
                break; 
 | 
            case SkillCastMode.Target: 
 | 
                // 目标是敌方主目标 
 | 
                BattleObject mainTarget = battleField.battleObjMgr.GetBattleObject((int)tagUseSkillAttack.AttackID); 
 | 
                if (mainTarget == null) 
 | 
                { 
 | 
                    Debug.LogError("目标为空 mainTarget == null AttackID : " + tagUseSkillAttack.AttackID); 
 | 
                    OnSkillFinished(); 
 | 
                    return; 
 | 
                } 
 | 
                MoveToTarget(mainTarget.Camp, mainTarget.teamHero.positionNum, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); })))); 
 | 
                break; 
 | 
            case SkillCastMode.Allies: 
 | 
                MoveToTarget(caster.Camp, skillConfig.CastIndexNum, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); })))); 
 | 
                break; 
 | 
            // case SkillCastMode.DashCast: 
 | 
            //     DashToTarget(() => BackToOrigin(OnSkillFinished)); 
 | 
            //     break; 
 | 
            default: 
 | 
                Debug.LogError("暂时不支持其他的方式释放 有需求请联系策划"); 
 | 
                break; 
 | 
        } 
 | 
    } 
 | 
  
 | 
    //    冲刺的技能 动作 跟移动 是同时进行的 移动到目标的一瞬间就要进行技能逻辑 
 | 
    // protected void DashToTarget(Action _onComplete) 
 | 
    // { 
 | 
    //     TrackEntry entry = PlayCastAnimation(); 
 | 
    //     BattleObject mainTarget = battleField.battleObjMgr.GetBattleObject((int)tagUseSkillAttack.AttackID); 
 | 
    //     if (mainTarget == null) 
 | 
    //     { 
 | 
    //         Debug.LogError("目标为空 mainTarget == null AttackID : " + tagUseSkillAttack.AttackID); 
 | 
    //         _onComplete?.Invoke(); 
 | 
    //         return; 
 | 
    //     } 
 | 
  
 | 
    //     //    做一个微微的提前 
 | 
    //     MoveToTarget(mainTarget.Camp, mainTarget.teamHero.positionNum, entry.AnimationEnd - 0.05f, () => DoSkillLogic(_onComplete)); 
 | 
    // } 
 | 
  
 | 
    //    这里其实是技能后摇结束的地方 
 | 
    protected virtual void DoSkillLogic(Action _onComplete = null) 
 | 
    { 
 | 
         
 | 
    } 
 | 
  
 | 
    protected TrackEntry PlayCastAnimation(Action onComplete = null) 
 | 
    { 
 | 
        // 播放施法动作 
 | 
        return caster.motionBase.PlaySkillAnimation(skillConfig, onComplete, 
 | 
                OnStartSkillFrame,//攻击前摇结束 
 | 
                OnActiveSkillFrame);//攻击中摇结束 
 | 
    } 
 | 
  
 | 
    public void MoveToTarget(BattleCamp camp, int index, float duration = 0.2f, Action _onComplete = null) 
 | 
    { 
 | 
        // GetTargetNode(); 
 | 
        targetNode = battleField.GetTeamNode(camp, index); 
 | 
  
 | 
        Vector2 offset = new Vector2(skillConfig.CastDistance, 0); 
 | 
        RectTransform selfRect = caster.heroGo.transform as RectTransform; 
 | 
        RectTransform targetRect = targetNode; 
 | 
  
 | 
        var tweener = BattleUtility.MoveToTarget(selfRect, targetRect, offset, duration, _onComplete); 
 | 
        battleField.battleTweenMgr.OnPlayTween(tweener); 
 | 
    } 
 | 
  
 | 
    public void TurnBack(Action _onComplete) 
 | 
    { 
 | 
        if (skillConfig.CastDistance < 0) 
 | 
        { 
 | 
            //    转身 
 | 
            caster.heroGo.transform.localScale = new Vector3(-1, 1, 1); 
 | 
        } 
 | 
        _onComplete?.Invoke(); 
 | 
    } 
 | 
  
 | 
    public void BackToOrigin(Action _onComplete = null) 
 | 
    { 
 | 
        RectTransform selfRect = caster.heroGo.transform as RectTransform; 
 | 
        Vector2 targetAnchoredPos = Vector2.zero; 
 | 
        var tween = selfRect.DOAnchorPos(targetAnchoredPos, 0.2f) 
 | 
            .SetEase(Ease.Linear) 
 | 
            .OnComplete(() => 
 | 
            { 
 | 
                //    转成正确方向 
 | 
                caster.heroGo.transform.localScale = Vector3.one; 
 | 
                _onComplete?.Invoke(); 
 | 
            }); 
 | 
  
 | 
        battleField.battleTweenMgr.OnPlayTween(tween); 
 | 
    } 
 | 
  
 | 
    protected void HighLightAllTargets() 
 | 
    { 
 | 
        // 高亮所有目标 
 | 
        HashSet<BattleObject> highlightList = new HashSet<BattleObject>(battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack)); 
 | 
        highlightList.Add(caster); 
 | 
  
 | 
         
 | 
  
 | 
        //    把这些BO全高亮 或者说把除了这些的都放在遮罩后面 
 | 
        //    YYL TODO 
 | 
    } 
 | 
  
 | 
    //    命中目标后的回调 正常是以各技能的方式来处理的 
 | 
    protected virtual void OnHitTargets(int _hitIndex, List<H0604_tagUseSkillAttack.tagSkillHurtObj> hitList) 
 | 
    { 
 | 
        for (int i = 0; i < hitList.Count; i++) 
 | 
        { 
 | 
            H0604_tagUseSkillAttack.tagSkillHurtObj hurt = hitList[i]; 
 | 
  
 | 
            BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID); 
 | 
            if (target == null) 
 | 
            { 
 | 
                Debug.LogError("目标为空 target == null ObjId : " + hurt.ObjID); 
 | 
                continue; 
 | 
            } 
 | 
  
 | 
            // 伤害结算 
 | 
            int[] damageDivide = skillConfig.DamageDivide[_hitIndex]; 
 | 
  
 | 
            List<long> damageList = new List<long>(); 
 | 
  
 | 
            long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx); 
 | 
  
 | 
            for (int j = 0; j < damageDivide.Length; j++) 
 | 
            { 
 | 
                long damage = totalDamage * damageDivide[j] / 10000; 
 | 
                damageList.Add(damage); 
 | 
            } 
 | 
  
 | 
            OnHitEachTarget(target, damageList, ref hurt); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    protected virtual void OnHitEachTarget(BattleObject target, List<long> damageList, ref H0604_tagUseSkillAttack.tagSkillHurtObj hurt) 
 | 
    { 
 | 
        target.Hurt(damageList, hurt.AttackType); 
 | 
  
 | 
                //    击中目标的时候,不管近战远程 都确认一下是否有爆炸特效 然后播放 
 | 
        if (skillConfig.ExplosionEffectId > 0) 
 | 
        { 
 | 
            // 播放爆炸特效 
 | 
            target.battleField.battleEffectMgr.PlayEffect( 
 | 
                target.ObjID, 
 | 
                skillConfig.ExplosionEffectId, 
 | 
                target.heroGo.transform 
 | 
            ); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public virtual bool IsFinished() 
 | 
    { 
 | 
        return isFinished; 
 | 
    } 
 | 
  
 | 
    public virtual void ForceFinished() 
 | 
    { 
 | 
        isFinished = true; 
 | 
    } 
 | 
  
 | 
    public void OnSkillFinished() 
 | 
    { 
 | 
        isFinished = true; 
 | 
    } 
 | 
} 
 |