diff options
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 45 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 5 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 8 |
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) |