fix(Core/QAston): fixed shields oneshotting (#13271)

* fix(Core/QAston): fixed shields oneshotting

* fix build
This commit is contained in:
Angelo Venturini
2022-10-04 14:37:48 -03:00
committed by GitHub
parent a818bcf3e2
commit e05f61d1b3
4 changed files with 57 additions and 40 deletions

View File

@@ -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;