Main/System/Battle/Skill/SkillBase.cs
@@ -505,20 +505,57 @@
        if (skillConfig.FuncType != 2)
            return;
        List<BattleObject> targetList = battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack);
        List<BattleObject> highlightList = new List<BattleObject>(targetList) { caster };
        List<BattleObject> allList = battleField.battleObjMgr.allBattleObjDict.Values.ToList<BattleObject>();
        // 收集所有目标(包含 HurtList、每个 Hurt 的 HurtListEx、以及顶层 HurtListEx)
        var targetSet = new HashSet<BattleObject>();
        if (tagUseSkillAttack != null)
        {
            // 主目标列表
            if (tagUseSkillAttack.HurtList != null)
            {
                foreach (var hurt in tagUseSkillAttack.HurtList)
                {
                    var bo = battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
                    if (bo != null) targetSet.Add(bo);
        // 修复:使用HashSet优化性能,避免重复设置
        var targetSet = new HashSet<BattleObject>(targetList);
                    // 主目标的额外目标(弹射/平摊)
                    if (hurt.HurtListEx != null)
                    {
                        foreach (var hurtEx in hurt.HurtListEx)
                        {
                            var exBo = battleField.battleObjMgr.GetBattleObject((int)hurtEx.ObjID);
                            if (exBo != null) targetSet.Add(exBo);
                        }
                    }
                }
            }
            // 技能包顶层的 HurtListEx(如溅射、顶层平摊)
            if (tagUseSkillAttack.HurtListEx != null)
            {
                foreach (var hurtEx in tagUseSkillAttack.HurtListEx)
                {
                    var exBo = battleField.battleObjMgr.GetBattleObject((int)hurtEx.ObjID);
                    if (exBo != null) targetSet.Add(exBo);
                }
            }
        }
        // 确保施法者也被高亮(原逻辑)
        var highlightList = new List<BattleObject>(targetSet) { caster };
        var allList = battleField.battleObjMgr.allBattleObjDict.Values.ToList();
        // 构造集合便于判断
        var targetSetLookup = new HashSet<BattleObject>(targetSet);
        var highlightSet = new HashSet<BattleObject>(highlightList);
        // 先把施法者的 InfoBar 隐藏(原逻辑保留)
        caster.heroInfoBar.SetActive(false);
        foreach (BattleObject bo in allList)
        {
            bool isHighlight = highlightSet.Contains(bo);
            bool isTarget = targetSet.Contains(bo);
            bool isTarget = targetSetLookup.Contains(bo);
            if (isHighlight)
            {
@@ -529,16 +566,16 @@
                bo.layerMgr.SetBack();
            }
            // 目标(含 HurtListEx)都应显示 InfoBar
            bo.heroInfoBar.SetActive(isTarget);
        }
        battleField.battleRootNode.skillMaskNode.SetActive(true);
        // battleField.battleRootNode.SetSortingOrder();
    }
    protected long suckHp = 0;
    // 命中目标回调:处理所有被命中的目标
    // 命中目标回调:处理所有被命中的目标(包括主目标、弹射目标、溅射目标)
    protected virtual void OnHitTargets(int _hitIndex, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hitList)
    {
        //  造成伤害前先处理血量刷新包
@@ -546,11 +583,13 @@
        suckHp = 0;
        // 统计吸血总量(主目标)
        foreach (var hurt in hitList)
        {
            suckHp += hurt.SuckHP;
        }
        // 处理主目标列表
        foreach (var hurt in hitList)
        { 
            BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
@@ -561,6 +600,38 @@
            }
            OnHitEachTarget(_hitIndex, target, hurt);
            // 处理该目标的额外目标列表(如弹射伤害的平摊目标)
            if (hurt.HurtListEx != null && hurt.HurtListEx.Length > 0)
            {
                foreach (var hurtEx in hurt.HurtListEx)
                {
                    BattleObject exTarget = caster.battleField.battleObjMgr.GetBattleObject((int)hurtEx.ObjID);
                    if (exTarget == null)
                    {
                        Debug.LogError($"额外目标为空 HurtListEx target == null ObjId : {hurtEx.ObjID}");
                        continue;
                    }
                    OnHitEachTargetEx(_hitIndex, exTarget, hurtEx);
                }
            }
        }
        // 处理技能包顶层的额外目标列表(如溅射伤害、平摊伤害)
        if (tagUseSkillAttack.HurtListEx != null && tagUseSkillAttack.HurtListEx.Length > 0)
        {
            foreach (var hurtEx in tagUseSkillAttack.HurtListEx)
            {
                BattleObject exTarget = caster.battleField.battleObjMgr.GetBattleObject((int)hurtEx.ObjID);
                if (exTarget == null)
                {
                    Debug.LogError($"顶层额外目标为空 tagUseSkillAttack.HurtListEx target == null ObjId : {hurtEx.ObjID}");
                    continue;
                }
                OnHitEachTargetEx(_hitIndex, exTarget, hurtEx);
            }
        }
    }
@@ -586,6 +657,42 @@
        caster.OnHurtTarget(hurtParam);
    }
    // 处理额外目标被命中(HurtListEx):溅射、弹射、平摊伤害等
    protected virtual void OnHitEachTargetEx(int _hitIndex, BattleObject target, HB427_tagSCUseSkill.tagSCUseSkillHurtEx hurtEx)
    {
        // ============ 获取临时数据(掉落、死亡等) ============
        int objID = (int)target.ObjID;
        tempDropList.TryGetValue(objID, out BattleDrops battleDrops);
        tempDeadPackList.TryGetValue(objID, out HB422_tagMCTurnFightObjDead deadPack);
        // ============ 参数打包(将 tagSCUseSkillHurtEx 转换为 tagSCUseSkillHurt)============
        HB427_tagSCUseSkill.tagSCUseSkillHurt hurt = new HB427_tagSCUseSkill.tagSCUseSkillHurt
        {
            ObjID = hurtEx.ObjID,
            AttackTypes = hurtEx.AttackTypes,
            HurtHP = hurtEx.HurtHP,
            HurtHPEx = hurtEx.HurtHPEx,
            CurHP = hurtEx.CurHP,
            CurHPEx = hurtEx.CurHPEx,
            SuckHP = hurtEx.SuckHP,
            BounceHP = 0, // HurtEx 没有反伤字段
            HurtCountEx = 0,
            HurtListEx = null
        };
        BattleHurtParam hurtParam = BattleUtility.CalcBattleHurtParam(this, _hitIndex, target, hurt, battleDrops, deadPack);
#if UNITY_EDITOR
        PrintHurtParamDebugInfo(hurtParam);
#endif
        // 先调用目标受伤
        target.Hurt(hurtParam);
        // 再调用施法者吸血/反伤
        caster.OnHurtTarget(hurtParam);
    }
#if UNITY_EDITOR
    private void PrintHurtParamDebugInfo(BattleHurtParam hurtParam)
    {