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<long> 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<BattleDmg> targetDamageList = new List<BattleDmg>();
|
public List<BattleDmg> casterDamageList = new List<BattleDmg>();
|
|
#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);
|
}
|
}
|
|
/// <summary>
|
/// 计算最大伤害段数
|
/// </summary>
|
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;
|
}
|
|
/// <summary>
|
/// 处理反伤伤害
|
/// </summary>
|
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
|
});
|
}
|
}
|
|
/// <summary>
|
/// 处理吸血伤害
|
/// </summary>
|
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
|
});
|
}
|
}
|
|
/// <summary>
|
/// 处理主要伤害
|
/// </summary>
|
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);
|
}
|
}
|
|
/// <summary>
|
/// 处理被格挡的伤害
|
/// </summary>
|
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);
|
}
|
}
|
|
/// <summary>
|
/// 处理正常伤害(未被格挡)
|
/// </summary>
|
private void ProcessNormalDamage(long actualDamage, int rawAttackType)
|
{
|
if (IsRealdamage())
|
{
|
AddRealdamageToList(actualDamage);
|
}
|
else
|
{
|
AddNormalDamageToList(actualDamage, rawAttackType);
|
}
|
}
|
|
/// <summary>
|
/// 添加真实伤害到列表
|
/// </summary>
|
private void AddRealdamageToList(long damage)
|
{
|
int showAttackType = (int)DamageType.Realdamage + (IsCrit() ? (int)DamageType.Crit : 0);
|
targetDamageList.Add(new BattleDmg { damage = damage, attackType = showAttackType });
|
}
|
|
/// <summary>
|
/// 添加普通伤害/治疗到列表
|
/// </summary>
|
private void AddNormalDamageToList(long damage, int attackType)
|
{
|
attackType = ValidateAndFixAttackType(attackType);
|
targetDamageList.Add(new BattleDmg { damage = damage, attackType = attackType });
|
}
|
|
/// <summary>
|
/// 验证并修复攻击类型
|
/// </summary>
|
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<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;
|
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
|
}
|