From 4ccfe1ebed4a9025fff48bcce6328031b6583f11 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Mon, 9 Jun 2025 11:08:43 +0200 Subject: [PATCH] Core/Spells: fixed several special damage calculations for class spells and fixed a duplicate application of mastery --- .../world/4.3.4/2025_06_08_01_world.sql | 7 + .../game/Spells/Auras/SpellAuraEffects.cpp | 7 +- src/server/game/Spells/SpellEffects.cpp | 165 +++++------------- src/server/scripts/Spells/spell_dk.cpp | 7 +- src/server/scripts/Spells/spell_druid.cpp | 41 +++-- src/server/scripts/Spells/spell_hunter.cpp | 86 ++++++++- 6 files changed, 168 insertions(+), 145 deletions(-) create mode 100644 sql/updates/world/4.3.4/2025_06_08_01_world.sql diff --git a/sql/updates/world/4.3.4/2025_06_08_01_world.sql b/sql/updates/world/4.3.4/2025_06_08_01_world.sql new file mode 100644 index 0000000000..a4a0042701 --- /dev/null +++ b/sql/updates/world/4.3.4/2025_06_08_01_world.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_hun_aimed_shot', 'spell_hun_explosive_shot'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(19434, 'spell_hun_aimed_shot'), +(82928, 'spell_hun_aimed_shot'), +(53301, 'spell_hun_explosive_shot'); + +-- dk strike dmg bonus diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 96104d8544..b60cb3b356 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -482,12 +482,7 @@ void AuraEffect::GetApplicationList(Container& applicationContainer) const int32 AuraEffect::CalculateAmount(Unit* caster) { // default amount calculation - int32 amount = 0; - - if (!m_spellInfo->HasAttribute(SPELL_ATTR8_MASTERY_AFFECTS_POINTS) || G3D::fuzzyEq(m_spellInfo->Effects[m_effIndex].BonusMultiplier, 0.0f)) - amount = m_spellInfo->Effects[m_effIndex].CalcValue(caster, &m_baseAmount, GetBase()->GetOwner()->ToUnit()); - else if (caster && caster->GetTypeId() == TYPEID_PLAYER) - amount = int32(caster->GetFloatValue(PLAYER_MASTERY) * m_spellInfo->Effects[m_effIndex].BonusMultiplier); + int32 amount = amount = m_spellInfo->Effects[m_effIndex].CalcValue(caster, &m_baseAmount, GetBase()->GetOwner()->ToUnit());; // check item enchant aura cast if (!amount && caster) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 5aad12e55e..ab052d5fdb 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2760,24 +2760,39 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) if (!unitTarget || !unitTarget->IsAlive()) return; - uint32 effectType = m_spellInfo->Effects[effIndex].Effect; - bool useWeaponDamage = true; - /* - Multiple weapon damage effect case. SPELL_EFFECT_WEAPON_PERCENT_DAMAGE is being prioritized for calculating weapon damage values. - The other effects only add their fixed bonus to the damage sum. - */ - if (m_spellInfo->HasEffect(SPELL_EFFECT_WEAPON_PERCENT_DAMAGE) && effectType != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE) - useWeaponDamage = false; + for(uint8 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j) + { + switch (m_spellInfo->Effects[j].Effect) + { + case SPELL_EFFECT_WEAPON_DAMAGE: + case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: + case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: + case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: + return; + default: + break; + } + } // some spell specific modifiers float totalDamagePercentMod = 1.0f; // applied to final bonus+weapon damage int32 fixed_bonus = 0; + switch (m_spellInfo->SpellFamilyName) + { + case SPELLFAMILY_SHAMAN: + { + // Skyshatter Harness item set bonus + // Stormstrike + if (AuraEffect* aurEff = unitCaster->IsScriptOverriden(m_spellInfo, 5634)) + unitCaster->CastSpell(nullptr, 38430, aurEff); + break; + } + } + bool normalized = false; float weaponDamagePercentMod = 1.0f; - Mechanics mechanic = MECHANIC_NONE; - for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) { switch (m_spellInfo->Effects[j].Effect) @@ -2794,101 +2809,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) ApplyPct(weaponDamagePercentMod, CalculateDamage(j, unitTarget)); break; default: - continue; // not weapon damage effect, just skip - } - - if (m_spellInfo->Effects[j].Mechanic != MECHANIC_NONE && mechanic == MECHANIC_NONE) - mechanic = m_spellInfo->Effects[j].Mechanic; - } - - if (useWeaponDamage) - { - switch (m_spellInfo->SpellFamilyName) - { - case SPELLFAMILY_SHAMAN: - { - // Skyshatter Harness item set bonus - // Stormstrike - if (AuraEffect* aurEff = unitCaster->IsScriptOverriden(m_spellInfo, 5634)) - unitCaster->CastSpell(unitCaster, 38430, aurEff); - break; - } - case SPELLFAMILY_DRUID: - { - // Mangle (Cat): CP - if (m_spellInfo->SpellFamilyFlags[1] & 0x400) - unitCaster->CastSpell(unitTarget, 34071, true); - // Shred, Maul - Rend and Tear - else if (m_spellInfo->SpellFamilyFlags[0] & 0x00008800 && unitTarget->HasAuraState(AURA_STATE_BLEEDING)) - { - if (AuraEffect const* rendAndTear = unitCaster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0)) - AddPct(totalDamagePercentMod, rendAndTear->GetAmount()); - } - break; - } - case SPELLFAMILY_DEATHKNIGHT: - { - // Death Strike - if (m_spellInfo->SpellFamilyFlags[0] & 0x10) - { - // Glyph of Death Strike - // 2% more damage per 5 runic power, up to a maximum of 40% - if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(59336, EFFECT_0)) - if (uint32 runic = std::min(uint32(unitCaster->GetPower(POWER_RUNIC_POWER) / 2.5f), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(unitCaster))) - AddPct(totalDamagePercentMod, runic); - } - - // Obliterate / Blood Strike / Blood-Caked Strike (12.5% more damage per disease) / Heart Strike (15% more damage per disease) - if (m_spellInfo->SpellFamilyFlags[1] & 0x20000 || m_spellInfo->SpellFamilyFlags[0] & 0x400000 - || m_spellInfo->SpellFamilyFlags[0] & 0x1000000 || m_spellInfo->Id == 50463) - { - float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue(m_caster); - uint8 diseaseCount = unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), false); - - if (m_spellInfo->SpellFamilyFlags[1] & 0x20000) // Obliterate - 50% of Basepoints as bonus - bonusPct *= 0.5f; - else if (m_spellInfo->SpellFamilyFlags[0] & 0x400000) // Blood Strike - 10% of Basepoints as bonus - bonusPct *= 0.1f; - - float bonusAmount = bonusPct * diseaseCount; - // Death Knight T8 Melee 4P Bonus - if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(64736, EFFECT_0)) - AddPct(bonusAmount, aurEff->GetAmount()); - - AddPct(totalDamagePercentMod, bonusAmount); - } - - // Blood-Caked Strike - Blood-Caked Blade - if (m_spellInfo->SpellIconID == 1736) - AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(unitCaster->GetGUID()) * 50.0f); - - // Merciless Combat (Obliterate and Frost Strike) - if (m_spellInfo->SpellFamilyFlags[1] & 0x20000 || m_spellInfo->SpellFamilyFlags[1] & 0x4) - if (unitTarget->GetHealthPct() < 35.0f) - if (AuraEffect const* mercilessCombat = unitCaster->GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 2656, 0)) - AddPct(totalDamagePercentMod, mercilessCombat->GetAmount()); - break; - } - case SPELLFAMILY_WARLOCK: - { - if (useWeaponDamage) - { - // Felstorm and Legion Strike - if (m_spellInfo->Id == 89753) - { - if (unitCaster->IsPet()) - if (Unit* owner = unitCaster->GetOwner()) - m_damage += ((owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SHADOW) * 0.5f) * 2) * 0.231f; - } - else if (m_spellInfo->Id == 30213) - { - if (unitCaster->IsPet()) - if (Unit* owner = unitCaster->GetOwner()) - m_damage += ((owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SHADOW) * 0.5f) * 2) * 0.264f; - } - } - break; - } + break; // not weapon damage effect, just skip } } @@ -2911,20 +2832,30 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) fixed_bonus = int32(fixed_bonus * weapon_total_pct); } - int32 weaponDamage = useWeaponDamage ? unitCaster->CalculateDamage(m_attackType, normalized, addPctMods) : 0; + int32 weaponDamage = unitCaster->CalculateDamage(m_attackType, normalized, addPctMods); + Mechanics mechanic = MECHANIC_NONE; - switch (effectType) + // Sequence is important + for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) { - case SPELL_EFFECT_WEAPON_DAMAGE: - case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: - case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: - weaponDamage += fixed_bonus; - break; - case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: - weaponDamage = int32(weaponDamage * weaponDamagePercentMod); - break; - default: - break; + // We assume that a spell have at most one fixed_bonus + // and at most one weaponDamagePercentMod + switch (m_spellInfo->Effects[j].Effect) + { + case SPELL_EFFECT_WEAPON_DAMAGE: + case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: + case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: + weaponDamage += fixed_bonus; + break; + case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: + weaponDamage = int32(weaponDamage * weaponDamagePercentMod); + break; + default: + break; + } + + if (m_spellInfo->Effects[j].Mechanic != MECHANIC_NONE && mechanic == MECHANIC_NONE) + mechanic = m_spellInfo->Effects[j].Mechanic; } weaponDamage = int32(weaponDamage * totalDamagePercentMod); diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index bd1e9243c3..ac6722f60c 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -1456,9 +1456,12 @@ class spell_dk_disease : public AuraScript } // According to tooltip: ($m1*1.15+$AP*0.055*1.15) - void CalculateDamage(AuraEffect const* /*aurEff*/, Unit* /*victim*/, int32& damage, int32& /*flatMod*/, float& /*pctMod*/) + void CalculateDamage(AuraEffect const* /*aurEff*/, Unit* /*victim*/, int32& damage, int32& flatMod, float& /*pctMod*/) { - damage = damage * 1.15f + GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK) * 0.055f * 1.15f; + damage *= 1.15f; + + if (Unit* caster = GetCaster()) + flatMod = caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.055f * 1.15f; } void HandleResilientInfection(DispelInfo* /*dispelInfo*/) diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 9efbfc1972..00e383b26c 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -1594,33 +1594,44 @@ class spell_dru_pulverize : public SpellScript }); } - void ChangeDamage(SpellEffIndex /*effIndex*/) + void CalculateDamage(Unit* victim, int32& damage, int32& flatMod, float& /*pctMod*/) { Unit* caster = GetCaster(); - Unit* target = GetHitUnit(); - if (!caster || !target) - return; - // Formular: $m3 * $m1 / 100 - int32 bp = CalculatePct(GetEffectValue() * GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster), 1); + int32 normalizedWeaponDamage = GetSpellInfo()->Effects[EFFECT_2].CalcValue(caster); - if (Aura* aura = target->GetAura(SPELL_DRUID_LACERATE, caster->GetGUID())) + // Subtract the normalized weapon damage bonus because it's not supposed to be used in the regular way + damage -= normalizedWeaponDamage; + + if (Aura* aura = victim->GetAura(SPELL_DRUID_LACERATE, caster->GetGUID())) { - uint8 stacks = aura->GetStackAmount(); - bp *= stacks; - SetEffectValue(bp); + // Damage bonus per application of Lacerate: + // ${$m3*$m1/100} + int32 weaponPctDamage = GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster); + int32 lacerateBonus = CalculatePct(normalizedWeaponDamage, weaponPctDamage); + + flatMod += lacerateBonus * aura->GetStackAmount(); + } + } + + void HandleLacerateRemoval(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + + if (Aura* aura = GetHitUnit()->GetAura(SPELL_DRUID_LACERATE, caster->GetGUID())) + { + // Crit chance bonus per Lacerate stack consumed + int32 critPerStack = sSpellMgr->GetSpellInfo(SPELL_DRUID_PULVERIZE_TRIGGERED)->Effects[EFFECT_0].CalcValue(caster); + caster->CastSpell(caster, SPELL_DRUID_PULVERIZE_TRIGGERED, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellBP0(critPerStack * aura->GetStackAmount())); - uint32 critPerStack = sSpellMgr->GetSpellInfo(SPELL_DRUID_PULVERIZE_TRIGGERED)->Effects[EFFECT_0].BasePoints; - caster->CastSpell(caster, SPELL_DRUID_PULVERIZE_TRIGGERED, CastSpellExtraArgs(true).AddSpellBP0(int32(critPerStack * stacks))); aura->Remove(); } - else - SetEffectValue(0); } void Register() override { - OnEffectLaunchTarget.Register(&spell_dru_pulverize::ChangeDamage, EFFECT_2, SPELL_EFFECT_NORMALIZED_WEAPON_DMG); + CalcDamage.Register(&spell_dru_pulverize::CalculateDamage); + OnEffectHitTarget.Register(&spell_dru_pulverize::HandleLacerateRemoval, EFFECT_0, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE); } }; diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 6a6a27566e..cf4ac4bf53 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -34,7 +34,6 @@ namespace Spells::Hunter { enum HunterSpells { - SPELL_HUNTER_AIMED_SHOT = 19434, SPELL_HUNTER_BESTIAL_WRATH = 19574, SPELL_HUNTER_CALL_PET_1 = 883, SPELL_HUNTER_CALL_PET_2 = 83242, @@ -140,9 +139,15 @@ class spell_hun_ancient_hysteria : public SpellScript // 3044 - Arcane Shot class spell_hun_arcane_shot : public SpellScript { - void CalculateDamage(Unit* /*victim*/, int32& /*damage*/, int32& flatMod, float& /*pctMod*/) + void CalculateDamage(Unit* /*victim*/, int32& damage, int32& /*flatMod*/, float& /*pctMod*/) { - flatMod += GetCaster()->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.0493f; + Unit* caster = GetCaster(); + + // Due to limited control over weapon damage effects, we have to override the default damage calculation + // Arcane shot has a very special calculation pattern + damage = CalculatePct(caster->CalculateDamage(RANGED_ATTACK, true, true), GetSpellInfo()->Effects[EFFECT_1].CalcValue(caster)); + damage += GetCaster()->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.0493f; + damage += GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster); } void Register() override @@ -173,6 +178,11 @@ class spell_hun_chimera_shot : public SpellScript return ValidateSpellInfo({ SPELL_HUNTER_CHIMERA_SHOT_HEAL }); } + void CalculateDamage(Unit* /*victim*/, int32& /*damage*/, int32& flatMod, float& /*pctMod*/) + { + flatMod += GetCaster()->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.732f; + } + void HandleScriptEffect(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); @@ -187,6 +197,7 @@ class spell_hun_chimera_shot : public SpellScript void Register() override { + CalcDamage.Register(&spell_hun_chimera_shot::CalculateDamage); OnEffectHitTarget.Register(&spell_hun_chimera_shot::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -204,6 +215,11 @@ class spell_hun_cobra_shot : public SpellScript return ValidateSpellInfo({ SPELL_HUNTER_GENERIC_ENERGIZE_FOCUS }); } + void CalculateDamage(Unit* /*victim*/, int32& /*damage*/, int32& flatMod, float& /*pctMod*/) + { + flatMod += GetCaster()->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.017f; + } + void HandleLaunch(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); @@ -234,6 +250,7 @@ class spell_hun_cobra_shot : public SpellScript void Register() override { + CalcDamage.Register(&spell_hun_cobra_shot::CalculateDamage); OnEffectLaunch.Register(&spell_hun_cobra_shot::HandleLaunch, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); OnEffectHitTarget.Register(&spell_hun_cobra_shot::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } @@ -669,9 +686,14 @@ class spell_hun_steady_shot : public SpellScript return ValidateSpellInfo({ SPELL_HUNTER_STEADY_SHOT_FOCUS }); } - void CalculateDamage(Unit* /*victim*/, int32& /*damage*/, int32& flatMod, float& /*pctMod*/) + void CalculateDamage(Unit* /*victim*/, int32& damage, int32& /*flatMod*/, float& /*pctMod*/) { - flatMod += GetCaster()->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.021f; + Unit* caster = GetCaster(); + // Due to limited control over weapon damage effects, we have to override the default damage calculation + // Steady shot has a very special calculation pattern + damage = CalculatePct(caster->CalculateDamage(RANGED_ATTACK, true, true), GetSpellInfo()->Effects[EFFECT_1].CalcValue(caster)); + damage += caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.021f; + damage += GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster); } void HandleLaunch(SpellEffIndex /*effIndex*/) @@ -904,6 +926,12 @@ class spell_hun_serpent_sting : public AuraScript return ValidateSpellInfo({ SPELL_HUNTER_IMPROVED_SERPENT_STING_DAMAGE }); } + void CalculateDamage(AuraEffect const* /*aurEff*/, Unit* /*victim*/, int32& /*damage*/, int32& flatMod, float& /*pctMod*/) + { + if (Unit* caster = GetCaster()) + flatMod += caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f / 5; + } + void HandleImprovedSerpentSting(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { Unit* caster = GetCaster(); @@ -919,6 +947,7 @@ class spell_hun_serpent_sting : public AuraScript void Register() override { + DoEffectCalcDamageAndHealing.Register(&spell_hun_serpent_sting::CalculateDamage, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); AfterEffectApply.Register(&spell_hun_serpent_sting::HandleImprovedSerpentSting, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); } }; @@ -1458,11 +1487,57 @@ class spell_hun_serpent_spread : public AuraScript OnEffectProc.Register(&spell_hun_serpent_spread::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); } }; + +// 19434 - Aimed Shot +// 82928 - Aimed Shot! (Master Marksman) +class spell_hun_aimed_shot : public SpellScript +{ + bool Load() override + { + return GetCaster()->IsPlayer(); + } + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HUNTER_STEADY_SHOT_FOCUS }); + } + + void CalculateDamage(Unit* /*victim*/, int32& damage, int32& /*flatMod*/, float& /*pctMod*/) + { + Unit* caster = GetCaster(); + // Due to limited control over weapon damage effects, we have to override the default damage calculation + // Aimed Shot has a very special calculation pattern + damage = CalculatePct(caster->CalculateDamage(RANGED_ATTACK, true, true), GetSpellInfo()->Effects[EFFECT_1].CalcValue(caster)); + damage += caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.724f; + damage += GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster); + } + + void Register() override + { + CalcDamage.Register(&spell_hun_aimed_shot::CalculateDamage); + } +}; + +// 53301 - Explosive Shot +class spell_hun_explosive_shot : public AuraScript +{ + void CalculateDamage(AuraEffect const* /*aurEff*/, Unit* /*victim*/, int32& /*damage*/, int32& flatMod, float& /*pctMod*/) + { + if (Unit* caster = GetCaster()) + flatMod += caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.273f; + } + + void Register() override + { + DoEffectCalcDamageAndHealing.Register(&spell_hun_explosive_shot::CalculateDamage, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } +}; } void AddSC_hunter_spell_scripts() { using namespace Spells::Hunter; + RegisterSpellScript(spell_hun_aimed_shot); RegisterSpellScript(spell_hun_ancient_hysteria); RegisterSpellScript(spell_hun_arcane_shot); RegisterSpellScript(spell_hun_camouflage); @@ -1472,6 +1547,7 @@ void AddSC_hunter_spell_scripts() RegisterSpellScript(spell_hun_cobra_shot); RegisterSpellScript(spell_hun_crouching_tiger_hidden_chimera); RegisterSpellScript(spell_hun_disengage); + RegisterSpellScript(spell_hun_explosive_shot); RegisterSpellScript(spell_hun_fervor); RegisterSpellAndAuraScriptPair(spell_hun_focus_fire, spell_hun_focus_fire_AuraScript); RegisterSpellScript(spell_hun_frenzy_effect);