TrinityCore
zone_bloodmyst_isle.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ScriptMgr.h"
19#include "CellImpl.h"
20#include "Containers.h"
21#include "GridNotifiersImpl.h"
22#include "Group.h"
23#include "MotionMaster.h"
24#include "ObjectAccessor.h"
25#include "Player.h"
26#include "ScriptedEscortAI.h"
27#include "SpellScript.h"
28
29/*######
30## Quest 9759: Ending Their World
31######*/
32
34{
36
58
61
65
70
71 NPC_SIRONAS = 17678,
73 NPC_LEGOSO = 17982,
74
78
81
83
87
92
104
142
144
146
149
151{
152 {
153 { -1954.946f, -10654.714f, 110.448f },
154 { -1956.331f, -10654.494f, 110.869f },
155 { -1955.906f, -10656.221f, 110.791f },
156 { -1957.294f, -10656.000f, 111.219f },
157 { -1954.462f, -10656.451f, 110.404f }
158 },
159 {
160 { -1915.137f, -10583.651f, 178.365f },
161 { -1914.006f, -10582.964f, 178.471f },
162 { -1912.717f, -10582.398f, 178.658f },
163 { -1915.056f, -10582.251f, 178.162f },
164 { -1913.883f, -10581.778f, 178.346f }
165 }
166};
167
168/*######
169## npc_sironas
170######*/
171
173{
174public:
175 npc_sironas() : CreatureScript("npc_sironas") { }
176
177 struct npc_sironasAI : public ScriptedAI
178 {
179 npc_sironasAI(Creature* creature) : ScriptedAI(creature) { }
180
181 void Reset() override
182 {
183 _events.Reset();
185 }
186
187 void JustEngagedWith(Unit* /*who*/) override
188 {
192 }
193
194 void JustDied(Unit* killer) override
195 {
196 me->SetObjectScale(1.0f);
197 _events.Reset();
198
199 if (!killer)
200 return;
201
203 {
204 if (killer->GetGUID() == legoso->GetGUID() ||
205 (killer->IsPlayer() && me->isTappedBy(killer->ToPlayer())) ||
206 killer->GetGUID() == legoso->AI()->GetGUID(DATA_EVENT_STARTER_GUID))
207 legoso->AI()->DoAction(ACTION_LEGOSO_SIRONAS_KILLED);
208 }
209 }
210
211 void UpdateAI(uint32 diff) override
212 {
213 if (!UpdateVictim())
214 return;
215
216 _events.Update(diff);
217
218 while (uint32 eventId = _events.ExecuteEvent())
219 {
220 switch (eventId)
221 {
222 case EVENT_UPPERCUT:
225 break;
226 case EVENT_IMMOLATE:
229 break;
233 break;
234 default:
235 break;
236 }
237 }
238 }
239
240 void DoAction(int32 param) override
241 {
242 switch (param)
243 {
245 {
247 std::list<Creature*> BeamList;
249 if (!BeamList.empty())
250 for (std::list<Creature*>::iterator itr = BeamList.begin(); itr != BeamList.end(); ++itr)
251 (*itr)->CastSpell(*itr, SPELL_BLOODMYST_TESLA);
252 break;
253 }
255 {
257 std::list<Creature*> creatureList;
259 if (!creatureList.empty())
260 {
261 for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr)
262 (*itr)->InterruptNonMeleeSpells(true, SPELL_BLOODMYST_TESLA);
263 }
264 break;
265 }
266 default:
267 break;
268 }
269 }
270
271 private:
273 };
274
275 CreatureAI* GetAI(Creature* creature) const override
276 {
277 return new npc_sironasAI(creature);
278 }
279};
280
281/*######
282## npc_demolitionist_legoso
283######*/
284
285static constexpr uint32 PATH_ESCORT_LEGOSO = 143858;
286
288{
289public:
290 npc_demolitionist_legoso() : CreatureScript("npc_demolitionist_legoso") { }
291
293 {
295 {
296 Initialize();
297 }
298
300 {
302 _moveTimer = 0;
303 }
304
305 void OnQuestAccept(Player* player, Quest const* quest) override
306 {
307 if (quest->GetQuestId() == QUEST_ENDING_THEIR_WORLD)
308 {
311 Start(true, player->GetGUID(), quest);
312 }
313 }
314
315 ObjectGuid GetGUID(int32 type) const override
316 {
317 if (type == DATA_EVENT_STARTER_GUID)
318 return _eventStarterGuid;
319
320 return ObjectGuid::Empty;
321 }
322
323 void SetGUID(ObjectGuid const& guid, int32 type) override
324 {
325 switch (type)
326 {
328 _eventStarterGuid = guid;
329 break;
330 default:
331 break;
332 }
333 }
334
335 void Reset() override
336 {
337 me->SetCanDualWield(true);
338 Initialize();
339 _events.Reset();
344 }
345
346 void UpdateAI(uint32 diff) override
347 {
348 _events.Update(diff);
349
350 if (UpdateVictim())
351 {
352 while (uint32 eventId = _events.ExecuteEvent())
353 {
354 switch (eventId)
355 {
360 break;
365 break;
370 break;
372 {
373 Unit* target = nullptr;
374 if (me->GetHealthPct() < 85)
375 target = me;
376 else if (Player* player = GetPlayerForEscort())
377 if (player->GetHealthPct() < 85)
378 target = player;
379 if (target)
380 {
383 }
384 else
386 break;
387 }
388 default:
389 break;
390 }
391 }
392 }
393
395 return;
396
397 EscortAI::UpdateAI(diff);
398
399 if (_phase)
400 {
401 if (_moveTimer <= diff)
402 {
403 switch (_phase)
404 {
405 case PHASE_WP_26: //debug skip path to point 26, buggy path calculation
406 me->GetMotionMaster()->MovePoint(WP_DEBUG_2, -2021.77f, -10648.8f, 129.903f, false);
409 break;
410 case PHASE_CONTINUE: // continue escort
411 SetEscortPaused(false);
414 break;
415 case PHASE_WP_22: //debug skip path to point 22, buggy path calculation
416 me->GetMotionMaster()->MovePoint(WP_EXPLOSIVES_FIRST_PLANT, -1958.026f, -10660.465f, 111.547f, false);
420 break;
421 case PHASE_PLANT_FIRST_KNEEL: // plant first explosives stage 1 kneel
425 break;
426 case PHASE_PLANT_FIRST_STAND: // plant first explosives stage 1 stand
430 break;
431 case PHASE_PLANT_FIRST_WORK: // plant first explosives stage 2 work
435 break;
436 case PHASE_PLANT_FIRST_FINISH: // plant first explosives finish
437 _explosivesGuids.clear();
438 for (uint8 i = 0; i != MAX_EXPLOSIVES; ++i)
439 {
441 _explosivesGuids.push_back(explosive->GetGUID());
442 }
443 me->HandleEmoteCommand(EMOTE_ONESHOT_NONE); // reset anim state
444 // force runoff movement so he will not screw up next waypoint
445 me->GetMotionMaster()->MovePoint(WP_EXPLOSIVES_FIRST_RUNOFF, -1955.6f, -10669.8f, 110.65f, false);
449 break;
450 case PHASE_PLANT_FIRST_TIMER_1: // first explosives detonate timer 1
454 break;
455 case PHASE_PLANT_FIRST_TIMER_2: // first explosives detonate timer 2
459 break;
460 case PHASE_PLANT_FIRST_TIMER_3: // first explosives detonate timer 3
464 break;
465 case PHASE_PLANT_FIRST_DETONATE: // first explosives detonate finish
466 for (GuidList::iterator itr = _explosivesGuids.begin(); itr != _explosivesGuids.end(); ++itr)
467 {
468 if (GameObject* explosive = ObjectAccessor::GetGameObject(*me, *itr))
469 me->RemoveGameObject(explosive, true);
470 }
471 _explosivesGuids.clear();
475 break;
476 case PHASE_PLANT_FIRST_SPEECH: // after detonation 1 speech
480 break;
481 case PHASE_PLANT_FIRST_ROTATE: // after detonation 1 rotate to next point
482 me->SetFacingTo(2.272f);
485 break;
486 case PHASE_PLANT_FIRST_POINT: // after detonation 1 send point anim and go on to next point
490 break;
491 case PHASE_FEEL_SIRONAS_1: // legoso exclamation before sironas 1.1
495 break;
496 case PHASE_FEEL_SIRONAS_2: // legoso exclamation before sironas 1.2
500 break;
501 case PHASE_MEET_SIRONAS_ROAR: // legoso exclamation before sironas 2.1
505 break;
506 case PHASE_MEET_SIRONAS_TURN: // legoso exclamation before sironas 2.2
507 if (Player* player = GetPlayerForEscort())
508 me->SetFacingToObject(player);
511 break;
512 case PHASE_MEET_SIRONAS_SPEECH: // legoso exclamation before sironas 2.3
516 break;
517 case PHASE_PLANT_SECOND_KNEEL: // plant second explosives stage 1 kneel
521 break;
522 case PHASE_PLANT_SECOND_SPEECH: // plant second explosives stage 2 kneel
526 break;
527 case PHASE_PLANT_SECOND_STAND: // plant second explosives finish
531 break;
532 case PHASE_PLANT_SECOND_FINISH: // plant second explosives finish - create explosives
533 _explosivesGuids.clear();
534 for (uint8 i = 0; i != MAX_EXPLOSIVES; ++i)
535 {
537 _explosivesGuids.push_back(explosive->GetGUID());
538 }
542 break;
543 case PHASE_PLANT_SECOND_WAIT: // plant second explosives finish - proceed to next point
546 break;
547 case PHASE_PLANT_SECOND_TIMER_1: // second explosives detonate timer 1
551 break;
552 case PHASE_PLANT_SECOND_TIMER_2: // second explosives detonate timer 2
556 break;
557 case PHASE_PLANT_SECOND_TIMER_3: // second explosives detonate timer 3
561 break;
562 case PHASE_PLANT_SECOND_DETONATE: // second explosives detonate finish
563 for (GuidList::iterator itr = _explosivesGuids.begin(); itr != _explosivesGuids.end(); ++itr)
564 {
565 if (GameObject* explosive = ObjectAccessor::GetGameObject(*me, *itr))
566 me->RemoveGameObject(explosive, true);
567 }
568 _explosivesGuids.clear();
570 {
571 sironas->SetImmuneToAll(false);
572 me->SetFacingToObject(sironas);
573 }
576 break;
577 case PHASE_FIGHT_SIRONAS_STOP: // sironas channel stop
579 sironas->AI()->DoAction(ACTION_SIRONAS_CHANNEL_STOP);
582 break;
583 case PHASE_FIGHT_SIRONAS_SPEECH_1: // sironas exclamation before aggro
585 sironas->AI()->Talk(SAY_SIRONAS_1);
588 break;
589 case PHASE_FIGHT_SIRONAS_SPEECH_2: // legoso exclamation before aggro
591 sironas->SetObjectScale(3.0f);
595 break;
596 case PHASE_FIGHT_SIRONAS_START: // legoso exclamation at aggro
598 {
599 Unit* target = GetPlayerForEscort();
600 if (!target)
601 target = me;
602
603 AddThreat(sironas, 0.001f, target);
604 sironas->Attack(target, true);
605 sironas->GetMotionMaster()->MoveChase(target);
606 }
609 break;
610 case PHASE_SIRONAS_SLAIN_SPEECH_1: // legoso exclamation after battle - stage 1.1
614 break;
615 case PHASE_SIRONAS_SLAIN_EMOTE_1: // legoso exclamation after battle - stage 1.2
619 break;
620 case PHASE_SIRONAS_SLAIN_EMOTE_2: // legoso exclamation after battle - stage 1.3
621 if (Player* player = GetPlayerForEscort())
622 player->GroupEventHappens(QUEST_ENDING_THEIR_WORLD, me);
626 break;
627 case PHASE_SIRONAS_SLAIN_SPEECH_2: // legoso exclamation after battle - stage 2
631 break;
632 default:
633 break;
634 }
635 }
636 else if (!me->IsInCombat())
637 _moveTimer -= diff;
638 }
639 }
640
641 void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
642 {
643 Player* player = GetPlayerForEscort();
644 if (!player)
645 return;
646
647 switch (waypointId)
648 {
649 case WP_START:
650 SetEscortPaused(true);
651 me->SetFacingToObject(player);
655 break;
657 SetEscortPaused(true);
661 break;
663 me->SetFacingTo(1.46f);
664 break;
666 SetEscortPaused(true);
667 me->SetFacingTo(1.05f);
670 break;
671 case WP_DEBUG_1:
672 SetEscortPaused(true);
675 break;
676 case WP_SIRONAS_HILL:
677 {
678 SetEscortPaused(true);
679
680 //Find Sironas and make it respawn if needed
681 Creature* sironas = nullptr;
685
686 if (sironas)
687 {
688 if (!sironas->IsAlive())
689 sironas->Respawn(true);
690
692 me->SetFacingToObject(sironas);
693 }
696 break;
697 }
699 SetEscortPaused(true);
702 break;
704 SetEscortPaused(true);
707 break;
709 SetEscortPaused(true);
710 me->SetFacingTo(5.7f);
713 break;
714 default:
715 break;
716 }
717 }
718
719 void DoAction(int32 param) override
720 {
721 switch (param)
722 {
726 break;
727 default:
728 break;
729 }
730 }
731
732 private:
738 };
739
740 CreatureAI* GetAI(Creature* creature) const override
741 {
742 return new npc_demolitionist_legosoAI(creature);
743 }
744};
745
746/*######
747## Quest 9670: They're Alive! Maybe...
748######*/
749
751{
764
766{
769};
770
771// 30950 - Free Webbed Creature
773{
774 bool Validate(SpellInfo const* /*spellInfo*/) override
775 {
777 }
778
779 void HandleDummy(SpellEffIndex /*effIndex*/)
780 {
782 }
783
784 void Register() override
785 {
787 }
788};
789
790// 31009 - Free Webbed Creature
792{
793 bool Validate(SpellInfo const* /*spellInfo*/) override
794 {
796 }
797
798 // This one is a bit different from the one used in Terokkar. There is additional spell 31011 which apply periodic aura to trigger
799 // summon spell 31010 after 1.5 sec. However in retail Expedition Researcher is summoned instantly, we'll use 31010 directly
800 void HandleDummy(SpellEffIndex /*effIndex*/)
801 {
802 Unit* caster = GetCaster();
803 Unit* target = GetHitUnit();
804
805 if (roll_chance_i(66))
807 else
808 target->CastSpell(caster, SPELL_FREE_WEBBED_11, true);
809 }
810
811 void Register() override
812 {
814 }
815};
816
818{
819 new npc_sironas();
823}
@ IN_MILLISECONDS
Definition: Common.h:35
uint8_t uint8
Definition: Define.h:144
int8_t int8
Definition: Define.h:140
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
#define SIZE_OF_GRIDS
Definition: GridDefines.h:40
std::list< ObjectGuid > GuidList
Definition: ObjectGuid.h:394
bool roll_chance_i(int chance)
Definition: Random.h:59
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
@ STATE_ESCORT_NONE
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_0
Definition: SharedDefines.h:30
@ EMOTE_ONESHOT_POINT
@ EMOTE_ONESHOT_EXCLAMATION
@ EMOTE_ONESHOT_CHEER
@ EMOTE_ONESHOT_NONE
@ SPELL_EFFECT_DUMMY
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
@ UNIT_STAND_STATE_KNEEL
Definition: UnitDefines.h:50
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:42
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition: Util.h:491
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void Respawn(bool force=false)
Definition: Creature.cpp:2303
void SetObjectScale(float scale) override
Definition: Creature.cpp:3391
void SetDisplayFromModel(uint32 modelIdx)
Definition: Creature.cpp:3413
bool isTappedBy(Player const *player) const
Definition: Creature.cpp:1381
void SetCanDualWield(bool value) override
Definition: Creature.cpp:1940
CreatureAI * AI() const
Definition: Creature.h:214
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void DelayEvents(Milliseconds delay)
Definition: EventMap.cpp:96
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
void Reset()
Definition: EventMap.cpp:21
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
bool IsPlayer() const
Definition: Object.h:212
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
uint32 GetQuestId() const
Definition: QuestDef.h:587
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHit
Definition: SpellScript.h:839
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
virtual void DoAction(int32)
Definition: UnitAI.h:72
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:5238
float GetHealthPct() const
Definition: Unit.h:784
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition: Unit.cpp:10100
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:3089
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition: Unit.cpp:12671
bool IsAlive() const
Definition: Unit.h:1164
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:12653
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition: Unit.cpp:1598
bool IsInCombat() const
Definition: Unit.h:1043
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition: Object.cpp:3312
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
GameObject * SummonGameObject(uint32 entry, Position const &pos, QuaternionData const &rot, Seconds respawnTime, GOSummonType summonType=GO_SUMMON_TIMED_OR_CORPSE_DESPAWN)
Definition: Object.cpp:2065
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
bool Validate(SpellInfo const *) override
void Register() override
void HandleDummy(SpellEffIndex)
bool Validate(SpellInfo const *) override
TC_GAME_API GameObject * GetGameObject(WorldObject const &u, ObjectGuid const &guid)
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:109
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:203
void Start(bool isActiveAttacker=true, ObjectGuid playerGUID=ObjectGuid::Empty, Quest const *quest=nullptr, bool instantRespawn=false, bool canLoopPath=false)
bool HasEscortState(uint32 escortState)
void LoadPath(uint32 pathId)
Player * GetPlayerForEscort()
void SetEscortPaused(bool on)
void UpdateAI(uint32 diff) override
constexpr float GetOrientation() const
Definition: Position.h:79
static QuaternionData fromEulerAnglesZYX(float Z, float Y, float X)
Definition: GameObject.cpp:118
void AddThreat(Unit *victim, float amount, Unit *who=nullptr)
void OnQuestAccept(Player *player, Quest const *quest) override
void SetGUID(ObjectGuid const &guid, int32 type) override
void WaypointReached(uint32 waypointId, uint32) override
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *) override
void JustDied(Unit *killer) override
void DoAction(int32 param) override
uint32 const CocoonSummonSpells[10]
Position const ExplosivesPos[2][MAX_EXPLOSIVES]
EndingTheirWorldMisc
@ PHASE_PLANT_FIRST_STAND
@ NPC_SIRONAS
@ PHASE_PLANT_FIRST_WORK
@ SAY_LEGOSO_5
@ SPELL_SIRONAS_CHANNELING
@ SAY_LEGOSO_12
@ PHASE_MEET_SIRONAS_TURN
@ EVENT_IMMOLATE
@ WP_SIRONAS_HILL
@ PHASE_PLANT_SECOND_SPEECH
@ SAY_LEGOSO_2
@ WP_EXPLOSIVES_SECOND_DETONATE
@ WP_EXPLOSIVES_FIRST_DETONATE
@ PHASE_SIRONAS_SLAIN_EMOTE_1
@ SPELL_BLOODMYST_TESLA
@ PHASE_PLANT_SECOND_FINISH
@ ACTION_LEGOSO_SIRONAS_KILLED
@ SAY_LEGOSO_11
@ SAY_LEGOSO_20
@ PHASE_MEET_SIRONAS_ROAR
@ WP_EXPLOSIVES_FIRST_RUNOFF
@ SAY_LEGOSO_13
@ PHASE_PLANT_SECOND_TIMER_3
@ GO_DRAENEI_EXPLOSIVES_1
@ EVENT_FROST_SHOCK
@ EVENT_STRENGTH_OF_EARTH_TOTEM
@ SAY_LEGOSO_1
@ SPELL_CURSE_OF_BLOOD
@ DATA_EVENT_STARTER_GUID
@ PHASE_PLANT_FIRST_FINISH
@ PHASE_CONTINUE
@ SAY_LEGOSO_7
@ SAY_LEGOSO_9
@ PHASE_PLANT_FIRST_SPEECH
@ SAY_LEGOSO_18
@ PHASE_FEEL_SIRONAS_1
@ SPELL_STRENGTH_OF_EARTH_TOTEM
@ EVENT_SEARING_TOTEM
@ SPELL_FROST_SHOCK
@ WP_DEBUG_1
@ PHASE_SIRONAS_SLAIN_SPEECH_1
@ PHASE_PLANT_SECOND_STAND
@ WP_DEBUG_2
@ SAY_LEGOSO_19
@ SAY_LEGOSO_6
@ NPC_LEGOSO
@ PHASE_PLANT_SECOND_KNEEL
@ PHASE_PLANT_FIRST_ROTATE
@ WP_EXPLOSIVES_SECOND_BATTLEROAR
@ QUEST_ENDING_THEIR_WORLD
@ ACTION_SIRONAS_CHANNEL_STOP
@ ACTION_SIRONAS_CHANNEL_START
@ PHASE_SIRONAS_SLAIN_EMOTE_2
@ EVENT_HEALING_SURGE
@ PHASE_PLANT_FIRST_KNEEL
@ PHASE_PLANT_SECOND_TIMER_2
@ PHASE_FIGHT_SIRONAS_SPEECH_2
@ PHASE_FIGHT_SIRONAS_SPEECH_1
@ SAY_LEGOSO_16
@ GO_FIRE_EXPLOSION
@ EVENT_CURSE_OF_BLOOD
@ MAX_EXPLOSIVES
@ SAY_LEGOSO_3
@ PHASE_PLANT_FIRST_TIMER_3
@ SPELL_IMMOLATE
@ PHASE_PLANT_FIRST_DETONATE
@ EVENT_UPPERCUT
@ GO_DRAENEI_EXPLOSIVES_2
@ SAY_LEGOSO_15
@ SAY_LEGOSO_21
@ PHASE_PLANT_FIRST_TIMER_1
@ WP_EXPLOSIVES_SECOND_PLANT
@ SAY_LEGOSO_4
@ SAY_LEGOSO_8
@ PHASE_FIGHT_SIRONAS_START
@ PHASE_PLANT_FIRST_TIMER_2
@ PHASE_PLANT_SECOND_DETONATE
@ PHASE_PLANT_FIRST_POINT
@ SPELL_SEARING_TOTEM
@ WP_EXPLOSIVES_FIRST_PLANT
@ PHASE_PLANT_SECOND_WAIT
@ PHASE_FEEL_SIRONAS_2
@ NPC_BLOODMYST_TESLA_COIL
@ PHASE_PLANT_SECOND_TIMER_1
@ SPELL_UPPERCUT
@ WP_EXPLOSIVES_FIRST_POINT
@ SAY_LEGOSO_10
@ PHASE_FIGHT_SIRONAS_STOP
@ SPELL_HEALING_SURGE
@ PHASE_SIRONAS_SLAIN_SPEECH_2
@ SAY_SIRONAS_1
@ PHASE_MEET_SIRONAS_SPEECH
@ SAY_LEGOSO_17
@ SAY_LEGOSO_14
void AddSC_bloodmyst_isle()
static constexpr uint32 PATH_ESCORT_LEGOSO
FreeWebbedBloodmyst
@ SPELL_FREE_WEBBED_4
@ SPELL_FREE_WEBBED_7
@ SPELL_FREE_WEBBED_10
@ SPELL_FREE_WEBBED_6
@ SPELL_FREE_WEBBED_8
@ SPELL_FREE_WEBBED_1
@ SPELL_FREE_WEBBED_9
@ SPELL_FREE_WEBBED_3
@ SPELL_FREE_WEBBED_5
@ SPELL_FREE_WEBBED_11
@ SPELL_FREE_WEBBED_2