Core/Entities: Port some refactors
Port From (https://github.com/TrinityCore/TrinityCore/commit/431a326e6974d3c86452192767368ab6c4ea9b0b)
This commit is contained in:
@@ -3130,7 +3130,7 @@ namespace Game.Entities
|
||||
return (T)i_AI;
|
||||
}
|
||||
|
||||
public override SpellSchoolMask GetMeleeDamageSchoolMask() { return m_meleeDamageSchoolMask; }
|
||||
public override SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = WeaponAttackType.BaseAttack) { return m_meleeDamageSchoolMask; }
|
||||
public void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = (SpellSchoolMask)(1 << (int)school); }
|
||||
|
||||
public sbyte GetOriginalEquipmentId() { return m_originalEquipmentId; }
|
||||
|
||||
@@ -1739,6 +1739,15 @@ namespace Game.Entities
|
||||
|
||||
public Dictionary<uint, PlayerSpell> GetSpellMap() { return m_spells; }
|
||||
|
||||
public override SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = WeaponAttackType.BaseAttack)
|
||||
{
|
||||
Item weapon = GetWeaponForAttack(attackType, true);
|
||||
if (weapon != null)
|
||||
return (SpellSchoolMask)(1 << (int)weapon.GetTemplate().GetDamageType());
|
||||
|
||||
return SpellSchoolMask.Normal;
|
||||
}
|
||||
|
||||
void CastAllObtainSpells()
|
||||
{
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
|
||||
@@ -556,17 +556,17 @@ namespace Game.Entities
|
||||
if (meleeAttackAuraEffect == null)
|
||||
{
|
||||
CalcDamageInfo damageInfo;
|
||||
CalculateMeleeDamage(victim, 0, out damageInfo, attType);
|
||||
CalculateMeleeDamage(victim, out damageInfo, attType);
|
||||
// Send log damage message to client
|
||||
DealDamageMods(damageInfo.attacker, victim, ref damageInfo.damage, ref damageInfo.absorb);
|
||||
DealDamageMods(damageInfo.Attacker, victim, ref damageInfo.Damage, ref damageInfo.Absorb);
|
||||
SendAttackStateUpdate(damageInfo);
|
||||
|
||||
DealMeleeDamage(damageInfo, true);
|
||||
|
||||
DamageInfo dmgInfo = new(damageInfo);
|
||||
ProcSkillsAndAuras(damageInfo.attacker, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, ProcFlagsSpellType.None, ProcFlagsSpellPhase.None, dmgInfo.GetHitMask(), null, dmgInfo, null);
|
||||
ProcSkillsAndAuras(damageInfo.Attacker, damageInfo.Target, damageInfo.ProcAttacker, damageInfo.ProcVictim, ProcFlagsSpellType.None, ProcFlagsSpellPhase.None, dmgInfo.GetHitMask(), null, dmgInfo, null);
|
||||
Log.outDebug(LogFilter.Unit, "AttackerStateUpdate: {0} attacked {1} for {2} dmg, absorbed {3}, blocked {4}, resisted {5}.",
|
||||
GetGUID().ToString(), victim.GetGUID().ToString(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist);
|
||||
GetGUID().ToString(), victim.GetGUID().ToString(), damageInfo.Damage, damageInfo.Absorb, damageInfo.Blocked, damageInfo.Resist);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -604,25 +604,27 @@ namespace Game.Entities
|
||||
SetFacingToObject(victim, false); // update client side facing to face the target (prevents visual glitches when casting untargeted spells)
|
||||
|
||||
CalcDamageInfo damageInfo = new();
|
||||
damageInfo.attacker = this;
|
||||
damageInfo.target = victim;
|
||||
damageInfo.damageSchoolMask = (uint)GetMeleeDamageSchoolMask();
|
||||
damageInfo.attackType = attType;
|
||||
damageInfo.damage = 0;
|
||||
damageInfo.originalDamage = 0;
|
||||
damageInfo.cleanDamage = 0;
|
||||
damageInfo.absorb = 0;
|
||||
damageInfo.resist = 0;
|
||||
damageInfo.blocked_amount = 0;
|
||||
damageInfo.Attacker = this;
|
||||
damageInfo.Target = victim;
|
||||
|
||||
damageInfo.DamageSchoolMask = (uint)GetMeleeDamageSchoolMask();
|
||||
damageInfo.OriginalDamage = 0;
|
||||
damageInfo.Damage = 0;
|
||||
damageInfo.Absorb = 0;
|
||||
damageInfo.Resist = 0;
|
||||
|
||||
damageInfo.AttackType = attType;
|
||||
damageInfo.CleanDamage = 0;
|
||||
damageInfo.Blocked = 0;
|
||||
|
||||
damageInfo.TargetState = VictimState.Hit;
|
||||
damageInfo.HitInfo = HitInfo.AffectsVictim | HitInfo.NormalSwing | HitInfo.FakeDamage;
|
||||
if (attType == WeaponAttackType.OffAttack)
|
||||
damageInfo.HitInfo |= HitInfo.OffHand;
|
||||
|
||||
damageInfo.procAttacker = ProcFlags.None;
|
||||
damageInfo.procVictim = ProcFlags.None;
|
||||
damageInfo.hitOutCome = MeleeHitOutcome.Normal;
|
||||
damageInfo.ProcAttacker = ProcFlags.None;
|
||||
damageInfo.ProcVictim = ProcFlags.None;
|
||||
damageInfo.HitOutCome = MeleeHitOutcome.Normal;
|
||||
|
||||
SendAttackStateUpdate(damageInfo);
|
||||
}
|
||||
@@ -693,15 +695,15 @@ namespace Game.Entities
|
||||
{
|
||||
CalcDamageInfo dmgInfo = new();
|
||||
dmgInfo.HitInfo = HitInfo;
|
||||
dmgInfo.attacker = this;
|
||||
dmgInfo.target = target;
|
||||
dmgInfo.damage = Damage - AbsorbDamage - Resist - BlockedAmount;
|
||||
dmgInfo.originalDamage = Damage;
|
||||
dmgInfo.damageSchoolMask = (uint)damageSchoolMask;
|
||||
dmgInfo.absorb = AbsorbDamage;
|
||||
dmgInfo.resist = Resist;
|
||||
dmgInfo.Attacker = this;
|
||||
dmgInfo.Target = target;
|
||||
dmgInfo.Damage = Damage - AbsorbDamage - Resist - BlockedAmount;
|
||||
dmgInfo.OriginalDamage = Damage;
|
||||
dmgInfo.DamageSchoolMask = (uint)damageSchoolMask;
|
||||
dmgInfo.Absorb = AbsorbDamage;
|
||||
dmgInfo.Resist = Resist;
|
||||
dmgInfo.TargetState = TargetState;
|
||||
dmgInfo.blocked_amount = BlockedAmount;
|
||||
dmgInfo.Blocked = BlockedAmount;
|
||||
SendAttackStateUpdate(dmgInfo);
|
||||
}
|
||||
|
||||
@@ -709,27 +711,27 @@ namespace Game.Entities
|
||||
{
|
||||
AttackerStateUpdate packet = new();
|
||||
packet.hitInfo = damageInfo.HitInfo;
|
||||
packet.AttackerGUID = damageInfo.attacker.GetGUID();
|
||||
packet.VictimGUID = damageInfo.target.GetGUID();
|
||||
packet.Damage = (int)damageInfo.damage;
|
||||
packet.OriginalDamage = (int)damageInfo.originalDamage;
|
||||
int overkill = (int)(damageInfo.damage - damageInfo.target.GetHealth());
|
||||
packet.AttackerGUID = damageInfo.Attacker.GetGUID();
|
||||
packet.VictimGUID = damageInfo.Target.GetGUID();
|
||||
packet.Damage = (int)damageInfo.Damage;
|
||||
packet.OriginalDamage = (int)damageInfo.OriginalDamage;
|
||||
int overkill = (int)(damageInfo.Damage - damageInfo.Target.GetHealth());
|
||||
packet.OverDamage = (overkill < 0 ? -1 : overkill);
|
||||
|
||||
SubDamage subDmg = new();
|
||||
subDmg.SchoolMask = (int)damageInfo.damageSchoolMask; // School of sub damage
|
||||
subDmg.FDamage = damageInfo.damage; // sub damage
|
||||
subDmg.Damage = (int)damageInfo.damage; // Sub Damage
|
||||
subDmg.Absorbed = (int)damageInfo.absorb;
|
||||
subDmg.Resisted = (int)damageInfo.resist;
|
||||
subDmg.SchoolMask = (int)damageInfo.DamageSchoolMask; // School of sub damage
|
||||
subDmg.FDamage = damageInfo.Damage; // sub damage
|
||||
subDmg.Damage = (int)damageInfo.Damage; // Sub Damage
|
||||
subDmg.Absorbed = (int)damageInfo.Absorb;
|
||||
subDmg.Resisted = (int)damageInfo.Resist;
|
||||
packet.SubDmg.Set(subDmg);
|
||||
|
||||
packet.VictimState = (byte)damageInfo.TargetState;
|
||||
packet.BlockAmount = (int)damageInfo.blocked_amount;
|
||||
packet.LogData.Initialize(damageInfo.attacker);
|
||||
packet.BlockAmount = (int)damageInfo.Blocked;
|
||||
packet.LogData.Initialize(damageInfo.Attacker);
|
||||
|
||||
ContentTuningParams contentTuningParams = new();
|
||||
if (contentTuningParams.GenerateDataForUnits(damageInfo.attacker, damageInfo.target))
|
||||
if (contentTuningParams.GenerateDataForUnits(damageInfo.Attacker, damageInfo.Target))
|
||||
packet.ContentTuning = contentTuningParams;
|
||||
|
||||
SendCombatLogMessage(packet);
|
||||
@@ -1086,26 +1088,28 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// TODO for melee need create structure as in
|
||||
void CalculateMeleeDamage(Unit victim, uint damage, out CalcDamageInfo damageInfo, WeaponAttackType attackType)
|
||||
void CalculateMeleeDamage(Unit victim, out CalcDamageInfo damageInfo, WeaponAttackType attackType)
|
||||
{
|
||||
damageInfo = new CalcDamageInfo();
|
||||
|
||||
damageInfo.attacker = this;
|
||||
damageInfo.target = victim;
|
||||
damageInfo.damageSchoolMask = (uint)SpellSchoolMask.Normal;
|
||||
damageInfo.attackType = attackType;
|
||||
damageInfo.damage = 0;
|
||||
damageInfo.originalDamage = 0;
|
||||
damageInfo.cleanDamage = 0;
|
||||
damageInfo.absorb = 0;
|
||||
damageInfo.resist = 0;
|
||||
damageInfo.blocked_amount = 0;
|
||||
damageInfo.Attacker = this;
|
||||
damageInfo.Target = victim;
|
||||
|
||||
damageInfo.TargetState = 0;
|
||||
damageInfo.DamageSchoolMask = (uint)SpellSchoolMask.Normal;
|
||||
damageInfo.Damage = 0;
|
||||
damageInfo.OriginalDamage = 0;
|
||||
damageInfo.Absorb = 0;
|
||||
damageInfo.Resist = 0;
|
||||
|
||||
damageInfo.Blocked = 0;
|
||||
damageInfo.HitInfo = 0;
|
||||
damageInfo.procAttacker = ProcFlags.None;
|
||||
damageInfo.procVictim = ProcFlags.None;
|
||||
damageInfo.hitOutCome = MeleeHitOutcome.Evade;
|
||||
damageInfo.TargetState = 0;
|
||||
|
||||
damageInfo.AttackType = attackType;
|
||||
damageInfo.ProcAttacker = ProcFlags.None;
|
||||
damageInfo.ProcVictim = ProcFlags.None;
|
||||
damageInfo.CleanDamage = 0;
|
||||
damageInfo.HitOutCome = MeleeHitOutcome.Evade;
|
||||
|
||||
if (victim == null)
|
||||
return;
|
||||
@@ -1117,12 +1121,12 @@ namespace Game.Entities
|
||||
switch (attackType)
|
||||
{
|
||||
case WeaponAttackType.BaseAttack:
|
||||
damageInfo.procAttacker = ProcFlags.DoneMeleeAutoAttack | ProcFlags.DoneMainHandAttack;
|
||||
damageInfo.procVictim = ProcFlags.TakenMeleeAutoAttack;
|
||||
damageInfo.ProcAttacker = ProcFlags.DoneMeleeAutoAttack | ProcFlags.DoneMainHandAttack;
|
||||
damageInfo.ProcVictim = ProcFlags.TakenMeleeAutoAttack;
|
||||
break;
|
||||
case WeaponAttackType.OffAttack:
|
||||
damageInfo.procAttacker = ProcFlags.DoneMeleeAutoAttack | ProcFlags.DoneOffHandAttack;
|
||||
damageInfo.procVictim = ProcFlags.TakenMeleeAutoAttack;
|
||||
damageInfo.ProcAttacker = ProcFlags.DoneMeleeAutoAttack | ProcFlags.DoneOffHandAttack;
|
||||
damageInfo.ProcVictim = ProcFlags.TakenMeleeAutoAttack;
|
||||
damageInfo.HitInfo = HitInfo.OffHand;
|
||||
break;
|
||||
default:
|
||||
@@ -1130,108 +1134,116 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// Physical Immune check
|
||||
if (damageInfo.target.IsImmunedToDamage((SpellSchoolMask)damageInfo.damageSchoolMask))
|
||||
if (damageInfo.Target.IsImmunedToDamage((SpellSchoolMask)damageInfo.DamageSchoolMask))
|
||||
{
|
||||
damageInfo.HitInfo |= HitInfo.NormalSwing;
|
||||
damageInfo.TargetState = VictimState.Immune;
|
||||
|
||||
damageInfo.damage = 0;
|
||||
damageInfo.cleanDamage = 0;
|
||||
damageInfo.Damage = 0;
|
||||
damageInfo.CleanDamage = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
damage += CalculateDamage(damageInfo.attackType, false, true);
|
||||
uint damage = 0;
|
||||
damage += CalculateDamage(damageInfo.AttackType, false, true);
|
||||
// Add melee damage bonus
|
||||
damage = MeleeDamageBonusDone(damageInfo.target, damage, damageInfo.attackType, DamageEffectType.Direct);
|
||||
damage = damageInfo.target.MeleeDamageBonusTaken(this, damage, damageInfo.attackType, DamageEffectType.Direct);
|
||||
damage = MeleeDamageBonusDone(damageInfo.Target, damage, damageInfo.AttackType, DamageEffectType.Direct, null, (SpellSchoolMask)damageInfo.DamageSchoolMask);
|
||||
damage = damageInfo.Target.MeleeDamageBonusTaken(this, damage, damageInfo.AttackType, DamageEffectType.Direct, null, (SpellSchoolMask)damageInfo.DamageSchoolMask);
|
||||
|
||||
// Script Hook For CalculateMeleeDamage -- Allow scripts to change the Damage pre class mitigation calculations
|
||||
Global.ScriptMgr.ModifyMeleeDamage(damageInfo.target, damageInfo.attacker, ref damage);
|
||||
Global.ScriptMgr.ModifyMeleeDamage(damageInfo.Target, damageInfo.Attacker, ref damage);
|
||||
|
||||
// Calculate armor reduction
|
||||
if (IsDamageReducedByArmor((SpellSchoolMask)damageInfo.damageSchoolMask))
|
||||
if (IsDamageReducedByArmor((SpellSchoolMask)damageInfo.DamageSchoolMask))
|
||||
{
|
||||
damageInfo.damage = CalcArmorReducedDamage(damageInfo.attacker, damageInfo.target, damage, null, damageInfo.attackType);
|
||||
damageInfo.cleanDamage += damage - damageInfo.damage;
|
||||
damageInfo.Damage = CalcArmorReducedDamage(damageInfo.Attacker, damageInfo.Target, damage, null, damageInfo.AttackType);
|
||||
damageInfo.CleanDamage += damage - damageInfo.Damage;
|
||||
}
|
||||
else
|
||||
damageInfo.damage = damage;
|
||||
damageInfo.Damage = damage;
|
||||
|
||||
damageInfo.hitOutCome = RollMeleeOutcomeAgainst(damageInfo.target, damageInfo.attackType);
|
||||
damageInfo.HitOutCome = RollMeleeOutcomeAgainst(damageInfo.Target, damageInfo.AttackType);
|
||||
|
||||
switch (damageInfo.hitOutCome)
|
||||
switch (damageInfo.HitOutCome)
|
||||
{
|
||||
case MeleeHitOutcome.Evade:
|
||||
damageInfo.HitInfo |= HitInfo.Miss | HitInfo.SwingNoHitSound;
|
||||
damageInfo.TargetState = VictimState.Evades;
|
||||
damageInfo.originalDamage = damageInfo.damage;
|
||||
damageInfo.damage = 0;
|
||||
damageInfo.cleanDamage = 0;
|
||||
damageInfo.OriginalDamage = damageInfo.Damage;
|
||||
|
||||
damageInfo.Damage = 0;
|
||||
damageInfo.CleanDamage = 0;
|
||||
return;
|
||||
case MeleeHitOutcome.Miss:
|
||||
damageInfo.HitInfo |= HitInfo.Miss;
|
||||
damageInfo.TargetState = VictimState.Intact;
|
||||
damageInfo.originalDamage = damageInfo.damage;
|
||||
damageInfo.damage = 0;
|
||||
damageInfo.cleanDamage = 0;
|
||||
damageInfo.OriginalDamage = damageInfo.Damage;
|
||||
|
||||
damageInfo.Damage = 0;
|
||||
damageInfo.CleanDamage = 0;
|
||||
break;
|
||||
case MeleeHitOutcome.Normal:
|
||||
damageInfo.TargetState = VictimState.Hit;
|
||||
damageInfo.originalDamage = damageInfo.damage;
|
||||
damageInfo.OriginalDamage = damageInfo.Damage;
|
||||
break;
|
||||
case MeleeHitOutcome.Crit:
|
||||
damageInfo.HitInfo |= HitInfo.CriticalHit;
|
||||
damageInfo.TargetState = VictimState.Hit;
|
||||
// Crit bonus calc
|
||||
damageInfo.damage += damageInfo.damage;
|
||||
damageInfo.Damage *= 2;
|
||||
|
||||
// Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
|
||||
float mod = (GetTotalAuraMultiplierByMiscMask(AuraType.ModCritDamageBonus, damageInfo.damageSchoolMask) - 1.0f) * 100;
|
||||
float mod = (GetTotalAuraMultiplierByMiscMask(AuraType.ModCritDamageBonus, damageInfo.DamageSchoolMask) - 1.0f) * 100;
|
||||
|
||||
if (mod != 0)
|
||||
MathFunctions.AddPct(ref damageInfo.damage, mod);
|
||||
MathFunctions.AddPct(ref damageInfo.Damage, mod);
|
||||
|
||||
damageInfo.originalDamage = damageInfo.damage;
|
||||
damageInfo.OriginalDamage = damageInfo.Damage;
|
||||
break;
|
||||
case MeleeHitOutcome.Parry:
|
||||
damageInfo.TargetState = VictimState.Parry;
|
||||
damageInfo.originalDamage = damageInfo.damage;
|
||||
damageInfo.cleanDamage += damageInfo.damage;
|
||||
damageInfo.damage = 0;
|
||||
damageInfo.CleanDamage += damageInfo.Damage;
|
||||
|
||||
damageInfo.OriginalDamage = damageInfo.Damage;
|
||||
damageInfo.Damage = 0;
|
||||
break;
|
||||
case MeleeHitOutcome.Dodge:
|
||||
damageInfo.TargetState = VictimState.Dodge;
|
||||
damageInfo.originalDamage = damageInfo.damage;
|
||||
damageInfo.cleanDamage += damageInfo.damage;
|
||||
damageInfo.damage = 0;
|
||||
damageInfo.CleanDamage += damageInfo.Damage;
|
||||
|
||||
damageInfo.OriginalDamage = damageInfo.Damage;
|
||||
damageInfo.Damage = 0;
|
||||
break;
|
||||
case MeleeHitOutcome.Block:
|
||||
damageInfo.TargetState = VictimState.Hit;
|
||||
damageInfo.HitInfo |= HitInfo.Block;
|
||||
damageInfo.originalDamage = damageInfo.damage;
|
||||
// 30% damage blocked, double blocked amount if block is critical
|
||||
damageInfo.blocked_amount = MathFunctions.CalculatePct(damageInfo.damage, damageInfo.target.IsBlockCritical() ? damageInfo.target.GetBlockPercent(GetLevel()) * 2 : damageInfo.target.GetBlockPercent(GetLevel()));
|
||||
damageInfo.damage -= damageInfo.blocked_amount;
|
||||
damageInfo.cleanDamage += damageInfo.blocked_amount;
|
||||
damageInfo.Blocked = MathFunctions.CalculatePct(damageInfo.Damage, damageInfo.Target.GetBlockPercent(GetLevel()));
|
||||
if (damageInfo.Target.IsBlockCritical())
|
||||
damageInfo.Blocked *= 2;
|
||||
|
||||
damageInfo.OriginalDamage = damageInfo.Damage;
|
||||
damageInfo.Damage -= damageInfo.Blocked;
|
||||
damageInfo.CleanDamage += damageInfo.Blocked;
|
||||
break;
|
||||
case MeleeHitOutcome.Glancing:
|
||||
damageInfo.HitInfo |= HitInfo.Glancing;
|
||||
damageInfo.TargetState = VictimState.Hit;
|
||||
damageInfo.originalDamage = damageInfo.damage;
|
||||
int leveldif = (int)victim.GetLevel() - (int)GetLevel();
|
||||
if (leveldif > 3)
|
||||
leveldif = 3;
|
||||
|
||||
damageInfo.OriginalDamage = damageInfo.Damage;
|
||||
float reducePercent = 1.0f - leveldif * 0.1f;
|
||||
damageInfo.cleanDamage += damageInfo.damage - (uint)(reducePercent * damageInfo.damage);
|
||||
damageInfo.damage = (uint)(reducePercent * damageInfo.damage);
|
||||
damageInfo.CleanDamage += damageInfo.Damage - (uint)(reducePercent * damageInfo.Damage);
|
||||
damageInfo.Damage = (uint)(reducePercent * damageInfo.Damage);
|
||||
break;
|
||||
case MeleeHitOutcome.Crushing:
|
||||
damageInfo.HitInfo |= HitInfo.Crushing;
|
||||
damageInfo.TargetState = VictimState.Hit;
|
||||
// 150% normal damage
|
||||
damageInfo.damage += (damageInfo.damage / 2);
|
||||
damageInfo.originalDamage = damageInfo.damage;
|
||||
damageInfo.Damage += (damageInfo.Damage / 2);
|
||||
damageInfo.OriginalDamage = damageInfo.Damage;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1242,34 +1254,34 @@ namespace Game.Entities
|
||||
if (!damageInfo.HitInfo.HasAnyFlag(HitInfo.Miss))
|
||||
damageInfo.HitInfo |= HitInfo.AffectsVictim;
|
||||
|
||||
int resilienceReduction = (int)damageInfo.damage;
|
||||
int resilienceReduction = (int)damageInfo.Damage;
|
||||
if (CanApplyResilience())
|
||||
ApplyResilience(victim, ref resilienceReduction);
|
||||
|
||||
resilienceReduction = (int)damageInfo.damage - resilienceReduction;
|
||||
damageInfo.damage -= (uint)resilienceReduction;
|
||||
damageInfo.cleanDamage += (uint)resilienceReduction;
|
||||
resilienceReduction = (int)damageInfo.Damage - resilienceReduction;
|
||||
damageInfo.Damage -= (uint)resilienceReduction;
|
||||
damageInfo.CleanDamage += (uint)resilienceReduction;
|
||||
|
||||
// Calculate absorb resist
|
||||
if (damageInfo.damage > 0)
|
||||
if (damageInfo.Damage > 0)
|
||||
{
|
||||
damageInfo.procVictim |= ProcFlags.TakenDamage;
|
||||
damageInfo.ProcVictim |= ProcFlags.TakenDamage;
|
||||
// Calculate absorb & resists
|
||||
DamageInfo dmgInfo = new(damageInfo);
|
||||
CalcAbsorbResist(dmgInfo);
|
||||
damageInfo.absorb = dmgInfo.GetAbsorb();
|
||||
damageInfo.resist = dmgInfo.GetResist();
|
||||
damageInfo.Absorb = dmgInfo.GetAbsorb();
|
||||
damageInfo.Resist = dmgInfo.GetResist();
|
||||
|
||||
if (damageInfo.absorb != 0)
|
||||
damageInfo.HitInfo |= (damageInfo.damage - damageInfo.absorb == 0 ? HitInfo.FullAbsorb : HitInfo.PartialAbsorb);
|
||||
if (damageInfo.Absorb != 0)
|
||||
damageInfo.HitInfo |= (damageInfo.Damage - damageInfo.Absorb == 0 ? HitInfo.FullAbsorb : HitInfo.PartialAbsorb);
|
||||
|
||||
if (damageInfo.resist != 0)
|
||||
damageInfo.HitInfo |= (damageInfo.damage - damageInfo.resist == 0 ? HitInfo.FullResist : HitInfo.PartialResist);
|
||||
if (damageInfo.Resist != 0)
|
||||
damageInfo.HitInfo |= (damageInfo.Damage - damageInfo.Resist == 0 ? HitInfo.FullResist : HitInfo.PartialResist);
|
||||
|
||||
damageInfo.damage = dmgInfo.GetDamage();
|
||||
damageInfo.Damage = dmgInfo.GetDamage();
|
||||
}
|
||||
else // Impossible get negative result but....
|
||||
damageInfo.damage = 0;
|
||||
damageInfo.Damage = 0;
|
||||
}
|
||||
|
||||
MeleeHitOutcome RollMeleeOutcomeAgainst(Unit victim, WeaponAttackType attType)
|
||||
@@ -1431,14 +1443,7 @@ namespace Game.Entities
|
||||
maxDamage = Math.Max(0.0f, maxDamage);
|
||||
|
||||
if (minDamage > maxDamage)
|
||||
{
|
||||
minDamage += maxDamage;
|
||||
maxDamage = minDamage - maxDamage;
|
||||
minDamage -= maxDamage;
|
||||
}
|
||||
|
||||
if (maxDamage == 0.0f)
|
||||
maxDamage = 5.0f;
|
||||
Extensions.Swap(ref minDamage, ref maxDamage);
|
||||
|
||||
return RandomHelper.URand(minDamage, maxDamage);
|
||||
}
|
||||
|
||||
@@ -239,17 +239,17 @@ namespace Game.Entities
|
||||
|
||||
public DamageInfo(CalcDamageInfo dmgInfo)
|
||||
{
|
||||
m_attacker = dmgInfo.attacker;
|
||||
m_victim = dmgInfo.target;
|
||||
m_damage = dmgInfo.damage;
|
||||
m_originalDamage = dmgInfo.damage;
|
||||
m_attacker = dmgInfo.Attacker;
|
||||
m_victim = dmgInfo.Target;
|
||||
m_damage = dmgInfo.Damage;
|
||||
m_originalDamage = dmgInfo.Damage;
|
||||
m_spellInfo = null;
|
||||
m_schoolMask = (SpellSchoolMask)dmgInfo.damageSchoolMask;
|
||||
m_schoolMask = (SpellSchoolMask)dmgInfo.DamageSchoolMask;
|
||||
m_damageType = DamageEffectType.Direct;
|
||||
m_attackType = dmgInfo.attackType;
|
||||
m_absorb = dmgInfo.absorb;
|
||||
m_resist = dmgInfo.resist;
|
||||
m_block = dmgInfo.blocked_amount;
|
||||
m_attackType = dmgInfo.AttackType;
|
||||
m_absorb = dmgInfo.Absorb;
|
||||
m_resist = dmgInfo.Resist;
|
||||
m_block = dmgInfo.Blocked;
|
||||
|
||||
switch (dmgInfo.TargetState)
|
||||
{
|
||||
@@ -271,7 +271,7 @@ namespace Game.Entities
|
||||
m_hitMask |= ProcFlagsHit.Block;
|
||||
|
||||
bool damageNullified = dmgInfo.HitInfo.HasAnyFlag(HitInfo.FullAbsorb | HitInfo.FullResist) || m_hitMask.HasAnyFlag(ProcFlagsHit.Immune | ProcFlagsHit.FullBlock);
|
||||
switch (dmgInfo.hitOutCome)
|
||||
switch (dmgInfo.HitOutCome)
|
||||
{
|
||||
case MeleeHitOutcome.Miss:
|
||||
m_hitMask |= ProcFlagsHit.Miss;
|
||||
@@ -428,22 +428,23 @@ namespace Game.Entities
|
||||
|
||||
public class CalcDamageInfo
|
||||
{
|
||||
public Unit attacker { get; set; } // Attacker
|
||||
public Unit target { get; set; } // Target for damage
|
||||
public uint damageSchoolMask { get; set; }
|
||||
public uint damage;
|
||||
public uint originalDamage;
|
||||
public uint absorb;
|
||||
public uint resist;
|
||||
public uint blocked_amount { get; set; }
|
||||
public Unit Attacker { get; set; } // Attacker
|
||||
public Unit Target { get; set; } // Target for damage
|
||||
public uint DamageSchoolMask { get; set; }
|
||||
public uint Damage;
|
||||
public uint OriginalDamage { get; set; }
|
||||
public uint Absorb;
|
||||
public uint Resist { get; set; }
|
||||
public uint Blocked { get; set; }
|
||||
public HitInfo HitInfo { get; set; }
|
||||
public VictimState TargetState { get; set; }
|
||||
|
||||
// Helper
|
||||
public WeaponAttackType attackType { get; set; }
|
||||
public ProcFlags procAttacker { get; set; }
|
||||
public ProcFlags procVictim { get; set; }
|
||||
public uint cleanDamage { get; set; } // Used only for rage calculation
|
||||
public MeleeHitOutcome hitOutCome { get; set; } // TODO: remove this field (need use TargetState)
|
||||
public WeaponAttackType AttackType { get; set; }
|
||||
public ProcFlags ProcAttacker { get; set; }
|
||||
public ProcFlags ProcVictim { get; set; }
|
||||
public uint CleanDamage { get; set; } // Used only for rage calculation
|
||||
public MeleeHitOutcome HitOutCome { get; set; } // TODO: remove this field (need use TargetState)
|
||||
}
|
||||
|
||||
public class SpellNonMeleeDamage
|
||||
|
||||
@@ -1845,12 +1845,6 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
void TriggerAurasProcOnEvent(CalcDamageInfo damageInfo)
|
||||
{
|
||||
DamageInfo dmgInfo = new(damageInfo);
|
||||
TriggerAurasProcOnEvent(null, null, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, ProcFlagsSpellType.None, ProcFlagsSpellPhase.None, dmgInfo.GetHitMask(), null, dmgInfo, null);
|
||||
}
|
||||
|
||||
void TriggerAurasProcOnEvent(List<AuraApplication> myProcAuras, List<AuraApplication> targetProcAuras, Unit actionTarget, ProcFlags typeMaskActor, ProcFlags typeMaskActionTarget, ProcFlagsSpellType spellTypeMask, ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell spell, DamageInfo damageInfo, HealInfo healInfo)
|
||||
{
|
||||
// prepare data for self trigger
|
||||
|
||||
@@ -2920,7 +2920,7 @@ namespace Game.Entities
|
||||
|
||||
void DealMeleeDamage(CalcDamageInfo damageInfo, bool durabilityLoss)
|
||||
{
|
||||
Unit victim = damageInfo.target;
|
||||
Unit victim = damageInfo.Target;
|
||||
|
||||
if (!victim.IsAlive() || victim.HasUnitState(UnitState.InFlight) || (victim.IsTypeId(TypeId.Unit) && victim.ToCreature().IsEvadingAttacks()))
|
||||
return;
|
||||
@@ -2928,7 +2928,7 @@ namespace Game.Entities
|
||||
// Hmmmm dont like this emotes client must by self do all animations
|
||||
if (damageInfo.HitInfo.HasAnyFlag(HitInfo.CriticalHit))
|
||||
victim.HandleEmoteCommand(Emote.OneshotWoundCritical);
|
||||
if (damageInfo.blocked_amount != 0 && damageInfo.TargetState != VictimState.Blocks)
|
||||
if (damageInfo.Blocked != 0 && damageInfo.TargetState != VictimState.Blocks)
|
||||
victim.HandleEmoteCommand(Emote.OneshotParryShield);
|
||||
|
||||
if (damageInfo.TargetState == VictimState.Parry &&
|
||||
@@ -2965,11 +2965,11 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// Call default DealDamage
|
||||
CleanDamage cleanDamage = new(damageInfo.cleanDamage, damageInfo.absorb, damageInfo.attackType, damageInfo.hitOutCome);
|
||||
DealDamage(this, victim, damageInfo.damage, cleanDamage, DamageEffectType.Direct, (SpellSchoolMask)damageInfo.damageSchoolMask, null, durabilityLoss);
|
||||
CleanDamage cleanDamage = new(damageInfo.CleanDamage, damageInfo.Absorb, damageInfo.AttackType, damageInfo.HitOutCome);
|
||||
DealDamage(this, victim, damageInfo.Damage, cleanDamage, DamageEffectType.Direct, (SpellSchoolMask)damageInfo.DamageSchoolMask, null, durabilityLoss);
|
||||
|
||||
// If this is a creature and it attacks from behind it has a probability to daze it's victim
|
||||
if ((damageInfo.hitOutCome == MeleeHitOutcome.Crit || damageInfo.hitOutCome == MeleeHitOutcome.Crushing || damageInfo.hitOutCome == MeleeHitOutcome.Normal || damageInfo.hitOutCome == MeleeHitOutcome.Glancing) &&
|
||||
if ((damageInfo.HitOutCome == MeleeHitOutcome.Crit || damageInfo.HitOutCome == MeleeHitOutcome.Crushing || damageInfo.HitOutCome == MeleeHitOutcome.Normal || damageInfo.HitOutCome == MeleeHitOutcome.Glancing) &&
|
||||
!IsTypeId(TypeId.Player) && !ToCreature().IsControlledByPlayer() && !victim.HasInArc(MathFunctions.PI, this)
|
||||
&& (victim.IsTypeId(TypeId.Player) || !victim.ToCreature().IsWorldBoss()) && !victim.IsVehicle())
|
||||
{
|
||||
@@ -2999,7 +2999,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// Do effect if any damage done to target
|
||||
if (damageInfo.damage != 0)
|
||||
if (damageInfo.Damage != 0)
|
||||
{
|
||||
// We're going to call functions which can modify content of the list during iteration over it's elements
|
||||
// Let's copy the list so we can prevent iterator invalidation
|
||||
@@ -3042,7 +3042,7 @@ namespace Game.Entities
|
||||
damageShield.Defender = GetGUID();
|
||||
damageShield.SpellID = spellInfo.Id;
|
||||
damageShield.TotalDamage = damage;
|
||||
damageShield.OriginalDamage = (int)damageInfo.originalDamage;
|
||||
damageShield.OriginalDamage = (int)damageInfo.OriginalDamage;
|
||||
damageShield.OverKill = (uint)Math.Max(damage - GetHealth(), 0);
|
||||
damageShield.SchoolMask = (uint)spellInfo.SchoolMask;
|
||||
damageShield.LogAbsorbed = damageInfo1.GetAbsorb();
|
||||
@@ -3810,10 +3810,10 @@ namespace Game.Entities
|
||||
return damage;
|
||||
|
||||
float mitigation = Math.Min(armor / (armor + armorConstant), 0.85f);
|
||||
return Math.Max((uint)(damage * (1.0f - mitigation)), 1);
|
||||
return Math.Max((uint)(damage * (1.0f - mitigation)), 0);
|
||||
}
|
||||
|
||||
public uint MeleeDamageBonusDone(Unit victim, uint pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo spellProto = null)
|
||||
public uint MeleeDamageBonusDone(Unit victim, uint pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo spellProto = null, SpellSchoolMask damageSchoolMask = SpellSchoolMask.Normal)
|
||||
{
|
||||
if (victim == null || pdamage == 0)
|
||||
return 0;
|
||||
@@ -3856,12 +3856,13 @@ namespace Game.Entities
|
||||
// Done total percent damage auras
|
||||
float DoneTotalMod = 1.0f;
|
||||
|
||||
SpellSchoolMask schoolMask = spellProto != null ? spellProto.GetSchoolMask() : damageSchoolMask;
|
||||
|
||||
if (spellProto != null)
|
||||
if ((schoolMask & SpellSchoolMask.Normal) == 0)
|
||||
{
|
||||
// Some spells don't benefit from pct done mods
|
||||
// mods for SPELL_SCHOOL_MASK_NORMAL are already factored in base melee damage calculation
|
||||
if (!spellProto.HasAttribute(SpellAttr6.IgnoreCasterDamageModifiers) && !spellProto.GetSchoolMask().HasAnyFlag(SpellSchoolMask.Normal))
|
||||
if (spellProto == null || !spellProto.HasAttribute(SpellAttr6.IgnoreCasterDamageModifiers))
|
||||
{
|
||||
float maxModDamagePercentSchool = 0.0f;
|
||||
Player thisPlayer = ToPlayer();
|
||||
@@ -3869,21 +3870,22 @@ namespace Game.Entities
|
||||
{
|
||||
for (var i = SpellSchools.Holy; i < SpellSchools.Max; ++i)
|
||||
{
|
||||
if (Convert.ToBoolean((int)spellProto.GetSchoolMask() & (1 << (int)i)))
|
||||
if (Convert.ToBoolean((int)schoolMask & (1 << (int)i)))
|
||||
maxModDamagePercentSchool = Math.Max(maxModDamagePercentSchool, thisPlayer.m_activePlayerData.ModDamageDonePercent[(int)i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
maxModDamagePercentSchool = GetTotalAuraMultiplierByMiscMask(AuraType.ModDamagePercentDone, (uint)spellProto.GetSchoolMask());
|
||||
maxModDamagePercentSchool = GetTotalAuraMultiplierByMiscMask(AuraType.ModDamagePercentDone, (uint)schoolMask);
|
||||
|
||||
DoneTotalMod *= maxModDamagePercentSchool;
|
||||
}
|
||||
else
|
||||
{
|
||||
// melee attack
|
||||
foreach (AuraEffect autoAttackDamage in GetAuraEffectsByType(AuraType.ModAutoAttackDamage))
|
||||
MathFunctions.AddPct(ref DoneTotalMod, autoAttackDamage.GetAmount());
|
||||
}
|
||||
}
|
||||
|
||||
if (spellProto == null)
|
||||
{
|
||||
// melee attack
|
||||
foreach (AuraEffect autoAttackDamage in GetAuraEffectsByType(AuraType.ModAutoAttackDamage))
|
||||
MathFunctions.AddPct(ref DoneTotalMod, autoAttackDamage.GetAmount());
|
||||
}
|
||||
|
||||
DoneTotalMod *= GetTotalAuraMultiplierByMiscMask(AuraType.ModDamageDoneVersus, creatureTypeMask);
|
||||
@@ -3919,7 +3921,7 @@ namespace Game.Entities
|
||||
return (uint)Math.Max(tmpDamage, 0.0f);
|
||||
}
|
||||
|
||||
public uint MeleeDamageBonusTaken(Unit attacker, uint pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo spellProto = null)
|
||||
public uint MeleeDamageBonusTaken(Unit attacker, uint pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo spellProto = null, SpellSchoolMask damageSchoolMask = SpellSchoolMask.Normal)
|
||||
{
|
||||
if (pdamage == 0)
|
||||
return 0;
|
||||
@@ -3996,7 +3998,7 @@ namespace Game.Entities
|
||||
// Sanctified Wrath (bypass damage reduction)
|
||||
if (attacker != null && TakenTotalMod < 1.0f)
|
||||
{
|
||||
SpellSchoolMask attackSchoolMask = spellProto != null ? spellProto.GetSchoolMask() : SpellSchoolMask.Normal;
|
||||
SpellSchoolMask attackSchoolMask = spellProto != null ? spellProto.GetSchoolMask() : damageSchoolMask;
|
||||
|
||||
float damageReduction = 1.0f - TakenTotalMod;
|
||||
var casterIgnoreResist = attacker.GetAuraEffectsByType(AuraType.ModIgnoreTargetResist);
|
||||
@@ -4022,7 +4024,7 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual SpellSchoolMask GetMeleeDamageSchoolMask() { return SpellSchoolMask.None; }
|
||||
public virtual SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = WeaponAttackType.BaseAttack) { return SpellSchoolMask.None; }
|
||||
|
||||
float CalculateDefaultCoefficient(SpellInfo spellInfo, DamageEffectType damagetype)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user