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
+53 -38
View File
@@ -192,7 +192,7 @@ void DamageInfo::AbsorbDamage(uint32 amount)
amount = std::min(amount, GetDamage()); amount = std::min(amount, GetDamage());
m_absorb += amount; m_absorb += amount;
m_damage -= amount; m_damage -= amount;
m_hitMask |= PROC_HIT_ABSORB;m_damage -= amount; m_hitMask |= PROC_HIT_ABSORB;
} }
void DamageInfo::ResistDamage(uint32 amount) void DamageInfo::ResistDamage(uint32 amount)
@@ -1413,8 +1413,11 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
// double blocked amount if block is critical // double blocked amount if block is critical
if (victim->isBlockCritical()) if (victim->isBlockCritical())
damageInfo->blocked *= 2; damageInfo->blocked *= 2;
if (damage < int32(damageInfo->blocked)) if (damage <= int32(damageInfo->blocked))
{
damageInfo->blocked = uint32(damage); damageInfo->blocked = uint32(damage);
damageInfo->fullBlock = true;
}
damage -= damageInfo->blocked; damage -= damageInfo->blocked;
cleanDamage += damageInfo->blocked; cleanDamage += damageInfo->blocked;
@@ -1468,14 +1471,18 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
damageInfo->damage = std::max(0, damage); damageInfo->damage = std::max(0, damage);
// Calculate absorb resist // Calculate absorb resist
if (damageInfo->damage > 0) DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE, BASE_ATTACK, PROC_HIT_NONE);
{ Unit::CalcAbsorbResist(dmgInfo);
DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE, BASE_ATTACK, 0); damageInfo->absorb = dmgInfo.GetAbsorb();
Unit::CalcAbsorbResist(dmgInfo); damageInfo->resist = dmgInfo.GetResist();
damageInfo->absorb = dmgInfo.GetAbsorb();
damageInfo->resist = dmgInfo.GetResist(); if (damageInfo->absorb)
damageInfo->damage = dmgInfo.GetDamage(); 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*/) 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 // Ignore Absorption Auras
float auraAbsorbMod = 0; float auraAbsorbMod = victim->GetMaxPositiveAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL, dmgInfo.GetSchoolMask());;
if (attacker) 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); if (!(aurEff->GetMiscValue() & schoolMask))
for (AuraEffectList::const_iterator itr = AbsIgnoreAurasA.begin(); itr != AbsIgnoreAurasA.end(); ++itr) continue;
{
if (!((*itr)->GetMiscValue() & schoolMask))
continue;
if ((*itr)->GetAmount() > auraAbsorbMod) if (!aurEff->IsAffectedOnSpell(spellInfo))
auraAbsorbMod = float((*itr)->GetAmount()); continue;
}
AuraEffectList const& AbsIgnoreAurasB = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL); if (aurEff->GetAmount() > auraAbsorbMod)
for (AuraEffectList::const_iterator itr = AbsIgnoreAurasB.begin(); itr != AbsIgnoreAurasB.end(); ++itr) auraAbsorbMod = float(aurEff->GetAmount());
{
if (!((*itr)->GetMiscValue() & schoolMask))
continue;
if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectedOnSpell(spellInfo))
auraAbsorbMod = float((*itr)->GetAmount());
}
RoundToInterval(auraAbsorbMod, 0.0f, 100.0f);
} }
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 // 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 // Let's copy the list so we can prevent iterator invalidation
AuraEffectList vSchoolAbsorbCopy(victim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB)); AuraEffectList vSchoolAbsorbCopy(victim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB));
@@ -12190,14 +12191,13 @@ uint32 createProcHitMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCond
hitMask |= PROC_HIT_PARRY; hitMask |= PROC_HIT_PARRY;
break; break;
case SPELL_MISS_BLOCK: 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; break;
case SPELL_MISS_EVADE: case SPELL_MISS_EVADE:
hitMask |= PROC_HIT_EVADE; hitMask |= PROC_HIT_EVADE;
break; break;
case SPELL_MISS_IMMUNE: case SPELL_MISS_IMMUNE:
hitMask |= PROC_HIT_IMMUNE;
break;
case SPELL_MISS_IMMUNE2: case SPELL_MISS_IMMUNE2:
hitMask |= PROC_HIT_IMMUNE; hitMask |= PROC_HIT_IMMUNE;
break; break;
@@ -12210,6 +12210,9 @@ uint32 createProcHitMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCond
case SPELL_MISS_REFLECT: case SPELL_MISS_REFLECT:
hitMask |= PROC_HIT_REFLECT; hitMask |= PROC_HIT_REFLECT;
break; break;
case SPELL_MISS_RESIST:
hitMask |= PROC_HIT_FULL_RESIST;
break;
default: default:
break; break;
} }
@@ -12218,15 +12221,27 @@ uint32 createProcHitMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCond
{ {
// On block // On block
if (damageInfo->blocked) if (damageInfo->blocked)
{
hitMask |= PROC_HIT_BLOCK; hitMask |= PROC_HIT_BLOCK;
if (damageInfo->fullBlock)
hitMask |= PROC_HIT_FULL_BLOCK;
}
// On absorb // On absorb
if (damageInfo->absorb) if (damageInfo->absorb)
hitMask |= PROC_HIT_ABSORB; hitMask |= PROC_HIT_ABSORB;
// On crit
if (damageInfo->HitInfo & SPELL_HIT_TYPE_CRIT) // Don't set hit/crit hitMask if damage is nullified
hitMask |= PROC_HIT_CRITICAL; bool const damageNullified = (damageInfo->HitInfo & (HITINFO_FULL_ABSORB | HITINFO_FULL_RESIST)) != 0 || (hitMask & PROC_HIT_FULL_BLOCK) != 0;
else if (!damageNullified)
hitMask |= PROC_HIT_NORMAL; {
// 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; return hitMask;
+2 -1
View File
@@ -891,7 +891,7 @@ struct SpellNonMeleeDamage
{ {
SpellNonMeleeDamage(Unit* _attacker, Unit* _target, SpellInfo const* _spellInfo, uint32 _schoolMask) SpellNonMeleeDamage(Unit* _attacker, Unit* _target, SpellInfo const* _spellInfo, uint32 _schoolMask)
: target(_target), attacker(_attacker), spellInfo(_spellInfo), damage(0), overkill(0), schoolMask(_schoolMask), : target(_target), attacker(_attacker), spellInfo(_spellInfo), damage(0), overkill(0), schoolMask(_schoolMask),
absorb(0), resist(0), physicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0) absorb(0), resist(0), physicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0), fullBlock(false)
{} {}
Unit* target; Unit* target;
@@ -908,6 +908,7 @@ struct SpellNonMeleeDamage
uint32 HitInfo; uint32 HitInfo;
// Used for help // Used for help
uint32 cleanDamage; uint32 cleanDamage;
bool fullBlock;
}; };
struct SpellPeriodicAuraLogInfo struct SpellPeriodicAuraLogInfo
@@ -6468,7 +6468,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
if (damage) if (damage)
{ {
procVictim |= PROC_FLAG_TAKEN_DAMAGE; procVictim |= PROC_FLAG_TAKEN_DAMAGE;
hitMask = crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL; hitMask |= crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL;
} }
int32 overkill = damage - target->GetHealth(); int32 overkill = damage - target->GetHealth();
+1
View File
@@ -311,6 +311,7 @@ void Spell::EffectEnvironmentalDMG(SpellEffIndex /*effIndex*/)
else else
{ {
DamageInfo dmgInfo(m_caster, unitTarget, damage, m_spellInfo, m_spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE, BASE_ATTACK); DamageInfo dmgInfo(m_caster, unitTarget, damage, m_spellInfo, m_spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE, BASE_ATTACK);
m_caster->CalcAbsorbResist(dmgInfo);
uint32 absorb = dmgInfo.GetAbsorb(); uint32 absorb = dmgInfo.GetAbsorb();
uint32 resist = dmgInfo.GetResist(); uint32 resist = dmgInfo.GetResist();