Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_morogrim_tidewalker.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6/* ScriptData
7SDName: Boss_Morogrim_Tidewalker
8SD%Complete: 90
9SDComment: Water globules don't explode properly, remove hacks
10SDCategory: Coilfang Resevoir, Serpent Shrine Cavern
11EndScriptData */
12
13#include "ScriptMgr.h"
14#include "ScriptedCreature.h"
15#include "serpent_shrine.h"
16
30
51
53{
54 // Creatures
57};
58
59float MurlocCords[10][4] =
60{
61 {424.36f, -715.4f, -7.14f, 0.124f},
62 {425.13f, -719.3f, -7.14f, 0.124f},
63 {425.05f, -724.23f, -7.14f, 0.124f},
64 {424.91f, -728.68f, -7.14f, 0.124f},
65 {424.84f, -732.18f, -7.14f, 0.124f},
66 {321.05f, -734.2f, -13.15f, 0.124f},
67 {321.05f, -729.4f, -13.15f, 0.124f},
68 {321.05f, -724.03f, -13.15f, 0.124f},
69 {321.05f, -718.73f, -13.15f, 0.124f},
70 {321.05f, -714.24f, -13.15f, 0.124f}
71};
72
73//Morogrim Tidewalker AI
75{
76public:
77 boss_morogrim_tidewalker() : CreatureScript("boss_morogrim_tidewalker") { }
78
80 {
82 {
83 instance = creature->GetInstanceScript();
88 Playercount = 0;
89 counter = 0;
90
91 for (uint8 i = 0; i < 4; i++)
92 globulespell[4] = 0;
93
94 Earthquake = false;
95 Phase2 = false;
96
97 PlayerList = { };
98 }
99
117
119 {
121
122 if (instance)
124 }
125
126 void KilledUnit(Unit* /*victim*/) OVERRIDE
127 {
128 Talk(SAY_SLAY);
129 }
130
131 void JustDied(Unit* /*killer*/) OVERRIDE
132 {
134
135 if (instance)
137 }
138
139 void EnterCombat(Unit* /*who*/) OVERRIDE
140 {
141 PlayerList = &me->GetMap()->GetPlayers();
142 Playercount = PlayerList->getSize();
143 StartEvent();
144 }
145
146 void ApplyWateryGrave(Unit* player, uint8 i)
147 {
148 switch (i)
149 {
150 case 0: player->CastSpell(player, SPELL_WATERY_GRAVE_1, true); break;
151 case 1: player->CastSpell(player, SPELL_WATERY_GRAVE_2, true); break;
152 case 2: player->CastSpell(player, SPELL_WATERY_GRAVE_3, true); break;
153 case 3: player->CastSpell(player, SPELL_WATERY_GRAVE_4, true); break;
154 }
155 }
156
158 {
159 //Return since we have no target
160 if (!UpdateVictim())
161 return;
162
163 //Earthquake_Timer
164 if (Earthquake_Timer <= diff)
165 {
166 if (!Earthquake)
167 {
169 Earthquake = true;
170 Earthquake_Timer = 10000;
171 }
172 else
173 {
175
176 for (uint8 i = 0; i < 10; ++i)
177 {
178 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
180 Murloc->AI()->AttackStart(target);
181 }
183 Earthquake = false;
184 Earthquake_Timer = 40000+rand()%5000;
185 }
186 } else Earthquake_Timer -= diff;
187
188 //TidalWave_Timer
189 if (TidalWave_Timer <= diff)
190 {
192 TidalWave_Timer = 20000;
193 } else TidalWave_Timer -= diff;
194
195 if (!Phase2)
196 {
197 //WateryGrave_Timer
198 if (WateryGrave_Timer <= diff)
199 {
200 //Teleport 4 players under the waterfalls
201 Unit* target;
202 std::set<uint64> list;
203 std::set<uint64>::const_iterator itr;
204 for (uint8 i = 0; i < 4; ++i)
205 {
206 counter = 0;
207 do
208 {
209 target = SelectTarget(SELECT_TARGET_RANDOM, 1, 50, true); //target players only
210 if (counter < Playercount)
211 break;
212 if (target)
213 itr = list.find(target->GetGUID());
214 ++counter;
215 } while (itr != list.end());
216
217 if (target)
218 {
219 list.insert(target->GetGUID());
220 ApplyWateryGrave(target, i);
221 }
222 }
223
225
227 WateryGrave_Timer = 30000;
228 } else WateryGrave_Timer -= diff;
229
230 //Start Phase2
231 if (HealthBelowPct(25))
232 Phase2 = true;
233 }
234 else
235 {
236 //WateryGlobules_Timer
237 if (WateryGlobules_Timer <= diff)
238 {
239 Unit* pGlobuleTarget;
240 std::set<uint64> globulelist;
241 std::set<uint64>::const_iterator itr;
242 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
243 {
244 counter = 0;
245 do
246 {
247 pGlobuleTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true);
248 if (pGlobuleTarget)
249 itr = globulelist.find(pGlobuleTarget->GetGUID());
250 if (counter > Playercount)
251 break;
252 ++counter;
253 } while (itr != globulelist.end());
254 if (pGlobuleTarget)
255 {
256 globulelist.insert(pGlobuleTarget->GetGUID());
257 pGlobuleTarget->CastSpell(pGlobuleTarget, globulespell[g], true);
258 }
259 }
261 WateryGlobules_Timer = 25000;
262 } else WateryGlobules_Timer -= diff;
263 }
264
266 }
267
268 private:
279 bool Phase2;
280 };
281
283 {
284 return new boss_morogrim_tidewalkerAI(creature);
285 }
286};
287
289{
290public:
291 npc_water_globule() : CreatureScript("npc_water_globule") { }
292
294 {
296 {
297 Check_Timer = 0;
298 }
299
301 {
302 Check_Timer = 1000;
303
306 me->setFaction(14);
307 }
308
309 void EnterCombat(Unit* /*who*/) OVERRIDE { }
310
312
313 {
314 if (!who || me->GetVictim())
315 return;
316
317 if (me->CanCreatureAttack(who))
318 {
319 //no attack radius check - it attacks the first target that moves in his los
320 //who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
321 AttackStart(who);
322 }
323 }
324
326 {
327 //Return since we have no target
328 if (!UpdateVictim())
329 return;
330
331 if (Check_Timer <= diff)
332 {
333 if (me->IsWithinDistInMap(me->GetVictim(), 5))
334 {
336
337 //despawn
338 me->DespawnOrUnsummon();
339 return;
340 }
341 Check_Timer = 500;
342 } else Check_Timer -= diff;
343
344 //do NOT deal any melee damage to the target.
345 }
346
347 private:
349 };
350
352 {
353 return new npc_water_globuleAI(creature);
354 }
355};
356
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::int8_t int8
Definition Define.h:75
#define OVERRIDE
Definition Define.h:60
@ IN_PROGRESS
@ DONE
@ NOT_STARTED
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition Object.h:71
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
Creatures
@ SAY_SLAY
#define SAY_DEATH
#define SAY_AGGRO
@ SPELL_TIDAL_WAVE
@ SPELL_EARTHQUAKE
@ SPELL_SUMMON_WATER_GLOBULE_3
@ SPELL_WATERY_GRAVE_EXPLOSION
@ SPELL_SUMMON_WATER_GLOBULE_2
@ SPELL_SUMMON_WATER_GLOBULE_4
@ SPELL_SUMMON_WATER_GLOBULE_1
@ SPELL_GLOBULE_EXPLOSION
float MurlocCords[10][4]
void AddSC_boss_morogrim_tidewalker()
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureScript(const char *name)
MapRefManager PlayerList
Definition Map.h:406
uint64 GetGUID() const
Definition Object.h:119
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
Unit * SelectTarget(SelectAggroTarget targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, int32 aura=0)
Definition UnitAI.cpp:66
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
Definition Unit.h:1367
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
@ DATA_MOROGRIMTIDEWALKEREVENT
Creature * me
bool HealthBelowPct(uint32 pct) const
ScriptedAI(Creature *creature)
void AttackStart(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================