From 7acf0b568ffd4a077b8ccb21f5ec65624b0990db Mon Sep 17 00:00:00 2001
From: offl <11556157+offl@users.noreply.github.com>
Date: Sat, 11 Apr 2026 12:13:44 +0300
Subject: [PATCH] Scripts/Serpentshrine Cavern: Rewrite Morogrim (#31733)
(cherry picked from commit 355e2ef0dcece565f717bce09580826162db8b64)
---
...026_06_30_18_world_2026_04_11_00_world.sql | 53 ++
.../boss_morogrim_tidewalker.cpp | 499 ++++++++++--------
2 files changed, 318 insertions(+), 234 deletions(-)
create mode 100644 sql/updates/world/master/2026_06_30_18_world_2026_04_11_00_world.sql
diff --git a/sql/updates/world/master/2026_06_30_18_world_2026_04_11_00_world.sql b/sql/updates/world/master/2026_06_30_18_world_2026_04_11_00_world.sql
new file mode 100644
index 0000000000..f336f69ace
--- /dev/null
+++ b/sql/updates/world/master/2026_06_30_18_world_2026_04_11_00_world.sql
@@ -0,0 +1,53 @@
+-- Morogrim
+UPDATE `creature_template` SET `speed_run` = 2.14286, `BaseAttackTime` = 1600 WHERE `entry` = 21213;
+UPDATE `creature_model_info` SET `BoundingRadius` = 6.315, `CombatReach` = 6 WHERE `DisplayID` = 20739;
+
+UPDATE `creature_text` SET `Type` = 41 WHERE `CreatureID` = 21213 AND `GroupID` IN (5,7);
+
+UPDATE `creature` SET `position_x` = 370.829, `position_y` = -723.939, `position_z` = -14.005, `orientation` = 2.93215 WHERE `id` = 21213;
+
+-- Murlocs
+DELETE FROM `spell_target_position` WHERE `ID` IN (37766,37923,37925,37926,37927,39813,39814,39815,39816,39817,37772,37928,37929,37931,37932,39818,39819,39820,39821,39822);
+INSERT INTO `spell_target_position` (`ID`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `VerifiedBuild`) VALUES
+(37766,0,548,266,-707,-2.91667,5.34071,0),
+(37925,0,548,260,-712,-2.91667,5.34071,0),
+(37927,0,548,254,-719,-2.91667,5.34071,0),
+(39814,0,548,260,-704,-2.91667,5.11381,0),
+(39816,0,548,253,-707,-2.91667,5.2709,0),
+(39817,0,548,250,-708,-2.91667,5.14872,0),
+
+(37928,0,548,528,-699,-6.91667,3.9968,0),
+(37931,0,548,534,-706,-6.91667,3.9968,0),
+(39818,0,548,540,-700,-6.91667,4.32842,0),
+(39820,0,548,535,-695,-6.91667,4.01426,0),
+(39821,0,548,533,-691,-6.91667,4.31096,0),
+(39822,0,548,529,-691,-6.91667,4.31096,0);
+
+UPDATE `creature_template` SET `speed_walk` = 1.6, `speed_run` = 1.42857 WHERE `entry` = 21920;
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` = 21920 AND `source_type` = 0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`event_param5`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_param4`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(21920,0,0,0,37,0,100,0,0,0,0,0,0,116,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Tidewalker Lurker - On AI Initialize - Set Corpse Delay"),
+(21920,0,1,0,0,0,100,0,5000,10000,5000,10000,0,11,41932,0,0,0,0,0,2,0,0,0,0,0,0,0,0,"Tidewalker Lurker - In Combat - Cast 'Carnivorous Bite'");
+
+-- Watery Grave (first is sniffed, other copied from Water Globule spells)
+UPDATE `spell_target_position` SET `PositionX` = 334, `PositionY` = -728, `PositionZ` = -14, `Orientation` = 0, `VerifiedBuild` = 26365 WHERE `ID` = 37850;
+UPDATE `spell_target_position` SET `PositionX` = 366, `PositionY` = -736, `PositionZ` = -14, `Orientation` = 2.513274 WHERE `ID` = 38023;
+UPDATE `spell_target_position` SET `PositionX` = 366, `PositionY` = -709, `PositionZ` = -14, `Orientation` = 2.513274 WHERE `ID` = 38024;
+UPDATE `spell_target_position` SET `PositionX` = 372, `PositionY` = -690, `PositionZ` = -14, `Orientation` = 4.258604 WHERE `ID` = 38025;
+
+-- Water Globule
+UPDATE `spell_target_position` SET `PositionX` = 334, `PositionY` = -728, `PositionZ` = -14, `Orientation` = 0, `VerifiedBuild` = 26365 WHERE `ID` = 37854;
+UPDATE `spell_target_position` SET `PositionX` = 366, `PositionY` = -736, `PositionZ` = -14, `Orientation` = 2.513274, `VerifiedBuild` = 26365 WHERE `ID` = 37858;
+UPDATE `spell_target_position` SET `PositionX` = 366, `PositionY` = -709, `PositionZ` = -14, `Orientation` = 2.513274, `VerifiedBuild` = 26365 WHERE `ID` = 37860;
+UPDATE `spell_target_position` SET `PositionX` = 372, `PositionY` = -690, `PositionZ` = -14, `Orientation` = 4.258604, `VerifiedBuild` = 26365 WHERE `ID` = 37861;
+
+UPDATE `creature_template` SET `speed_walk` = 0.4, `speed_run` = 0.285714 WHERE `entry` = 21913;
+
+-- Spell scripts
+DELETE FROM `spell_script_names` WHERE `ScriptName` IN (
+'spell_morogrim_tidewalker_watery_grave',
+'spell_morogrim_tidewalker_summon_water_globules');
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(38028, 'spell_morogrim_tidewalker_watery_grave'),
+(37866, 'spell_morogrim_tidewalker_summon_water_globules');
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp
index c9736fcacb..95cce958f0 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp
@@ -15,117 +15,189 @@
* with this program. If not, see .
*/
-/* ScriptData
-SDName: Boss_Morogrim_Tidewalker
-SD%Complete: 90
-SDComment: Water globules don't explode properly, remove hacks
-SDCategory: Coilfang Resevoir, Serpent Shrine Cavern
-EndScriptData */
+/*
+ * Combat timers requires to be revisited
+ * Everything requires sniff verification, especially Water Globule
+ */
#include "ScriptMgr.h"
-#include "InstanceScript.h"
-#include "Map.h"
+#include "Containers.h"
#include "ScriptedCreature.h"
#include "serpent_shrine.h"
-#include "TemporarySummon.h"
+#include "SpellInfo.h"
+#include "SpellScript.h"
-enum Yells
+enum MorogrimTexts
{
- // Yell
SAY_AGGRO = 0,
SAY_SUMMON = 1,
SAY_SUMMON_BUBL = 2,
SAY_SLAY = 3,
SAY_DEATH = 4,
- // Emotes
EMOTE_WATERY_GRAVE = 5,
EMOTE_EARTHQUAKE = 6,
- EMOTE_WATERY_GLOBULES = 7
+ EMOTE_WATER_GLOBULES = 7
};
-enum Spells
+enum MorogrimSpells
{
- SPELL_TIDAL_WAVE = 37730,
- SPELL_WATERY_GRAVE = 38049,
- SPELL_EARTHQUAKE = 37764,
- SPELL_WATERY_GRAVE_EXPLOSION = 37852,
+ // Passive
+ SPELL_DOUBLE_ATTACK = 18943,
- SPELL_WATERY_GRAVE_1 = 38023,
- SPELL_WATERY_GRAVE_2 = 38024,
- SPELL_WATERY_GRAVE_3 = 38025,
- SPELL_WATERY_GRAVE_4 = 37850,
+ // Combat
+ SPELL_TIDAL_WAVE = 37730,
+ SPELL_EARTHQUAKE = 37764,
+ SPELL_WATERY_GRAVE = 38028,
+ SPELL_SUMMON_WATER_GLOBULES = 37866,
+
+ SPELL_SUMMON_MURLOC_A1 = 37766,
+ SPELL_SUMMON_MURLOC_A2 = 37923,
+ SPELL_SUMMON_MURLOC_A3 = 37925,
+ SPELL_SUMMON_MURLOC_A4 = 37926,
+ SPELL_SUMMON_MURLOC_A5 = 37927,
+ SPELL_SUMMON_MURLOC_A6 = 39813,
+ SPELL_SUMMON_MURLOC_A7 = 39814,
+ SPELL_SUMMON_MURLOC_A8 = 39815,
+ SPELL_SUMMON_MURLOC_A9 = 39816,
+ SPELL_SUMMON_MURLOC_A10 = 39817,
+
+ SPELL_SUMMON_MURLOC_B1 = 37772,
+ SPELL_SUMMON_MURLOC_B2 = 37928,
+ SPELL_SUMMON_MURLOC_B3 = 37929,
+ SPELL_SUMMON_MURLOC_B4 = 37931,
+ SPELL_SUMMON_MURLOC_B5 = 37932,
+ SPELL_SUMMON_MURLOC_B6 = 39818,
+ SPELL_SUMMON_MURLOC_B7 = 39819,
+ SPELL_SUMMON_MURLOC_B8 = 39820,
+ SPELL_SUMMON_MURLOC_B9 = 39821,
+ SPELL_SUMMON_MURLOC_B10 = 39822,
+
+ // Water Globule
+ SPELL_WATER_GLOBULE_EXPLODE = 37871,
+ SPELL_WATER_GLOBULE_NEW_TARGET = 39848,
+
+ // Scripts
+ SPELL_WATERY_GRAVE_TELEPORT_1 = 37850,
+ SPELL_WATERY_GRAVE_TELEPORT_2 = 38023,
+ SPELL_WATERY_GRAVE_TELEPORT_3 = 38024,
+ SPELL_WATERY_GRAVE_TELEPORT_4 = 38025,
SPELL_SUMMON_WATER_GLOBULE_1 = 37854,
SPELL_SUMMON_WATER_GLOBULE_2 = 37858,
SPELL_SUMMON_WATER_GLOBULE_3 = 37860,
- SPELL_SUMMON_WATER_GLOBULE_4 = 37861,
-
- // Water Globule
- SPELL_GLOBULE_EXPLOSION = 37871
+ SPELL_SUMMON_WATER_GLOBULE_4 = 37861
};
-enum Creatures
+enum MorogrimEvents
{
- // Creatures
- NPC_WATER_GLOBULE = 21913,
- NPC_TIDEWALKER_LURKER = 21920
+ EVENT_TIDAL_WAVE = 1,
+ EVENT_EARTHQUAKE,
+ EVENT_WATERY_GRAVE,
+ EVENT_SUMMON_WATER_GLOBULES
};
-float MurlocCords[10][4] =
+static constexpr std::array SummonMurlocsNorthSpells =
{
- {424.36f, -715.4f, -7.14f, 0.124f},
- {425.13f, -719.3f, -7.14f, 0.124f},
- {425.05f, -724.23f, -7.14f, 0.124f},
- {424.91f, -728.68f, -7.14f, 0.124f},
- {424.84f, -732.18f, -7.14f, 0.124f},
- {321.05f, -734.2f, -13.15f, 0.124f},
- {321.05f, -729.4f, -13.15f, 0.124f},
- {321.05f, -724.03f, -13.15f, 0.124f},
- {321.05f, -718.73f, -13.15f, 0.124f},
- {321.05f, -714.24f, -13.15f, 0.124f}
+ SPELL_SUMMON_MURLOC_A1,
+ SPELL_SUMMON_MURLOC_A3,
+ SPELL_SUMMON_MURLOC_A5,
+ SPELL_SUMMON_MURLOC_A7,
+ SPELL_SUMMON_MURLOC_A9,
+ SPELL_SUMMON_MURLOC_A10
};
-//Morogrim Tidewalker AI
+static constexpr std::array SummonMurlocsSouthSpells =
+{
+ SPELL_SUMMON_MURLOC_B2,
+ SPELL_SUMMON_MURLOC_B4,
+ SPELL_SUMMON_MURLOC_B6,
+ SPELL_SUMMON_MURLOC_B8,
+ SPELL_SUMMON_MURLOC_B9,
+ SPELL_SUMMON_MURLOC_B10
+};
+
+static constexpr std::array WateryGraveTeleportSpells =
+{
+ SPELL_WATERY_GRAVE_TELEPORT_1,
+ SPELL_WATERY_GRAVE_TELEPORT_2,
+ SPELL_WATERY_GRAVE_TELEPORT_3,
+ SPELL_WATERY_GRAVE_TELEPORT_4
+};
+
+static constexpr std::array SummonWaterGlobulesSpells =
+{
+ SPELL_SUMMON_WATER_GLOBULE_1,
+ SPELL_SUMMON_WATER_GLOBULE_2,
+ SPELL_SUMMON_WATER_GLOBULE_3,
+ SPELL_SUMMON_WATER_GLOBULE_4
+};
+
+// 21213 - Morogrim Tidewalker
struct boss_morogrim_tidewalker : public BossAI
{
- boss_morogrim_tidewalker(Creature* creature) : BossAI(creature, BOSS_MOROGRIM_TIDEWALKER)
- {
- Initialize();
- Playercount = 0;
- counter = 0;
- }
-
- void Initialize()
- {
- TidalWave_Timer = 10000;
- WateryGrave_Timer = 30000;
- Earthquake_Timer = 40000;
- WateryGlobules_Timer = 0;
- globulespell[0] = SPELL_SUMMON_WATER_GLOBULE_1;
- globulespell[1] = SPELL_SUMMON_WATER_GLOBULE_2;
- globulespell[2] = SPELL_SUMMON_WATER_GLOBULE_3;
- globulespell[3] = SPELL_SUMMON_WATER_GLOBULE_4;
-
- Earthquake = false;
- Phase2 = false;
- }
-
- uint32 TidalWave_Timer;
- uint32 WateryGrave_Timer;
- uint32 Earthquake_Timer;
- uint32 WateryGlobules_Timer;
- uint32 globulespell[4];
- int8 Playercount;
- int8 counter;
-
- bool Earthquake;
- bool Phase2;
+ boss_morogrim_tidewalker(Creature* creature) : BossAI(creature, BOSS_MOROGRIM_TIDEWALKER), _isSecondPhaseStarted(false) { }
void Reset() override
{
- Initialize();
-
_Reset();
+
+ _isSecondPhaseStarted = false;
+
+ DoCastSelf(SPELL_DOUBLE_ATTACK);
+ }
+
+ void JustEngagedWith(Unit* who) override
+ {
+ BossAI::JustEngagedWith(who);
+
+ Talk(SAY_AGGRO);
+
+ events.ScheduleEvent(EVENT_TIDAL_WAVE, 10s, 15s);
+ events.ScheduleEvent(EVENT_EARTHQUAKE, 35s, 45s);
+ events.ScheduleEvent(EVENT_WATERY_GRAVE, 20s, 25s);
+ }
+
+ void OnSpellCast(SpellInfo const* spellInfo) override
+ {
+ switch (spellInfo->Id)
+ {
+ case SPELL_EARTHQUAKE:
+ Talk(EMOTE_EARTHQUAKE);
+ Talk(SAY_SUMMON);
+
+ for (uint32 spell : SummonMurlocsNorthSpells)
+ DoCastSelf(spell, true);
+
+ for (uint32 spell : SummonMurlocsSouthSpells)
+ DoCastSelf(spell, true);
+
+ break;
+ case SPELL_WATERY_GRAVE:
+ Talk(EMOTE_WATERY_GRAVE);
+ break;
+ case SPELL_SUMMON_WATER_GLOBULES:
+ Talk(EMOTE_WATER_GLOBULES);
+ Talk(SAY_SUMMON_BUBL);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ {
+ if (!_isSecondPhaseStarted && me->HealthBelowPctDamaged(25, damage))
+ {
+ _isSecondPhaseStarted = true;
+ events.ScheduleEvent(EVENT_SUMMON_WATER_GLOBULES, 0s);
+ events.CancelEvent(EVENT_WATERY_GRAVE);
+ }
+ }
+
+ void JustReachedHome() override
+ {
+ _JustReachedHome();
+ DoCastSelf(SPELL_DOUBLE_ATTACK);
}
void KilledUnit(Unit* /*victim*/) override
@@ -135,197 +207,154 @@ struct boss_morogrim_tidewalker : public BossAI
void JustDied(Unit* /*killer*/) override
{
- Talk(SAY_DEATH);
-
_JustDied();
- }
-
- void JustEngagedWith(Unit* who) override
- {
- Playercount = me->GetMap()->GetPlayers().size();
- Talk(SAY_AGGRO);
- _JustEngagedWith(who);
- }
-
- void ApplyWateryGrave(Unit* player, uint8 i)
- {
- switch (i)
- {
- case 0: player->CastSpell(player, SPELL_WATERY_GRAVE_1, true); break;
- case 1: player->CastSpell(player, SPELL_WATERY_GRAVE_2, true); break;
- case 2: player->CastSpell(player, SPELL_WATERY_GRAVE_3, true); break;
- case 3: player->CastSpell(player, SPELL_WATERY_GRAVE_4, true); break;
- }
+ Talk(SAY_DEATH);
}
void UpdateAI(uint32 diff) override
{
- //Return since we have no target
if (!UpdateVictim())
return;
- //Earthquake_Timer
- if (Earthquake_Timer <= diff)
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (!Earthquake)
+ switch (eventId)
{
- DoCastVictim(SPELL_EARTHQUAKE);
- Earthquake = true;
- Earthquake_Timer = 10000;
+ case EVENT_TIDAL_WAVE:
+ DoCastSelf(SPELL_TIDAL_WAVE, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD);
+ events.Repeat(20s, 25s);
+ break;
+ case EVENT_EARTHQUAKE:
+ DoCastSelf(SPELL_EARTHQUAKE, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD);
+ events.Repeat(50s, 60s);
+ break;
+ case EVENT_WATERY_GRAVE:
+ DoCastSelf(SPELL_WATERY_GRAVE, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD);
+ events.Repeat(30s, 35s);
+ break;
+ case EVENT_SUMMON_WATER_GLOBULES:
+ DoCastSelf(SPELL_SUMMON_WATER_GLOBULES);
+ events.Repeat(40s, 50s);
+ break;
+ default:
+ break;
}
- else
- {
- Talk(SAY_SUMMON);
- for (uint8 i = 0; i < 10; ++i)
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
- if (Creature* Murloc = me->SummonCreature(NPC_TIDEWALKER_LURKER, MurlocCords[i][0], MurlocCords[i][1], MurlocCords[i][2], MurlocCords[i][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10s))
- Murloc->AI()->AttackStart(target);
- }
- Talk(EMOTE_EARTHQUAKE);
- Earthquake = false;
- Earthquake_Timer = 40000 + rand32() % 5000;
- }
- } else Earthquake_Timer -= diff;
-
- //TidalWave_Timer
- if (TidalWave_Timer <= diff)
- {
- DoCastVictim(SPELL_TIDAL_WAVE);
- TidalWave_Timer = 20000;
- } else TidalWave_Timer -= diff;
-
- if (!Phase2)
- {
- //WateryGrave_Timer
- if (WateryGrave_Timer <= diff)
- {
- //Teleport 4 players under the waterfalls
- GuidSet targets;
- GuidSet::const_iterator itr = targets.begin();
- for (uint8 i = 0; i < 4; ++i)
- {
- counter = 0;
- Unit* target;
- do
- {
- target = SelectTarget(SelectTargetMethod::Random, 1, 50, true); //target players only
- if (counter < Playercount)
- break;
- if (target)
- itr = targets.find(target->GetGUID());
- ++counter;
- } while (itr != targets.end());
-
- if (target)
- {
- targets.insert(target->GetGUID());
- ApplyWateryGrave(target, i);
- }
- }
-
- Talk(SAY_SUMMON_BUBL);
-
- Talk(EMOTE_WATERY_GRAVE);
- WateryGrave_Timer = 30000;
- } else WateryGrave_Timer -= diff;
-
- //Start Phase2
- if (HealthBelowPct(25))
- Phase2 = true;
- }
- else
- {
- //WateryGlobules_Timer
- if (WateryGlobules_Timer <= diff)
- {
- GuidSet globules;
- GuidSet::const_iterator itr = globules.begin();
- for (uint8 g = 0; g < 4; g++) //one unit can't cast more than one spell per update, so some players have to cast for us XD
- {
- counter = 0;
- Unit* pGlobuleTarget;
- do
- {
- pGlobuleTarget = SelectTarget(SelectTargetMethod::Random, 0, 50, true);
- if (pGlobuleTarget)
- itr = globules.find(pGlobuleTarget->GetGUID());
- if (counter > Playercount)
- break;
- ++counter;
- } while (itr != globules.end());
-
- if (pGlobuleTarget)
- {
- globules.insert(pGlobuleTarget->GetGUID());
- pGlobuleTarget->CastSpell(pGlobuleTarget, globulespell[g], true);
- }
- }
- Talk(EMOTE_WATERY_GLOBULES);
- WateryGlobules_Timer = 25000;
- } else WateryGlobules_Timer -= diff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
}
}
+
+private:
+ bool _isSecondPhaseStarted;
};
+// 21913 - Water Globule
struct npc_water_globule : public ScriptedAI
{
- npc_water_globule(Creature* creature) : ScriptedAI(creature)
+ using ScriptedAI::ScriptedAI;
+
+ void JustAppeared() override
{
- Initialize();
+ DoZoneInCombat();
+
+ _scheduler
+ .Schedule(0s, [this](TaskContext& task)
+ {
+ ResetThreatList();
+ DoCastSelf(SPELL_WATER_GLOBULE_NEW_TARGET, { SPELLVALUE_MAX_TARGETS, 1 });
+ task.Repeat(7s, 10s);
+ })
+ .Schedule(0s, [this](TaskContext& task)
+ {
+ if (me->IsWithinDistInMap(me->GetVictim(), 5.0f))
+ DoCastVictim(SPELL_WATER_GLOBULE_EXPLODE);
+ task.Repeat(1200ms);
+ });
}
- void Initialize()
+ void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
{
- Check_Timer = 1000;
- }
-
- uint32 Check_Timer;
-
- void Reset() override
- {
- Initialize();
-
- me->SetFaction(FACTION_MONSTER);
- }
-
- void JustEngagedWith(Unit* /*who*/) override { }
-
- void MoveInLineOfSight(Unit* who) override
-
- {
- if (!who || me->GetVictim())
- return;
-
- if (me->CanCreatureAttack(who))
+ switch (spellInfo->Id)
{
- //no attack radius check - it attacks the first target that moves in his los
- //who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
- AttackStart(who);
+ case SPELL_WATER_GLOBULE_NEW_TARGET:
+ if (Unit* unit = target->ToUnit())
+ AddThreat(unit, 3000000.0f);
+ break;
+ case SPELL_WATER_GLOBULE_EXPLODE:
+ me->DespawnOrUnsummon();
+ break;
+ default:
+ break;
}
}
void UpdateAI(uint32 diff) override
{
- //Return since we have no target
if (!UpdateVictim())
return;
- if (Check_Timer <= diff)
- {
- if (me->IsWithinDistInMap(me->GetVictim(), 5))
- {
- DoCastVictim(SPELL_GLOBULE_EXPLOSION);
+ _scheduler.Update(diff);
+ }
- //despawn
- me->DespawnOrUnsummon();
- return;
- }
- Check_Timer = 500;
- } else Check_Timer -= diff;
+private:
+ TaskScheduler _scheduler;
+};
- //do NOT deal any melee damage to the target.
+// 38028 - Watery Grave
+class spell_morogrim_tidewalker_watery_grave : public SpellScript
+{
+public:
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo(WateryGraveTeleportSpells);
+ }
+
+ void FilterTargets(std::list& targets)
+ {
+ targets.remove(GetCaster()->GetVictim());
+ Trinity::Containers::RandomResize(targets, 4);
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetHitUnit(), WateryGraveTeleportSpells[std::min(_targetCount, WateryGraveTeleportSpells.size() - 1)], true);
+ _targetCount++;
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_morogrim_tidewalker_watery_grave::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_morogrim_tidewalker_watery_grave::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+
+private:
+ std::size_t _targetCount = 0;
+};
+
+// 37866 - Summon Water Globules
+class spell_morogrim_tidewalker_summon_water_globules : public SpellScript
+{
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo(SummonWaterGlobulesSpells);
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ for (uint32 spell : SummonWaterGlobulesSpells)
+ caster->CastSpell(caster, spell, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHit += SpellEffectFn(spell_morogrim_tidewalker_summon_water_globules::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
@@ -333,4 +362,6 @@ void AddSC_boss_morogrim_tidewalker()
{
RegisterSerpentshrineCavernCreatureAI(boss_morogrim_tidewalker);
RegisterSerpentshrineCavernCreatureAI(npc_water_globule);
+ RegisterSpellScript(spell_morogrim_tidewalker_watery_grave);
+ RegisterSpellScript(spell_morogrim_tidewalker_summon_water_globules);
}