diff options
6 files changed, 231 insertions, 325 deletions
diff --git a/sql/updates/world/3.3.5/2025_07_13_00_world.sql b/sql/updates/world/3.3.5/2025_07_13_00_world.sql new file mode 100644 index 00000000000..dd6a753563e --- /dev/null +++ b/sql/updates/world/3.3.5/2025_07_13_00_world.sql @@ -0,0 +1,6 @@ +-- +UPDATE `creature_template` SET `ScriptName` = 'boss_celebras_the_cursed' WHERE `entry` = 12225; + +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_noxxion_summon_spawns'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(21708, 'spell_noxxion_summon_spawns'); diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp index 23381de577d..70c9ee7571d 100644 --- a/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp +++ b/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp @@ -15,101 +15,77 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Celebras_the_Cursed -SD%Complete: 100 -SDComment: -SDCategory: Maraudon -EndScriptData */ - #include "ScriptMgr.h" #include "maraudon.h" #include "ScriptedCreature.h" -enum Spells +enum CelebrasSpells { SPELL_WRATH = 21807, - SPELL_ENTANGLINGROOTS = 12747, + SPELL_ENTANGLING_ROOTS = 12747, SPELL_CORRUPT_FORCES = 21968 }; -class celebras_the_cursed : public CreatureScript +enum CelebrasMisc +{ + NPC_CELEBRAS_THE_REDEEMED = 13716 +}; + +// 12225 - Celebras the Cursed +struct boss_celebras_the_cursed : public ScriptedAI { -public: - celebras_the_cursed() : CreatureScript("celebras_the_cursed") { } + boss_celebras_the_cursed(Creature* creature) : ScriptedAI(creature) { } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetMaraudonAI<celebras_the_cursedAI>(creature); + _scheduler.CancelAll(); } - struct celebras_the_cursedAI : public ScriptedAI + void JustEngagedWith(Unit* /*who*/) override { - celebras_the_cursedAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - WrathTimer = 8000; - EntanglingRootsTimer = 2000; - CorruptForcesTimer = 30000; - } - - uint32 WrathTimer; - uint32 EntanglingRootsTimer; - uint32 CorruptForcesTimer; - - void Reset() override - { - Initialize(); - } - - void JustEngagedWith(Unit* /*who*/) override { } - - void JustDied(Unit* /*killer*/) override - { - me->SummonCreature(13716, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10min); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - //Wrath - if (WrathTimer <= diff) + _scheduler + .SetValidator([this] { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - DoCast(target, SPELL_WRATH); - WrathTimer = 8000; - } - else WrathTimer -= diff; - - //EntanglingRoots - if (EntanglingRootsTimer <= diff) + return !me->HasUnitState(UNIT_STATE_CASTING); + }) + .Schedule(0s, 6s, [this](TaskContext task) { - DoCastVictim(SPELL_ENTANGLINGROOTS); - EntanglingRootsTimer = 20000; - } - else EntanglingRootsTimer -= diff; - - //CorruptForces - if (CorruptForcesTimer <= diff) + DoCastVictim(SPELL_WRATH); + task.Repeat(4s, 8s); + }) + .Schedule(0s, 5s, [this](TaskContext task) { - me->InterruptNonMeleeSpells(false); - DoCast(me, SPELL_CORRUPT_FORCES); - CorruptForcesTimer = 20000; - } - else CorruptForcesTimer -= diff; + DoCastVictim(SPELL_ENTANGLING_ROOTS); + task.Repeat(20s); + }) + .Schedule(30s, [this](TaskContext task) + { + DoCastSelf(SPELL_CORRUPT_FORCES); + task.Repeat(20s); + }); + } + + void JustDied(Unit* /*killer*/) override + { + me->SummonCreature(NPC_CELEBRAS_THE_REDEEMED, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + _scheduler.Update(diff, [this] + { DoMeleeAttackIfReady(); - } - }; + }); + } + +private: + TaskScheduler _scheduler; }; void AddSC_boss_celebras_the_cursed() { - new celebras_the_cursed(); + RegisterMaraudonCreatureAI(boss_celebras_the_cursed); } diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp index 07eae93c6e3..eddbd5baf85 100644 --- a/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp +++ b/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp @@ -15,100 +15,78 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Landslide -SD%Complete: 100 -SDComment: -SDCategory: Maraudon -EndScriptData */ - #include "ScriptMgr.h" #include "maraudon.h" #include "ScriptedCreature.h" -enum Spells +enum LandslideSpells { - SPELL_KNOCKAWAY = 18670, + SPELL_KNOCK_AWAY = 18670, SPELL_TRAMPLE = 5568, SPELL_LANDSLIDE = 21808 }; -class boss_landslide : public CreatureScript +// 12203 - Landslide +struct boss_landslide : public ScriptedAI { -public: - boss_landslide() : CreatureScript("boss_landslide") { } + boss_landslide(Creature* creature) : ScriptedAI(creature), _landslide(false) { } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetMaraudonAI<boss_landslideAI>(creature); + _scheduler.CancelAll(); + _landslide = false; } - struct boss_landslideAI : public ScriptedAI + void JustEngagedWith(Unit* /*who*/) override { - boss_landslideAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } + _scheduler + .SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }) + .Schedule(5s, 10s, [this](TaskContext task) + { + DoCastVictim(SPELL_KNOCK_AWAY); + task.Repeat(15s, 25s); + }) + .Schedule(10s, 15s, [this](TaskContext task) + { + DoCastSelf(SPELL_TRAMPLE); + task.Repeat(10s, 20s); + }); + } - void Initialize() + void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override + { + if (!_landslide && me->HealthBelowPctDamaged(50, damage)) { - KnockAwayTimer = 8000; - TrampleTimer = 2000; - LandslideTimer = 0; - } - - uint32 KnockAwayTimer; - uint32 TrampleTimer; - uint32 LandslideTimer; + _landslide = true; - void Reset() override - { - Initialize(); + _scheduler.Schedule(0s, [this](TaskContext task) + { + DoCastSelf(SPELL_LANDSLIDE); + task.Repeat(30s, 40s); + }); } + } - void JustEngagedWith(Unit* /*who*/) override - { - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void UpdateAI(uint32 diff) override + _scheduler.Update(diff, [this] { - if (!UpdateVictim()) - return; - - //KnockAwayTimer - if (KnockAwayTimer <= diff) - { - DoCastVictim(SPELL_KNOCKAWAY); - KnockAwayTimer = 15000; - } - else KnockAwayTimer -= diff; - - //TrampleTimer - if (TrampleTimer <= diff) - { - DoCast(me, SPELL_TRAMPLE); - TrampleTimer = 8000; - } - else TrampleTimer -= diff; - - //Landslide - if (HealthBelowPct(50)) - { - if (LandslideTimer <= diff) - { - me->InterruptNonMeleeSpells(false); - DoCast(me, SPELL_LANDSLIDE); - LandslideTimer = 60000; - } - else LandslideTimer -= diff; - } - DoMeleeAttackIfReady(); - } - }; + }); + } + +private: + TaskScheduler _scheduler; + bool _landslide; }; void AddSC_boss_landslide() { - new boss_landslide(); + RegisterMaraudonCreatureAI(boss_landslide); } diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp index ac6d038bfa9..756c6eaad62 100644 --- a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp +++ b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp @@ -15,135 +15,106 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Noxxion -SD%Complete: 100 -SDComment: -SDCategory: Maraudon -EndScriptData */ - #include "ScriptMgr.h" #include "maraudon.h" #include "ScriptedCreature.h" +#include "SpellScript.h" -enum Spells +enum NoxxionSpells { - SPELL_TOXICVOLLEY = 21687, - SPELL_UPPERCUT = 22916 + SPELL_TOXIC_VOLLEY = 21687, + SPELL_UPPERCUT = 22916, + SPELL_SUMMON_SPAWNS_DUMMY = 21708, + SPELL_SUMMON_SPAWNS = 21707 }; -class boss_noxxion : public CreatureScript +// 13282 - Noxxion +struct boss_noxxion : public ScriptedAI { -public: - boss_noxxion() : CreatureScript("boss_noxxion") { } + boss_noxxion(Creature* creature) : ScriptedAI(creature) { } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetMaraudonAI<boss_noxxionAI>(creature); + _scheduler.CancelAll(); } - struct boss_noxxionAI : public ScriptedAI + void JustEngagedWith(Unit* /*who*/) override { - boss_noxxionAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } + _scheduler + .SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }) + .Schedule(5s, 10s, [this](TaskContext task) + { + DoCastSelf(SPELL_TOXIC_VOLLEY); + task.Repeat(15s, 20s); + }) + .Schedule(15s, 20s, [this](TaskContext task) + { + DoCastVictim(SPELL_UPPERCUT); + task.Repeat(20s, 30s); + }) + .Schedule(30s, 40s, [this](TaskContext task) + { + DoCastSelf(SPELL_SUMMON_SPAWNS_DUMMY); + task.Repeat(50s, 60s); + }); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void Initialize() + _scheduler.Update(diff, [this] { - ToxicVolleyTimer = 7000; - UppercutTimer = 16000; - AddsTimer = 19000; - InvisibleTimer = 15000; //Too much too low? - Invisible = false; - } + DoMeleeAttackIfReady(); + }); + } - uint32 ToxicVolleyTimer; - uint32 UppercutTimer; - uint32 AddsTimer; - uint32 InvisibleTimer; - bool Invisible; +private: + TaskScheduler _scheduler; +}; - void Reset() override - { - Initialize(); - } +// 21708 - Summon Noxxion's Spawns +class spell_noxxion_summon_spawns : public AuraScript +{ + PrepareAuraScript(spell_noxxion_summon_spawns); - void JustEngagedWith(Unit* /*who*/) override { } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SUMMON_SPAWNS }); + } - void SummonAdds(Unit* victim) + void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) { - if (Creature* Add = DoSpawnCreature(13456, float(irand(-7, 7)), float(irand(-7, 7)), 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90s)) - Add->AI()->AttackStart(victim); + target->SetReactState(REACT_PASSIVE); + target->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE); + target->CastSpell(target, SPELL_SUMMON_SPAWNS, true); } + } - void UpdateAI(uint32 diff) override + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) { - if (Invisible && InvisibleTimer <= diff) - { - //Become visible again - me->SetFaction(FACTION_MONSTER); - me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - //Noxxion model - me->SetDisplayId(11172); - Invisible = false; - //me->m_canMove = true; - } - else if (Invisible) - { - InvisibleTimer -= diff; - //Do nothing while invisible - return; - } - - //Return since we have no target - if (!UpdateVictim()) - return; - - //ToxicVolleyTimer - if (ToxicVolleyTimer <= diff) - { - DoCastVictim(SPELL_TOXICVOLLEY); - ToxicVolleyTimer = 9000; - } - else ToxicVolleyTimer -= diff; - - //UppercutTimer - if (UppercutTimer <= diff) - { - DoCastVictim(SPELL_UPPERCUT); - UppercutTimer = 12000; - } - else UppercutTimer -= diff; - - //AddsTimer - if (!Invisible && AddsTimer <= diff) - { - //Interrupt any spell casting - //me->m_canMove = true; - me->InterruptNonMeleeSpells(false); - me->SetFaction(FACTION_FRIENDLY); - me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - // Invisible Model - me->SetDisplayId(11686); - SummonAdds(me->GetVictim()); - SummonAdds(me->GetVictim()); - SummonAdds(me->GetVictim()); - SummonAdds(me->GetVictim()); - SummonAdds(me->GetVictim()); - Invisible = true; - InvisibleTimer = 15000; - - AddsTimer = 40000; - } - else AddsTimer -= diff; - - DoMeleeAttackIfReady(); + target->SetReactState(REACT_AGGRESSIVE); + target->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); } - }; + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_noxxion_summon_spawns::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectApplyFn(spell_noxxion_summon_spawns::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; void AddSC_boss_noxxion() { - new boss_noxxion(); + RegisterMaraudonCreatureAI(boss_noxxion); + RegisterSpellScript(spell_noxxion_summon_spawns); } diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp index 01cf3575970..267f9e4e397 100644 --- a/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp +++ b/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp @@ -15,111 +15,84 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Princess_Theradras -SD%Complete: 100 -SDComment: -SDCategory: Maraudon -EndScriptData */ - #include "ScriptMgr.h" #include "maraudon.h" #include "ScriptedCreature.h" -enum Spells +enum TheradrasSpells { - SPELL_DUSTFIELD = 21909, + SPELL_DUST_FIELD = 21909, SPELL_BOULDER = 21832, SPELL_THRASH = 3391, - SPELL_REPULSIVEGAZE = 21869 + SPELL_REPULSIVE_GAZE = 21869 +}; + +enum TheradrasMisc +{ + NPC_ZAETARS_SPIRIT = 12238 }; -class boss_princess_theradras : public CreatureScript +// 12201 - Princess Theradras +struct boss_princess_theradras : public ScriptedAI { -public: - boss_princess_theradras() : CreatureScript("boss_princess_theradras") { } + boss_princess_theradras(Creature* creature) : ScriptedAI(creature) { } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetMaraudonAI<boss_ptheradrasAI>(creature); + _scheduler.CancelAll(); } - struct boss_ptheradrasAI : public ScriptedAI + void JustEngagedWith(Unit* /*who*/) override { - boss_ptheradrasAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - DustfieldTimer = 8000; - BoulderTimer = 2000; - ThrashTimer = 5000; - RepulsiveGazeTimer = 23000; - } - - uint32 DustfieldTimer; - uint32 BoulderTimer; - uint32 ThrashTimer; - uint32 RepulsiveGazeTimer; - - void Reset() override - { - Initialize(); - } - - void JustEngagedWith(Unit* /*who*/) override { } - - void JustDied(Unit* /*killer*/) override - { - me->SummonCreature(12238, 28.1887f, 62.3964f, -123.161f, 4.31096f, TEMPSUMMON_TIMED_DESPAWN, 10min); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - //DustfieldTimer - if (DustfieldTimer <= diff) + _scheduler + .SetValidator([this] { - DoCast(me, SPELL_DUSTFIELD); - DustfieldTimer = 14000; - } - else DustfieldTimer -= diff; - - //BoulderTimer - if (BoulderTimer <= diff) + return !me->HasUnitState(UNIT_STATE_CASTING); + }) + .Schedule(20s, 25s, [this](TaskContext task) + { + DoCastSelf(SPELL_DUST_FIELD); + task.Repeat(20s, 25s); + }) + .Schedule(20s, 30s, [this](TaskContext task) { if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) DoCast(target, SPELL_BOULDER); - BoulderTimer = 10000; - } - else BoulderTimer -= diff; - - //RepulsiveGazeTimer - if (RepulsiveGazeTimer <= diff) + task.Repeat(15s, 25s); + }) + .Schedule(10s, 20s, [this](TaskContext task) { - DoCastVictim(SPELL_REPULSIVEGAZE); - RepulsiveGazeTimer = 20000; - } - else RepulsiveGazeTimer -= diff; - - //ThrashTimer - if (ThrashTimer <= diff) + DoCastSelf(SPELL_THRASH); + task.Repeat(10s, 20s); + }) + .Schedule(25s, 35s, [this](TaskContext task) { - DoCast(me, SPELL_THRASH); - ThrashTimer = 18000; - } - else ThrashTimer -= diff; + DoCastSelf(SPELL_REPULSIVE_GAZE); + task.Repeat(30s, 40s); + }); + } + + void JustDied(Unit* /*killer*/) override + { + me->SummonCreature(NPC_ZAETARS_SPIRIT, 28.1887f, 62.3964f, -123.161f, 4.31096f, TEMPSUMMON_MANUAL_DESPAWN); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + _scheduler.Update(diff, [this] + { DoMeleeAttackIfReady(); - } - }; + }); + } + +private: + TaskScheduler _scheduler; }; void AddSC_boss_ptheradras() { - new boss_princess_theradras(); + RegisterMaraudonCreatureAI(boss_princess_theradras); } diff --git a/src/server/scripts/Kalimdor/Maraudon/maraudon.h b/src/server/scripts/Kalimdor/Maraudon/maraudon.h index 01226e42411..a00aeb1c9a0 100644 --- a/src/server/scripts/Kalimdor/Maraudon/maraudon.h +++ b/src/server/scripts/Kalimdor/Maraudon/maraudon.h @@ -28,4 +28,6 @@ inline AI* GetMaraudonAI(T* obj) return GetInstanceAI<AI>(obj, MaraudonScriptName); } +#define RegisterMaraudonCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetMaraudonAI) + #endif // maraudon_h__ |