using System.Collections.Generic; using UnityEngine; public class BattleDmg { public long damage; public int attackType; public bool IsType(DamageType damageType) { return (attackType & (int)damageType) == (int)damageType; } } public class BattleDmgInfo { public string battleFieldGuid { get; private set; } public BattleHurtParam battleHurtParam { get; private set; } public List damageList { get { return battleHurtParam.damageList; } } public BattleObject hurtObj { get { return battleHurtParam.hurtObj; } } public BattleObject casterObj { get { return battleHurtParam.casterObj; } } public HB427_tagSCUseSkill.tagSCUseSkillHurt hurt { get { return battleHurtParam.hurt; } } public SkillConfig skillConfig { get { return battleHurtParam.skillConfig; } } public bool isBlocked = false; public bool isLastHit = false; public List targetDamageList = new List(); public List casterDamageList = new List(); #region Initialization public BattleDmgInfo(string battleFieldGuid, BattleHurtParam battleHurtParam) { this.battleFieldGuid = battleFieldGuid; this.battleHurtParam = battleHurtParam; this.isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillConfig.DamageDivide.Length - 1; HandleDamageType(); HandleAttackTypeAndDamage(); } #endregion #region Damage Type Processing private void HandleDamageType() { if (hurt == null) return; int attackTypes = 0; foreach (ServerDamageType serverDamageType in System.Enum.GetValues(typeof(ServerDamageType))) { int nsdt = (int)serverDamageType; if ((hurt.AttackTypes & nsdt) == nsdt) { attackTypes += nsdt; } } hurt.AttackTypes = (uint)attackTypes; } #endregion #region Damage List Generation private void HandleAttackTypeAndDamage() { isBlocked = HaveBlockDamage(); int rawAttackType = hurt == null ? 0 : (int)hurt.AttackTypes; int maxCount = CalculateMaxDamageSegmentCount(); for (int i = 0; i < maxCount; i++) { ProcessReflectDamage(i); ProcessSuckHpDamage(i); ProcessMainDamage(i, rawAttackType); } } /// /// 计算最大伤害段数 /// private int CalculateMaxDamageSegmentCount() { int maxCount = damageList != null ? damageList.Count : 0; maxCount = Mathf.Max(maxCount, battleHurtParam.suckHpList != null ? battleHurtParam.suckHpList.Count : 0); maxCount = Mathf.Max(maxCount, battleHurtParam.reflectHpList != null ? battleHurtParam.reflectHpList.Count : 0); return maxCount; } /// /// 处理反伤伤害 /// private void ProcessReflectDamage(int segmentIndex) { if (battleHurtParam.reflectHpList == null || segmentIndex >= battleHurtParam.reflectHpList.Count) return; long reflectHp = battleHurtParam.reflectHpList[segmentIndex]; if (reflectHp > 0) { casterDamageList.Add(new BattleDmg { damage = reflectHp, attackType = (int)DamageType.Reflect }); } } /// /// 处理吸血伤害 /// private void ProcessSuckHpDamage(int segmentIndex) { if (battleHurtParam.suckHpList == null || segmentIndex >= battleHurtParam.suckHpList.Count) return; long suckHp = battleHurtParam.suckHpList[segmentIndex]; if (suckHp > 0) { casterDamageList.Add(new BattleDmg { damage = suckHp, attackType = (int)DamageType.SuckHP }); } } /// /// 处理主要伤害 /// private void ProcessMainDamage(int segmentIndex, int rawAttackType) { if (damageList == null || segmentIndex >= damageList.Count) return; long actualDamage = damageList[segmentIndex]; if (isBlocked) { ProcessBlockedDamage(actualDamage, rawAttackType); } else { ProcessNormalDamage(actualDamage, rawAttackType); } } /// /// 处理被格挡的伤害 /// private void ProcessBlockedDamage(long actualDamage, int rawAttackType) { float blockRatio = GeneralDefine.blockRatio; int attackType = rawAttackType & (~(int)DamageType.Block); // 添加格挡伤害显示 long totalDamage = (long)(actualDamage / (1 - blockRatio)); long blockDmg = totalDamage - actualDamage; targetDamageList.Add(new BattleDmg { damage = blockDmg, attackType = (int)DamageType.Block }); // 添加实际伤害显示 if (IsRealdamage()) { AddRealdamageToList(actualDamage); } else { AddNormalDamageToList(actualDamage, attackType); } } /// /// 处理正常伤害(未被格挡) /// private void ProcessNormalDamage(long actualDamage, int rawAttackType) { if (IsRealdamage()) { AddRealdamageToList(actualDamage); } else { AddNormalDamageToList(actualDamage, rawAttackType); } } /// /// 添加真实伤害到列表 /// private void AddRealdamageToList(long damage) { int showAttackType = (int)DamageType.Realdamage + (IsCrit() ? (int)DamageType.Crit : 0); targetDamageList.Add(new BattleDmg { damage = damage, attackType = showAttackType }); } /// /// 添加普通伤害/治疗到列表 /// private void AddNormalDamageToList(long damage, int attackType) { attackType = ValidateAndFixAttackType(attackType); targetDamageList.Add(new BattleDmg { damage = damage, attackType = attackType }); } /// /// 验证并修复攻击类型 /// private int ValidateAndFixAttackType(int attackType) { if (DamageNumConfig.Get(attackType) != null) return attackType; UnityEngine.Debug.LogError($"服务器给的伤害类型不对,强制转换为普通伤害/治疗, attackType: {attackType}"); if ((attackType & (int)DamageType.Damage) != 0) return (int)DamageType.Damage; if ((attackType & (int)DamageType.Recovery) != 0) return (int)DamageType.Recovery; UnityEngine.Debug.LogError($"强制转换失败,该类型不是治疗也不是伤害 {attackType}"); return attackType; } #endregion #region Type Checking public bool IsType(DamageType damageType) { return hurt != null && (hurt.AttackTypes & (int)damageType) == (int)damageType; } public bool IsCrit() { return IsType(DamageType.Crit); } public bool HaveBlockDamage() { return IsType(DamageType.Block); } public bool IsRealdamage() { return skillConfig.HurtType / 10 == 1; } public bool IsDamage() { return IsType(DamageType.Damage) || IsRealdamage() || IsType((DamageType)11) || IsType((DamageType)12); } #endregion } public class BattleHurtParam { public BattleObject casterObj; public BattleObject hurtObj; public List damageList; public List suckHpList; public List reflectHpList; public long fromShieldValue; public long toShieldValue; public long fromHp; public long toHp; public BattleDrops battleDrops; public HB427_tagSCUseSkill.tagSCUseSkillHurt hurt; public int hitIndex; public HB422_tagMCTurnFightObjDead deadPack; public SkillConfig skillConfig; public long maxHp; #region Shield Value Calculations public long MaxSheildValue { get { return hurtObj == null ? 0 : hurtObj.teamHero.maxHp; } } 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 }