From 07c783225765cdb3089ad18d3c06959bd220b2b2 Mon Sep 17 00:00:00 2001 From: ratkosrb Date: Tue, 25 Feb 2025 17:59:21 +0200 Subject: [PATCH] Add more spell scripts. --- sql/migrations/20250217072022_world.sql | 2 +- sql/migrations/20250225150702_world.sql | 29 +++++++ src/game/Spells/SpellEffects.cpp | 85 ------------------- src/scripts/CMakeLists.txt | 3 +- src/scripts/ScriptLoader.cpp | 2 + .../naxxramas/boss_gluth.cpp | 23 +++++ .../naxxramas/boss_grobbulus.cpp | 47 ++++++++-- .../naxxramas/boss_kelthuzad.cpp | 27 ++++++ .../naxxramas/boss_thaddius.cpp | 48 +++++++++++ .../ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp | 31 +++++++ .../kalimdor/ungoro_crater/ungoro_crater.cpp | 24 ++++++ src/scripts/spells/spell_special.cpp | 72 ++++++++++++++++ 12 files changed, 297 insertions(+), 96 deletions(-) create mode 100644 sql/migrations/20250225150702_world.sql create mode 100644 src/scripts/spells/spell_special.cpp diff --git a/sql/migrations/20250217072022_world.sql b/sql/migrations/20250217072022_world.sql index 9add6764d4b..da37638ebe0 100644 --- a/sql/migrations/20250217072022_world.sql +++ b/sql/migrations/20250217072022_world.sql @@ -12,7 +12,7 @@ UPDATE `spell_template` SET `script_name`='spell_golemaggs_trust' WHERE `entry`= UPDATE `spell_template` SET `script_name`='spell_haunting_phantoms' WHERE `entry`= 16336; UPDATE `spell_template` SET `script_name`='spell_haunting_spirits' WHERE `entry`= 7057; UPDATE `spell_template` SET `script_name`='spell_gargoyle_stoneform' WHERE `entry`= 29153; -UPDATE `spell_template` SET `script_name`='spell_mutating_injection' WHERE `entry`= 28169; +UPDATE `spell_template` SET `script_name`='spell_grobbulus_mutating_injection' WHERE `entry`= 28169; -- End of migration. END IF; diff --git a/sql/migrations/20250225150702_world.sql b/sql/migrations/20250225150702_world.sql new file mode 100644 index 00000000000..becf50dbb3a --- /dev/null +++ b/sql/migrations/20250225150702_world.sql @@ -0,0 +1,29 @@ +DROP PROCEDURE IF EXISTS add_migration; +DELIMITER ?? +CREATE PROCEDURE `add_migration`() +BEGIN +DECLARE v INT DEFAULT 1; +SET v = (SELECT COUNT(*) FROM `migrations` WHERE `id`='20250225150702'); +IF v = 0 THEN +INSERT INTO `migrations` VALUES ('20250225150702'); +-- Add your query below. + + +-- Assign more spell scripts. +UPDATE `spell_template` SET `script_name`='spell_meteor' WHERE `entry` IN (24340, 26558, 26789, 28884) && `build` >= 5086; +UPDATE `spell_template` SET `script_name`='spell_rajaxx_thundercrash' WHERE `entry`=25599; +UPDATE `spell_template` SET `script_name`='spell_simone_seductress_chain_lightning' WHERE `entry`=23206; +UPDATE `spell_template` SET `script_name`='spell_thaddius_positive_charge' WHERE `entry`=28062; +UPDATE `spell_template` SET `script_name`='spell_thaddius_negative_charge' WHERE `entry`=28085; +UPDATE `spell_template` SET `script_name`='spell_gluth_decimate' WHERE `entry`=28375; +UPDATE `spell_template` SET `script_name`='spell_grobbulus_mutagen_explosion' WHERE `entry`=28206; +UPDATE `spell_template` SET `script_name`='spell_kelthuzad_void_blast' WHERE `entry`=27812; +UPDATE `spell_template` SET `script_name`='spell_darkmoon_steam_tonk_cannon' WHERE `entry`=24933; + + +-- End of migration. +END IF; +END?? +DELIMITER ; +CALL add_migration(); +DROP PROCEDURE IF EXISTS add_migration; diff --git a/src/game/Spells/SpellEffects.cpp b/src/game/Spells/SpellEffects.cpp index 8b6ebbbeb41..283c5f65c72 100644 --- a/src/game/Spells/SpellEffects.cpp +++ b/src/game/Spells/SpellEffects.cpp @@ -305,92 +305,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) switch (m_spellInfo->SpellFamilyName) { case SPELLFAMILY_GENERIC: - { - switch (m_spellInfo->Id) // better way to check unknown - { -#if SUPPORTED_CLIENT_BUILD > CLIENT_BUILD_1_8_4 - // Meteor like spells (divided damage to targets) - case 24340: - case 26558: - case 28884: // Meteor - case 26789: // Shard of the Fallen Star - { - uint32 count = 0; - for (const auto& ihit : m_UniqueTargetInfo) - if (ihit.effectMask & (1 << effect_idx)) - ++count; - - damage /= count; // divide to all targets - break; - } -#endif - // percent from health with min - case 25599: // Thundercrash - { - damage = unitTarget->GetHealth() / 2.F; - if (damage < 200) - damage = 200; - break; - } - case 23206: // Chain Lightning (Simone the Seductress) - { - if (unitTarget->HasAura(20190)) // reduce damage by 75% if target has Aspect of the Wild (Rank 2) - damage *= 0.25; - break; - } - // Thaddius positive charge tick - case 28062: - { - // Target also has positive charge, so no damage - if (unitTarget->HasAura(28059)) - damage = 0; - break; - } - // Thaddius negative charge tick - case 28085: - { - // Target also has negative charge, so no damage - if (unitTarget->HasAura(28084)) - damage = 0; - break; - } - case 28375: // Gluth decimate - { - // damage should put target at maximum 5% hp, but not reduce it below that - damage = std::max(0, int32(unitTarget->GetHealth() - uint32(unitTarget->GetMaxHealth() * 0.05f))); - break; - } - case 28206: // Grobbulus Mutagen Explosion - { - // All sources say the explosion should do around 4.5k physical dmg if it runs out, - // but "less" if dispelled. I have been able to find different variations of this spell, - // so the hack has become to set m_triggeredBySpellInfo when casting this spell from Aura::HandleAuraDummy - // when 28169 expires, and NOT set m_triggeredBySpellInfo 28169 is dispelled. - if (m_triggeredBySpellInfo) - damage = damage * 1.5f; - else - damage = damage / 1.5f; - break; - } - case 27812: // Kel'Thuzad Void Blast - { - // If target has the chains of kel'thuzad aura the spell should not do any damage. - // This check should not be necessary as you should be friendly to the caster of - // the spell, but some bug caused players to take damage anyway, and even if that is fixed, - // this is a safetycheck. - if (unitTarget->HasAura(28410)) - damage = 0; - break; - } - case 24933: // Cannon (Darkmoon Steam Tonk) - { - m_caster->CastSpell(unitTarget, 27766, true); - break; - } - } break; - } - case SPELLFAMILY_MAGE: break; case SPELLFAMILY_WARRIOR: diff --git a/src/scripts/CMakeLists.txt b/src/scripts/CMakeLists.txt index dc894e9282f..79b35cf38d3 100644 --- a/src/scripts/CMakeLists.txt +++ b/src/scripts/CMakeLists.txt @@ -242,9 +242,10 @@ set (SCRIPTS_SRCS kalimdor/ungoro_crater/ungoro_crater.cpp kalimdor/winterspring/winterspring.cpp spells/spell_hunter.cpp + spells/spell_item.cpp + spells/spell_special.cpp spells/spell_warlock.cpp spells/spell_warrior.cpp - spells/spell_item.cpp world/areatrigger_scripts.cpp world/elemental_invasions.cpp world/fireworks_show.cpp diff --git a/src/scripts/ScriptLoader.cpp b/src/scripts/ScriptLoader.cpp index 090c012963e..a9be1eb554e 100644 --- a/src/scripts/ScriptLoader.cpp +++ b/src/scripts/ScriptLoader.cpp @@ -244,6 +244,7 @@ void AddSC_hunter_spell_scripts(); void AddSC_warrior_spell_scripts(); void AddSC_warlock_spell_scripts(); void AddSC_item_spell_scripts(); +void AddSC_special_spell_scripts(); void AddScripts() { @@ -484,4 +485,5 @@ void AddScripts() AddSC_warrior_spell_scripts(); AddSC_warlock_spell_scripts(); AddSC_item_spell_scripts(); + AddSC_special_spell_scripts(); } diff --git a/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_gluth.cpp b/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_gluth.cpp index c677e26a9a9..0bb95d5137d 100644 --- a/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_gluth.cpp +++ b/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_gluth.cpp @@ -375,6 +375,24 @@ CreatureAI* GetAI_mob_zombieChow(Creature* pCreature) return new mob_zombieChow(pCreature); } +// 28375 - Decimate (Gluth) +struct GluthDecimateScript : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const final + { + if (effIdx == EFFECT_INDEX_0 && spell->GetUnitTarget()) + { + // damage should put target at maximum 5% hp, but not reduce it below that + spell->damage = std::max(0, int32(spell->GetUnitTarget()->GetHealth() - uint32(spell->GetUnitTarget()->GetMaxHealth() * 0.05f))); + } + } +}; + +SpellScript* GetScript_GluthDecimate(SpellEntry const*) +{ + return new GluthDecimateScript(); +} + void AddSC_boss_gluth() { Script* NewScript; @@ -387,4 +405,9 @@ void AddSC_boss_gluth() NewScript->Name = "mob_zombie_chow"; NewScript->GetAI = &GetAI_mob_zombieChow; NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "spell_gluth_decimate"; + NewScript->GetSpellScript = &GetScript_GluthDecimate; + NewScript->RegisterSelf(); } diff --git a/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_grobbulus.cpp b/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_grobbulus.cpp index 25a844d6299..659a0cea05f 100644 --- a/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_grobbulus.cpp +++ b/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_grobbulus.cpp @@ -235,8 +235,8 @@ CreatureAI* GetAI_boss_grobbulus(Creature* pCreature) return new boss_grobbulusAI(pCreature); } -// 28169 - Mutating Injection -struct MutatingInjectionScript : public AuraScript +// 28169 - Mutating Injection (Grobbulus) +struct GrobbulusMutatingInjectionScript : public AuraScript { void OnBeforeApply(Aura* aura, bool apply) final { @@ -262,7 +262,12 @@ struct MutatingInjectionScript : public AuraScript } }; -// 28241 - Poison (Naxxramas, Grobbulus Cloud) +AuraScript* GetScript_GrobbulusMutatingInjection(SpellEntry const*) +{ + return new GrobbulusMutatingInjectionScript(); +} + +// 28241 - Poison (Grobbulus Cloud) struct GrobbulusCloudPoisonScript : SpellScript { void OnSetTargetMap(Spell* spell, SpellEffectIndex /*effIdx*/, uint32& /*targetMode*/, float& radius, uint32& /*unMaxTargets*/, bool& /*selectClosestTargets*/) const final @@ -283,14 +288,33 @@ struct GrobbulusCloudPoisonScript : SpellScript } }; -AuraScript* GetScript_MutatingInjection(SpellEntry const*) +SpellScript* GetScript_GrobbulusCloudPoison(SpellEntry const*) { - return new MutatingInjectionScript(); + return new GrobbulusCloudPoisonScript(); } -SpellScript* GetScript_GrobbulusCloudPoison(SpellEntry const*) +// 28206 - Mutagen Explosion (Grobbulus) +struct GrobbulusMutagenExplosionScript : public SpellScript { - return new GrobbulusCloudPoisonScript(); + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const final + { + if (effIdx == EFFECT_INDEX_0 && spell->GetUnitTarget()) + { + // All sources say the explosion should do around 4.5k physical dmg if it runs out, + // but "less" if dispelled. I have been able to find different variations of this spell, + // so the hack has become to set m_triggeredBySpellInfo when casting this spell from Aura::HandleAuraDummy + // when 28169 expires, and NOT set m_triggeredBySpellInfo 28169 is dispelled. + if (spell->m_triggeredBySpellInfo) + spell->damage = spell->damage * 1.5f; + else + spell->damage = spell->damage / 1.5f; + } + } +}; + +SpellScript* GetScript_GrobbulusMutagenExplosion(SpellEntry const*) +{ + return new GrobbulusMutagenExplosionScript(); } void AddSC_boss_grobbulus() @@ -303,12 +327,17 @@ void AddSC_boss_grobbulus() pNewScript->RegisterSelf(); pNewScript = new Script; - pNewScript->Name = "spell_mutating_injection"; - pNewScript->GetAuraScript = &GetScript_MutatingInjection; + pNewScript->Name = "spell_grobbulus_mutating_injection"; + pNewScript->GetAuraScript = &GetScript_GrobbulusMutatingInjection; pNewScript->RegisterSelf(); pNewScript = new Script; pNewScript->Name = "spell_grobbulus_cloud_poison"; pNewScript->GetSpellScript = &GetScript_GrobbulusCloudPoison; pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "spell_grobbulus_mutagen_explosion"; + pNewScript->GetSpellScript = &GetScript_GrobbulusMutagenExplosion; + pNewScript->RegisterSelf(); } diff --git a/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_kelthuzad.cpp b/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_kelthuzad.cpp index 8ec02a4aa31..bec80834a6d 100644 --- a/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_kelthuzad.cpp +++ b/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_kelthuzad.cpp @@ -1119,6 +1119,28 @@ void instance_naxxramas::OnKTAreaTrigger(AreaTriggerEntry const* pAT) } } +// 27812 - Void Blast (Kel'Thuzad) +struct KelThuzadVoidBlastScript : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const final + { + if (effIdx == EFFECT_INDEX_0 && spell->GetUnitTarget()) + { + // If target has the chains of kel'thuzad aura the spell should not do any damage. + // This check should not be necessary as you should be friendly to the caster of + // the spell, but some bug caused players to take damage anyway, and even if that is fixed, + // this is a safetycheck. + if (spell->GetUnitTarget()->HasAura(28410)) + spell->damage = 0; + } + } +}; + +SpellScript* GetScript_KelThuzadVoidBlast(SpellEntry const*) +{ + return new KelThuzadVoidBlastScript(); +} + void AddSC_boss_kelthuzad() { Script* NewScript; @@ -1152,4 +1174,9 @@ void AddSC_boss_kelthuzad() NewScript->Name = "mob_shadow_fissure"; NewScript->GetAI = &GetAI_mob_shadow_fissure; NewScript->RegisterSelf(); + + NewScript = new Script; + NewScript->Name = "spell_kelthuzad_void_blast"; + NewScript->GetSpellScript = &GetScript_KelThuzadVoidBlast; + NewScript->RegisterSelf(); } diff --git a/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_thaddius.cpp b/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_thaddius.cpp index 0f9ec148076..0f6c6f1adc2 100644 --- a/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_thaddius.cpp +++ b/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_thaddius.cpp @@ -1087,6 +1087,44 @@ CreatureAI* GetAI_boss_thaddius(Creature* pCreature) return new boss_thaddiusAI(pCreature); } +// 28062 - Positive Charge (Thaddius) +struct ThaddiusPositiveChargeScript : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const final + { + if (effIdx == EFFECT_INDEX_0 && spell->GetUnitTarget()) + { + // Target also has positive charge, so no damage + if (spell->GetUnitTarget()->HasAura(28059)) + spell->damage = 0; + } + } +}; + +SpellScript* GetScript_ThaddiusPositiveCharge(SpellEntry const*) +{ + return new ThaddiusPositiveChargeScript(); +} + +// 28085 - Negative Charge (Thaddius) +struct ThaddiusNegativeChargeScript : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const final + { + if (effIdx == EFFECT_INDEX_0 && spell->GetUnitTarget()) + { + // Target also has negative charge, so no damage + if (spell->GetUnitTarget()->HasAura(28084)) + spell->damage = 0; + } + } +}; + +SpellScript* GetScript_ThaddiusNegativeCharge(SpellEntry const*) +{ + return new ThaddiusNegativeChargeScript(); +} + void AddSC_boss_thaddius() { Script* pNewScript; @@ -1110,4 +1148,14 @@ void AddSC_boss_thaddius() pNewScript->Name = "npc_tesla_coil"; pNewScript->GetAI = &GetAI_npc_tesla_coil; pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "spell_thaddius_positive_charge"; + pNewScript->GetSpellScript = &GetScript_ThaddiusPositiveCharge; + pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "spell_thaddius_negative_charge"; + pNewScript->GetSpellScript = &GetScript_ThaddiusNegativeCharge; + pNewScript->RegisterSelf(); } diff --git a/src/scripts/kalimdor/silithus/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp b/src/scripts/kalimdor/silithus/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp index ddca0dd058b..25da0ac3409 100644 --- a/src/scripts/kalimdor/silithus/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp +++ b/src/scripts/kalimdor/silithus/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp @@ -1088,6 +1088,32 @@ SpellScript* GetScript_AQ20DrainMana(SpellEntry const*) return new AQ20DrainManaScript(); } +// 25599 - Thundercrash +struct RajaxxThundercrashScript : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const final + { + if (effIdx == EFFECT_INDEX_0 && spell->GetUnitTarget()) + { + // percent from health with min + int32 damage = spell->GetUnitTarget()->GetHealth() / 2; + if (damage < 200) + damage = 200; + +#if SUPPORTED_CLIENT_BUILD >= CLIENT_BUILD_1_11_2 + spell->damage = damage; +#else + spell->m_caster->CastCustomSpell(spell->GetUnitTarget(), 25598, damage, {}, {}, true); +#endif + } + } +}; + +SpellScript* GetScript_RajaxxThundercrash(SpellEntry const*) +{ + return new RajaxxThundercrashScript(); +} + void AddSC_ruins_of_ahnqiraj() { Script* newscript; @@ -1155,4 +1181,9 @@ void AddSC_ruins_of_ahnqiraj() newscript->Name = "spell_aq20_drain_mana"; newscript->GetSpellScript = &GetScript_AQ20DrainMana; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "spell_rajaxx_thundercrash"; + newscript->GetSpellScript = &GetScript_RajaxxThundercrash; + newscript->RegisterSelf(); } diff --git a/src/scripts/kalimdor/ungoro_crater/ungoro_crater.cpp b/src/scripts/kalimdor/ungoro_crater/ungoro_crater.cpp index e2b1e0675af..0e21e1ffc25 100644 --- a/src/scripts/kalimdor/ungoro_crater/ungoro_crater.cpp +++ b/src/scripts/kalimdor/ungoro_crater/ungoro_crater.cpp @@ -943,6 +943,25 @@ CreatureAI* GetAI_npc_simone_the_inconspicuous(Creature* pCreature) return new npc_simone_the_inconspicuousAI(pCreature); } +// 23206 - Chain Lightning (Simone the Seductress) +struct SimoneSeductressChainLightningScript : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const final + { + if (effIdx == EFFECT_INDEX_0 && spell->GetUnitTarget()) + { + // reduce damage by 75% if target has Aspect of the Wild (Rank 2) + if (spell->GetUnitTarget()->HasAura(20190)) + spell->damage *= 0.25; + } + } +}; + +SpellScript* GetScript_SimoneSeductressChainLightning(SpellEntry const*) +{ + return new SimoneSeductressChainLightningScript(); +} + void AddSC_ungoro_crater() { Script* newscript; @@ -985,4 +1004,9 @@ void AddSC_ungoro_crater() newscript->Name = "mob_captured_felwood_ooze"; newscript->GetAI = &GetAI_mob_captured_felwood_ooze; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "spell_simone_seductress_chain_lightning"; + newscript->GetSpellScript = &GetScript_SimoneSeductressChainLightning; + newscript->RegisterSelf(); } diff --git a/src/scripts/spells/spell_special.cpp b/src/scripts/spells/spell_special.cpp new file mode 100644 index 00000000000..c9f2b9b4f85 --- /dev/null +++ b/src/scripts/spells/spell_special.cpp @@ -0,0 +1,72 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "scriptPCH.h" + +// 24340, 26558, 28884 - Meteor +// 26789 - Shard of the Fallen Star +struct MeteorScript : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const final + { + if (effIdx == EFFECT_INDEX_0) + { + uint32 count = 0; + for (const auto& ihit : spell->m_UniqueTargetInfo) + if (ihit.effectMask & (1 << effIdx)) + ++count; + + spell->damage /= count; // divide to all targets + } + } +}; + +SpellScript* GetScript_Meteor(SpellEntry const*) +{ + return new MeteorScript(); +} + +// 24933 - Cannon (Darkmoon Steam Tonk) +struct DarkmoonSteamTonkCannonScript : public SpellScript +{ + void OnEffectExecute(Spell* spell, SpellEffectIndex effIdx) const final + { + if (effIdx == EFFECT_INDEX_0 && spell->GetUnitTarget()) + { + spell->m_caster->CastSpell(spell->GetUnitTarget(), 27766, true); + } + } +}; + +SpellScript* GetScript_DarkmoonSteamTonkCannon(SpellEntry const*) +{ + return new DarkmoonSteamTonkCannonScript(); +} + +void AddSC_special_spell_scripts() +{ + Script* newscript; + + newscript = new Script; + newscript->Name = "spell_meteor"; + newscript->GetSpellScript = &GetScript_Meteor; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "spell_darkmoon_steam_tonk_cannon"; + newscript->GetSpellScript = &GetScript_DarkmoonSteamTonkCannon; + newscript->RegisterSelf(); +}