| Main/Config/PartialConfigs/SkillConfig.Partial.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/System/Battle/BattleUtility.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/System/Battle/Define/BattleDmgInfo.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/System/Battle/Skill/SkillBase.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/System/Battle/UIComp/BattleHeroInfoBar.cs | ●●●●● 补丁 | 查看 | 原始文档 | 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)); }