yyl
5 天以前 c124d98bdf9659cf764bebb799bee42c30eb152f
Main/System/Battle/Skill/SkillBase.cs
@@ -1,237 +1,705 @@
using System.Collections.Generic;
using UnityEngine;
using System;
using DG.Tweening;
using Spine;
using System.Linq;
using System;
public class SkillBase
{
   protected H0604_tagUseSkillAttack tagUseSkillAttack;
    const float moveTime = 0.5f;
   protected SkillConfig skillConfig;
    protected SkillEffect skillEffect;
    protected HB427_tagSCUseSkill tagUseSkillAttack;
    public SkillConfig skillConfig;
    protected bool isFinished = false;
    protected BattleField battleField = null; // 战场
    protected RectTransform targetNode = null; // 目标节点
    protected BattleObject caster = null; // 施法者
    protected List<GameNetPackBasic> packList;
    protected List<SkillRecordAction> otherSkillActionList = new List<SkillRecordAction>();
    protected List<H0704_tagRolePackRefresh> dropPackList = new List<H0704_tagRolePackRefresh>();
    protected List<HB405_tagMCAddExp> expPackList = new List<HB405_tagMCAddExp>();
    protected bool moveFinished = false;
    public int fromSkillId;
    public bool isPlay = false;
   protected bool isFinished = false;
    private Dictionary<int, BattleDrops> tempDropList = new Dictionary<int, BattleDrops>();
    private Dictionary<int, HB422_tagMCTurnFightObjDead> tempDeadPackList = new Dictionary<int, HB422_tagMCTurnFightObjDead>();
   protected BattleField battleField = null; // 战场
    // 构造函数:初始化技能基础数据
    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;
    }
   protected RectTransform targetNode = null; // 目标节点
    // 技能运行主逻辑:处理技能效果和其他技能动作
    public virtual void Run()
    {
        if (skillEffect != null)
        {
            if (skillEffect.IsFinished())
            {
                skillEffect = null;
                OnSkillFinished();
            }
            else
            {
                skillEffect.Run();
            }
            return;
        }
   protected BattleObject caster = null; // 施法者
        if (otherSkillActionList.Count > 0)
        {
            for (int i = otherSkillActionList.Count - 1; i >= 0; i--)
            {
                var action = otherSkillActionList[i];
                if (action.IsFinished())
                {
                    otherSkillActionList.RemoveAt(i);
                    OnSkillFinished();
                }
                else if (moveFinished)
                {
                    action.Run();
                }
            }
        }
    }
   protected bool startCounting = false;
    // 技能释放主逻辑:广播事件、高亮目标、执行释放
    public virtual void Cast()
    {
        // 广播技能释放事件
        string guid = battleField.guid;
        TeamHero teamHero = caster.teamHero;
        EventBroadcast.Instance.Broadcast<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, guid, skillConfig, teamHero);
   protected bool pauseState = false;
        // 高亮所有本次技能相关的目标
        HighLightAllTargets();
   protected int curFrame = 0;
        // 根据释放模式执行相应逻辑
        switch (skillConfig.castMode)
        {
            case SkillCastMode.Self:
                CastImpl(OnAttackFinish);
                break;
            case SkillCastMode.Enemy:
                CastToEnemy();
                break;
            case SkillCastMode.Target:
                CastToTarget();
                break;
            case SkillCastMode.Allies:
                CastToAllies();
                break;
            case SkillCastMode.DashCast:
                DashCast(OnAttackFinish);
                break;
            default:
                Debug.LogError("强制结束技能 暂时不支持其他的方式释放 有需求please联系策划 技能id:" + skillConfig.SkillID + " cast position " + skillConfig.CastPosition);
                ForceFinished();
                break;
        }
    }
   protected List<int> triggerFrames = new List<int>();
    // 冲撞攻击模式(待实现)
    protected void DashCast(Action _onComplete)
    {
        Debug.LogError("DashCast 还没实现");
        ForceFinished();
    }
   public SkillBase(BattleObject _caster, SkillConfig _skillCfg, H0604_tagUseSkillAttack vNetData, BattleField _battleField = null)
   {
      caster = _caster;
      skillConfig = _skillCfg;
      tagUseSkillAttack = vNetData;
      battleField = _battleField;
    // 对敌方释放技能:移动到敌方区域进行攻击
    protected void CastToEnemy()
    {
        RectTransform target = battleField.GetTeamNode(caster.GetEnemyCamp(), skillConfig);
        ExecuteMoveAndCastSequence(target, () =>
        {
            MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, OnAttackFinish, 750F);
        });
    }
      triggerFrames.Clear();
      triggerFrames.AddRange(skillConfig.TriggerFrames);
   }
    // 对指定目标释放技能:移动到主要目标位置进行攻击
    protected void CastToTarget()
    {
        if (tagUseSkillAttack.HurtCount <= 0)
        {
            Debug.LogError("技能攻击包没有目标 HurtCount <= 0");
            OnSkillFinished();
            return;
        }
   public virtual void Run()
   {
      if (startCounting)
      {
         curFrame++;
        int mainTargetPosNum = BattleUtility.GetMainTargetPositionNum(caster, tagUseSkillAttack.HurtList.ToList(), skillConfig);
        BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
        RectTransform targetTrans = battleField.GetTeamNode(battleCamp, mainTargetPosNum);
         if (triggerFrames.Contains(curFrame))
         {
            OnTriggerEvent(triggerFrames.IndexOf(curFrame), curFrame);
         }
      }
   }
        ExecuteMoveAndCastSequence(targetTrans, () =>
        {
            RectTransform rectTransform = battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum);
            MoveToTarget(rectTransform, Vector2.zero, OnAttackFinish, 750F);
        });
    }
   protected virtual void OnTriggerEvent(int triggerIndex, int triggerFrame)
   {
    // 对友方释放技能:移动到友方区域进行治疗或增益
    protected void CastToAllies()
    {
        RectTransform target = battleField.GetTeamNode(caster.Camp, skillConfig);
        ExecuteMoveAndCastSequence(target, () =>
        {
            MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, OnAttackFinish, 750F);
        });
    }
   }
    // 执行移动-施法-返回序列:通用的移动攻击流程
    private void ExecuteMoveAndCastSequence(RectTransform target, Action onReturnComplete)
    {
        MoveToTarget(target, new Vector2(skillConfig.CastDistance, 0), () =>
        {
            TurnBack(() =>
            {
                CastImpl(() =>
                {
                    TurnBack(() =>
                    {
                        try
                        {
                            onReturnComplete?.Invoke(); // 添加异常处理防止回调异常导致状态不完整
                        }
                        catch (Exception ex)
                        {
                            Debug.LogError($"ExecuteMoveAndCastSequence回调异常: {ex.Message}");
                            throw;
                        }
                    }, -1f);
                });
            }, -1f);
        });
    }
   public void Pause()
   {
      pauseState = startCounting;
      startCounting = false;
   }
    // 移动到目标位置:处理角色的移动动画和逻辑
    protected void MoveToTarget(RectTransform target, Vector2 offset, Action _onComplete = null, float speed = 500f)
    {
        if (skillConfig.CastDistance >= 9999)
        {
            _onComplete?.Invoke();
            return;
        }
   public void Resume()
   {
      startCounting = pauseState;
   }
        caster.motionBase.PlayAnimation(MotionName.run, true);
        var tweener = BattleUtility.MoveToTarget(caster.heroRectTrans, target, offset, () =>
        {
            caster.motionBase.PlayAnimation(MotionName.idle, true);
            _onComplete?.Invoke();
        }, speed);
        battleField.battleTweenMgr.OnPlayTween(tweener);
    }
   // 0·移动到距离目标n码,的距离释放(可配置,9999即原地释放,负数则是移动到人物背面,人物要转身)
   // 1·移动到距离阵容位置n码的距离(如2号位,5号位)释放(即战场中央此类)
   public virtual void Cast()
   {
      //   高亮所有本次技能相关的目标
      HighLightAllTargets();
    // 转身逻辑:根据技能配置处理角色转向
    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();
    }
      switch (skillConfig.castMode)
      {
         case SkillCastMode.StandCast:
            PlayCastAnimation(() => DoSkillLogic(OnSkillFinished));
            break;
         case SkillCastMode.MoveToTarget:
            MoveToTarget(_onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); }))));
            break;
         case SkillCastMode.DashCast:
            DashToTarget(() => BackToOrigin(OnSkillFinished));
            break;
         default:
            Debug.LogError("暂时不支持其他的方式释放 有需求请联系策划");
            break;
      }
   }
    // 攻击完成后的处理:转身、恢复状态、播放待机动画
    protected void OnAttackFinish()
    {
        TurnBack(null, 1f);
        OnAllAttackMoveFinished();
        caster.motionBase.PlayAnimation(MotionName.idle, true);
    }
   //   冲刺的技能 动作 跟移动 是同时进行的 移动到目标的一瞬间就要进行技能逻辑
   protected void DashToTarget(Action _onComplete)
   {
      TrackEntry entry = PlayCastAnimation();
      //   做一个微微的提前
      MoveToTarget(entry.TrackTime - 0.05f, () => DoSkillLogic(_onComplete));
   }
    // 所有攻击移动完成后的处理:恢复UI显示状态
    protected virtual void OnAllAttackMoveFinished()
    {
        moveFinished = true;
        List<BattleObject> allList = battleField.battleObjMgr.allBattleObjDict.Values.ToList<BattleObject>();
        foreach (BattleObject bo in allList)
        {
            bo.layerMgr.SetFront();
            bo.heroInfoBar.SetActive(true);
        }
        battleField.battleRootNode.skillMaskNode.SetActive(false);
    }
   protected void GetTargetNode()
   {
      targetNode = null;
    // 执行技能释放动画和逻辑:播放施法动作并提供回调
    protected TrackEntry CastImpl(Action onComplete = null)
    {
        return caster.motionBase.PlaySkillAnimation(skillConfig, this, tagUseSkillAttack.BattleType == 4, onComplete);
    }
      if (skillConfig.castMode == SkillCastMode.StandCast)
      {
         //   原地施法
         targetNode = caster.heroGo.transform as RectTransform;
      }
      else if (skillConfig.castMode == SkillCastMode.MoveToTarget || skillConfig.castMode == SkillCastMode.DashCast)
      {
         if (tagUseSkillAttack.AttackID <= 0)
         {
            Debug.LogError("技能没有指定目标");
            return;
         }
    // 技能开始回调:处理死亡、子技能、技能效果初始化
    public void OnSkillStart()
    {
        HandleDead();
        skillEffect = SkillEffectFactory.CreateSkillEffect(caster, skillConfig, tagUseSkillAttack);
        skillEffect.Play(OnHitTargets);
        foreach (var subSkillPack in tagUseSkillAttack.subSkillList)
        {
            SkillRecordAction recordAction = CustomHB426CombinePack.CreateSkillAction(battleField.guid, new List<GameNetPackBasic>() { subSkillPack });
            otherSkillActionList.Add(recordAction);
            battleField.recordPlayer.ImmediatelyPlay(recordAction);
        }
        isPlay = true;
    }
         //   移动到目标位置施法
         BattleObject _mainTarget = battleField.battleObjMgr.GetBattleObject((int)tagUseSkillAttack.AttackID);
         if (_mainTarget == null)
         {
            Debug.LogError("技能指定的目标不存在");
            return;
         }
    // 技能前摇结束回调
    public virtual void OnStartSkillFrameEnd() { }
         targetNode = _mainTarget.heroGo.transform as RectTransform;
      }
      else if (skillConfig.castMode == SkillCastMode.MoveToFormation)
      {
         //   TODO YYL
         targetNode = /*caster.GetEnemyTeamNode();*/ battleField.GetTeamNode(caster.Camp == BattleCamp.Blue ? BattleCamp.Red : BattleCamp.Blue);
      }
      else
      {
         Debug.LogError("未知的施法方式 技能id:" + skillConfig.SkillID);
         return;
      }
   }
    // 技能中摇开始回调:通知技能效果处理中摇开始
    public virtual void OnMiddleFrameStart(int times)
    {
        skillEffect?.OnMiddleFrameStart(times); // 修复:添加空值检查
    }
   protected List<BattleObject> GetTargetList()
   {
      return battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack);
   }
    // 技能中摇结束回调:通知技能效果处理中摇结束
    public virtual void OnMiddleFrameEnd(int times, int hitIndex)
    {
        skillEffect?.OnMiddleFrameEnd(times, hitIndex); // 修复:添加空值检查
    }
   protected virtual void DoSkillLogic(Action _onComplete = null)
   {
      //   子类实现具体的技能逻辑
   }
    // 技能后摇开始回调:通知技能效果处理后摇开始
    public virtual void OnFinalFrameStart()
    {
        skillEffect?.OnFinalFrameStart(); // 修复:添加空值检查
    }
   protected TrackEntry PlayCastAnimation(Action onComplete = null)
   {
      // 播放施法动作
      MotionName motionName = skillConfig.GetMotionName();
      TrackEntry trackEntry = caster.motionBase.PlayAnimation(motionName, false, onComplete);
      return trackEntry;
   }
    // 技能后摇结束回调:通知技能效果处理后摇结束
    public virtual void OnFinalFrameEnd()
    {
        skillEffect?.OnFinalFrameEnd(); // 修复:添加空值检查
    }
   public void MoveToTarget(float duration = 0.2f, Action _onComplete = null)
   {
      GetTargetNode();
      Vector2 offset = new Vector2(skillConfig.CastDistance, 0);
      RectTransform selfRect = caster.heroGo.transform as RectTransform;
      RectTransform targetRect = targetNode;
    // 高亮所有相关目标:设置施法者和目标的显示层级
    protected void HighLightAllTargets()
    {
        caster.layerMgr.SetSortingOrder(BattleConst.ActiveHeroActionSortingOrder);
      var tweener = BattleUtility.MoveToTarget(selfRect, targetRect, offset, duration, _onComplete);
      battleField.battleTweenMgr.OnPlayTween(tweener);
   }
        if (skillConfig.FuncType != 2)
            return;
   public void TurnBack(Action _onComplete)
   {
      if (skillConfig.CastDistance < 0)
      {
         caster.heroGo.transform.localScale = new Vector3(-1, 1, 1);
      }
      _onComplete?.Invoke();
   }
        List<BattleObject> targetList = battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack);
        List<BattleObject> highlightList = new List<BattleObject>(targetList) { caster };
        List<BattleObject> allList = battleField.battleObjMgr.allBattleObjDict.Values.ToList<BattleObject>();
        // 修复:使用HashSet优化性能,避免重复设置
        var targetSet = new HashSet<BattleObject>(targetList);
        var highlightSet = new HashSet<BattleObject>(highlightList);
        caster.heroInfoBar.SetActive(false);
   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();
         });
        foreach (BattleObject bo in allList)
        {
            bool isHighlight = highlightSet.Contains(bo);
            bool isTarget = targetSet.Contains(bo);
            if (isHighlight)
            {
                bo.layerMgr.SetFront();
            }
            else
            {
                bo.layerMgr.SetBack();
            }
      battleField.battleTweenMgr.OnPlayTween(tween);
   }
            bo.heroInfoBar.SetActive(isTarget);
        }
   protected void HighLightAllTargets()
   {
      // 高亮所有目标
      HashSet<BattleObject> highlightList = new HashSet<BattleObject>(battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack));
      highlightList.Add(caster);
        battleField.battleRootNode.skillMaskNode.SetActive(true);
        battleField.battleRootNode.SetSortingOrder();
    }
    // 命中目标回调:处理所有被命中的目标
    protected virtual void OnHitTargets(int _hitIndex, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hitList)
    {
        foreach (var hurt in hitList)
        {
            BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
            if (target == null)
            {
                Debug.LogError("目标为空 target == null ObjId : " + hurt.ObjID);
                continue;
            }
      //   把这些BO全高亮 或者说把除了这些的都放在遮罩后面
      //   YYL TODO
   }
            OnHitEachTarget(_hitIndex, target, hurt);
        }
    }
   public virtual bool IsFinished()
   {
      return isFinished;
   }
    // 处理单个目标被命中:应用伤害和施法者效果
    protected virtual void OnHitEachTarget(int _hitIndex, BattleObject target, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt)
    {
        List<int> damageDivide = new List<int>();
        if (_hitIndex == 0 && skillConfig.DamageDivide.Length <= 0)
        {
            damageDivide.Add(10000);
        }
        else
        {
            if (skillConfig.DamageDivide.Length <= _hitIndex)
            {
                Debug.LogError("技能伤害分布配置错误 skillId: " + skillConfig.SkillID + " hitIndex: " + _hitIndex);
                damageDivide.Add(10000);
            }
            else
            {
                damageDivide = skillConfig.DamageDivide[_hitIndex].ToList();
            }
        }
   public virtual void ForceFinished()
   {
      isFinished = true;
   }
        // 伤害分布计算和应用
        long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx);
        List<long> damageList = BattleUtility.DivideDamageToList(damageDivide.ToArray(), totalDamage);
   public void OnSkillFinished()
   {
      isFinished = true;
   }
        // 获取临时数据并应用伤害
        int objID = (int)target.ObjID;
        tempDropList.TryGetValue(objID, out BattleDrops battleDrops);
        tempDeadPackList.TryGetValue(objID, out HB422_tagMCTurnFightObjDead deadPack);
        target.Hurt(damageList, totalDamage, hurt, skillConfig, _hitIndex, battleDrops, deadPack);
#if UNITY_EDITOR_STOP_USING
   public virtual List<BattleObject> GetTargetList(BattleField _battleField)
   {
      SkillTargetType targetType = SkillTargetType.Enemy;
      SkillTargetRangeType rangeType = SkillTargetRangeType.LowestHP;
        // 处理施法者相关效果
        caster.SuckHp(hurt.SuckHP, skillConfig);
        caster.HurtByReflect(hurt.BounceHP, skillConfig);
    }
      List<BattleObject> affectList = _battleField.battleObjMgr.GetTargetList(caster, targetType, rangeType);
      return affectList;
   }
    // 处理死亡相关逻辑:分配掉落和经验
    protected void HandleDead()
    {
        var deadPackList = BattleUtility.FindDeadPack(packList);
        if (deadPackList.Count <= 0) return;
   public virtual List<Dictionary<int, List<int>>> GetDamageList(BattleField _battleField)
   {
      Debug.LogError("SkillBase GetDamageList should be overridden by derived class");
      return null;
   }
#endif
        CheckAfterDeadhPack();
        // 修复:先收集要删除的包,避免在foreach中修改集合
        var dropPacksToRemove = new List<H0704_tagRolePackRefresh>(dropPackList);
        foreach (var _dropPack in dropPacksToRemove)
        {
            PackageRegedit.Distribute(_dropPack);
            packList.Remove(_dropPack);
        }
        // 获取并分配掉落物品和经验
        var dropPack = PackManager.Instance.GetSinglePack(PackType.DropItem);
        var itemDict = dropPack.GetAllItems();
        List<ItemModel> itemList = new List<ItemModel>(itemDict.Values.Where(item => item != null && item.isAuction));
        var dropAssign = AssignDrops(itemList, deadPackList.Count);
        var expAssign = AssignExp(expPackList, deadPackList.Count);
        // 构造BattleDrops并缓存
        for (int i = 0; i < deadPackList.Count; i++)
        {
            int objID = (int)deadPackList[i].ObjID;
            BattleObject deadTarget = battleField.battleObjMgr.GetBattleObject(objID);
            // 修复:添加空值检查
            if (deadTarget == null)
            {
                Debug.LogError($"找不到死亡目标,ObjID: {objID}");
                continue;
            }
            List<int> itemIndexList = dropAssign[i].Select(item => item.gridIndex).ToList();
            BattleDrops battleDrops = new BattleDrops()
            {
                rectTransform = deadTarget.heroRectTrans,
                dropItemPackIndex = itemIndexList,
                expDrops = expAssign[i]
            };
            // 修复:避免字典键冲突,使用安全的添加方式
            if (!tempDropList.ContainsKey(objID))
            {
                tempDropList.Add(objID, battleDrops);
            }
            else
            {
                Debug.LogWarning($"tempDropList中已存在ObjID={objID}的记录,将覆盖原值");
                tempDropList[objID] = battleDrops; // 覆盖现有值
            }
            if (!tempDeadPackList.ContainsKey(objID))
            {
                tempDeadPackList.Add(objID, deadPackList[i]);
            }
            else
            {
                Debug.LogWarning($"tempDeadPackList中已存在ObjID={objID}的记录,将覆盖原值");
                tempDeadPackList[objID] = deadPackList[i]; // 覆盖现有值
            }
        }
        // 修复:避免在遍历时修改集合,先收集后删除
        var deadPacksToRemove = new List<GameNetPackBasic>(deadPackList.Cast<GameNetPackBasic>());
        foreach (var deadPack in deadPacksToRemove)
        {
            packList.Remove(deadPack);
        }
    }
    // 分配掉落物品:将掉落物品平均分配给死亡对象
    protected List<List<ItemModel>> AssignDrops(List<ItemModel> itemList, int deadCount)
    {
        var dropAssign = new List<List<ItemModel>>();
        for (int i = 0; i < deadCount; i++)
            dropAssign.Add(new List<ItemModel>());
        for (int i = 0; i < itemList.Count; i++)
            dropAssign[i % deadCount].Add(itemList[i]);
        return dropAssign;
    }
    // 分配经验值:将经验包平均分配给每个死亡对象
    protected List<List<HB405_tagMCAddExp>> AssignExp(List<HB405_tagMCAddExp> expList, int deadCount)
    {
        var expAssign = new List<List<HB405_tagMCAddExp>>();
        for (int i = 0; i < deadCount; i++)
            expAssign.Add(new List<HB405_tagMCAddExp>());
        // 修复:检查除零风险
        if (deadCount == 0)
        {
            Debug.LogWarning("AssignExp: deadCount为0,无法分配经验");
            return expAssign;
        }
        // 修复:先收集要删除的包,避免在foreach中修改packList
        var expPacksToRemove = new List<HB405_tagMCAddExp>();
        foreach (var expPack in expList)
        {
            long totalExp = GeneralDefine.GetFactValue(expPack.Exp, expPack.ExpPoint);
            long avgExp = totalExp / deadCount;
            long remain = totalExp % deadCount;
            for (int i = 0; i < deadCount; i++)
            {
                long assignExp = avgExp + (i < remain ? 1 : 0);
                var newPack = new HB405_tagMCAddExp
                {
                    Exp = (uint)(assignExp % 100000000),
                    ExpPoint = (uint)(assignExp / 100000000),
                    Source = expPack.Source
                };
                expAssign[i].Add(newPack);
            }
            expPacksToRemove.Add(expPack);
        }
        // 统一删除收集的包
        foreach (var pack in expPacksToRemove)
        {
            packList.Remove(pack);
        }
        return expAssign;
    }
    // 检查死亡后的包处理:处理技能包、掉落包、经验包
    protected void CheckAfterDeadhPack()
    {
        List<int> removeIndexList = new List<int>();
        for (int i = 0; i < packList.Count; i++)
        {
            var pack = packList[i];
            // 复活基本都靠技能包
            if (pack is CustomHB426CombinePack combinePack && combinePack.startTag.Tag.StartsWith("Skill_"))
                break;
            if (pack is H0704_tagRolePackRefresh h0704Pack && h0704Pack.PackType == (byte)PackType.DropItem && h0704Pack.IsBind == 1)
            {
                dropPackList.Add(h0704Pack);
                removeIndexList.Add(i);
            }
            if (pack is HB405_tagMCAddExp h405Pack && h405Pack.Source == 2)
            {
                expPackList.Add(h405Pack);
                removeIndexList.Add(i);
            }
        }
        for (int i = removeIndexList.Count - 1; i >= 0; i--)
            packList.RemoveAt(removeIndexList[i]);
    }
    // 检查技能是否完成:综合检查所有完成条件
    public virtual bool IsFinished()
    {
        if (!isPlay) return false;
        // 检查技能效果是否完成
        if (skillEffect != null)
        {
            if (!skillEffect.IsFinished()) return false;
            skillEffect = null;
            OnSkillFinished();
            return false;
        }
        // 检查其他技能动作是否完成
        if (otherSkillActionList.Count > 0)
        {
            for (int i = otherSkillActionList.Count - 1; i >= 0; i--)
            {
                var action = otherSkillActionList[i];
                if (action.IsFinished())
                {
                    otherSkillActionList.RemoveAt(i);
                    OnSkillFinished();
                }
            }
            if (otherSkillActionList.Count > 0) return false;
        }
        // 检查最终完成状态
        if (isFinished && moveFinished)
        {
            if (packList.Count > 0)
            {
                OnSkillFinished();
                return false;
            }
            return true;
        }
        return false;
    }
    // 强制结束技能:立即结束所有技能相关的处理
    public virtual void ForceFinished()
    {
        skillEffect?.ForceFinished();
        otherSkillActionList.ForEach(action => action.ForceFinish());
        otherSkillActionList.Clear();
        isFinished = true;
        moveFinished = true;
        isPlay = true;
        // 处理所有剩余包
        while (packList.Count > 0)
        {
            var pack = packList[0];
            packList.RemoveAt(0);
            if (pack is CustomHB426CombinePack combinePack && combinePack.startTag.Tag.StartsWith("Skill_"))
            {
                var otherSkillAction = combinePack.CreateSkillAction();
                otherSkillAction.fromSkillId = skillConfig.SkillID;
                otherSkillAction.ForceFinish();
            }
            else
            {
                if (pack is CustomB421ActionPack actionPack)
                    actionPack.Distribute();
                PackageRegedit.Distribute(pack);
            }
        }
    }
    // 技能完成处理:正常完成时的清理工作
    public void OnSkillFinished()
    {
        // 修复:使用循环代替递归,避免栈溢出风险
        try
        {
            while (true)
            {
                // 验证技能效果是否完成
                if (skillEffect != null && !skillEffect.IsFinished())
                    return;
                if (skillEffect != null)
                {
                    skillEffect = null;
                    continue; // 使用continue代替递归调用
                }
                // 验证其他技能动作是否完成
                if (otherSkillActionList.Count > 0)
                {
                    bool hasFinishedAction = false;
                    for (int i = otherSkillActionList.Count - 1; i >= 0; i--)
                    {
                        var action = otherSkillActionList[i];
                        if (action.IsFinished())
                        {
                            otherSkillActionList.RemoveAt(i);
                            hasFinishedAction = true;
                        }
                    }
                    if (hasFinishedAction)
                    {
                        continue; // 使用continue代替递归调用
                    }
                    return;
                }
                break; // 没有更多需要处理的,退出循环
            }
            // 处理剩余包
            while (packList.Count > 0)
            {
                var pack = packList[0];
                packList.RemoveAt(0);
                if (pack is CustomHB426CombinePack combinePack && combinePack.startTag.Tag.StartsWith("Skill_"))
                {
                    BattleDebug.LogError("other skill casting " + combinePack.startTag.Tag);
                    var otherSkillAction = combinePack.CreateSkillAction();
                    otherSkillAction.fromSkillId = skillConfig.SkillID;
                    otherSkillActionList.Add(otherSkillAction);
                    return;
                }
                if (pack is CustomB421ActionPack actionPack)
                    actionPack.Distribute();
                PackageRegedit.Distribute(pack);
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"OnSkillFinished异常: {ex.Message},技能ID={skillConfig.SkillID}");
            // 确保状态一致性,即使出现异常也要标记完成
            isFinished = true;
            throw; // 重新抛出异常供上层处理
        }
        isFinished = true;
    }
    // 添加清理方法:防止内存泄漏
    public virtual void Cleanup()
    {
        tempDropList?.Clear();
        tempDeadPackList?.Clear();
        otherSkillActionList?.Clear();
        dropPackList?.Clear();
        expPackList?.Clear();
        skillEffect = null;
        packList = null;
    }
}