aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp45
-rw-r--r--src/server/game/Entities/Unit/Unit.h5
-rw-r--r--src/server/game/Spells/Spell.cpp8
3 files changed, 12 insertions, 46 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index b9ab6b81c69..78552b3da0f 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -1081,7 +1081,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, Spell* spell /*= nullptr*/)
+void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType, bool crit /*= false*/, bool blocked /*= false*/, Spell* spell /*= nullptr*/)
{
if (damage < 0)
return;
@@ -1098,7 +1098,6 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
if (Unit::IsDamageReducedByArmor(damageSchoolMask, spellInfo))
damage = Unit::CalcArmorReducedDamage(damageInfo->attacker, victim, damage, spellInfo, attackType);
- bool blocked = false;
// Per-school calc
switch (spellInfo->DmgClass)
{
@@ -1106,17 +1105,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_ATTR3_COMPLETELY_BLOCKED))
- {
- // Get blocked status
- blocked = isSpellBlocked(victim, spellInfo, attackType);
- }
- }
-
if (crit)
{
damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
@@ -1140,7 +1128,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
{
// double blocked amount if block is critical
uint32 value = victim->GetBlockPercent(GetLevel());
- if (victim->isBlockCritical())
+ if (victim->IsBlockCritical())
value *= 2; // double blocked percent
damageInfo->blocked = CalculatePct(damage, value);
if (damage <= int32(damageInfo->blocked))
@@ -1355,7 +1343,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(GetLevel()));
- if (damageInfo->Target->isBlockCritical())
+ if (damageInfo->Target->IsBlockCritical())
damageInfo->Blocked *= 2;
damageInfo->OriginalDamage = damageInfo->Damage;
@@ -2353,27 +2341,7 @@ void Unit::SendMeleeAttackStop(Unit* victim)
TC_LOG_DEBUG("entities.unit", "%s stopped attacking", GetGUID().ToString().c_str());
}
-bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType)
-{
- // These spells can't be blocked
- if (spellProto && (spellProto->HasAttribute(SPELL_ATTR0_NO_ACTIVE_DEFENSE) || spellProto->HasAttribute(SPELL_ATTR3_ALWAYS_HIT)))
- 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(attackType, victim);
- if (blockChance && roll_chance_f(blockChance))
- return true;
- }
-
- return false;
-}
-
-bool Unit::isBlockCritical()
+bool Unit::IsBlockCritical()
{
if (roll_chance_i(GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_CRIT_CHANCE)))
return true;
@@ -2452,7 +2420,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
bool canDodge = !spellInfo->HasAttribute(SPELL_ATTR7_NO_ATTACK_DODGE);
bool canParry = !spellInfo->HasAttribute(SPELL_ATTR7_NO_ATTACK_PARRY);
- bool canBlock = spellInfo->HasAttribute(SPELL_ATTR3_COMPLETELY_BLOCKED);
+ bool canBlock = true; // all melee and ranged attacks can be blocked
// if victim is casting or cc'd it can't avoid attacks
if (victim->IsNonMeleeSpellCast(false, false, true) || victim->HasUnitState(UNIT_STATE_CONTROLLED))
@@ -2462,7 +2430,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
canBlock = false;
}
- // Ranged attacks can only miss, resist and deflect
+ // Ranged attacks can only miss, resist and deflect and get blocked
if (attType == RANGED_ATTACK)
{
canParry = false;
@@ -2476,7 +2444,6 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
if (roll < tmp)
return SPELL_MISS_DEFLECT;
}
- return SPELL_MISS_NONE;
}
// Check for attack from behind
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 920f4fabcc9..3589a004690 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1061,7 +1061,7 @@ class TC_GAME_API Unit : public WorldObject
void SetLastDamagedTargetGuid(ObjectGuid guid) { _lastDamagedTargetGuid = guid; }
ObjectGuid GetLastDamagedTargetGuid() const { return _lastDamagedTargetGuid; }
- void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false, Spell* spell = nullptr);
+ void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false, bool blocked = false, Spell* spell = nullptr);
void DealSpellDamage(SpellNonMeleeDamage const* damageInfo, bool durabilityLoss);
// player or player's pet resilience (-1%)
@@ -1702,8 +1702,7 @@ class TC_GAME_API Unit : public WorldObject
uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto = nullptr, SpellEffectInfo const* spellEffectInfo = nullptr, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL);
uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto = nullptr, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL);
- bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK);
- bool isBlockCritical();
+ bool IsBlockCritical();
float SpellCritChanceDone(Spell* spell, AuraEffect const* aurEff, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const;
float SpellCritChanceTaken(Unit const* caster, Spell* spell, AuraEffect const* aurEff, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType = BASE_ATTACK) const;
static uint32 SpellCriticalDamageBonus(Unit const* caster, SpellInfo const* spellProto, uint32 damage, Unit* victim);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 2987aa544fd..17d8db166ef 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2570,7 +2570,7 @@ void Spell::TargetInfo::PreprocessTarget(Spell* spell)
spell->m_healing = Healing;
_spellHitTarget = nullptr;
- if (MissCondition == SPELL_MISS_NONE)
+ if (MissCondition == SPELL_MISS_NONE || (MissCondition == SPELL_MISS_BLOCK && !spell->GetSpellInfo()->HasAttribute(SPELL_ATTR3_COMPLETELY_BLOCKED)))
_spellHitTarget = unit;
else if (MissCondition == SPELL_MISS_REFLECT && ReflectResult == SPELL_MISS_NONE)
_spellHitTarget = spell->m_caster->ToUnit();
@@ -2776,7 +2776,7 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell)
caster->SetLastDamagedTargetGuid(spell->unitTarget->GetGUID());
// Add bonuses and fill damageInfo struct
- caster->CalculateSpellDamageTaken(&damageInfo, spell->m_damage, spell->m_spellInfo, spell->m_attackType, IsCrit, spell);
+ caster->CalculateSpellDamageTaken(&damageInfo, spell->m_damage, spell->m_spellInfo, spell->m_attackType, IsCrit, MissCondition == SPELL_MISS_BLOCK, spell);
Unit::DealDamageMods(damageInfo.attacker, damageInfo.target, damageInfo.damage, &damageInfo.absorb);
hitMask |= createProcHitMask(&damageInfo, MissCondition);
@@ -4754,7 +4754,7 @@ void Spell::UpdateSpellCastDataTargets(WorldPackets::Spells::SpellCastData& data
// possibly SPELL_MISS_IMMUNE2 for this??
targetInfo.MissCondition = SPELL_MISS_IMMUNE2;
- if (targetInfo.MissCondition == SPELL_MISS_NONE) // hits
+ if (targetInfo.MissCondition == SPELL_MISS_NONE || (targetInfo.MissCondition == SPELL_MISS_BLOCK && !m_spellInfo->HasAttribute(SPELL_ATTR3_COMPLETELY_BLOCKED))) // Add only hits and partial blocked
{
data.HitTargets.push_back(targetInfo.TargetGUID);
data.HitStatus.emplace_back(SPELL_MISS_NONE);
@@ -8206,7 +8206,7 @@ void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, Spe
{
Unit* unit = nullptr;
// In case spell hit target, do all effect on that target
- if (targetInfo.MissCondition == SPELL_MISS_NONE)
+ if (targetInfo.MissCondition == SPELL_MISS_NONE || (targetInfo.MissCondition == SPELL_MISS_BLOCK && !m_spellInfo->HasAttribute(SPELL_ATTR3_COMPLETELY_BLOCKED)))
unit = m_caster->GetGUID() == targetInfo.TargetGUID ? m_caster->ToUnit() : ObjectAccessor::GetUnit(*m_caster, targetInfo.TargetGUID);
// In case spell reflect from target, do all effect on caster (if hit)
else if (targetInfo.MissCondition == SPELL_MISS_REFLECT && targetInfo.ReflectResult == SPELL_MISS_NONE)