|
|
|
|
@@ -192,7 +192,7 @@ void DamageInfo::AbsorbDamage(uint32 amount)
|
|
|
|
|
amount = std::min(amount, GetDamage());
|
|
|
|
|
m_absorb += amount;
|
|
|
|
|
m_damage -= amount;
|
|
|
|
|
m_hitMask |= PROC_HIT_ABSORB;m_damage -= amount;
|
|
|
|
|
m_hitMask |= PROC_HIT_ABSORB;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DamageInfo::ResistDamage(uint32 amount)
|
|
|
|
|
@@ -1413,8 +1413,11 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
|
|
|
|
|
// double blocked amount if block is critical
|
|
|
|
|
if (victim->isBlockCritical())
|
|
|
|
|
damageInfo->blocked *= 2;
|
|
|
|
|
if (damage < int32(damageInfo->blocked))
|
|
|
|
|
if (damage <= int32(damageInfo->blocked))
|
|
|
|
|
{
|
|
|
|
|
damageInfo->blocked = uint32(damage);
|
|
|
|
|
damageInfo->fullBlock = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
damage -= damageInfo->blocked;
|
|
|
|
|
cleanDamage += damageInfo->blocked;
|
|
|
|
|
@@ -1468,14 +1471,18 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
|
|
|
|
|
damageInfo->damage = std::max(0, damage);
|
|
|
|
|
|
|
|
|
|
// Calculate absorb resist
|
|
|
|
|
if (damageInfo->damage > 0)
|
|
|
|
|
{
|
|
|
|
|
DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE, BASE_ATTACK, 0);
|
|
|
|
|
Unit::CalcAbsorbResist(dmgInfo);
|
|
|
|
|
damageInfo->absorb = dmgInfo.GetAbsorb();
|
|
|
|
|
damageInfo->resist = dmgInfo.GetResist();
|
|
|
|
|
damageInfo->damage = dmgInfo.GetDamage();
|
|
|
|
|
}
|
|
|
|
|
DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE, BASE_ATTACK, PROC_HIT_NONE);
|
|
|
|
|
Unit::CalcAbsorbResist(dmgInfo);
|
|
|
|
|
damageInfo->absorb = dmgInfo.GetAbsorb();
|
|
|
|
|
damageInfo->resist = dmgInfo.GetResist();
|
|
|
|
|
|
|
|
|
|
if (damageInfo->absorb)
|
|
|
|
|
damageInfo->HitInfo |= (damageInfo->damage - damageInfo->absorb == 0 ? HITINFO_FULL_ABSORB : HITINFO_PARTIAL_ABSORB);
|
|
|
|
|
|
|
|
|
|
if (damageInfo->resist)
|
|
|
|
|
damageInfo->HitInfo |= (damageInfo->damage - damageInfo->resist == 0 ? HITINFO_FULL_RESIST : HITINFO_PARTIAL_RESIST);
|
|
|
|
|
|
|
|
|
|
damageInfo->damage = dmgInfo.GetDamage();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss, Spell const* spell /*= nullptr*/)
|
|
|
|
|
@@ -2070,31 +2077,25 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ignore Absorption Auras
|
|
|
|
|
float auraAbsorbMod = 0;
|
|
|
|
|
if (attacker)
|
|
|
|
|
float auraAbsorbMod = victim->GetMaxPositiveAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL, dmgInfo.GetSchoolMask());;
|
|
|
|
|
AuraEffectList const& abilityAbsorbAuras = victim->GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL);
|
|
|
|
|
for (AuraEffect const* aurEff : abilityAbsorbAuras)
|
|
|
|
|
{
|
|
|
|
|
AuraEffectList const& AbsIgnoreAurasA = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL);
|
|
|
|
|
for (AuraEffectList::const_iterator itr = AbsIgnoreAurasA.begin(); itr != AbsIgnoreAurasA.end(); ++itr)
|
|
|
|
|
{
|
|
|
|
|
if (!((*itr)->GetMiscValue() & schoolMask))
|
|
|
|
|
continue;
|
|
|
|
|
if (!(aurEff->GetMiscValue() & schoolMask))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if ((*itr)->GetAmount() > auraAbsorbMod)
|
|
|
|
|
auraAbsorbMod = float((*itr)->GetAmount());
|
|
|
|
|
}
|
|
|
|
|
if (!aurEff->IsAffectedOnSpell(spellInfo))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
AuraEffectList const& AbsIgnoreAurasB = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL);
|
|
|
|
|
for (AuraEffectList::const_iterator itr = AbsIgnoreAurasB.begin(); itr != AbsIgnoreAurasB.end(); ++itr)
|
|
|
|
|
{
|
|
|
|
|
if (!((*itr)->GetMiscValue() & schoolMask))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectedOnSpell(spellInfo))
|
|
|
|
|
auraAbsorbMod = float((*itr)->GetAmount());
|
|
|
|
|
}
|
|
|
|
|
RoundToInterval(auraAbsorbMod, 0.0f, 100.0f);
|
|
|
|
|
if (aurEff->GetAmount() > auraAbsorbMod)
|
|
|
|
|
auraAbsorbMod = float(aurEff->GetAmount());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RoundToInterval(auraAbsorbMod, 0.f, 100.f);
|
|
|
|
|
|
|
|
|
|
int32 absorbIgnoringDamage = CalculatePct(dmgInfo.GetDamage(), auraAbsorbMod);
|
|
|
|
|
dmgInfo.ModifyDamage(-absorbIgnoringDamage);
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
AuraEffectList vSchoolAbsorbCopy(victim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB));
|
|
|
|
|
@@ -12190,14 +12191,13 @@ uint32 createProcHitMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCond
|
|
|
|
|
hitMask |= PROC_HIT_PARRY;
|
|
|
|
|
break;
|
|
|
|
|
case SPELL_MISS_BLOCK:
|
|
|
|
|
hitMask |= PROC_HIT_BLOCK;
|
|
|
|
|
// spells can't be partially blocked (it's damage can though)
|
|
|
|
|
hitMask |= PROC_HIT_BLOCK | PROC_HIT_FULL_BLOCK;
|
|
|
|
|
break;
|
|
|
|
|
case SPELL_MISS_EVADE:
|
|
|
|
|
hitMask |= PROC_HIT_EVADE;
|
|
|
|
|
break;
|
|
|
|
|
case SPELL_MISS_IMMUNE:
|
|
|
|
|
hitMask |= PROC_HIT_IMMUNE;
|
|
|
|
|
break;
|
|
|
|
|
case SPELL_MISS_IMMUNE2:
|
|
|
|
|
hitMask |= PROC_HIT_IMMUNE;
|
|
|
|
|
break;
|
|
|
|
|
@@ -12210,6 +12210,9 @@ uint32 createProcHitMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCond
|
|
|
|
|
case SPELL_MISS_REFLECT:
|
|
|
|
|
hitMask |= PROC_HIT_REFLECT;
|
|
|
|
|
break;
|
|
|
|
|
case SPELL_MISS_RESIST:
|
|
|
|
|
hitMask |= PROC_HIT_FULL_RESIST;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -12218,15 +12221,27 @@ uint32 createProcHitMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCond
|
|
|
|
|
{
|
|
|
|
|
// On block
|
|
|
|
|
if (damageInfo->blocked)
|
|
|
|
|
{
|
|
|
|
|
hitMask |= PROC_HIT_BLOCK;
|
|
|
|
|
if (damageInfo->fullBlock)
|
|
|
|
|
hitMask |= PROC_HIT_FULL_BLOCK;
|
|
|
|
|
}
|
|
|
|
|
// On absorb
|
|
|
|
|
if (damageInfo->absorb)
|
|
|
|
|
hitMask |= PROC_HIT_ABSORB;
|
|
|
|
|
// On crit
|
|
|
|
|
if (damageInfo->HitInfo & SPELL_HIT_TYPE_CRIT)
|
|
|
|
|
hitMask |= PROC_HIT_CRITICAL;
|
|
|
|
|
else
|
|
|
|
|
hitMask |= PROC_HIT_NORMAL;
|
|
|
|
|
|
|
|
|
|
// Don't set hit/crit hitMask if damage is nullified
|
|
|
|
|
bool const damageNullified = (damageInfo->HitInfo & (HITINFO_FULL_ABSORB | HITINFO_FULL_RESIST)) != 0 || (hitMask & PROC_HIT_FULL_BLOCK) != 0;
|
|
|
|
|
if (!damageNullified)
|
|
|
|
|
{
|
|
|
|
|
// On crit
|
|
|
|
|
if (damageInfo->HitInfo & SPELL_HIT_TYPE_CRIT)
|
|
|
|
|
hitMask |= PROC_HIT_CRITICAL;
|
|
|
|
|
else
|
|
|
|
|
hitMask |= PROC_HIT_NORMAL;
|
|
|
|
|
}
|
|
|
|
|
else if ((damageInfo->HitInfo & HITINFO_FULL_RESIST) != 0)
|
|
|
|
|
hitMask |= PROC_HIT_FULL_RESIST;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return hitMask;
|
|
|
|
|
|