Core/Units: Pass real damage taken after level scaling calculations to DamageDone and DamageTaken script hooks

Port From (https://github.com/TrinityCore/TrinityCore/commit/9f088c2e04cba1f1870c6d9da1b16e9593430c54)
This commit is contained in:
hondacrx
2023-02-19 02:10:23 -05:00
parent da3ec7e367
commit a831dff55d
+49 -35
View File
@@ -2410,16 +2410,33 @@ namespace Game.Entities
public static uint DealDamage(Unit attacker, Unit victim, uint damage, CleanDamage cleanDamage = null, DamageEffectType damagetype = DamageEffectType.Direct, SpellSchoolMask damageSchoolMask = SpellSchoolMask.Normal, SpellInfo spellProto = null, bool durabilityLoss = true) public static uint DealDamage(Unit attacker, Unit victim, uint damage, CleanDamage cleanDamage = null, DamageEffectType damagetype = DamageEffectType.Direct, SpellSchoolMask damageSchoolMask = SpellSchoolMask.Normal, SpellInfo spellProto = null, bool durabilityLoss = true)
{ {
UnitAI victimAI = victim.GetAI(); uint damageDone = damage;
if (victimAI != null) uint damageTaken = damage;
victimAI.DamageTaken(attacker, ref damage, damagetype, spellProto); if (attacker != null)
damageTaken = (uint)(damage / victim.GetHealthMultiplierForTarget(attacker));
UnitAI attackerAI = attacker ? attacker.GetAI() : null; // call script hooks
if (attackerAI != null) {
attackerAI.DamageDealt(victim, ref damage, damagetype); uint tmpDamage = damageTaken;
// Hook for OnDamage Event victim.GetAI()?.DamageTaken(attacker, ref tmpDamage, damagetype, spellProto);
Global.ScriptMgr.OnDamage(attacker, victim, ref damage);
attacker?.GetAI()?.DamageDealt(victim, ref tmpDamage, damagetype);
// Hook for OnDamage Event
Global.ScriptMgr.OnDamage(attacker, victim, ref tmpDamage);
// if any script modified damage, we need to also apply the same modification to unscaled damage value
if (tmpDamage != damageTaken)
{
if (attacker)
damageDone = (uint)(tmpDamage * victim.GetHealthMultiplierForTarget(attacker));
else
damageDone = tmpDamage;
damageTaken = tmpDamage;
}
}
// Signal to pets that their owner was attacked - except when DOT. // Signal to pets that their owner was attacked - except when DOT.
if (attacker != victim && damagetype != DamageEffectType.DOT) if (attacker != victim && damagetype != DamageEffectType.DOT)
@@ -2451,7 +2468,7 @@ namespace Game.Entities
else else
victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Damage); victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Damage);
if (damage == 0 && damagetype != DamageEffectType.DOT && cleanDamage != null && cleanDamage.absorbed_damage != 0) if (damageTaken == 0 && damagetype != DamageEffectType.DOT && cleanDamage != null && cleanDamage.absorbed_damage != 0)
{ {
if (victim != attacker && victim.IsPlayer()) if (victim != attacker && victim.IsPlayer())
{ {
@@ -2482,7 +2499,7 @@ namespace Game.Entities
SpellInfo spell = aura.GetSpellInfo(); SpellInfo spell = aura.GetSpellInfo();
uint share = MathFunctions.CalculatePct(damage, aura.GetAmount()); uint share = MathFunctions.CalculatePct(damageDone, aura.GetAmount());
// @todo check packets if damage is done by victim, or by attacker of victim // @todo check packets if damage is done by victim, or by attacker of victim
DealDamageMods(attacker, shareDamageTarget, ref share); DealDamageMods(attacker, shareDamageTarget, ref share);
@@ -2500,7 +2517,7 @@ namespace Game.Entities
attacker.RewardRage(rage); attacker.RewardRage(rage);
} }
if (damage == 0) if (damageDone == 0)
return 0; return 0;
uint health = (uint)victim.GetHealth(); uint health = (uint)victim.GetHealth();
@@ -2508,18 +2525,18 @@ namespace Game.Entities
// duel ends when player has 1 or less hp // duel ends when player has 1 or less hp
bool duel_hasEnded = false; bool duel_hasEnded = false;
bool duel_wasMounted = false; bool duel_wasMounted = false;
if (victim.IsPlayer() && victim.ToPlayer().duel != null && damage >= (health - 1)) if (victim.IsPlayer() && victim.ToPlayer().duel != null && damageTaken >= (health - 1))
{ {
if (!attacker) if (!attacker)
return 0; return 0;
// prevent kill only if killed in duel and killed by opponent or opponent controlled creature // prevent kill only if killed in duel and killed by opponent or opponent controlled creature
if (victim.ToPlayer().duel.Opponent == attacker.GetControllingPlayer()) if (victim.ToPlayer().duel.Opponent == attacker.GetControllingPlayer())
damage = health - 1; damageTaken = health - 1;
duel_hasEnded = true; duel_hasEnded = true;
} }
else if (victim.IsVehicle() && damage >= (health - 1) && victim.GetCharmer() != null && victim.GetCharmer().IsTypeId(TypeId.Player)) else if (victim.IsVehicle() && damageTaken >= (health - 1) && victim.GetCharmer() != null && victim.GetCharmer().IsTypeId(TypeId.Player))
{ {
Player victimRider = victim.GetCharmer().ToPlayer(); Player victimRider = victim.GetCharmer().ToPlayer();
if (victimRider != null && victimRider.duel != null && victimRider.duel.IsMounted) if (victimRider != null && victimRider.duel != null && victimRider.duel.IsMounted)
@@ -2529,7 +2546,7 @@ namespace Game.Entities
// prevent kill only if killed in duel and killed by opponent or opponent controlled creature // prevent kill only if killed in duel and killed by opponent or opponent controlled creature
if (victimRider.duel.Opponent == attacker.GetControllingPlayer()) if (victimRider.duel.Opponent == attacker.GetControllingPlayer())
damage = health - 1; damageTaken = health - 1;
duel_wasMounted = true; duel_wasMounted = true;
duel_hasEnded = true; duel_hasEnded = true;
@@ -2546,32 +2563,29 @@ namespace Game.Entities
{ {
Battleground bg = killer.GetBattleground(); Battleground bg = killer.GetBattleground();
if (bg != null) if (bg != null)
bg.UpdatePlayerScore(killer, ScoreType.DamageDone, damage); bg.UpdatePlayerScore(killer, ScoreType.DamageDone, damageDone);
} }
killer.UpdateCriteria(CriteriaType.DamageDealt, health > damage ? damage : health, 0, 0, victim); killer.UpdateCriteria(CriteriaType.DamageDealt, health > damageDone ? damageDone : health, 0, 0, victim);
killer.UpdateCriteria(CriteriaType.HighestDamageDone, damage); killer.UpdateCriteria(CriteriaType.HighestDamageDone, damageDone);
} }
} }
if (victim.IsPlayer()) if (victim.IsPlayer())
victim.ToPlayer().UpdateCriteria(CriteriaType.HighestDamageTaken, damage); victim.ToPlayer().UpdateCriteria(CriteriaType.HighestDamageTaken, damageTaken);
if (attacker != null)
damage = (uint)(damage / victim.GetHealthMultiplierForTarget(attacker));
if (victim.GetTypeId() != TypeId.Player && (!victim.IsControlledByPlayer() || victim.IsVehicle())) if (victim.GetTypeId() != TypeId.Player && (!victim.IsControlledByPlayer() || victim.IsVehicle()))
{ {
victim.ToCreature().SetTappedBy(attacker); victim.ToCreature().SetTappedBy(attacker);
if (attacker == null || attacker.IsControlledByPlayer()) if (attacker == null || attacker.IsControlledByPlayer())
victim.ToCreature().LowerPlayerDamageReq(health < damage ? health : damage); victim.ToCreature().LowerPlayerDamageReq(health < damageTaken ? health : damageTaken);
} }
bool killed = false; bool killed = false;
bool skipSettingDeathState = false; bool skipSettingDeathState = false;
if (health <= damage) if (health <= damageTaken)
{ {
killed = true; killed = true;
@@ -2581,7 +2595,7 @@ namespace Game.Entities
if (damagetype != DamageEffectType.NoDamage && damagetype != DamageEffectType.Self && victim.HasAuraType(AuraType.SchoolAbsorbOverkill)) if (damagetype != DamageEffectType.NoDamage && damagetype != DamageEffectType.Self && victim.HasAuraType(AuraType.SchoolAbsorbOverkill))
{ {
var vAbsorbOverkill = victim.GetAuraEffectsByType(AuraType.SchoolAbsorbOverkill); var vAbsorbOverkill = victim.GetAuraEffectsByType(AuraType.SchoolAbsorbOverkill);
DamageInfo damageInfo = new(attacker, victim, damage, spellProto, damageSchoolMask, damagetype, cleanDamage != null ? cleanDamage.attackType : WeaponAttackType.BaseAttack); DamageInfo damageInfo = new(attacker, victim, damageTaken, spellProto, damageSchoolMask, damagetype, cleanDamage != null ? cleanDamage.attackType : WeaponAttackType.BaseAttack);
foreach (var absorbAurEff in vAbsorbOverkill) foreach (var absorbAurEff in vAbsorbOverkill)
{ {
@@ -2594,7 +2608,7 @@ namespace Game.Entities
continue; continue;
// cannot absorb over limit // cannot absorb over limit
if (damage >= victim.CountPctFromMaxHealth(100 + absorbAurEff.GetMiscValueB())) if (damageTaken >= victim.CountPctFromMaxHealth(100 + absorbAurEff.GetMiscValueB()))
continue; continue;
// get amount which can be still absorbed by the aura // get amount which can be still absorbed by the aura
@@ -2636,7 +2650,7 @@ namespace Game.Entities
} }
} }
damage = damageInfo.GetDamage(); damageTaken = damageInfo.GetDamage();
} }
} }
@@ -2648,9 +2662,9 @@ namespace Game.Entities
else else
{ {
if (victim.IsTypeId(TypeId.Player)) if (victim.IsTypeId(TypeId.Player))
victim.ToPlayer().UpdateCriteria(CriteriaType.TotalDamageTaken, damage); victim.ToPlayer().UpdateCriteria(CriteriaType.TotalDamageTaken, damageTaken);
victim.ModifyHealth(-(int)damage); victim.ModifyHealth(-(int)damageTaken);
if (damagetype == DamageEffectType.Direct || damagetype == DamageEffectType.SpellDirect) if (damagetype == DamageEffectType.Direct || damagetype == DamageEffectType.SpellDirect)
victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NonPeriodicDamage, spellProto); victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NonPeriodicDamage, spellProto);
@@ -2658,11 +2672,11 @@ namespace Game.Entities
if (!victim.IsTypeId(TypeId.Player)) if (!victim.IsTypeId(TypeId.Player))
{ {
// Part of Evade mechanics. DoT's and Thorns / Retribution Aura do not contribute to this // Part of Evade mechanics. DoT's and Thorns / Retribution Aura do not contribute to this
if (damagetype != DamageEffectType.DOT && damage > 0 && !victim.GetOwnerGUID().IsPlayer() && (spellProto == null || !spellProto.HasAura(AuraType.DamageShield))) if (damagetype != DamageEffectType.DOT && damageTaken > 0 && !victim.GetOwnerGUID().IsPlayer() && (spellProto == null || !spellProto.HasAura(AuraType.DamageShield)))
victim.ToCreature().SetLastDamagedTime(GameTime.GetGameTime() + SharedConst.MaxAggroResetTime); victim.ToCreature().SetLastDamagedTime(GameTime.GetGameTime() + SharedConst.MaxAggroResetTime);
if (attacker != null && (spellProto == null || !spellProto.HasAttribute(SpellAttr4.NoHarmfulThreat))) if (attacker != null && (spellProto == null || !spellProto.HasAttribute(SpellAttr4.NoHarmfulThreat)))
victim.GetThreatManager().AddThreat(attacker, damage, spellProto); victim.GetThreatManager().AddThreat(attacker, damageTaken, spellProto);
} }
else // victim is a player else // victim is a player
{ {
@@ -2695,7 +2709,7 @@ namespace Game.Entities
{ {
bool isCastInterrupted() bool isCastInterrupted()
{ {
if (damage == 0) if (damageTaken == 0)
return spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.ZeroDamageCancels); return spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.ZeroDamageCancels);
if (victim.IsPlayer() && spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.DamageCancelsPlayerOnly)) if (victim.IsPlayer() && spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.DamageCancelsPlayerOnly))
@@ -2709,7 +2723,7 @@ namespace Game.Entities
bool isCastDelayed() bool isCastDelayed()
{ {
if (damage == 0) if (damageTaken == 0)
return false; return false;
if (victim.IsPlayer() && spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.DamagePushbackPlayerOnly)) if (victim.IsPlayer() && spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.DamagePushbackPlayerOnly))
@@ -2729,7 +2743,7 @@ namespace Game.Entities
} }
} }
if (damage != 0 && victim.IsPlayer()) if (damageTaken != 0 && victim.IsPlayer())
{ {
Spell spell1 = victim.GetCurrentSpell(CurrentSpellTypes.Channeled); Spell spell1 = victim.GetCurrentSpell(CurrentSpellTypes.Channeled);
if (spell1 != null) if (spell1 != null)
@@ -2762,7 +2776,7 @@ namespace Game.Entities
if (victim.GetStandState() != 0 && victim.IsPlayer()) if (victim.GetStandState() != 0 && victim.IsPlayer())
victim.SetStandState(UnitStandStateType.Stand); victim.SetStandState(UnitStandStateType.Stand);
return damage; return damageTaken;
} }
void DealMeleeDamage(CalcDamageInfo damageInfo, bool durabilityLoss) void DealMeleeDamage(CalcDamageInfo damageInfo, bool durabilityLoss)