aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoroffl <11556157+offl@users.noreply.github.com>2025-07-13 22:03:02 +0300
committerGitHub <noreply@github.com>2025-07-13 21:03:02 +0200
commitf40409ce68624fc907d7f1e272317411b5a2fa65 (patch)
tree0852d80c943704ef566dd9e676079a10ed7f88f9
parent70d18754848c376f93e1ab9d7119c6818d594db8 (diff)
Scripts/Maraudon: Modernize scripts (#31092)
* New register model * Codestyle changes * TaskScheduler instead of timer variables * Implement one spell script for Noxxion encounter
-rw-r--r--sql/updates/world/3.3.5/2025_07_13_00_world.sql6
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp122
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp116
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp177
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp133
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/maraudon.h2
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__