Core/Units: correct block chance and damage calculation of melee spells

*MeleeSpellHitResult already returns a valid block roll result so we don't need a 2nd roll in CalculateSpellDamageTaken
This commit is contained in:
Ovahlord committed 2022-09-13 16:14:42 +02:00
1 parent 946f928ee2
commit a587f99c30
2 files changed
+7 -43

No files matched your search

+5 -40
View File
@@ -1030,7 +1030,7 @@ void Unit::CastStop(uint32 except_spellid)
InterruptSpell(CurrentSpellTypes(i), false);
}
void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType, bool crit)
void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType, bool crit, SpellMissInfo missCondition /*= SPELL_MISS_NONE*/)
{
if (damage < 0)
return;
@@ -1047,7 +1047,6 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
if (Unit::IsDamageReducedByArmor(damageSchoolMask, spellInfo))
damage = Unit::CalcArmorReducedDamage(this, victim, damage, spellInfo, attackType);
bool blocked = false;
// Per-school calc
switch (spellInfo->DmgClass)
{
@@ -1055,17 +1054,6 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
case SPELL_DAMAGE_CLASS_RANGED:
case SPELL_DAMAGE_CLASS_MELEE:
{
// Physical Damage
if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL)
{
// Spells with this attribute were already calculated in MeleeSpellHitResult
if (!spellInfo->HasAttribute(SPELL_ATTR8_CANT_BLOCK))
{
// Get blocked status
blocked = isSpellBlocked(victim, spellInfo);
}
}
if (crit)
{
damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
@@ -1092,11 +1080,11 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
}
// Spell weapon based damage CAN BE crit & blocked at same time
if (blocked)
if (missCondition == SPELL_MISS_BLOCK)
{
// double blocked amount if block is critical
uint32 value = victim->GetBlockPercent();
if (victim->isBlockCritical())
if (victim->IsBlockCritical())
value *= 2; // double blocked percent
if (spellInfo->HasAttribute(SPELL_ATTR3_COMPLETELY_BLOCKED))
value = 100;
@@ -1320,7 +1308,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon
damageInfo->HitInfo |= HITINFO_BLOCK;
// 30% damage blocked, double blocked amount if block is critical
damageInfo->Blocked = CalculatePct(damageInfo->Damage, damageInfo->Target->GetBlockPercent());
if (damageInfo->Target->isBlockCritical())
if (damageInfo->Target->IsBlockCritical())
damageInfo->Blocked *= 2;
damageInfo->OriginalDamage = damageInfo->Damage;
@@ -2236,30 +2224,7 @@ void Unit::SendMeleeAttackStop(Unit* victim)
TC_LOG_DEBUG("entities.unit", "%s %u stopped attacking", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUID().GetCounter());
}
bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto)
{
// These spells can't be blocked
if (spellProto
&& (spellProto->HasAttribute(SPELL_ATTR0_NO_ACTIVE_DEFENSE)
|| spellProto->HasAttribute(SPELL_ATTR3_ALWAYS_HIT)
|| spellProto->HasAttribute(SPELL_ATTR8_CANT_BLOCK)))
return false;
// Can't block when casting/controlled
if (victim->IsNonMeleeSpellCast(false) || victim->HasUnitState(UNIT_STATE_CONTROLLED))
return false;
if (victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION) || victim->HasInArc(float(M_PI), this))
{
float blockChance = GetUnitBlockChance(victim);
if (blockChance && roll_chance_f(blockChance))
return true;
}
return false;
}
bool Unit::isBlockCritical()
bool Unit::IsBlockCritical() const
{
if (roll_chance_i(GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_CRIT_CHANCE)))
return true;
+2 -3
View File
@@ -1049,7 +1049,7 @@ class TC_GAME_API Unit : public WorldObject
void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss);
void HandleProcExtraAttackFor(Unit* victim);
void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false);
void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false, SpellMissInfo missCondition = SPELL_MISS_NONE);
void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss);
// player or player's pet resilience (-1%)
@@ -1606,8 +1606,7 @@ class TC_GAME_API Unit : public WorldObject
uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr, bool useSpellBonusData = true, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL);
uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL);
bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto);
bool isBlockCritical();
bool IsBlockCritical() const;
float SpellCritChanceDone(SpellInfo const* spellInfo, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK, bool isPeriodic = false) const;
float SpellCritChanceTaken(Unit const* caster, SpellInfo const* spellInfo, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType = BASE_ATTACK, bool isPeriodic = false) const;
static uint32 SpellCriticalDamageBonus(Unit const* caster, SpellInfo const* spellProto, uint32 damage);