TrinityCore
zone_shadowmoon_valley.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/* ScriptData
19SDName: Shadowmoon_Valley
20SD%Complete: 100
21SDComment: Quest support: 10804, 10854, 10458, 10481, 10480, 10781, 10451.
22SDCategory: Shadowmoon Valley
23EndScriptData */
24
25/* ContentData
26npc_invis_infernal_caster
27npc_infernal_attacker
28npc_mature_netherwing_drake
29npc_enslaved_netherwing_drake
30npc_earthmender_wilda
31npc_torloth_the_magnificent
32npc_illidari_spawn
33npc_lord_illidan_stormrage
34go_crystal_prison
35npc_enraged_spirit
36EndContentData */
37
38#include "ScriptMgr.h"
39#include "GameObject.h"
40#include "GameObjectAI.h"
41#include "Group.h"
42#include "MotionMaster.h"
43#include "ObjectAccessor.h"
44#include "Player.h"
45#include "ScriptedEscortAI.h"
46#include "SpellInfo.h"
47#include "SpellScript.h"
48#include "TemporarySummon.h"
49
50/*#####
51# npc_invis_infernal_caster
52#####*/
53
55{
64 DATA_DIED = 1
65};
66
68{
69public:
70 npc_invis_infernal_caster() : CreatureScript("npc_invis_infernal_caster") { }
71
73 {
75 {
76 ground = 0.f;
77 }
78
79 void Reset() override
80 {
85 }
86
87 void SetData(uint32 id, uint32 data) override
88 {
89 if (id == TYPE_INFERNAL && data == DATA_DIED)
91 }
92
94 {
96 infernalGUID = infernal->GetGUID();
97 else
99 }
100
101 void UpdateAI(uint32 diff) override
102 {
103 events.Update(diff);
104
105 while (uint32 eventId = events.ExecuteEvent())
106 {
107 switch (eventId)
108 {
110 {
111 if (Unit* infernal = ObjectAccessor::GetUnit(*me, infernalGUID))
112 if (infernal->GetDisplayId() == MODEL_INVISIBLE)
113 me->CastSpell(infernal, SPELL_SUMMON_INFERNAL, true);
115 break;
116 }
117 default:
118 break;
119 }
120 }
121 }
122
123 private:
126 float ground;
127 };
128
129 CreatureAI* GetAI(Creature* creature) const override
130 {
131 return new npc_invis_infernal_casterAI(creature);
132 }
133};
134
135/*#####
136# npc_infernal_attacker
137#####*/
138
140{
141public:
142 npc_infernal_attacker() : CreatureScript("npc_infernal_attacker") { }
143
145 {
146 npc_infernal_attackerAI(Creature* creature) : ScriptedAI(creature) { }
147
148 void Reset() override
149 {
151 me->GetMotionMaster()->MoveRandom(5.0f);
152 }
153
154 void IsSummonedBy(WorldObject* summoner) override
155 {
156 if (summoner->ToCreature())
157 casterGUID = summoner->ToCreature()->GetGUID();
159 }
160
161 void JustDied(Unit* /*killer*/) override
162 {
164 caster->AI()->SetData(TYPE_INFERNAL, DATA_DIED);
165 }
166
167 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
168 {
169 if (spellInfo->Id == SPELL_SUMMON_INFERNAL)
170 {
171 me->SetUninteractible(false);
172 me->SetImmuneToPC(false);
174 // handle by the spell below when such auras will be not removed after evade
176 // DoCastSelf(SPELL_TRANSFORM_INFERNAL);
177 }
178 }
179
180 private:
182 };
183
184 CreatureAI* GetAI(Creature* creature) const override
185 {
186 return new npc_infernal_attackerAI(creature);
187 }
188};
189
190/*#####
191# npc_mature_netherwing_drake
192#####*/
193
195{
197
202
203 GO_CARCASS = 185155,
204
206 NPC_EVENT_PINGER = 22131
208
210{
211public:
212 npc_mature_netherwing_drake() : CreatureScript("npc_mature_netherwing_drake") { }
213
214 CreatureAI* GetAI(Creature* creature) const override
215 {
216 return new npc_mature_netherwing_drakeAI(creature);
217 }
218
220 {
222 {
223 Initialize();
224 }
225
227 {
229
230 bCanEat = false;
231 bIsEating = false;
232
233 EatTimer = 5000;
234 CastTimer = 5000;
235 }
236
238
241
244
245 void Reset() override
246 {
247 Initialize();
248 }
249
250 void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
251 {
252 if (bCanEat || bIsEating)
253 return;
254
255 if (caster->GetTypeId() == TYPEID_PLAYER && spellInfo->Id == SPELL_PLACE_CARCASS && !me->HasAura(SPELL_JUST_EATEN))
256 {
257 uiPlayerGUID = caster->GetGUID();
258 bCanEat = true;
259 }
260 }
261
262 void MovementInform(uint32 type, uint32 id) override
263 {
264 if (type != POINT_MOTION_TYPE)
265 return;
266
267 if (id == POINT_ID)
268 {
269 bIsEating = true;
270 EatTimer = 7000;
272 }
273 }
274
275 void UpdateAI(uint32 diff) override
276 {
277 if (bCanEat || bIsEating)
278 {
279 if (EatTimer <= diff)
280 {
281 if (bCanEat && !bIsEating)
282 {
284 {
285 if (GameObject* go = unit->FindNearestGameObject(GO_CARCASS, 10))
286 {
288 me->StopMoving();
289
290 me->GetMotionMaster()->MovePoint(POINT_ID, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
291 }
292 }
293 bCanEat = false;
294 }
295 else if (bIsEating)
296 {
299
301 {
302 player->KilledMonsterCredit(NPC_EVENT_PINGER);
303
304 if (GameObject* go = player->FindNearestGameObject(GO_CARCASS, 10))
305 go->Delete();
306 }
307
308 Reset();
310 }
311 }
312 else
313 EatTimer -= diff;
314
315 return;
316 }
317
318 if (!UpdateVictim())
319 return;
320
321 if (CastTimer <= diff)
322 {
324 CastTimer = 5000;
325 }
326 else
327 CastTimer -= diff;
328 }
329 };
330};
331
332/*###
333# npc_enslaved_netherwing_drake
334####*/
335
337{
338 // Spells
341
342 // Creatures
345
346 // Quests
348
349 // Movement
350 POINT_MOVE_UP = 1
352
354{
355public:
356 npc_enslaved_netherwing_drake() : CreatureScript("npc_enslaved_netherwing_drake") { }
357
359 {
361 {
362 Tapped = false;
364 }
365
366 void Reset() override
367 {
368 if (!Tapped)
370
371 me->SetDisableGravity(false);
372 }
373
374 void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
375 {
376 Player* playerCaster = caster->ToPlayer();
377 if (!playerCaster)
378 return;
379
380 if (spellInfo->Id == SPELL_HIT_FORCE_OF_NELTHARAKU && !Tapped)
381 {
382 Tapped = true;
383 PlayerGUID = playerCaster->GetGUID();
384
386
388 if (Dragonmaw)
389 {
390 AddThreat(Dragonmaw, 100000.0f);
391 AttackStart(Dragonmaw);
392 }
393
395 me->GetThreatManager().ClearThreat(playerCaster);
396 }
397 }
398
399 void MovementInform(uint32 type, uint32 id) override
400 {
401 if (type != POINT_MOTION_TYPE)
402 return;
403
404 if (id == 1)
405 {
406 if (!PlayerGUID.IsEmpty())
408
409 me->DespawnOrUnsummon(1ms);
410 }
411 }
412
413 void UpdateAI(uint32 diff) override
414 {
415 if (!UpdateVictim())
416 {
417 if (Tapped)
418 {
419 if (FlyTimer <= diff)
420 {
421 Tapped = false;
422 if (!PlayerGUID.IsEmpty())
423 {
426 {
427 DoCast(player, SPELL_FORCE_OF_NELTHARAKU, true);
428
429 Position pos;
430 if (Unit* EscapeDummy = me->FindNearestCreature(NPC_ESCAPE_DUMMY, 30))
431 pos = EscapeDummy->GetPosition();
432 else
433 {
434 pos = me->GetRandomNearPosition(20);
435 pos.m_positionZ += 25;
436 }
437
438 me->SetCanFly(true);
439 me->SetDisableGravity(true);
441 }
442 }
443 } else FlyTimer -= diff;
444 }
445 return;
446 }
447 }
448
449 private:
452 bool Tapped;
453 };
454
455 CreatureAI* GetAI(Creature* creature) const override
456 {
457 return new npc_enslaved_netherwing_drakeAI(creature);
458 }
459};
460
461/*####
462# npc_earthmender_wilda
463####*/
464
466{
474
479
482
484};
485
487{
488public:
489 npc_earthmender_wilda() : CreatureScript("npc_earthmender_wilda") { }
490
492 {
494 {
495 Initialize();
496 }
497
499 {
501 }
502
504
505 void Reset() override
506 {
507 Initialize();
508 }
509
510 void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
511 {
512 Player* player = GetPlayerForEscort();
513 if (!player)
514 return;
515
516 switch (waypointId)
517 {
518 case 13:
519 Talk(SAY_WIL_PROGRESS1, player);
521 break;
522 case 14:
524 break;
525 case 15:
526 Talk(SAY_WIL_FIND_EXIT, player);
527 break;
528 case 19:
529 DoRandomSay();
530 break;
531 case 20:
533 break;
534 case 26:
535 DoRandomSay();
536 break;
537 case 27:
539 break;
540 case 33:
541 DoRandomSay();
542 break;
543 case 34:
545 break;
546 case 37:
547 DoRandomSay();
548 break;
549 case 38:
551 break;
552 case 39:
553 Talk(SAY_WIL_JUST_AHEAD, player);
554 break;
555 case 43:
556 DoRandomSay();
557 break;
558 case 44:
560 break;
561 case 50:
562 Talk(SAY_WIL_END, player);
564 break;
565 }
566 }
567
568 void JustSummoned(Creature* summoned) override
569 {
570 if (summoned->GetEntry() == NPC_COILSKAR_ASSASSIN)
571 summoned->AI()->AttackStart(me);
572 }
573
574 //this is very unclear, random say without no real relevance to script/event
576 {
578 }
579
581 {
582 //unknown where they actually appear
584 }
585
586 void JustEngagedWith(Unit* who) override
587 {
588 //don't always use
589 if (rand32() % 5)
590 return;
591
592 //only aggro text if not player
593 if (who->GetTypeId() != TYPEID_PLAYER)
594 {
595 //appears to be random
596 if (urand(0, 1))
598 }
599 }
600
601 void UpdateAI(uint32 uiDiff) override
602 {
603 EscortAI::UpdateAI(uiDiff);
604
605 if (!UpdateVictim())
606 return;
607
609 if (!HealthAbovePct(30))
610 {
611 if (m_uiHealingTimer <= uiDiff)
612 {
614 m_uiHealingTimer = 15000;
615 }
616 else
617 m_uiHealingTimer -= uiDiff;
618 }
619 }
620
621 void OnQuestAccept(Player* player, Quest const* quest) override
622 {
623 if (quest->GetQuestId() == QUEST_ESCAPE_COILSCAR)
624 {
625 Talk(SAY_WIL_START, player);
627
629 Start(false, player->GetGUID(), quest);
630 }
631 }
632 };
633
634 CreatureAI* GetAI(Creature* creature) const override
635 {
636 return new npc_earthmender_wildaAI(creature);
637 }
638
639};
640
641/*#####
642# Quest: Battle of the crimson watch
643#####*/
644
645/* ContentData
646Battle of the crimson watch - creatures, gameobjects and defines
647npc_illidari_spawn : Adds that are summoned in the Crimson Watch battle.
648npc_torloth_the_magnificent : Final Creature that players have to face before quest is completed
649npc_lord_illidan_stormrage : Creature that controls the event.
650go_crystal_prison : GameObject that begins the event and hands out quest
651EndContentData */
652
653#define QUEST_BATTLE_OF_THE_CRIMSON_WATCH 10781
654#define EVENT_AREA_RADIUS 65 //65yds
655#define EVENT_COOLDOWN 30000 //in ms. appear after event completed or failed (should be = Adds despawn time)
656
658{
660};
661
662// Creature 0 - Torloth, 1 - Illidan
664{
665 {0, 2000},
666 {1, 7000},
667 {0, 3000},
668 {0, 2000}, // Torloth stand
669 {0, 1000},
670 {0, 3000},
671 {0, 0}
672};
673
674//Cordinates for Spawns
676{
677 //Cords used for:
678 {-4615.8556f, 1342.2532f, 139.9f, 1.612f}, //Illidari Soldier
679 {-4598.9365f, 1377.3182f, 139.9f, 3.917f}, //Illidari Soldier
680 {-4598.4697f, 1360.8999f, 139.9f, 2.427f}, //Illidari Soldier
681 {-4589.3599f, 1369.1061f, 139.9f, 3.165f}, //Illidari Soldier
682 {-4608.3477f, 1386.0076f, 139.9f, 4.108f}, //Illidari Soldier
683 {-4633.1889f, 1359.8033f, 139.9f, 0.949f}, //Illidari Soldier
684 {-4623.5791f, 1351.4574f, 139.9f, 0.971f}, //Illidari Soldier
685 {-4607.2988f, 1351.6099f, 139.9f, 2.416f}, //Illidari Soldier
686 {-4633.7764f, 1376.0417f, 139.9f, 5.608f}, //Illidari Soldier
687 {-4600.2461f, 1369.1240f, 139.9f, 3.056f}, //Illidari Mind Breaker
688 {-4631.7808f, 1367.9459f, 139.9f, 0.020f}, //Illidari Mind Breaker
689 {-4600.2461f, 1369.1240f, 139.9f, 3.056f}, //Illidari Highlord
690 {-4631.7808f, 1367.9459f, 139.9f, 0.020f}, //Illidari Highlord
691 {-4615.5586f, 1353.0031f, 139.9f, 1.540f}, //Illidari Highlord
692 {-4616.4736f, 1384.2170f, 139.9f, 4.971f}, //Illidari Highlord
693 {-4627.1240f, 1378.8752f, 139.9f, 2.544f} //Torloth The Magnificent
694};
695
696struct WaveData
697{
700};
701
703{
704 {9, 0, 22075, 10000, 7000}, //Illidari Soldier
705 {2, 9, 22074, 10000, 7000}, //Illidari Mind Breaker
706 {4, 11, 19797, 10000, 7000}, //Illidari Highlord
707 {1, 15, 22076, 10000, 7000} //Torloth The Magnificent
708};
709
710struct SpawnSpells
711{
713};
714
716{
717 {10000, 15000, 35871}, // Illidari Soldier Cast - Spellbreaker
718 {10000, 10000, 38985}, // Illidari Mind Breake Cast - Focused Bursts
719 {35000, 35000, 22884}, // Illidari Mind Breake Cast - Psychic Scream
720 {20000, 20000, 17194}, // Illidari Mind Breake Cast - Mind Blast
721 {8000, 15000, 38010}, // Illidari Highlord Cast - Curse of Flames
722 {12000, 20000, 16102}, // Illidari Highlord Cast - Flamestrike
723 {10000, 15000, 15284}, // Torloth the Magnificent Cast - Cleave
724 {18000, 20000, 39082}, // Torloth the Magnificent Cast - Shadowfury
725 {25000, 28000, 33961} // Torloth the Magnificent Cast - Spell Reflection
726};
727
728/*######
729# npc_torloth_the_magnificent
730#####*/
731
733{
734public:
735 npc_torloth_the_magnificent() : CreatureScript("npc_torloth_the_magnificent") { }
736
737 CreatureAI* GetAI(Creature* c) const override
738 {
739 return new npc_torloth_the_magnificentAI(c);
740 }
741
743 {
745 {
746 Initialize();
747 SpellTimer1 = 0;
748 SpellTimer2 = 0;
749 SpellTimer3 = 0;
750 }
751
753 {
754 AnimationTimer = 4000;
755 AnimationCount = 0;
758 Timers = false;
759 }
760
762
764
767
768 bool Timers;
769
770 void Reset() override
771 {
772 Initialize();
773
777 }
778
779 void JustEngagedWith(Unit* /*who*/) override { }
780
782 {
783 Creature* creature = me;
784
785 if (TorlothAnim[AnimationCount].creature == 1)
786 {
788
789 if (!creature)
790 return;
791 }
792
794
795 switch (AnimationCount)
796 {
797 case 0:
799 break;
800 case 3:
802 break;
803 case 5:
805 {
806 me->SetTarget(AggroTarget->GetGUID());
807 AddThreat(AggroTarget, 1);
809 }
810 break;
811 case 6:
813 {
816
817 float x, y, z;
818 AggroTarget->GetPosition(x, y, z);
819 me->GetMotionMaster()->MovePoint(0, x, y, z);
820 }
821 break;
822 }
824 }
825
826 void UpdateAI(uint32 diff) override
827 {
828 if (AnimationTimer)
829 {
830 if (AnimationTimer <= diff)
831 {
833 } else AnimationTimer -= diff;
834 }
835
836 if (AnimationCount < 6)
837 {
838 me->CombatStop();
839 } else if (!Timers)
840 {
844 Timers = true;
845 }
846
847 if (Timers)
848 {
849 if (SpellTimer1 <= diff)
850 {
851 DoCastVictim(SpawnCast[6].SpellId);//Cleave
852 SpellTimer1 = SpawnCast[6].Timer2 + (rand32() % 10 * 1000);
853 } else SpellTimer1 -= diff;
854
855 if (SpellTimer2 <= diff)
856 {
857 DoCastVictim(SpawnCast[7].SpellId);//Shadowfury
858 SpellTimer2 = SpawnCast[7].Timer2 + (rand32() % 5 * 1000);
859 } else SpellTimer2 -= diff;
860
861 if (SpellTimer3 <= diff)
862 {
863 DoCast(me, SpawnCast[8].SpellId);
864 SpellTimer3 = SpawnCast[8].Timer2 + (rand32() % 7 * 1000);//Spell Reflection
865 } else SpellTimer3 -= diff;
866 }
867 }
868
869 void JustDied(Unit* killer) override
870 {
871 if (!killer)
872 return;
873
874 switch (killer->GetTypeId())
875 {
876 case TYPEID_UNIT:
877 if (Unit* owner = killer->GetOwner())
878 if (Player* player = owner->ToPlayer())
879 player->GroupEventHappens(QUEST_BATTLE_OF_THE_CRIMSON_WATCH, me);
880 break;
881 case TYPEID_PLAYER:
882 if (Player* player = killer->ToPlayer())
883 player->GroupEventHappens(QUEST_BATTLE_OF_THE_CRIMSON_WATCH, me);
884 break;
885 default:
886 break;
887 }
888
890 LordIllidan->AI()->EnterEvadeMode();
891 }
892 };
893};
894
895/*#####
896# npc_lord_illidan_stormrage
897#####*/
898
900{
901public:
902 npc_lord_illidan_stormrage() : CreatureScript("npc_lord_illidan_stormrage") { }
903
904 CreatureAI* GetAI(Creature* c) const override
905 {
906 return new npc_lord_illidan_stormrageAI(c);
907 }
908
910 {
912 {
913 Initialize();
914 }
915
917 {
919
920 WaveTimer = 10000;
921 AnnounceTimer = 7000;
922 LiveCount = 0;
923 WaveCount = 0;
924
925 EventStarted = false;
926 Announced = false;
927 Failed = false;
928 }
929
931
934
937
940 bool Failed;
941
942 void Reset() override
943 {
944 Initialize();
945
946 me->SetVisible(false);
947 }
948
949 void JustEngagedWith(Unit* /*who*/) override { }
950 void MoveInLineOfSight(Unit* /*who*/) override { }
951
952 void AttackStart(Unit* /*who*/) override { }
953
954 void SummonNextWave();
955
957 {
959
960 if (!player)
961 return;
962
963 if (Group* EventGroup = player->GetGroup())
964 {
965 uint8 GroupMemberCount = 0;
966 uint8 DeadMemberCount = 0;
967 uint8 FailedMemberCount = 0;
968
969 Group::MemberSlotList const& members = EventGroup->GetMemberSlots();
970
971 for (Group::member_citerator itr = members.begin(); itr!= members.end(); ++itr)
972 {
974 if (!GroupMember)
975 continue;
977 {
979 ++FailedMemberCount;
980 }
981 ++GroupMemberCount;
982
983 if (GroupMember->isDead())
984 ++DeadMemberCount;
985 }
986
987 if (GroupMemberCount == FailedMemberCount)
988 {
989 Failed = true;
990 }
991
992 if (GroupMemberCount == DeadMemberCount)
993 {
994 for (Group::member_citerator itr = members.begin(); itr!= members.end(); ++itr)
995 {
996 if (Player* groupMember = ObjectAccessor::GetPlayer(*me, itr->guid))
997 if (groupMember->GetQuestStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH) == QUEST_STATUS_INCOMPLETE)
998 groupMember->FailQuest(QUEST_BATTLE_OF_THE_CRIMSON_WATCH);
999 }
1000 Failed = true;
1001 }
1002 } else if (player->isDead() || !player->IsWithinDistInMap(me, EVENT_AREA_RADIUS))
1003 {
1005 Failed = true;
1006 }
1007 }
1008
1010 {
1011 --LiveCount;
1012 if (!LiveCount)
1013 Announced = false;
1014 }
1015
1016 void UpdateAI(uint32 diff) override
1017 {
1018 if (!PlayerGUID || !EventStarted)
1019 return;
1020
1021 if (!LiveCount && WaveCount < 4)
1022 {
1023 if (!Announced && AnnounceTimer <= diff)
1024 {
1025 Announced = true;
1026 }
1027 else
1028 AnnounceTimer -= diff;
1029
1030 if (WaveTimer <= diff)
1031 {
1033 }
1034 else
1035 WaveTimer -= diff;
1036 }
1038
1039 if (Failed)
1041 }
1042 };
1043};
1044
1045/*######
1046# npc_illidari_spawn
1047######*/
1048
1050{
1051public:
1052 npc_illidari_spawn() : CreatureScript("npc_illidari_spawn") { }
1053
1054 CreatureAI* GetAI(Creature* c) const override
1055 {
1056 return new npc_illidari_spawnAI(c);
1057 }
1058
1060 {
1062 {
1063 Initialize();
1064 SpellTimer1 = 0;
1065 SpellTimer2 = 0;
1066 SpellTimer3 = 0;
1067 }
1068
1070 {
1072 Timers = false;
1073 }
1074
1078
1079 void Reset() override
1080 {
1081 Initialize();
1082 }
1083
1084 void JustEngagedWith(Unit* /*who*/) override { }
1085
1086 void JustDied(Unit* /*killer*/) override
1087 {
1091 }
1092
1093 void UpdateAI(uint32 diff) override
1094 {
1095 if (!UpdateVictim())
1096 return;
1097
1098 if (!Timers)
1099 {
1100 if (me->GetEntry() == 22075)//Illidari Soldier
1101 {
1102 SpellTimer1 = SpawnCast[0].Timer1 + (rand32() % 4 * 1000);
1103 }
1104 if (me->GetEntry() == 22074)//Illidari Mind Breaker
1105 {
1106 SpellTimer1 = SpawnCast[1].Timer1 + (rand32() % 10 * 1000);
1107 SpellTimer2 = SpawnCast[2].Timer1 + (rand32() % 4 * 1000);
1108 SpellTimer3 = SpawnCast[3].Timer1 + (rand32() % 4 * 1000);
1109 }
1110 if (me->GetEntry() == 19797)// Illidari Highlord
1111 {
1112 SpellTimer1 = SpawnCast[4].Timer1 + (rand32() % 4 * 1000);
1113 SpellTimer2 = SpawnCast[5].Timer1 + (rand32() % 4 * 1000);
1114 }
1115 Timers = true;
1116 }
1117 //Illidari Soldier
1118 if (me->GetEntry() == 22075)
1119 {
1120 if (SpellTimer1 <= diff)
1121 {
1122 DoCastVictim(SpawnCast[0].SpellId);//Spellbreaker
1123 SpellTimer1 = SpawnCast[0].Timer2 + (rand32() % 5 * 1000);
1124 } else SpellTimer1 -= diff;
1125 }
1126 //Illidari Mind Breaker
1127 if (me->GetEntry() == 22074)
1128 {
1129 if (SpellTimer1 <= diff)
1130 {
1132 {
1133 if (target->GetTypeId() == TYPEID_PLAYER)
1134 {
1135 DoCast(target, SpawnCast[1].SpellId); //Focused Bursts
1136 SpellTimer1 = SpawnCast[1].Timer2 + (rand32() % 5 * 1000);
1137 } else SpellTimer1 = 2000;
1138 }
1139 } else SpellTimer1 -= diff;
1140
1141 if (SpellTimer2 <= diff)
1142 {
1143 DoCastVictim(SpawnCast[2].SpellId);//Psychic Scream
1144 SpellTimer2 = SpawnCast[2].Timer2 + (rand32() % 13 * 1000);
1145 } else SpellTimer2 -= diff;
1146
1147 if (SpellTimer3 <= diff)
1148 {
1149 DoCastVictim(SpawnCast[3].SpellId);//Mind Blast
1150 SpellTimer3 = SpawnCast[3].Timer2 + (rand32() % 8 * 1000);
1151 } else SpellTimer3 -= diff;
1152 }
1153 //Illidari Highlord
1154 if (me->GetEntry() == 19797)
1155 {
1156 if (SpellTimer1 <= diff)
1157 {
1158 DoCastVictim(SpawnCast[4].SpellId);//Curse Of Flames
1159 SpellTimer1 = SpawnCast[4].Timer2 + (rand32() % 10 * 1000);
1160 } else SpellTimer1 -= diff;
1161
1162 if (SpellTimer2 <= diff)
1163 {
1164 DoCastVictim(SpawnCast[5].SpellId);//Flamestrike
1165 SpellTimer2 = SpawnCast[5].Timer2 + (rand32() % 7 * 13000);
1166 } else SpellTimer2 -= diff;
1167 }
1168 }
1169 };
1170};
1171
1173{
1176 uint8 FelguardCount = 0;
1177 uint8 DreadlordCount = 0;
1178
1179 for (uint8 i = 0; i < count; ++i)
1180 {
1182 ++LiveCount;
1183
1184 if (Spawn)
1185 {
1186 Spawn->LoadCreaturesAddon();
1187
1188 if (WaveCount == 0)//1 Wave
1189 {
1190 if (rand32() % 3 == 1 && FelguardCount<2)
1191 {
1192 Spawn->SetDisplayId(18654);
1193 ++FelguardCount;
1194 }
1195 else if (DreadlordCount < 3)
1196 {
1197 Spawn->SetDisplayId(19991);
1198 ++DreadlordCount;
1199 }
1200 else if (FelguardCount<2)
1201 {
1202 Spawn->SetDisplayId(18654);
1203 ++FelguardCount;
1204 }
1205 }
1206
1207 if (WaveCount < 3)//1-3 Wave
1208 {
1209 if (!PlayerGUID.IsEmpty())
1210 {
1212 {
1213 float x, y, z;
1214 target->GetPosition(x, y, z);
1215 Spawn->GetMotionMaster()->MovePoint(0, x, y, z);
1216 }
1217 }
1218 ENSURE_AI(npc_illidari_spawn::npc_illidari_spawnAI, Spawn->AI())->LordIllidanGUID = me->GetGUID();
1219 }
1220
1221 if (WavesInfo[WaveCount].CreatureId == 22076) // Torloth
1222 {
1224 if (!PlayerGUID.IsEmpty())
1226 }
1227 }
1228 }
1229 ++WaveCount;
1230 if (WaveCount < 4)
1231 {
1234 }
1235}
1236
1237/*#####
1238# go_crystal_prison
1239######*/
1240
1242{
1243public:
1244 go_crystal_prison() : GameObjectScript("go_crystal_prison") { }
1245
1247 {
1249
1250 void OnQuestAccept(Player* player, Quest const* quest) override
1251 {
1253 {
1254 Creature* illidan = player->FindNearestCreature(22083, 50);
1255 if (illidan && !ENSURE_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, illidan->AI())->EventStarted)
1256 {
1260 }
1261 }
1262 }
1263 };
1264
1265 GameObjectAI* GetAI(GameObject* go) const override
1266 {
1267 return new go_crystal_prisonAI(go);
1268 }
1269};
1270
1271/*####
1272# npc_enraged_spirits
1273####*/
1274
1276{
1277 // QUESTS
1281
1282 // Totem
1285
1286 // SPIRITS
1291
1292 // ENRAGED WATER SPIRIT SPELLS
1294
1295 // ENRAGED AIR SPIRIT SPELLS
1299
1300 // ENRAGED FIRE SPIRIT SPELLS - Will be using the enrage spell from Air Spirit
1302 SPELL_FEL_FIRE_AURA = 36006, // Earth spirit uses this one
1303
1304 // ENRAGED EARTH SPIRIT SPELLS
1307
1308 // SOULS
1312 NPC_ENRAGED_WATERY_SOUL = 21109, // wrong model
1313
1314 // SPELL KILLCREDIT - not working!?! - using KilledMonsterCredit
1319
1320 // KilledMonsterCredit Workaround
1325
1326 // Captured Spell / Buff
1327 SPELL_SOUL_CAPTURED = 36115
1329
1331{
1338
1340{
1341public:
1342 npc_enraged_spirit() : CreatureScript("npc_enraged_spirit") { }
1343
1344 CreatureAI* GetAI(Creature* creature) const override
1345 {
1346 return new npc_enraged_spiritAI(creature);
1347 }
1348
1350 {
1351 npc_enraged_spiritAI(Creature* creature) : ScriptedAI(creature) { }
1352
1353 void Reset() override { }
1354
1355 void JustEngagedWith(Unit* /*who*/) override
1356 {
1357 switch (me->GetEntry())
1358 {
1360 _events.ScheduleEvent(EVENT_ENRAGED_WATER_SPIRIT, 0s, Seconds(1));
1361 break;
1363 if (!me->GetAura(SPELL_FEL_FIRE_AURA))
1364 DoCastSelf(SPELL_FEL_FIRE_AURA);
1365 _events.ScheduleEvent(EVENT_ENRAGED_FIRE_SPIRIT, 2s, 10s);
1366 break;
1368 if (!me->GetAura(SPELL_FEL_FIRE_AURA))
1369 DoCastSelf(SPELL_FEL_FIRE_AURA);
1370 _events.ScheduleEvent(EVENT_ENRAGED_EARTH_SPIRIT, 3s, 4s);
1371 break;
1373 _events.ScheduleEvent(EVENT_ENRAGED_AIR_SPIRIT_CHAIN_LIGHTNING, 10s);
1374 break;
1375 default:
1376 break;
1377 }
1378 }
1379
1380 void UpdateAI(uint32 diff) override
1381 {
1382 if (!UpdateVictim())
1383 return;
1384 _events.Update(diff);
1385
1386 while (uint32 eventId = _events.ExecuteEvent())
1387 {
1388 switch (eventId)
1389 {
1391 if (UpdateVictim())
1392 DoCastVictim(SPELL_STORMBOLT);
1393 _events.Repeat(Seconds(17), Seconds(23));
1394 break;
1396 if (UpdateVictim())
1397 DoCastVictim(SPELL_FEL_FIREBALL);
1398 _events.Repeat(Seconds(6), Seconds(12));
1399 break;
1401 if (UpdateVictim())
1402 DoCastVictim(SPELL_FIERY_BOULDER);
1403 _events.Repeat(Seconds(6), Seconds(9));
1404 break;
1406 if (UpdateVictim())
1407 DoCastVictim(SPELL_CHAIN_LIGHTNING);
1408 _events.ScheduleEvent(EVENT_ENRAGED_AIR_SPIRIT_HURRICANE, 3s, 5s);
1409 break;
1411 if (UpdateVictim())
1412 DoCastVictim(SPELL_HURRICANE);
1413 _events.ScheduleEvent(EVENT_ENRAGED_AIR_SPIRIT_CHAIN_LIGHTNING, 15s, 20s);
1414 break;
1415 default:
1416 break;
1417 }
1418 }
1419
1420 if (me->GetEntry() == NPC_ENRAGED_FIRE_SPIRIT || me->GetEntry() == NPC_ENRAGED_AIR_SPIRIT)
1421 if (HealthBelowPct(35) && !me->GetAura(SPELL_ENRAGE))
1422 DoCastSelf(SPELL_ENRAGE);
1423 }
1424
1425 void JustDied(Unit* /*killer*/) override
1426 {
1427 // always spawn spirit on death
1428 // if totem around
1429 // move spirit to totem and cast kill count
1430 uint32 entry = 0;
1431 uint32 credit = 0;
1432
1433 switch (me->GetEntry())
1434 {
1436 entry = NPC_FIERY_SOUL;
1437 //credit = SPELL_FIERY_SOUL_CAPTURED_CREDIT;
1438 credit = NPC_CREDIT_FIRE;
1439 break;
1441 entry = NPC_EARTHEN_SOUL;
1442 //credit = SPELL_EARTHEN_SOUL_CAPTURED_CREDIT;
1443 credit = NPC_CREDIT_EARTH;
1445 break;
1447 entry = NPC_ENRAGED_AIRY_SOUL;
1448 //credit = SPELL_AIRY_SOUL_CAPTURED_CREDIT;
1449 credit = NPC_CREDIT_AIR;
1450 break;
1453 //credit = SPELL_WATERY_SOUL_CAPTURED_CREDIT;
1454 credit = NPC_CREDIT_WATER;
1455 break;
1456 default:
1457 break;
1458 }
1459
1460 // Spawn Soul on Kill ALWAYS!
1461 Creature* Summoned = nullptr;
1462 Unit* totemOspirits = nullptr;
1463
1464 if (entry != 0)
1465 Summoned = DoSpawnCreature(entry, 0, 0, 1, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s);
1466
1467 // FIND TOTEM, PROCESS QUEST
1468 if (Summoned)
1469 {
1471 if (totemOspirits)
1472 {
1473 Summoned->SetFaction(FACTION_FRIENDLY);
1474 Summoned->GetMotionMaster()->MovePoint(0, totemOspirits->GetPositionX(), totemOspirits->GetPositionY(), Summoned->GetPositionZ());
1475
1476 if (Unit* owner = totemOspirits->GetOwner())
1477 if (Player* player = owner->ToPlayer())
1478 player->KilledMonsterCredit(credit);
1479 DoCast(totemOspirits, SPELL_SOUL_CAPTURED);
1480 }
1481 }
1482 }
1483
1484 private:
1486 };
1487};
1488
1490{
1492};
1493
1494// 38790 - Unlocking Zuluhed's Chains
1496{
1497 public:
1498 spell_unlocking_zuluheds_chains() : SpellScriptLoader("spell_unlocking_zuluheds_chains") { }
1499
1501 {
1503 {
1504 if (Player* caster = GetCaster()->ToPlayer())
1505 if (Creature* karynaku = caster->FindNearestCreature(NPC_KARYNAKU, 15.0f))
1506 caster->KilledMonsterCredit(NPC_KARYNAKU, karynaku->GetGUID());
1507 }
1508
1509 void Register() override
1510 {
1511 AfterHit += SpellHitFn(spell_unlocking_zuluheds_chains_SpellScript::HandleAfterHit);
1512 }
1513 };
1514
1515 SpellScript* GetSpellScript() const override
1516 {
1518 }
1519};
1520
1522{
1525
1528
1531 DATA_BOAR = 1
1533
1535{
1536public:
1537 npc_shadowmoon_tuber_node() : CreatureScript("npc_shadowmoon_tuber_node") { }
1538
1540 {
1542
1543 void SetData(uint32 id, uint32 data) override
1544 {
1545 if (id == TYPE_BOAR && data == DATA_BOAR)
1546 {
1547 // Spawn chest GO
1548 DoCast(SPELL_SHADOWMOON_TUBER);
1549
1550 // Despawn the tuber
1552 {
1553 tuber->SetLootState(GO_JUST_DEACTIVATED);
1554 me->DespawnOrUnsummon();
1555 }
1556 }
1557 }
1558
1559 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
1560 {
1561 if (spellInfo->Id == SPELL_WHISTLE)
1562 {
1563 if (Creature* boar = me->FindNearestCreature(NPC_BOAR_ENTRY, 30.0f))
1564 {
1565 boar->SetWalk(false);
1566 boar->GetMotionMaster()->MovePoint(POINT_TUBER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
1567 }
1568 }
1569 }
1570 };
1571
1572 CreatureAI* GetAI(Creature* creature) const override
1573 {
1574 return new npc_shadowmoon_tuber_nodeAI(creature);
1575 }
1576};
1577
1578/*######
1579## Quest 10769, 10776: Dissension Amongst the Ranks...
1580######*/
1581
1583{
1588
1589// 38224 - Illidari Agent Illusion
1591{
1592 bool Validate(SpellInfo const* /*spellInfo*/) override
1593 {
1594 return ValidateSpellInfo({ SPELL_ILLIDARI_DISGUISE_MALE, SPELL_ILLIDARI_DISGUISE_FEMALE });
1595 }
1596
1597 void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1598 {
1599 if (Player* target = GetTarget()->ToPlayer())
1600 target->CastSpell(target, target->GetNativeGender() == GENDER_MALE ?
1602 }
1603
1604 void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1605 {
1606 Unit* target = GetTarget();
1609 }
1610
1611 void Register() override
1612 {
1615 }
1616};
1617
1618// 38223 - Quest Credit: Crazed Colossus
1620{
1621 bool Validate(SpellInfo const* spellInfo) override
1622 {
1623 return ValidateSpellInfo(
1624 {
1625 uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()),
1627 });
1628 }
1629
1630 void HandleScript(SpellEffIndex /*effIndex*/)
1631 {
1632 Unit* target = GetHitUnit();
1633 if (target->HasAura(uint32(GetEffectValue())))
1635 }
1636
1637 void Register() override
1638 {
1640 }
1641};
1642
1644{
1651 new go_crystal_prison();
1652 new npc_illidari_spawn();
1654 new npc_enraged_spirit();
1659}
@ IN_MILLISECONDS
Definition: Common.h:35
uint8_t uint8
Definition: Define.h:144
int8_t int8
Definition: Define.h:140
uint32_t uint32
Definition: Define.h:142
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:159
@ POINT_MOTION_TYPE
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition: ObjectDefines.h:66
@ TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
Definition: ObjectDefines.h:63
@ TYPEID_UNIT
Definition: ObjectGuid.h:40
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
@ QUEST_STATUS_INCOMPLETE
Definition: QuestDef.h:145
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
uint32 rand32()
Definition: Random.cpp:70
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_0
Definition: SharedDefines.h:30
@ GENDER_MALE
@ EMOTE_ONESHOT_POINT
@ EMOTE_ONESHOT_ATTACK_UNARMED
@ SPELL_EFFECT_SCRIPT_EFFECT
@ FACTION_ORC_DRAGONMAW
@ FACTION_FLAYER_HUNTER
@ FACTION_FRIENDLY
@ FACTION_EARTHEN_RING
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_DUMMY
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define AuraEffectApplyFn(F, I, N, M)
Definition: SpellScript.h:2029
#define SpellHitFn(F)
Definition: SpellScript.h:854
#define ENSURE_AI(a, b)
Definition: UnitAI.h:29
@ UNIT_STAND_STATE_KNEEL
Definition: UnitDefines.h:50
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:42
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:145
@ UNIT_STATE_ROOT
Definition: Unit.h:265
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:219
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
void AttackStart(Unit *victim) override
== Triggered Actions Requested ==================
Definition: CreatureAI.cpp:328
Creature *const me
Definition: CreatureAI.h:61
Creature * DoSummon(uint32 entry, Position const &pos, Milliseconds despawnTime=30s, TempSummonType summonType=TEMPSUMMON_CORPSE_TIMED_DESPAWN)
Definition: CreatureAI.cpp:464
bool LoadCreaturesAddon()
Definition: Creature.cpp:2749
void SetImmuneToPC(bool apply) override
Definition: Creature.h:170
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
void SetTarget(ObjectGuid const &guid) override
Definition: Creature.cpp:3419
void SetDisplayId(uint32 displayId, bool setNative=false) override
Definition: Creature.cpp:3402
CreatureAI * AI() const
Definition: Creature.h:214
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
Definition: Group.h:197
std::list< MemberSlot > MemberSlotList
Definition: Group.h:210
MemberSlotList::const_iterator member_citerator
Definition: Group.h:211
void MoveTakeoff(uint32 id, Position const &pos, Optional< int32 > tierTransitionId={}, Optional< float > velocity={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default)
void MoveRandom(float wanderDistance=0.0f, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_DEFAULT)
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 IsEmpty() const
Definition: ObjectGuid.h:319
void Clear()
Definition: ObjectGuid.h:286
static Creature * ToCreature(Object *o)
Definition: Object.h:219
TypeID GetTypeId() const
Definition: Object.h:173
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
void GroupEventHappens(uint32 questId, WorldObject const *pEventObject)
Definition: Player.cpp:16598
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: Player.cpp:16050
void FailQuest(uint32 quest_id)
Definition: Player.cpp:15446
Group * GetGroup(Optional< uint8 > partyIndex)
Definition: Player.h:2606
uint32 GetQuestId() const
Definition: QuestDef.h:587
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
Definition: SpellInfo.cpp:495
uint32 const Id
Definition: SpellInfo.h:325
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition: SpellInfo.h:577
void ClearThreat(Unit *target)
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:79
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void ClearUnitState(uint32 f)
Definition: Unit.h:733
void SetVisible(bool x)
Definition: Unit.cpp:8351
void CombatStop(bool includingCast=false, bool mutualPvP=true, bool(*unitFilter)(Unit const *otherUnit)=nullptr)
Definition: Unit.cpp:5827
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition: Unit.cpp:10100
ThreatManager & GetThreatManager()
Definition: Unit.h:1063
void SetFaction(uint32 faction) override
Definition: Unit.h:859
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void StopMoving()
Definition: Unit.cpp:10049
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition: Unit.cpp:12725
void SetUninteractible(bool apply)
Definition: Unit.cpp:8147
void AddUnitState(uint32 f)
Definition: Unit.h:731
bool SetCanFly(bool enable)
Definition: Unit.cpp:12820
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition: Unit.cpp:1598
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:833
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:834
bool isDead() const
Definition: Unit.h:1166
GameObject * FindNearestGameObject(uint32 entry, float range, bool spawnedOnly=true) const
Definition: Object.cpp:2170
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition: Object.cpp:2025
Unit * GetOwner() const
Definition: Object.cpp:2229
Position GetRandomNearPosition(float radius)
Definition: Object.cpp:3423
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
void UpdateGroundPositionZ(float x, float y, float &z) const
Definition: Object.cpp:1360
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition: Object.cpp:1147
GameObjectAI * GetAI(GameObject *go) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *c) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *c) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *c) const override
void AfterApply(AuraEffect const *, AuraEffectHandleModes)
void AfterRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *spellInfo) override
SpellScript * GetSpellScript() const override
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Player * GetPlayer(Map const *, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
void Start(bool isActiveAttacker=true, ObjectGuid playerGUID=ObjectGuid::Empty, Quest const *quest=nullptr, bool instantRespawn=false, bool canLoopPath=false)
void LoadPath(uint32 pathId)
Player * GetPlayerForEscort()
void UpdateAI(uint32 diff) override
constexpr float GetPositionX() const
Definition: Position.h:76
float m_positionZ
Definition: Position.h:55
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
constexpr float GetPositionZ() const
Definition: Position.h:78
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
bool HealthAbovePct(uint32 pct) const
void AddThreat(Unit *victim, float amount, Unit *who=nullptr)
uint32 CreatureId
uint8 UsedSpawnPoint
uint32 SpawnTimer
uint32 YellTimer
uint8 SpawnCount
void OnQuestAccept(Player *player, Quest const *quest) override
void WaypointReached(uint32 waypointId, uint32) override
void OnQuestAccept(Player *player, Quest const *quest) override
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
void IsSummonedBy(WorldObject *summoner) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
static WaveData WavesInfo[]
static SpawnSpells SpawnCast[]
@ SPELL_SHADOWMOON_TUBER
@ GO_SHADOWMOON_TUBER_MOUND
#define QUEST_BATTLE_OF_THE_CRIMSON_WATCH
static Position SpawnLocation[]
void AddSC_shadowmoon_valley()
@ EVENT_ENRAGED_AIR_SPIRIT_CHAIN_LIGHTNING
@ EVENT_ENRAGED_AIR_SPIRIT_HURRICANE
@ EVENT_ENRAGED_EARTH_SPIRIT
@ EVENT_ENRAGED_WATER_SPIRIT
@ EVENT_ENRAGED_FIRE_SPIRIT
static TorlothCinematic TorlothAnim[]
@ QUEST_ENRAGED_SPIRITS_FIRE_EARTH
@ SPELL_EARTHEN_SOUL_CAPTURED_CREDIT
@ NPC_ENRAGED_AIR_SPIRIT
@ SPELL_AIR_SPIRIT_CHAIN_LIGHTNING
@ NPC_ENRAGED_WATER_SPIRIT
@ NPC_ENRAGED_EARTH_SPIRIT
@ RADIUS_TOTEM_OF_SPIRITS
@ NPC_ENRAGED_WATERY_SOUL
@ SPELL_WATERY_SOUL_CAPTURED_CREDIT
@ ENTRY_TOTEM_OF_SPIRITS
@ SPELL_AIRY_SOUL_CAPTURED_CREDIT
@ QUEST_ENRAGED_SPIRITS_AIR
@ SPELL_FIERY_SOUL_CAPTURED_CREDIT
@ NPC_ENRAGED_AIRY_SOUL
@ QUEST_ENRAGED_SPIRITS_WATER
@ NPC_ENRAGED_FIRE_SPIRIT
@ SPELL_SUMMON_ENRAGED_EARTH_SHARD
@ SPELL_ILLIDARI_DISGUISE_MALE
@ SPELL_ILLIDARI_DISGUISE_FEMALE
@ SPELL_KILL_CREDIT_CRAZED_COLOSSUS
#define EVENT_AREA_RADIUS
@ NPC_COILSKAR_ASSASSIN
@ QUEST_ESCAPE_COILSCAR
@ SAY_WIL_JUST_AHEAD
@ SPELL_EARTHBING_TOTEM
@ SPELL_HEALING_WAVE
@ SPELL_CHAIN_LIGHTNING
@ SPELL_NETHER_BREATH
@ SPELL_PLACE_CARCASS
EnshlavedNetherwingDrake
@ NPC_DRAGONMAW_SUBJUGATOR
@ SPELL_HIT_FORCE_OF_NELTHARAKU
@ QUEST_THE_FORCE_OF_NELTHARAKU
@ SPELL_FORCE_OF_NELTHARAKU
@ SPELL_SPAWN_AND_PACIFY
@ SPELL_TRANSFORM_INFERNAL
@ EVENT_CAST_SUMMON_INFERNAL
@ SPELL_SUMMON_INFERNAL
@ NPC_INFERNAL_ATTACKER