yyl
1 天以前 2d3a60767d0cd69c8dec97e39937bcd0c667be1c
125 战斗 血条&护盾1护盾2表现
5个文件已修改
392 ■■■■ 已修改文件
Main/Config/PartialConfigs/SkillConfig.Partial.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleUtility.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Define/BattleDmgInfo.cs 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Skill/SkillBase.cs 163 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/UIComp/BattleHeroInfoBar.cs 100 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/SkillConfig.Partial.cs
@@ -9,6 +9,7 @@
using System;
using UnityEngine;
using LitJson;
using System.Linq;
public partial class SkillConfig : ConfigBase<int, SkillConfig>
{
@@ -78,4 +79,26 @@
        tempDic.TryGetValue(skillLv, out config);
        return config;
    }
    public List<int> GetDamageDivide(int _hitIndex)
    {
        List<int> damageDivide = new List<int>();
        if (_hitIndex == 0 && DamageDivide.Length <= 0)
        {
            damageDivide.Add(10000);
        }
        else
        {
            if (DamageDivide.Length <= _hitIndex)
            {
                Debug.LogError("技能伤害分布配置错误 skillId: " + SkillID + " hitIndex: " + _hitIndex);
                damageDivide.Add(10000);
            }
            else
            {
                damageDivide = DamageDivide[_hitIndex].ToList();
            }
        }
        return damageDivide;
    }
}
Main/System/Battle/BattleUtility.cs
@@ -296,6 +296,16 @@
        }
        return config.nums[_num - 48];
    }
    public static bool IsHealing(HB427_tagSCUseSkill.tagSCUseSkillHurt hurt)
    {
        return ((hurt.AttackTypes & (int)ServerDamageType.Recovery) != 0 ||
                          (hurt.AttackTypes & (int)ServerDamageType.DamageReverse) != 0) &&
                         (hurt.AttackTypes & (int)ServerDamageType.Damage) == 0 &&
                         (hurt.AttackTypes & (int)ServerDamageType.Realdamage) == 0 &&
                         (hurt.AttackTypes & (int)ServerDamageType.SuckHpReverse) == 0 &&
                         (hurt.AttackTypes & (int)ServerDamageType.SelfHarm) == 0;
    }
    
    /// <summary>
    /// 将整个技能的总伤害按命中次数和分段配置分配
Main/System/Battle/Define/BattleDmgInfo.cs
@@ -265,12 +265,6 @@
    public List<long> damageList;
    public List<long> suckHpList;
    public List<long> reflectHpList;
    public long fromShieldValue;
    public long toShieldValue;
    public long fromHp;
    public long toHp;
    public BattleDrops battleDrops;
    public HB427_tagSCUseSkill.tagSCUseSkillHurt hurt;
    public int hitIndex;
@@ -278,75 +272,35 @@
    public SkillConfig skillConfig;
    public long maxHp;
    #region Shield Value Calculations
    //  护盾值的变化应该从护盾2开始变化 也就是说 如果护盾2有值 则从护盾2开始变化 否则从护盾1开始变化
    //  再考虑护盾1 如果护盾1有值 则从护盾1开始变化 否则没有护盾变化
    //  但是其实可以从总血量下手 也就是说
    //  from护盾值 + from血量 = 表现的开始
    //  to护盾值 + to血量 = 表现的结束
    //  这样就不需要区分护盾1和护盾2了 只要在表现上做好就行
    public long MaxSheildValue
    public long fromShieldValue;
    public long toShieldValue;
    public long fromHp;
    public long toHp;
    //  未被护盾抵消前的伤害
    public long totalDamage
    {
        get
        {
            return hurtObj == null ? 0 : hurtObj.teamHero.maxHp;
            long total = 0;
            if (damageList != null)
            {
                foreach (var dmg in damageList)
                {
                    total += dmg;
                }
            }
            return total;
        }
    }
    public long phase1FromShieldValue
    {
        get
        {
            if (fromShieldValue > 0)
            {
                return Mathf.Min((int)fromShieldValue, (int)MaxSheildValue);
            }
            else
            {
                return 0;
            }
        }
    }
    public long phase1ToShieldValue
    {
        get
        {
            if (toShieldValue > 0)
            {
                return Mathf.Min((int)toShieldValue, (int)MaxSheildValue);
            }
            else
            {
                return 0;
            }
        }
    }
    public long phase2FromShieldValue
    {
        get
        {
            if (fromShieldValue > MaxSheildValue)
            {
                return fromShieldValue - MaxSheildValue;
            }
            else
            {
                return 0;
            }
        }
    }
    public long phase2ToShieldValue
    {
        get
        {
            if (toShieldValue > MaxSheildValue)
            {
                return toShieldValue - MaxSheildValue;
            }
            else
            {
                return 0;
            }
        }
    }
    #endregion
}
Main/System/Battle/Skill/SkillBase.cs
@@ -489,25 +489,6 @@
    // 处理单个目标被命中:应用伤害和施法者效果
    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();
            }
        }
        // 计算总伤害和分段伤害列表
        long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx);
        List<long> damageList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, totalDamage);
@@ -515,29 +496,21 @@
        long totalSuckHp = suckHp;
        List<long> suckHpList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, totalSuckHp);
        long totalReflectHp = hurt.BounceHP;
        List<long> reflectHpList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, totalReflectHp);
        // ============ 第二步:刷新实际血量 ============
        long fromHp = target.teamHero.curHp;
        // ============处理反伤 ===============
        //  也要按每一击平均算 最后要补齐伤害
        long reflectHp = hurt.BounceHP;
        List<long> reflectHpList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, reflectHp);
        // long currentSuckHp = suckHp / tagUseSkillAttack.HurtCount;
        // 计算当前这一击的实际伤害(所有分段伤害之和)
        // 计算当前这一击的各项数值
        long currentHitDamage = 0;
        foreach (long dmg in damageList)
        {
            currentHitDamage += dmg;
        }
        long currentHitSuckHp = 0;
        foreach (long suck in suckHpList)
        {
            currentHitSuckHp += suck;
        }
        long currentHitReflectHp = 0;
        foreach (long reflect in reflectHpList)
@@ -545,54 +518,74 @@
            currentHitReflectHp += reflect;
        }
        long shieldValue = target.buffMgr.GetShieldValue();
        long remainSheild = shieldValue - currentHitDamage;
        long toShieldValue = Math.Max(0, shieldValue - currentHitDamage);
        long shieldRecieveDamage = shieldValue - toShieldValue;
        // if (shieldValue > 0 && remainSheild >= 0)
        // {
        //     currentHitDamage = 0;
        //     target.buffMgr.ReduceShieldValue(currentHitDamage);
        // }
        // else if (shieldValue > 0 && remainSheild < 0)
        // {
        //     currentHitDamage = Math.Abs(remainSheild);
        //     target.buffMgr.ClearShield();
        // }
        long toHp = fromHp; //Math.Max(0, fromHp - currentHitDamage);
        // ============ 第二步:获取目标当前状态 ============
        long fromHp = target.teamHero.curHp;
        long maxHp = target.teamHero.maxHp;
        long fromShieldValue = target.buffMgr.GetShieldValue();
        // 判断是治疗还是伤害
        bool isHealing = ((hurt.AttackTypes & (int)ServerDamageType.Recovery) != 0 ||
                          (hurt.AttackTypes & (int)ServerDamageType.DamageReverse) != 0) &&
                         (hurt.AttackTypes & (int)ServerDamageType.Damage) == 0 &&
                         (hurt.AttackTypes & (int)ServerDamageType.Realdamage) == 0 &&
                         (hurt.AttackTypes & (int)ServerDamageType.SuckHpReverse) == 0 &&
                         (hurt.AttackTypes & (int)ServerDamageType.SelfHarm) == 0;
        bool isHealing = BattleUtility.IsHealing(hurt);
        // ============ 第三步:计算目标血量和护盾变化 ============
        long toHp;
        long toShieldValue;
        if (isHealing)
        {
            // 治疗逻辑:直接加血,不考虑护盾
            toHp = Math.Min(target.teamHero.maxHp, fromHp + currentHitDamage);
            // 治疗逻辑:直接加血,护盾不变
            toHp = Math.Min(maxHp, fromHp + currentHitDamage);
            toShieldValue = fromShieldValue;
        }
        else
        {
            // 伤害逻辑:先扣护盾,再扣血
            if (remainSheild < 0)
            // 伤害逻辑:先扣护盾,护盾不足再扣血
            if (fromShieldValue >= currentHitDamage)
            {
                // 盾被打破
                toHp = Math.Max(0, fromHp + remainSheild);
                // 护盾足够承受所有伤害
                toShieldValue = fromShieldValue - currentHitDamage;
                toHp = fromHp;
            }
            else
            {
                // 护盾不足,先扣完护盾,剩余伤害扣血
                long remainingDamage = currentHitDamage - fromShieldValue;
                toShieldValue = 0;
                toHp = Math.Max(0, fromHp - remainingDamage);
            }
        }
        // 更新目标血量
        // ============ 第四步:更新目标实际血量 ============
        target.teamHero.curHp = toHp;
        // ============ 第五步:计算并更新施法者血量变化 ============
        long casterFromHp = caster.teamHero.curHp;
        long casterMaxHp = caster.teamHero.maxHp;
        long casterToHp = casterFromHp;
        // 处理吸血
        if (currentHitSuckHp > 0)
        {
            casterToHp = Math.Min(casterMaxHp, casterToHp + currentHitSuckHp);
        }
        // 处理反伤(施法者受到伤害)
        if (currentHitReflectHp > 0)
        {
            long casterShieldValue = caster.buffMgr.GetShieldValue();
            if (casterShieldValue >= currentHitReflectHp)
            {
                // 施法者护盾足够,血量不变
            }
            else
            {
                // 施法者护盾不足,扣血
                long remainingReflect = currentHitReflectHp - casterShieldValue;
                casterToHp = Math.Max(0, casterToHp - remainingReflect);
            }
        }
        // 更新施法者血量
        caster.teamHero.curHp = casterToHp;
#if UNITY_EDITOR
        BattleDebug.LogError(
@@ -600,37 +593,32 @@
            $"攻击者: {caster.teamHero.name}\n" +
            $"目标: {target.teamHero.name}\n" +
            $"技能: {skillConfig.SkillName} (第{_hitIndex}击)\n" +
            $"伤害: {currentHitDamage} 实际受到伤害: {fromHp-toHp} (总伤害: {totalDamage})\n" +
            $"承伤前护盾值: {shieldValue}\n" +
            $"承伤后护盾值: {toShieldValue}\n" +
            $"护盾承受伤害: {shieldRecieveDamage}\n" +
            $"伤害: {currentHitDamage} (总伤害: {totalDamage})\n" +
            $"吸血: {currentHitSuckHp}\n" +
            $"反伤: {currentHitReflectHp}\n" +
            $"血量变化: {fromHp} -> {toHp}\n" +
            $"技能包里的血量是: {GeneralDefine.GetFactValue(hurt.CurHP, hurt.CurHPEx)}\n"
            $"目标护盾变化: {fromShieldValue} -> {toShieldValue}\n" +
            $"目标血量变化: {fromHp} -> {toHp}\n" +
            $"施法者血量变化: {casterFromHp} -> {casterToHp}\n"
        );
#endif
        bool isLastHit = _hitIndex >= skillConfig.DamageDivide.Length - 1;
        // ============ 第三步:获取临时数据(掉落、死亡等) ============
        // ============ 第六步:获取临时数据(掉落、死亡等) ============
        int objID = (int)target.ObjID;
        tempDropList.TryGetValue(objID, out BattleDrops battleDrops);
        tempDeadPackList.TryGetValue(objID, out HB422_tagMCTurnFightObjDead deadPack);
        //  参数打包
        // ============ 第七步:参数打包并调用目标Hurt ============
        BattleHurtParam hurtParam = new BattleHurtParam()
        {
            casterObj = caster,
            hurtObj = target,
            damageList = damageList,
            suckHpList = suckHpList, //suckHpList,
            reflectHpList = reflectHpList,
            suckHpList = suckHpList,      // 用于casterDamageList飘字
            reflectHpList = reflectHpList, // 用于casterDamageList飘字
            fromHp = fromHp,
            toHp = toHp,
            maxHp = target.teamHero.maxHp,
            fromShieldValue = shieldValue,
            maxHp = maxHp,
            fromShieldValue = fromShieldValue,
            toShieldValue = toShieldValue,
            battleDrops = battleDrops,
            hurt = hurt,
@@ -639,10 +627,7 @@
            skillConfig = skillConfig
        };
        // ============ 第四步:执行表现(飘字、动画等) ============
        target.Hurt(hurtParam);
    }
    // 处理HP刷新包(简化逻辑)
Main/System/Battle/UIComp/BattleHeroInfoBar.cs
@@ -87,11 +87,16 @@
        UpdateXP(battleObject.teamHero.rage, battleObject.teamHero.rage, 100, false);
        long shieldValue = battleObject.buffMgr.GetShieldValue();
        long curHp = battleObject.teamHero.curHp;
        long maxHp = battleObject.teamHero.maxHp;
        //  第一条护盾的值最大值是当前的MaxHp 第二条护盾的最大值其实也是MaxHp 多余的不做显示
        sliderShield1.value = maxHp > 0 ? Mathf.Min((float)shieldValue, (float)maxHp) / (float)maxHp : 0;
        sliderShield2.value = maxHp > 0 ? Mathf.Max((float)(shieldValue - maxHp), 0f) / (float)maxHp : 0;
        // 护盾1的值 = min(当前血量 + 护盾值, maxHp) / maxHp
        float shield1Value = maxHp > 0 ? Mathf.Min((float)(curHp + shieldValue), (float)maxHp) / (float)maxHp : 0;
        // 护盾2的值 = max(当前血量 + 护盾值 - maxHp, 0) / maxHp
        float shield2Value = maxHp > 0 ? Mathf.Max((float)(curHp + shieldValue - maxHp), 0f) / (float)maxHp : 0;
        sliderShield1.value = shield1Value;
        sliderShield2.value = shield2Value;
    }
    
    public void SetActive(bool active)
@@ -117,12 +122,18 @@
            }
        }
        //  check shield buff
        // check shield buff
        long shieldValue = battleObject.buffMgr.GetShieldValue();
        long curHp = battleObject.teamHero.curHp;
        long maxHp = battleObject.teamHero.maxHp;
        //  第一条护盾的值最大值是当前的MaxHp 第二条护盾的最大值其实也是MaxHp 多余的不做显示
        sliderShield1.value = maxHp > 0 ? Mathf.Min((float)shieldValue, (float)maxHp) / (float)maxHp : 0;
        sliderShield2.value = maxHp > 0 ? Mathf.Max((float)(shieldValue - maxHp), 0f) / (float)maxHp : 0;
        // 护盾1的值 = min(当前血量 + 护盾值, maxHp) / maxHp
        float shield1Value = maxHp > 0 ? Mathf.Min((float)(curHp + shieldValue), (float)maxHp) / (float)maxHp : 0;
        // 护盾2的值 = max(当前血量 + 护盾值 - maxHp, 0) / maxHp
        float shield2Value = maxHp > 0 ? Mathf.Max((float)(curHp + shieldValue - maxHp), 0f) / (float)maxHp : 0;
        sliderShield1.value = shield1Value;
        sliderShield2.value = shield2Value;
    }
    
    /// <summary>
@@ -251,8 +262,6 @@
        KillTween(ref damageSequence);
        long maxHp = dmgInfo.battleHurtParam.maxHp;
        long fromShield = dmgInfo.battleHurtParam.fromShieldValue;
        long toShield = dmgInfo.battleHurtParam.toShieldValue;
        if (maxHp <= 0)
        {
@@ -261,33 +270,66 @@
            return;
        }
        //  第一条护盾的值最大值是当前的MaxHp 第二条护盾的最大值其实也是MaxHp 多余的不做显示
        float fromValue1 = (float)dmgInfo.battleHurtParam.phase1FromShieldValue / (float)maxHp;
        float targetValue1 = (float)dmgInfo.battleHurtParam.phase1ToShieldValue / (float)maxHp;
        float fromValue2 = (float)dmgInfo.battleHurtParam.phase2FromShieldValue / (float)maxHp;
        float targetValue2 = (float)dmgInfo.battleHurtParam.phase2ToShieldValue / (float)maxHp;
        long fromHp = dmgInfo.battleHurtParam.fromHp;
        long toHp = dmgInfo.battleHurtParam.toHp;
        long fromShield = dmgInfo.battleHurtParam.fromShieldValue;
        long toShield = dmgInfo.battleHurtParam.toShieldValue;
        damageSequence = DOTween.Sequence();
        sliderShield2.value = fromValue2;
        if (fromValue2 > 0  && fromValue2 != targetValue2)
        // 设置初始值
        if (fromShield > 0)
        {
            damageSequence.Append(sliderShield2.DOValue(targetValue2, 0.2f));
            // 护盾1的值 = min(当前血量 + 当前护盾值, maxHp) / maxHp
            float fromShield1Value = Mathf.Min((float)(fromHp + fromShield), (float)maxHp) / (float)maxHp;
            // 护盾2的值 = max(当前血量 + 当前护盾值 - maxHp, 0) / maxHp
            float fromShield2Value = Mathf.Max((float)(fromHp + fromShield - maxHp), 0f) / (float)maxHp;
            sliderShield1.value = fromShield1Value;
            sliderShield2.value = fromShield2Value;
            // 如果护盾2有值,先播放护盾2的动画
            if (fromShield2Value > 0)
            {
                // 计算护盾2的初始值和目标值
                long beginShield2Value = fromHp + fromShield - maxHp;
                long endShield2Value = Mathf.Max(0, (int)(toHp + toShield - maxHp));
                float toShield2Value = (float)endShield2Value / (float)maxHp;
                if (Mathf.Abs(fromShield2Value - toShield2Value) > 0.001f)
                {
                    damageSequence.Append(sliderShield2.DOValue(toShield2Value, 0.2f));
                }
            }
            // 播放护盾1的动画
            if (fromShield1Value > 0)
            {
                // 计算护盾1的目标值
                float toShield1Value = Mathf.Min((float)(toHp + toShield), (float)maxHp) / (float)maxHp;
                if (Mathf.Abs(fromShield1Value - toShield1Value) > 0.001f)
                {
                    damageSequence.Append(sliderShield1.DOValue(toShield1Value, 0.2f));
                }
            }
        }
        else
        {
            // 没有护盾,直接设置为0
            sliderShield1.value = 0f;
            sliderShield2.value = 0f;
        }
        sliderShield1.value = fromValue1;
        if (fromValue1 > 0 && fromValue1 != targetValue1)
        {
            damageSequence.Append(sliderShield1.DOValue(targetValue1, 0.2f));
        }
        // 血量动画
        float fromHpValue = (float)fromHp / (float)maxHp;
        float toHpValue = (float)toHp / (float)maxHp;
        sliderHp.value = fromHpValue;
        if (dmgInfo.battleHurtParam.fromHp != dmgInfo.battleHurtParam.toHp)
        if (Mathf.Abs(fromHpValue - toHpValue) > 0.001f)
        {
            float fromHpValue = (float)dmgInfo.battleHurtParam.fromHp / (float)maxHp;
            float toHpValue = (float)dmgInfo.battleHurtParam.toHp / (float)maxHp;
            sliderHp.value = fromHpValue;
            damageSequence.Append(sliderHp.DOValue(toHpValue, 0.2f));
        }