yyl
2 天以前 d1d7db670b09a507cb73f71f99d2ca22c96307a5
Main/System/Battle/Skill/SkillBase.cs
@@ -1,10 +1,9 @@
using System.Collections.Generic;
using UnityEngine;
using System;
using DG.Tweening;
using Spine;
using System.Linq;
using PlasticGui.WorkspaceWindow.BranchExplorer;
using System;
public class SkillBase
@@ -15,7 +14,7 @@
   protected HB427_tagSCUseSkill tagUseSkillAttack;
   protected SkillConfig skillConfig;
   public SkillConfig skillConfig;
   protected bool isFinished = false;
@@ -25,12 +24,6 @@
   protected BattleObject caster = null; // 施法者
   protected bool startCounting = false;
   protected bool pauseState = false;
   protected int curFrame = 0;
   protected List<GameNetPackBasic> packList;
   protected SkillRecordAction otherSkillAction;
@@ -39,26 +32,42 @@
   protected List<HB405_tagMCAddExp> expPackList = new List<HB405_tagMCAddExp>();
   public SkillBase(BattleObject _caster, SkillConfig _skillCfg, HB427_tagSCUseSkill vNetData, List<GameNetPackBasic> _packList, BattleField _battleField = null)
   protected bool moveFinished = false;
    public int fromSkillId;
   public bool isPlay = false;
    public SkillBase(BattleObject _caster, SkillConfig _skillCfg, HB427_tagSCUseSkill vNetData, List<GameNetPackBasic> _packList, BattleField _battleField = null)
   {
      caster = _caster;
      if (null == caster)
      {
         throw new Exception("SkillBase caster is null ");
      }
      skillConfig = _skillCfg;
      tagUseSkillAttack = vNetData;
      battleField = _battleField;
      packList = _packList;
      // Debug.LogError("start a skill id " + skillConfig.SkillID + " caster " + caster.teamHero.heroId + " pos " + caster.teamHero.positionNum + " camp " + caster.Camp);
   }
   public virtual void Run()
   {
      if (startCounting)
      {
         curFrame++;
      }
      if (null != skillEffect)
      {
         skillEffect.Run();
         if (skillEffect.IsFinished())
         {
            skillEffect = null;
            OnSkillFinished();
         }
         else
         {
            skillEffect.Run();
         }
         return;
      }
      if (otherSkillAction != null)
@@ -70,39 +79,32 @@
         }
         else
         {
            otherSkillAction.Run();
            if (moveFinished)
            {
               otherSkillAction.Run();
            }
         }
         return;
      }
   }
   public void Pause()
   {
      pauseState = startCounting;
      startCounting = false;
   }
   public void Resume()
   {
      startCounting = pauseState;
   }
   // 0·移动到距离目标n码,的距离释放(可配置,9999即原地释放,负数则是移动到人物背面,人物要转身)
   // 1·移动到距离阵容位置n码的距离(如2号位,5号位)释放(即战场中央此类)
   public virtual void Cast()
   {
      BattleDebug.LogError(GetType().Name + " Skill Cast Start");
      // Debug.LogError("Cast skill " + skillConfig.SkillID + " cast position " + skillConfig.CastPosition + " cast mode " + skillConfig.castMode);
      string guid = battleField.guid;
      TeamHero teamHero = caster.teamHero;
      EventBroadcast.Instance.Broadcast<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, guid, skillConfig, teamHero);
      //   高亮所有本次技能相关的目标
      HighLightAllTargets();
      //   距离配成负数要转身 TurnBack
      BattleDebug.LogError(GetType().Name + " Skill CastMode : " + skillConfig.castMode);
      switch (skillConfig.castMode)
      {
         case SkillCastMode.Self:
            CastImpl();
            CastImpl(OnAttackFinish);
            break;
         case SkillCastMode.Enemy:
            CastToEnemy();
@@ -113,33 +115,59 @@
         case SkillCastMode.Allies:
            CastToAllies();
            break;
         // case SkillCastMode.DashCast:
         //    DashToTarget(() => BackToOrigin(OnSkillFinished));
         //    break;
         case SkillCastMode.DashCast:
            DashCast(OnAttackFinish);
            break;
         default:
            BattleDebug.LogError("暂时不支持其他的方式释放 有需求请联系策划 技能id:" + skillConfig.SkillID + " cast position " + skillConfig.CastPosition);
            OnSkillFinished();
            Debug.LogError("强制结束技能 暂时不支持其他的方式释放 有需求请联系策划 技能id:" + skillConfig.SkillID + " cast position " + skillConfig.CastPosition);
            ForceFinished();
            break;
      }
   }
   protected void MoveToTarget(RectTransform target, Vector2 offset, float duration, Action onComplete = null)
   //   冲撞攻击
   protected void DashCast(Action _onComplete)
   {
      BattleDebug.LogError("Move to target , target is " + target.name);
      Debug.LogError("DashCast 还没实现");
      ForceFinished();
      //   YYL TODO
      // var entry = caster.motionBase.PlayAnimation(skillConfig.GetMotionName(), false);
      // float animationTime = entry.AnimationTime;
      // int mainTargetPosNum = BattleUtility.GetMainTargetPositionNum(caster, tagUseSkillAttack.HurtList.ToList(), skillConfig);
      // BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
      // RectTransform targetTrans = battleField.GetTeamNode(battleCamp, mainTargetPosNum);
      // var tweener = BattleUtility.MoveToTarget(caster.heroRectTrans, targetTrans, new Vector2(skillConfig.CastDistance, 0), animationTime * 0.9f, () =>
      // {
      //    caster.motionBase.PlayAnimation(MotionName.idle, true);
      //    _onComplete?.Invoke();
      // });
      // battleField.battleTweenMgr.OnPlayTween(tweener);
   }
   protected void MoveToTarget(RectTransform target, Vector2 offset, Action _onComplete = null, float speed = 500f)
   {
      //   原地释放
      if (skillConfig.CastDistance >= 9999)
      {
         onComplete?.Invoke();
         _onComplete?.Invoke();
         return;
      }
      caster.motionBase.PlayAnimation(MotionName.run, true);
      var tweener = BattleUtility.MoveToTarget(caster.heroRectTrans, target, offset, duration, () =>
      var tweener = BattleUtility.MoveToTarget(caster.heroRectTrans, target, offset, () =>
      {
         caster.motionBase.PlayAnimation(MotionName.idle, true);
         onComplete?.Invoke();
      });
         _onComplete?.Invoke();
      }, speed);
      battleField.battleTweenMgr.OnPlayTween(tweener);
      // Debug.LogError("move to tarrget " + target.name + " offset " + offset + " speed " + speed + " time " + tweener.Duration());
   }
   protected void TurnBack(Action _onComplete, float forward)
@@ -159,7 +187,7 @@
      RectTransform target = battleField.GetTeamNode(caster.GetEnemyCamp(), skillConfig);
      MoveToTarget(target, new Vector2(skillConfig.CastDistance, 0), moveTime, () =>
      MoveToTarget(target, new Vector2(skillConfig.CastDistance, 0), () =>
      {
         //   到位置转身(不一定非要转身 但是流程要写)
         TurnBack(() =>
@@ -171,12 +199,8 @@
                  () =>
                  {
                     //   回到原来的位置
                     MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, moveTime, () =>
                     {
                        TurnBack(null, 1f);
                        caster.motionBase.PlayAnimation(MotionName.idle, true);
                        OnAllAttackMoveFinished();
                     });
                     MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero,
                        OnAttackFinish, 750F);
                  }
               , -1f);
            });
@@ -191,22 +215,18 @@
      // 目标是敌方主目标
      if (tagUseSkillAttack.HurtCount <= 0)
      {
         BattleDebug.LogError("技能攻击包没有目标 HurtCount <= 0");
         Debug.LogError("技能攻击包没有目标 HurtCount <= 0");
         OnSkillFinished();
         return;
      }
      var mainHurt = tagUseSkillAttack.HurtList[0];
      int mainTargetPosNum = BattleUtility.GetMainTargetPositionNum(caster, tagUseSkillAttack.HurtList.ToList(), skillConfig);
      BattleObject mainTarget = battleField.battleObjMgr.GetBattleObject((int)mainHurt.ObjID);
      if (mainTarget == null)
      {
         BattleDebug.LogError("目标为空 mainTarget == null ObjID : " + mainHurt.ObjID);
         OnSkillFinished();
         return;
      }
      BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
      MoveToTarget(mainTarget.heroRectTrans, new Vector2(skillConfig.CastDistance, 0), moveTime, () =>
      RectTransform targetTrans = battleField.GetTeamNode(battleCamp, mainTargetPosNum);
      MoveToTarget(targetTrans, new Vector2(skillConfig.CastDistance, 0), () =>
      {
         //   到位置转身(不一定非要转身 但是流程要写)
         TurnBack(() =>
@@ -217,13 +237,9 @@
               TurnBack(
                  () =>
                  {
                     RectTransform rectTransform = battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum);
                     //   回到原来的位置
                     MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, moveTime, () =>
                     {
                        TurnBack(null, 1f);
                        caster.motionBase.PlayAnimation(MotionName.idle, true);
                        OnAllAttackMoveFinished();
                     });
                     MoveToTarget(rectTransform, Vector2.zero, OnAttackFinish, 750F);
                  }
               , -1f);
            });
@@ -233,14 +249,24 @@
   protected virtual void OnAllAttackMoveFinished()
   {
      moveFinished = true;
      List<BattleObject> allList = battleField.battleObjMgr.allBattleObjDict.Values.ToList<BattleObject>();
      for (int i = 0; i < allList.Count; i++)
      {
         BattleObject bo = allList[i];
         bo.layerMgr.SetFront();
         // bo.heroRectTrans.SetParent(battleField.GetTeamNode(bo.Camp, bo.teamHero.positionNum), true);
         bo.heroInfoBar.SetActive(true);
      }
      battleField.battleRootNode.skillMaskNode.SetActive(false);
      // Debug.LogError("OnAllAttackMoveFinished skill " + skillConfig.SkillID + " cast position " + skillConfig.CastPosition + " cast mode " + skillConfig.castMode);
   }
   protected void CastToAllies()
   {
      RectTransform target = battleField.GetTeamNode(caster.Camp, skillConfig);
      MoveToTarget(target, new Vector2(skillConfig.CastDistance, 0), moveTime, () =>
      MoveToTarget(target, new Vector2(skillConfig.CastDistance, 0), () =>
      {
         //   到位置转身(不一定非要转身 但是流程要写)
         TurnBack(() =>
@@ -252,17 +278,20 @@
                  () =>
                  {
                     //   回到原来的位置
                     MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, moveTime, () =>
                     {
                        TurnBack(null, 1f);
                        caster.motionBase.PlayAnimation(MotionName.idle, true);
                        OnAllAttackMoveFinished();
                     });
                     MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum),
                        Vector2.zero, OnAttackFinish, 750F);
                  }
               , -1f);
            });
         }, -1f);
      });
   }
   protected void OnAttackFinish()
   {
      TurnBack(null, 1f);
      OnAllAttackMoveFinished();
      caster.motionBase.PlayAnimation(MotionName.idle, true);
   }
@@ -279,27 +308,28 @@
      // OnMiddleFrameEnd 中摇结束
      // OnFinalFrameStart 后摇开始
      // OnFinalFrameEnd 后摇结束
      return caster.motionBase.PlaySkillAnimation(skillConfig, this, onComplete);
   }
   //   技能开始
   public virtual void OnSkillStart()
   public void OnSkillStart()
   {
      skillEffect = SkillEffectFactory.CreateSkillEffect(
            caster,
            skillConfig,
            tagUseSkillAttack
         );
      if (skillEffect != null)
      {
         skillEffect.Play(OnHitTargets);
      }
      skillEffect.Play(OnHitTargets);
      isPlay = true;
   }
   //   技能前摇帧结束
   public virtual void OnStartSkillFrameEnd()
   {
   }
   /// <summary>
@@ -321,15 +351,17 @@
   /// </summary>
   public virtual void OnFinalFrameStart()
   {
      skillEffect.OnFinalFrameStart();
   }
   /// <summary>
   /// 后摇结束
   /// </summary>
   public virtual void OnFinalFrameEnd()
   {
   {
      skillEffect.OnFinalFrameEnd();
      HandleDead();
   }
@@ -337,11 +369,50 @@
   protected void HighLightAllTargets()
   {
      if (skillConfig.FuncType != 2)
         return;
      // 高亮所有目标
      HashSet<BattleObject> highlightList = new HashSet<BattleObject>(battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack));
      List<BattleObject> targetList = battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack);
      List<BattleObject> highlightList = new List<BattleObject>(targetList);
      highlightList.Add(caster);
      List<BattleObject> allList = battleField.battleObjMgr.allBattleObjDict.Values.ToList<BattleObject>();
      caster.heroInfoBar.SetActive(false);
      for (int i = 0; i < allList.Count; i++)
      {
         BattleObject bo = allList[i];
         if (highlightList.Contains(bo))
         {
            bo.layerMgr.SetFront();
            bo.heroInfoBar.SetActive(true);
            // bo.heroRectTrans.SetParent(battleField.battleRootNode.skillFrontNode, true);
         }
         else
         {
            bo.layerMgr.SetBack();
            // bo.heroRectTrans.SetParent(battleField.battleRootNode.skillBackNode, true);
         }
         if (targetList.Contains(bo))
         {
            bo.heroInfoBar.SetActive(true);
         }
         else
         {
            bo.heroInfoBar.SetActive(false);
         }
      }
      caster.layerMgr.SetSortingOrder(BattleConst.ActiveHeroActionSortingOrder);
      battleField.battleRootNode.skillMaskNode.SetActive(true);
      battleField.battleRootNode.SetSortingOrder();
      // caster.battleField.skillMask
      //   把这些BO全高亮 或者说把除了这些的都放在遮罩后面
      //   YYL TODO
   }
@@ -356,23 +427,50 @@
         BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
         if (target == null)
         {
            BattleDebug.LogError("目标为空 target == null ObjId : " + hurt.ObjID);
            Debug.LogError("目标为空 target == null ObjId : " + hurt.ObjID);
            continue;
         }
         // 伤害分布 (万分比)
         int[] damageDivide = skillConfig.DamageDivide[_hitIndex];
         long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx);
         // 保证所有分配项加起来等于totalDamage,避免因整除导致的误差
         List<long> damageList = BattleUtility.DivideDamageToList(damageDivide, totalDamage);
         OnHitEachTarget(target, totalDamage, damageList, ref hurt);
         OnHitEachTarget(_hitIndex, target, hurt);
      }
      HandleDead();
   }
   protected virtual void OnHitEachTarget(int _hitIndex, BattleObject target, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt)
   {
      // 伤害分布 (万分比)
      // Debug.LogError("skillConfig.DamageDivide.Count " + skillConfig.DamageDivide.Length + " _hitIndex " + _hitIndex);
      bool isLastHit = _hitIndex >= skillConfig.DamageDivide.Length - 1;
      int[] damageDivide = skillConfig.DamageDivide[_hitIndex];
      long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx);
      // 保证所有分配项加起来等于totalDamage,避免因整除导致的误差
      List<long> damageList = BattleUtility.DivideDamageToList(damageDivide, totalDamage);
      // public uint ObjID;
      // public uint AttackTypes;        // 飘血类型汇总,支持多种类型并存,如无视防御且暴击同时被格挡,二进制或运算最终值;0-失败;1-普通;2-回血;5-格挡;6-无视防御;7-暴击;9-闪避
      // public uint HurtHP;        // 飘血值,求余亿部分
      // public uint HurtHPEx;        // 飘血值,整除亿部分
      // public uint CurHP;        // 更新剩余血量,求余亿部分
      // public uint CurHPEx;        // 更新剩余血量,整除亿部分
      // public uint SuckHP;        // 本次伤害转化的吸血量
      // public uint BounceHP;        // 本次伤害反弹的伤害量
      //   TODO YYL AttackTypes  要表现成什么样呢? 支持多种类型并存,如无视防御且暴击同时被格挡,二进制或运算最终值;0-失败;1-普通;2-回血;5-格挡;6-无视防御;7-暴击;9-闪避
      List<HB422_tagMCTurnFightObjDead> deadPacks = BattleUtility.FindDeadPack(packList);
      bool isTargetDead = deadPacks.Exists(p => p.ObjID == target.ObjID);
      bool playAnimation = !(isLastHit && isTargetDead);
      target.Hurt(damageList, totalDamage, hurt, skillConfig, playAnimation);
      //   TODO YYL 这里是要做统一计算后再hurt跟suckhp还是怎样
      caster.SuckHp(hurt.SuckHP, skillConfig);//   吸血
      caster.HurtByReflect(hurt.BounceHP, skillConfig);// 反弹伤害
   }
   protected void HandleDead()
   {
@@ -390,7 +488,6 @@
      // 处理掉落包 提前distribute之后 PackManager才有掉落物 所以不跟assignexp一样distribute
      foreach (var _dropPack in dropPackList)
      {
         BattleDebug.LogError("distribute pack " + _dropPack.GetType().Name);
         PackageRegedit.Distribute(_dropPack);
         packList.Remove(_dropPack);
      }
@@ -433,8 +530,6 @@
         packList.Remove(deadPack);
      }
      deadPackList.Clear();
   }
@@ -482,12 +577,6 @@
   }
   protected virtual void OnHitEachTarget(BattleObject target, long totalDamage, List<long> damageList, ref HB427_tagSCUseSkill.tagSCUseSkillHurt hurt)
   {
      target.Hurt(damageList, totalDamage, hurt.AttackTypes);
   }
   protected void CheckAfterDeadhPack()
   {
@@ -545,25 +634,122 @@
   }
   public virtual bool IsFinished()
   {
      if (!isPlay)
      {
         return false;
      }
      if (skillEffect != null)
      {
         if (!skillEffect.IsFinished())
         {
            return false;
         }
         else
         {
            skillEffect = null;
            OnSkillFinished();
            return false;
         }
      }
      return isFinished;
      if (otherSkillAction != null)
      {
         if (!otherSkillAction.IsFinished())
         {
            return false;
         }
         else
         {
            otherSkillAction = null;
            OnSkillFinished();
            return false;
         }
      }
      if (isFinished && moveFinished)
      {
         if (packList.Count > 0)
         {
            OnSkillFinished();
            return false;
         }
         return true;
      }
      else
      {
         return false;
      }
   }
   public virtual void ForceFinished()
   {
      skillEffect?.ForceFinished();
      if (otherSkillAction != null)
      {
         otherSkillAction.ForceFinish();
         otherSkillAction = null;
      }
      HandleDead();
      isFinished = true;
      moveFinished = true;
      isPlay = true;
      while (packList.Count > 0)
      {
         var pack = packList[0];
         packList.RemoveAt(0);
         if (pack is CustomHB426CombinePack combinePack)
         {
            if (combinePack.startTag.Tag.StartsWith("Skill_"))
            {
               otherSkillAction = combinePack.CreateSkillAction();
               otherSkillAction.fromSkillId = skillConfig.SkillID;
               //   强制结束其他技能
               otherSkillAction.ForceFinish();
               continue;
            }
         }
         else if (pack is CustomB421ActionPack actionPack)
         {
            actionPack.Distribute();
         }
         PackageRegedit.Distribute(pack);
      }
   }
   public void OnSkillFinished()
   {
      BattleDebug.LogError(GetType().Name + " Skill Finished");
      if (skillEffect != null)
      {
         if (!skillEffect.IsFinished())
         {
            return;
         }
         else
         {
            skillEffect = null;
            OnSkillFinished();
         }
      }
      if (otherSkillAction != null)
      {
         if (!otherSkillAction.IsFinished())
         {
            return;
         }
         else
         {
            otherSkillAction = null;
            OnSkillFinished();
         }
      }
      while (packList.Count > 0)
      {
         var pack = packList[0];
@@ -574,11 +760,18 @@
            var combinePack = pack as CustomHB426CombinePack;
            if (combinePack.startTag.Tag.StartsWith("Skill_"))
            {
               BattleDebug.LogError("other skill casting " + combinePack.startTag.Tag);
               otherSkillAction = combinePack.CreateSkillAction();
               otherSkillAction.fromSkillId = skillConfig.SkillID;
               return;
            }
         }
         BattleDebug.LogError("distribute pack " + pack.GetType().Name);
         else if (pack is CustomB421ActionPack actionPack)
         {
            actionPack.Distribute();
         }
         // Debug.LogError("Distribute pack " + pack.GetType().ToString());
         PackageRegedit.Distribute(pack);
      }