yyl
2025-08-20 8f983d0dab26becb6b85dbbb616fde21c3ad8f02
Main/System/Battle/Skill/SkillBase.cs
@@ -9,6 +9,8 @@
public class SkillBase
{
   protected SkillEffect skillEffect;
   protected HB427_tagSCUseSkill tagUseSkillAttack;
   protected SkillConfig skillConfig;
@@ -68,7 +70,6 @@
   public void Pause()
   {
      pauseState = startCounting;
@@ -80,24 +81,98 @@
      startCounting = pauseState;
   }
   // 0·移动到距离目标n码,的距离释放(可配置,9999即原地释放,负数则是移动到人物背面,人物要转身)
   // 1·移动到距离阵容位置n码的距离(如2号位,5号位)释放(即战场中央此类)
   public virtual void Cast()
   {
      Debug.LogError(GetType().Name + " Skill Cast Start");
      //   高亮所有本次技能相关的目标
      HighLightAllTargets();
      //   距离配成负数要转身 TurnBack
      Debug.LogError(GetType().Name + " Skill CastMode : " + skillConfig.castMode);
      switch (skillConfig.castMode)
      {
         case SkillCastMode.Self:
            PlayCastAnimation(() => DoSkillLogic(OnSkillFinished));
            CastImpl();
            break;
         case SkillCastMode.Enemy:
            MoveToTarget(caster.GetEnemyCamp(), skillConfig, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); }))));
            CastToEnemy();
            break;
         case SkillCastMode.Target:
            CastToTarget();
            break;
         case SkillCastMode.Allies:
            CastToAllies();
            break;
         // case SkillCastMode.DashCast:
         //    DashToTarget(() => BackToOrigin(OnSkillFinished));
         //    break;
         default:
            Debug.LogError("暂时不支持其他的方式释放 有需求请联系策划 技能id:" + skillConfig.SkillID + " cast position " + skillConfig.CastPosition);
            OnSkillFinished();
            break;
      }
   }
   protected void MoveToTarget(RectTransform target, Vector2 offset, float duration, Action onComplete = null)
   {
      caster.motionBase.PlayAnimation(MotionName.run, true);
      var tweener = BattleUtility.MoveToTarget(caster.heroRectTrans, target, offset, duration, () =>
      {
         caster.motionBase.PlayAnimation(MotionName.idle, true);
         onComplete?.Invoke();
      });
      battleField.battleTweenMgr.OnPlayTween(tweener);
   }
   protected void TurnBack(Action _onComplete, float forward)
   {
      if (skillConfig.CastDistance < 0)
      {
         //   转身
         Vector3 scale = caster.heroGo.transform.localScale;
         scale.x = Mathf.Abs(scale.x) * forward;
         caster.heroGo.transform.localScale = scale;
      }
      _onComplete?.Invoke();
   }
   protected void CastToEnemy()
   {
      const float moveTime = 0.5f;
      RectTransform target = battleField.GetTeamNode(caster.GetEnemyCamp(), skillConfig);
      MoveToTarget(target, new Vector2(skillConfig.CastDistance, 0), moveTime, () =>
      {
         //   到位置转身(不一定非要转身 但是流程要写)
         TurnBack(() =>
         {
            //   到达目标位置
            CastImpl(() =>
            {
               TurnBack(
                  () =>
                  {
                     //   回到原来的位置
                     MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, moveTime, () =>
                     {
                        TurnBack(null, 1f);
                        caster.motionBase.PlayAnimation(MotionName.idle, true);
                     });
                  }
               , -1f);
            });
         }, -1f);
      });
   }
   protected void CastToTarget()
   {
            // 目标是敌方主目标
            if (tagUseSkillAttack.HurtCount <= 0)
            {
@@ -115,84 +190,122 @@
               OnSkillFinished();
               return;
            }
            MoveToTarget(mainTarget.Camp, mainTarget, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); }))));
            break;
         case SkillCastMode.Allies:
            MoveToTarget(caster.Camp, skillConfig, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); }))));
            break;
         // case SkillCastMode.DashCast:
         //    DashToTarget(() => BackToOrigin(OnSkillFinished));
         //    break;
         default:
            Debug.LogError("暂时不支持其他的方式释放 有需求请联系策划" + skillConfig.SkillID);
            OnSkillFinished();
            break;
      }
      // MoveToTarget(mainTarget.Camp, mainTarget, _onComplete: () => TurnBack(() => CastImpl(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); }))));
   }
   //   这里其实是技能后摇结束的地方
   protected virtual void DoSkillLogic(Action _onComplete = null)
   protected void CastToAllies()
   {
      // MoveToTarget(caster.Camp, skillConfig, _onComplete: () => TurnBack(() => CastImpl(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); }))));
   }
   protected TrackEntry PlayCastAnimation(Action onComplete = null)
   protected TrackEntry CastImpl(Action onComplete = null)
   {
      // 播放施法动作
      return caster.motionBase.PlaySkillAnimation(skillConfig, onComplete,
            OnStartSkillFrame,//攻击前摇结束
            OnActiveSkillFrame);//攻击中摇结束
      return caster.motionBase.PlaySkillAnimation(skillConfig, this, onComplete);//攻击中摇结束
   }
   public void MoveToTarget(BattleCamp camp, BattleObject target, float duration = 0.2f, Action _onComplete = null)
   //   技能开始
   public virtual void OnSkillStart()
   {
      targetNode = battleField.GetTeamNode(camp, target);
      Vector2 offset = new Vector2(skillConfig.CastDistance, 0);
      RectTransform selfRect = caster.heroRectTrans;
      RectTransform targetRect = targetNode;
      var tweener = BattleUtility.MoveToTarget(selfRect, targetRect, offset, duration, _onComplete);
      battleField.battleTweenMgr.OnPlayTween(tweener);
      skillEffect = SkillEffectFactory.CreateSkillEffect(
            caster,
            skillConfig,
            tagUseSkillAttack
         );
      if (skillEffect != null)
      {
         skillEffect.Play(OnHitTargets);
      }
   }
   public void MoveToTarget(BattleCamp camp, SkillConfig skillCfg, float duration = 0.2f, Action _onComplete = null)
   //   技能前摇帧结束
   public virtual void OnStartSkillFrameEnd()
   {
      targetNode = battleField.GetTeamNode(camp, skillCfg);
      Vector2 offset = new Vector2(skillConfig.CastDistance, 0);
      RectTransform selfRect = caster.heroRectTrans;
      RectTransform targetRect = targetNode;
      var tweener = BattleUtility.MoveToTarget(selfRect, targetRect, offset, duration, _onComplete);
      battleField.battleTweenMgr.OnPlayTween(tweener);
   }
   public void TurnBack(Action _onComplete)
   /// <summary>
   /// 中摇开始 times=第几次循环 从0开始
   /// </summary>
   /// <param name="times"></param>
   public virtual void OnMiddleFrameStart(int times)
   {
      if (skillConfig.CastDistance < 0)
      {
         //   转身
         caster.heroGo.transform.localScale = new Vector3(-1, 1, 1);
      }
      _onComplete?.Invoke();
   }
   public void BackToOrigin(Action _onComplete = null)
   public virtual void OnMiddleFrameEnd(int times, int hitIndex)
   {
      RectTransform selfRect = caster.heroRectTrans;
      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);
   }
   /// <summary>
   /// 后摇开始
   /// </summary>
   public virtual void OnFinalFrameStart()
   {
   }
   /// <summary>
   /// 后摇结束
   /// </summary>
   public virtual void OnFinalFrameEnd()
   {
   }
   // public void MoveToTarget(BattleCamp camp, BattleObject target, float duration = 0.2f, Action _onComplete = null)
   // {
   //    targetNode = battleField.GetTeamNode(camp, target);
   //    Vector2 offset = new Vector2(skillConfig.CastDistance, 0);
   //    RectTransform selfRect = caster.heroRectTrans;
   //    RectTransform targetRect = targetNode;
   //    var tweener = BattleUtility.MoveToTarget(selfRect, targetRect, offset, duration, _onComplete);
   //    battleField.battleTweenMgr.OnPlayTween(tweener);
   // }
   // public void MoveToTarget(BattleCamp camp, SkillConfig skillCfg, float duration = 0.2f, Action _onComplete = null)
   // {
   //    targetNode = battleField.GetTeamNode(camp, skillCfg);
   //    Vector2 offset = new Vector2(skillConfig.CastDistance, 0);
   //    RectTransform selfRect = caster.heroRectTrans;
   //    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.heroRectTrans;
   //    Vector2 targetAnchoredPos = Vector2.zero;
   //    var tween = selfRect.DOAnchorPos(targetAnchoredPos, 0.2f)
   //       .SetEase(Ease.Linear);
   //    tween.onComplete += () =>
   //    {
   //       //   转成正确方向
   //       caster.heroGo.transform.localScale = Vector3.one;
   //       _onComplete?.Invoke();
   //    };
   //    battleField.battleTweenMgr.OnPlayTween(tween);
   // }
   protected void HighLightAllTargets()
   {
@@ -225,7 +338,7 @@
         long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx);
         // 保证所有分配项加起来等于totalDamage,避免因整除导致的误差
         List<long> damageList = DivideDamageToList(damageDivide, totalDamage);
         List<long> damageList = BattleUtility.DivideDamageToList(damageDivide, totalDamage);
         OnHitEachTarget(target, totalDamage, damageList, ref hurt);
      }
@@ -235,7 +348,7 @@
   protected void HandleDead()
   {
      var deadPackList = FindDeadPack();
      var deadPackList = BattleUtility.FindDeadPack(packList);
      CheckAfterDeadhPack();
      // 处理掉落包 提前distribute之后 PackManager才有掉落物 所以不跟assignexp一样distribute
@@ -276,13 +389,14 @@
      }
      // 分发死亡包
      battleField.OnObjsDead(deadPackList);
      foreach (var deadPack in deadPackList)
      {
         PackageRegedit.Distribute(deadPack);
         packList.Remove(deadPack);
      }
      deadPackList.Clear();
   }
   // 分配掉落
@@ -327,32 +441,7 @@
      return expAssign;
   }
   /// <summary>
   /// 保证所有分配项加起来等于totalDamage,避免因整除导致的误差
   /// </summary>
   protected List<long> DivideDamageToList(int[] damageDivide, long totalDamage)
   {
      List<long> fixedDamageList = new List<long>();
      long assigned = 0;
      int count = damageDivide.Length;
      for (int i = 0; i < count; i++)
      {
         long damage;
         if (i == count - 1)
         {
            // 最后一个分配项修正为剩余
            damage = totalDamage - assigned;
         }
         else
         {
            damage = (totalDamage * damageDivide[i] + 5000) / 10000; // 四舍五入
            assigned += damage;
         }
         fixedDamageList.Add(damage);
      }
      return fixedDamageList;
   }
   protected virtual void OnHitEachTarget(BattleObject target, long totalDamage, List<long> damageList, ref HB427_tagSCUseSkill.tagSCUseSkillHurt hurt)
   {
@@ -368,57 +457,6 @@
            target.heroGo.transform
         );
      }
   }
   protected HB423_tagMCTurnFightObjReborn FindRebornPack(BattleObject target)
   {
      HB423_tagMCTurnFightObjReborn rebornPack = null;
      for (int i = 0; i < packList.Count; i++)
      {
         var pack = packList[i];
         if (pack is HB423_tagMCTurnFightObjReborn)
         {
            rebornPack = pack as HB423_tagMCTurnFightObjReborn;
            if (rebornPack.ObjID == target.ObjID)
            {
               return rebornPack;
            }
         }
         else if (pack is CustomHB426CombinePack)
         {
            var combinePack = pack as CustomHB426CombinePack;
            if (combinePack.startTag.Tag.StartsWith("Skill_"))
            {
               break; // 找到技能包就不需要再处理了
            }
         }
      }
      return null;
   }
   protected List<HB422_tagMCTurnFightObjDead> FindDeadPack()
   {
      List<HB422_tagMCTurnFightObjDead> deadPacks = new List<HB422_tagMCTurnFightObjDead>();
      for (int i = 0; i < packList.Count; i++)
      {
         var pack = packList[i];
         //   寻找死亡包 找到死亡包之后要找掉落包 不能超过技能包
         if (pack is HB422_tagMCTurnFightObjDead)
         {
            var deadPack = pack as HB422_tagMCTurnFightObjDead;
            deadPacks.Add(deadPack);
         }
         else if (pack is CustomHB426CombinePack)
         {
            //   找死亡包不要越过技能包
            var combinePack = pack as CustomHB426CombinePack;
            if (combinePack.startTag.Tag.StartsWith("Skill_"))
            {
               break;
            }
         }
      }
      return deadPacks;
   }
   protected void CheckAfterDeadhPack()
@@ -487,7 +525,8 @@
   public void OnSkillFinished()
   {
      while (packList.Count > 0)
      Debug.LogError(GetType().Name + " Skill Finished");
      if (packList.Count > 0)
      {
         var pack = packList[0];
         packList.RemoveAt(0);
@@ -506,21 +545,5 @@
      }
      isFinished = true;
   }
   protected virtual void OnActiveSkillFrame()
   {
   }
   protected virtual void OnStartSkillFrame()
   {
   }
   protected virtual void OnEndSkillFrame()
   {
   }
}