From b00809605784bbdb66d091319a64a657a847f4ca Mon Sep 17 00:00:00 2001 From: Ovahlord <18347559+Ovahlord@users.noreply.github.com> Date: Sun, 22 Mar 2026 19:33:40 +0100 Subject: [PATCH] Core/Units: only grant 50% crit damage bonus for magical periodic effects originating from ranged attacks supercedes #463 --- src/server/game/Entities/Unit/Unit.cpp | 18 +++++++++++++----- src/server/game/Entities/Unit/Unit.h | 2 +- .../game/Spells/Auras/SpellAuraEffects.cpp | 4 ++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 22634ee9f4..bc6d64c5ca 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -7003,7 +7003,7 @@ float Unit::SpellCritChanceTaken(Unit const* caster, SpellInfo const* spellInfo, return std::max(crit_chance, 0.0f); } -/*static*/ uint32 Unit::SpellCriticalDamageBonus(Unit const* caster, SpellInfo const* spellProto, uint32 damage) +/*static*/ uint32 Unit::SpellCriticalDamageBonus(Unit const* caster, SpellInfo const* spellProto, uint32 damage, bool periodicDamage /*= false*/) { // Calculate critical bonus int32 crit_bonus = damage; @@ -7011,13 +7011,21 @@ float Unit::SpellCritChanceTaken(Unit const* caster, SpellInfo const* spellInfo, switch (spellProto->DmgClass) { - case SPELL_DAMAGE_CLASS_MELEE: // for melee based spells is 100% - case SPELL_DAMAGE_CLASS_RANGED: - /// @todo write here full calculation for melee/ranged spells + // Spells which are either marked as ranged or melee damage, will deal 100% additional damage + case SPELL_DAMAGE_CLASS_MELEE: crit_bonus += damage; break; + case SPELL_DAMAGE_CLASS_RANGED: + // Ranged spells which have magic periodic damage effect on the other hand, only deal 50% damage, just like spells + // This is a very specific case that is currently only known for Hunter spells, such as Serpent Sting and Black Arrow + if (periodicDamage && (spellProto->GetSchoolMask() & SPELL_SCHOOL_MASK_MAGIC) != 0) + crit_bonus += damage / 2; + else + crit_bonus += damage; + break; default: - crit_bonus += damage / 2; // for spells is 50% + // Magic spells will simply deal 50% additional crit damage + crit_bonus += damage / 2; break; } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index b0aa46ee44..26a5ccfad7 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1458,7 +1458,7 @@ class TC_GAME_API Unit : public WorldObject 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); + static uint32 SpellCriticalDamageBonus(Unit const* caster, SpellInfo const* spellProto, uint32 damage, bool periodicDamage = false); static uint32 SpellCriticalHealingBonus(Unit const* caster, uint32 damage); uint32 GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) const; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index f3f60714a8..216e6c9478 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5839,7 +5839,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const crit = roll_chance_f(GetCritChanceFor(caster, target)); if (crit) - damage = Unit::SpellCriticalDamageBonus(caster, m_spellInfo, damage); + damage = Unit::SpellCriticalDamageBonus(caster, m_spellInfo, damage, true); uint32 unmitigatedDamage = damage; @@ -5928,7 +5928,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c crit = roll_chance_f(GetCritChanceFor(caster, target)); if (crit) - damage = Unit::SpellCriticalDamageBonus(caster, m_spellInfo, damage); + damage = Unit::SpellCriticalDamageBonus(caster, m_spellInfo, damage, true); uint32 unmitigatedDamage = damage;