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:
1 parent
946f928ee2
commit
a587f99c30
2 files changed
+7
-43
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user