TrinityCore
Loading...
Searching...
No Matches
zone_silverpine_forest.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 "CellImpl.h"
19#include "CombatAI.h"
20#include "CreatureAIImpl.h"
21#include "GameObject.h"
22#include "GameObjectAI.h"
23#include "GridNotifiers.h"
24#include "Group.h"
25#include "MotionMaster.h"
26#include "ObjectAccessor.h"
27#include "ObjectMgr.h"
28#include "Object.h"
29#include "Player.h"
30#include "ScriptMgr.h"
31#include "ScriptedCreature.h"
32#include "ScriptedGossip.h"
33#include "SharedDefines.h"
34#include "SpellAuras.h"
35#include "SpellAuraEffects.h"
36#include "SpellScript.h"
37#include "SpellMgr.h"
38#include "TemporarySummon.h"
39#include "Unit.h"
40#include "Vehicle.h"
41#include "WorldSession.h"
42
83
84// 44731 - Horde Hauler
86{
88
89 void JustAppeared() override
90 {
92 }
93
94 void PassengerBoarded(Unit* passenger, int8 seatId, bool apply) override
95 {
96 if (apply && passenger->IsPlayer())
97 {
98 _playerGUID = passenger->GetGUID();
99
100 if (seatId == SEAT_HAULER_PLAYER)
101 {
102 if (Creature* engineer = me->FindNearestCreature(NPC_HORDE_ENGINEER_HAULER, 15.0f, true))
103 {
105 {
106 if (engineer->IsAIEnabled())
107 engineer->AI()->Talk(TALK_HAULER_BOARDED, player);
108 }
109 }
110 }
111 }
112
113 if (!apply && !passenger->IsPlayer())
114 {
115 uint32 pathId = 0;
116
117 switch (seatId)
118 {
120 pathId = PATH_TROOPER_1;
121 break;
123 pathId = PATH_TROOPER_2;
124 break;
126 pathId = PATH_TROOPER_3;
127 break;
129 pathId = PATH_TROOPER_4;
130 break;
132 pathId = PATH_TROOPER_5;
133 break;
134
135 default:
136 break;
137 }
138
139 passenger->GetMotionMaster()->MovePath(pathId, false);
140 }
141 }
142
143 void WaypointReached(uint32 waypointId, uint32 pathId) override
144 {
145 if (pathId == PATH_FROM_NORTH_TO_SOUTH)
146 {
147 if (waypointId == WAYPOINT_ON_FORSAKEN_HIGH)
149 else if (waypointId == WAYPOINT_ON_SEPULCHER)
151 else if (waypointId == WAYPOINT_ON_FORSAKEN_FRONT)
153 else if (waypointId == WAYPOINT_ON_DESPAWN_POINT_SOUTH)
155 }
156 }
157
158 void UpdateAI(uint32 diff) override
159 {
160 _events.Update(diff);
161
162 while (uint32 eventId = _events.ExecuteEvent())
163 {
164 switch (eventId)
165 {
166 case EVENT_START_PATH:
168 break;
169
171 {
172 if (Creature* engineer = me->FindNearestCreature(NPC_HORDE_ENGINEER_HAULER, 15.0f, true))
173 {
174 if (engineer->IsAIEnabled())
175 engineer->AI()->Talk(TALK_ON_FORSAKEN_HIGH);
176 }
177 break;
178 }
179
181 {
182 if (Creature* engineer = me->FindNearestCreature(NPC_HORDE_ENGINEER_HAULER, 15.0f, true))
183 {
184 if (engineer->IsAIEnabled())
185 engineer->AI()->Talk(TALK_ON_SEPULCHER);
186 }
187 break;
188 }
189
191 {
192 if (Creature* engineer = me->FindNearestCreature(NPC_HORDE_ENGINEER_HAULER, 15.0f, true))
193 {
194 if (engineer->IsAIEnabled())
195 engineer->AI()->Talk(TALK_ON_FORSAKEN_FRONT);
196 }
197
199
201 break;
202 }
203
204 default:
205 break;
206 }
207 }
208 }
209
210private:
213};
214
220
221// 84238 - Magical Chains (Hauler)
223{
224 bool Validate(SpellInfo const* /*spellInfo*/) override
225 {
226 return ValidateSpellInfo
227 ({
230 });
231 }
232
233 void HandlePeriodic(AuraEffect const* /*aurEff*/)
234 {
237 }
238
243};
244
246{
247 { 1358.62f, 1054.72f, 53.1200f, 0.0f },
248 { 1393.27f, 1021.20f, 53.2225f, 0.0f },
249 { 1404.71f, 1063.73f, 60.5617f, 0.0f }
250};
251
253{
254 { 1387.90f, 1029.71f, 53.21853f, 2.827433f },
255 { 1389.79f, 1024.51f, 53.20833f, 2.827433f },
256 { 1388.05f, 1026.91f, 53.20833f, 2.827433f },
257 { 1388.16f, 1020.88f, 53.25523f, 2.827433f },
258 { 1385.79f, 1025.99f, 53.22593f, 2.827433f },
259 { 1386.69f, 1023.26f, 53.24393f, 2.827433f },
260 { 1384.33f, 1022.04f, 53.28123f, 2.827433f },
261 { 1391.10f, 1027.73f, 53.20483f, 2.827433f },
262
263 { 1359.10f, 1046.55f, 52.97053f, 5.253441f },
264 { 1360.89f, 1051.81f, 53.19793f, 5.253441f },
265 { 1360.75f, 1048.84f, 53.12893f, 5.253441f },
266 { 1364.43f, 1053.62f, 53.29343f, 5.253441f },
267 { 1363.08f, 1048.15f, 53.22223f, 5.253441f },
268 { 1364.08f, 1050.84f, 53.29163f, 5.253441f },
269 { 1366.69f, 1050.31f, 53.34203f, 5.253441f },
270 { 1357.85f, 1050.12f, 52.99823f, 5.253441f }
271};
272
273Position const GarroshPos = { 1402.45f, 1061.62f, 60.56173f, 3.926991f };
274
275Position const GarroshJumpPos = { 1378.65f, 1044.23f, 53.8389f, 5.51524f };
276
277Position const CromushPos = { 1404.71f, 1063.73f, 60.5617f, 2.827433f };
278
279Position const AgathaPreRisePos = { 1364.02f, 1028.54f, 66.99143f };
280
281Position const AgathaRisePos = { 1368.65f, 1032.19f, 63.3033f };
282
283Position const AgathaPreResetPos = { 1364.02f, 1028.54f, 55.9914f };
284
285Position const AgathaResetPos = { 1364.02f, 1028.54f, 58.1319f };
286
288{
290
302
307
311 EVENT_AGATHA_RAISE_FORSAKEN = 4, // Note: 4-8 are used.
312 EVENT_SCENE_TALK_COMETH = 9, // Note: 9-36 are used.
313
315
340
341 PATH_CROMUSH = 3571216,
342 PATH_GARROSH = 3570320,
343
348
355
356// 44615 - Grand Executor Mortuus
358{
360
361 void OnQuestAccept(Player* /*player*/, Quest const* quest) override
362 {
364 {
366 return;
367
369 }
370 }
371
372 void Reset() override
373 {
374 _events.Reset();
379 _summons.clear();
380 _eventInProgress = false;
381 }
382
383 void JustSummoned(Creature* summon) override
384 {
385 _summons.Summon(summon);
386
387 switch (summon->GetEntry())
388 {
390 summon->CastSpell(summon, SPELL_SIMPLE_TELEPORT);
391 _garroshGUID = summon->GetGUID();
392 break;
393
395 summon->CastSpell(summon, SPELL_SIMPLE_TELEPORT);
396 break;
397
398 default:
399 break;
400 }
401 }
402
403 void DoAction(int32 param) override
404 {
405 switch (param)
406 {
408 {
409 _eventInProgress = true;
410
412 {
413 _sylvanasGUID = sylvanas->GetGUID();
414
415 if (Creature* agatha = me->FindNearestCreature(NPC_AGATHA_COMETH, 100.0f))
416 {
417 _agathaGUID = agatha->GetGUID();
418
420 }
421 }
422
423 break;
424 }
425
426 default:
427 break;
428 }
429 }
430
431 void UpdateAI(uint32 diff) override
432 {
433 _events.Update(diff);
434
435 while (uint32 eventId = _events.ExecuteEvent())
436 {
437 switch (eventId)
438 {
443 break;
444
447 break;
448
451 break;
452
454 {
456 {
457 if (sylvanas->IsAIEnabled())
458 sylvanas->AI()->Talk(TALK_SYLVANAS_COMETH_0);
459
461 }
462 break;
463 }
464
466 {
468 {
469 sylvanas->SetFacingTo(0.808979f);
470
471 if (sylvanas->IsAIEnabled())
472 sylvanas->AI()->Talk(TALK_SYLVANAS_COMETH_1);
473
475 }
476 break;
477 }
478
480 {
482 {
483 garrosh->GetMotionMaster()->MoveJump(EVENT_JUMP, GarroshJumpPos, 16.0f);
484
486 }
487 break;
488 }
489
491 {
493 {
494 sylvanas->SetFacingTo(3.924652f);
495
497 }
498 break;
499 }
500
502 {
504 {
506 garrosh->SetFacingToObject(sylvanas);
507
508 garrosh->PlayOneShotAnimKitId(ANIMKIT_GARROSH_1);
509
510 if (garrosh->IsAIEnabled())
511 garrosh->AI()->Talk(TALK_GARROSH_COMETH_0);
512
514 }
515 break;
516 }
517
519 {
521 {
522 garrosh->SetFacingTo(3.9444442f);
523
524 if (garrosh->IsAIEnabled())
525 garrosh->AI()->Talk(TALK_GARROSH_COMETH_1);
526
528 }
529 break;
530 }
531
533 {
535 {
536 sylvanas->SetFacingTo(2.4260077f);
537
538 if (sylvanas->IsAIEnabled())
539 sylvanas->AI()->Talk(TALK_SYLVANAS_COMETH_2);
540
542 }
543 break;
544 }
545
547 {
549 {
550 sylvanas->SetFacingTo(3.7350047f);
551 sylvanas->PlayOneShotAnimKitId(ANIMKIT_SYLV_1);
552
553 if (sylvanas->IsAIEnabled())
554 sylvanas->AI()->Talk(TALK_SYLVANAS_COMETH_3);
555
557 }
558 break;
559 }
560
562 {
564 {
565 if (sylvanas->IsAIEnabled())
566 sylvanas->AI()->Talk(TALK_SYLVANAS_COMETH_4);
567
569 }
570 break;
571 }
572
574 {
576 {
577 if (garrosh->IsAIEnabled())
578 garrosh->AI()->Talk(TALK_GARROSH_COMETH_2);
579
581 }
582 break;
583 }
584
585 case EVENT_SCENE_TALK_COMETH + 10:
586 {
588 {
589 if (sylvanas->IsAIEnabled())
590 sylvanas->AI()->Talk(TALK_SYLVANAS_COMETH_5);
591
593 }
594 break;
595 }
596
597 case EVENT_SCENE_TALK_COMETH + 11:
598 {
600 {
601 if (sylvanas->IsAIEnabled())
602 sylvanas->AI()->Talk(TALK_SYLVANAS_COMETH_6);
603
605 }
606 break;
607 }
608
609 case EVENT_SCENE_TALK_COMETH + 12:
610 {
612 {
613 sylvanas->PlayOneShotAnimKitId(ANIMKIT_SYLV_2);
614
615 if (sylvanas->IsAIEnabled())
616 sylvanas->AI()->Talk(TALK_SYLVANAS_COMETH_7);
617
619 }
620 break;
621 }
622
623 case EVENT_SCENE_TALK_COMETH + 13:
624 {
626 {
627 if (sylvanas->IsAIEnabled())
628 sylvanas->AI()->Talk(TALK_SYLVANAS_COMETH_8);
629
631 }
632 break;
633 }
634
636 {
638 {
639 agatha->GetMotionMaster()->MovePoint(POINT_AGATHA_PRE_RISE, AgathaPreRisePos, false);
640
642 }
643 break;
644 }
645
647 {
649 {
650 agatha->SetWalk(true);
651 agatha->GetMotionMaster()->MovePoint(POINT_AGATHA_RISE, AgathaRisePos, false);
652
654 }
655 break;
656 }
657
659 {
661 {
662 agatha->CastSpell(agatha, SPELL_RAISE_FORSAKEN_COMETH);
663
665 }
666 break;
667 }
668
670 {
672 {
673 agatha->GetMotionMaster()->MovePoint(POINT_AGATHA_PRE_RESET, AgathaPreResetPos, false, 0.855211f);
674
676 }
677 break;
678 }
679
680 case EVENT_SCENE_TALK_COMETH + 14:
681 {
683 {
684 if (cromush->IsAIEnabled())
685 cromush->AI()->Talk(TALK_CROMUSH_COMETH_0);
686
688 }
689 break;
690 }
691
692 case EVENT_SCENE_TALK_COMETH + 15:
693 {
695 {
696 garrosh->PlayOneShotAnimKitId(ANIMKIT_GENERAL_1);
697
698 if (garrosh->IsAIEnabled())
699 garrosh->AI()->Talk(TALK_GARROSH_COMETH_3);
700
702 agatha->SetWalk(false);
703
705 }
706 break;
707 }
708
710 {
712 {
713 agatha->GetMotionMaster()->MovePoint(POINT_AGATHA_RESET, AgathaResetPos, false, 0.7155f);
714
716 }
717 break;
718 }
719
720 case EVENT_SCENE_TALK_COMETH + 16:
721 {
723 {
724 sylvanas->PlayOneShotAnimKitId(ANIMKIT_GENERAL_1);
725
726 if (sylvanas->IsAIEnabled())
727 sylvanas->AI()->Talk(TALK_SYLVANAS_COMETH_9);
728
730 }
731 break;
732 }
733
734 case EVENT_SCENE_TALK_COMETH + 17:
735 {
737 {
738 if (garrosh->IsAIEnabled())
739 garrosh->AI()->Talk(TALK_GARROSH_COMETH_4);
740
742 }
743 break;
744 }
745
746 case EVENT_SCENE_TALK_COMETH + 18:
747 {
749 {
750 if (garrosh->IsAIEnabled())
751 garrosh->AI()->Talk(TALK_GARROSH_COMETH_5);
752
754 }
755 break;
756 }
757
758 case EVENT_SCENE_TALK_COMETH + 19:
759 {
761 {
762 if (sylvanas->IsAIEnabled())
763 sylvanas->AI()->Talk(TALK_SYLVANAS_COMETH_10);
764
766 }
767 break;
768 }
769
770 case EVENT_SCENE_TALK_COMETH + 20:
771 {
773 {
774 garrosh->SetFacingTo(5.51524f);
775
776 if (garrosh->IsAIEnabled())
777 garrosh->AI()->Talk(TALK_GARROSH_COMETH_6);
778
780 }
781 break;
782 }
783
784 case EVENT_SCENE_TALK_COMETH + 21:
785 {
787 {
789 {
790 garrosh->SetFacingToObject(cromush);
791
793 }
794 }
795 break;
796 }
797
798 case EVENT_SCENE_TALK_COMETH + 22:
799 {
801 {
802 garrosh->PlayOneShotAnimKitId(ANIMKIT_GARROSH_2);
803
804 if (garrosh->IsAIEnabled())
805 garrosh->AI()->Talk(TALK_GARROSH_COMETH_7);
806
808 }
809 break;
810 }
811
812 case EVENT_SCENE_TALK_COMETH + 23:
813 {
815 {
816 if (cromush->IsAIEnabled())
817 cromush->AI()->Talk(TALK_CROMUSH_COMETH_1);
818
820 {
821 cromush->SetFacingToObject(garrosh);
822
824 }
825 }
826 break;
827 }
828
829 case EVENT_SCENE_TALK_COMETH + 24:
830 {
832 {
833 garrosh->SetFacingTo(5.6199603f);
834 garrosh->PlayOneShotAnimKitId(ANIMKIT_GARROSH_2);
835
836 if (garrosh->IsAIEnabled())
837 garrosh->AI()->Talk(TALK_GARROSH_COMETH_8);
838
840 }
841 break;
842 }
843
844 case EVENT_SCENE_TALK_COMETH + 25:
845 {
847 {
848 garrosh->CastSpell(garrosh, SPELL_WELCOME_TO_SILVERPINE_CREDIT, true);
849
850 garrosh->GetMotionMaster()->MovePath(PATH_GARROSH, false);
851
853 }
854 break;
855 }
856
857 case EVENT_SCENE_TALK_COMETH + 26:
860 break;
861
862 case EVENT_SCENE_TALK_COMETH + 27:
864 Reset();
865 break;
866
867 default:
868 break;
869 }
870 }
871
872 if (!UpdateVictim())
873 return;
874 }
875
877 {
878 for (Position const& pos : OrgrimmarPortalPos)
880
881 std::list<Creature*> orgrimmarPortals;
883
884 for (Creature* portal : orgrimmarPortals)
885 portal->CastSpell(portal, SPELL_AIR_REVENANT_ENTRANCE);
886 }
887
889 {
890 for (Position const& pos : HellscreamElitePos)
892
894
896 {
897 _cromushGUID = cromush->GetGUID();
898
899 cromush->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
900 cromush->GetMotionMaster()->MovePath(PATH_CROMUSH, false);
901 }
902 }
903
905 {
906 for (ObjectGuid const& summonedCreature : _summons)
907 {
908 if (Creature* summon = ObjectAccessor::GetCreature(*me, summonedCreature))
909 summon->CastSpell(summon, SPELL_SIMPLE_TELEPORT);
910 }
911 }
912
913private:
921};
922
933
934// 83173 - Raise Forsaken
936{
937 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
938 {
939 Unit* target = GetTarget();
940
941 if (Creature* fallenHuman = target->ToCreature())
942 {
943 if (fallenHuman->IsAIEnabled())
944 fallenHuman->AI()->DoAction(ACTION_RISE_DURING_RAISE);
945 }
946 }
947
948 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
949 {
950 Unit* target = GetTarget();
951
952 if (Creature* fallenHuman = target->ToCreature())
953 {
954 if (fallenHuman->IsAIEnabled())
955 fallenHuman->AI()->DoAction(ACTION_DESCEND_AFTER_RAISE);
956 }
957 }
958
964};
965
976
977// 44592, 44593 - Fallen Human
979{
981
982 void Reset() override
983 {
984 _transformDone = false;
985 _events.Reset();
986 }
987
988 void DoAction(int32 action) override
989 {
990 switch (action)
991 {
995 break;
996
998 me->SetWalk(false);
1002 break;
1003
1004 default:
1005 break;
1006 }
1007 }
1008
1009 void UpdateAI(uint32 diff) override
1010 {
1011 _events.Update(diff);
1012
1013 while (uint32 eventId = _events.ExecuteEvent())
1014 {
1015 switch (eventId)
1016 {
1017 case EVENT_ASCEND:
1018 me->SetWalk(true);
1020 break;
1021
1023 {
1024 if (_transformDone)
1025 return;
1026
1028
1029 _transformDone = true;
1030
1032 break;
1033 }
1034
1036 me->SetFacingTo(0.706837f);
1038 break;
1039
1042 me->DespawnOrUnsummon(80s);
1043 break;
1044
1045 default:
1046 break;
1047 }
1048 }
1049 }
1050
1051private:
1054};
1055
1076
1077// 83149 - Forsaken Trooper Master Script (Forsaken High Command)
1079{
1094
1096 {
1097 if (Unit* caster = GetCaster())
1098 {
1099 caster->RemoveAura(SPELL_FEIGNED);
1100
1102
1103 switch (caster->GetDisplayId())
1104 {
1105 case DISPLAY_MALE_01_HC:
1107 break;
1108 case DISPLAY_MALE_02_HC:
1110 break;
1111 case DISPLAY_MALE_03_HC:
1113 break;
1114 case DISPLAY_MALE_04_HC:
1116 break;
1119 break;
1122 break;
1125 break;
1128 break;
1129 default:
1130 break;
1131 }
1132
1133 caster->CastSpell(caster, spellId, true);
1134 }
1135 }
1136
1141};
1142
1154
1155// 44365 - Lady Sylvanas Windrunner (Forsaken High Command)
1157{
1159
1164
1165 void JustSummoned(Creature* summon) override
1166 {
1167 switch (summon->GetEntry())
1168 {
1170 // Note: the Forsaken Horse must be set in the same visibility mask that Sylvanas is in.
1172 break;
1173 default:
1174 break;
1175 }
1176 }
1177
1178 void OnQuestReward(Player* player, Quest const* quest, LootItemType /*type*/, uint32 /*opt*/) override
1179 {
1180 switch (quest->GetQuestId())
1181 {
1182 case QUEST_NO_ESCAPE:
1183 player->CastSpell(player, SPELL_DESPAWN_ALL_SUMMONS_AGATHA, true);
1184 break;
1185 default:
1186 break;
1187 }
1188 }
1189};
1190
1191// 44789, 44790 - Deathstalker and Deathstalker Commander Belmont
1193{
1195
1196 void JustAppeared() override
1197 {
1198 // @TODO: figure out a common system to allow energy usage without scripts.
1201 me->SetPower(POWER_ENERGY, 100, true);
1202 }
1203};
1204
1213
1214// 44793 - Worgen Renegade
1216{
1218
1219 void Reset() override
1220 {
1221 _events.Reset();
1222
1223 // Note: this is for a later usage during Lordaeron (questId 27098).
1224 if (me->IsSummon())
1226
1228 }
1229
1230 void JustEngagedWith(Unit* /*who*/) override
1231 {
1233 }
1234
1235 void UpdateAI(uint32 diff) override
1236 {
1237 if (!UpdateVictim())
1238 return;
1239
1240 _events.Update(diff);
1241
1242 while (uint32 eventId = _events.ExecuteEvent())
1243 {
1244 switch (eventId)
1245 {
1248 _events.Repeat(15s, 18s);
1249 break;
1250
1251 default:
1252 break;
1253 }
1254 }
1255 }
1256
1257private:
1259};
1260
1261// 80365 - Flurry of Claws
1263{
1264 bool Validate(SpellInfo const* spellInfo) override
1265 {
1266 return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell });
1267 }
1268
1269 void HandlePeriodic(AuraEffect const* /*aurEff*/)
1270 {
1271 GetTarget()->CastSpell(nullptr, GetSpellInfo()->GetEffect(EFFECT_0).TriggerSpell, true);
1272 }
1273
1278};
1279
1290
1291// 44791, 44792 - Forsaken Trooper
1293{
1295
1296 void Reset() override
1297 {
1298 _events.Reset();
1299
1300 // Note: these texts are sent aswell during Lordaeron (questId 27098).
1301 if (urand(0, 1))
1303 }
1304
1305 void JustEngagedWith(Unit* /*who*/) override
1306 {
1308 }
1309
1310 void UpdateAI(uint32 diff) override
1311 {
1312 if (!UpdateVictim())
1313 return;
1314
1315 _events.Update(diff);
1316
1317 while (uint32 eventId = _events.ExecuteEvent())
1318 {
1319 switch (eventId)
1320 {
1321 case EVENT_CLEAVE:
1323 _events.Repeat(5s, 8s);
1324 break;
1325
1326 default:
1327 break;
1328 }
1329 }
1330 }
1331
1332private:
1334};
1335
1346
1347// 44825 - Bat Handler Maggotbreath
1349{
1351
1363
1364 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
1365 {
1366 switch (player->PlayerTalkClass->GetGossipOptionAction(gossipListId))
1367 {
1370 player->CastSpell(player, SPELL_SUMMON_FORSAKEN_BAT, true);
1371 break;
1372
1373 // Note: Blizzard messed up this OptionNpc. It sends GossipOptionNpc::None rather than GossipOptionNpc::TaxiNode,
1374 // making it useless. To keep it blizzlike, we're just sending TaxiMenu forcefully as well.
1375 case GOSSIP_ACTION_INFO_DEF + 1:
1376 player->GetSession()->SendTaxiMenu(me);
1377 break;
1378
1379 default:
1380 break;
1381 }
1382
1383 CloseGossipMenuFor(player);
1384 return true;
1385 }
1386};
1387
1416
1417// 44821 - Forsaken Bat
1419{
1421 {
1422 Initialize();
1423 }
1424
1426 {
1428 }
1429
1430 void IsSummonedBy(WorldObject* summoner) override
1431 {
1432 if (Player* player = summoner->ToPlayer())
1433 _playerGUID = player->GetGUID();
1434
1435 me->SetDisableGravity(true);
1436 }
1437
1438 void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override
1439 {
1440 if (apply)
1441 {
1442 if (Player* player = passenger->ToPlayer())
1443 {
1444 if (player->GetQuestStatus(QUEST_ITERATING_UPON_SUCCESS) == QUEST_STATUS_INCOMPLETE)
1445 {
1446 player->KilledMonsterCredit(NPC_BAT_HANDLER_MAGGOTBREATH);
1447
1448 me->SetUninteractible(true);
1449
1450 me->SetSpeed(UnitMoveType::MOVE_RUN, 17.794235f);
1452
1454 }
1455 }
1456 }
1457 }
1458
1459 void WaypointReached(uint32 waypointId, uint32 pathId) override
1460 {
1461 switch (pathId)
1462 {
1463 case PATH_BAT_TO_LAKE:
1464 {
1465 if (waypointId == WAYPOINT_LAST_POINT_TO_LAKE)
1466 {
1467 me->SetSpeed(UnitMoveType::MOVE_RUN, 17.982668f);
1469
1471
1473 {
1475
1476 player->VehicleSpellInitialize();
1477 }
1478 }
1479 break;
1480 }
1481
1483 {
1484 if (waypointId == WAYPOINT_LAST_POINT_AROUND_LAKE)
1485 {
1487 {
1488 if (player->GetQuestStatus(QUEST_ITERATING_UPON_SUCCESS) == QUEST_STATUS_INCOMPLETE)
1490 }
1491 }
1492 break;
1493 }
1494
1495 case PATH_BAT_TO_HOME:
1496 {
1497 if (waypointId == WAYPOINT_LAST_POINT_TO_HOME)
1498 {
1501 }
1502 break;
1503 }
1504
1505 default:
1506 break;
1507 }
1508 }
1509
1510 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
1511 {
1512 if (spellInfo->Id == SPELL_GO_HOME)
1514 }
1515
1516 void DoAction(int32 param) override
1517 {
1518 switch (param)
1519 {
1520 case ACTION_GO_HOME:
1521 {
1523 {
1524 me->PauseMovement();
1525 me->GetMotionMaster()->Clear();
1526 me->SetSpeed(UnitMoveType::MOVE_RUN, 35.78791f);
1528
1530
1531 player->VehicleSpellInitialize();
1532
1533 Talk(TALK_BAT_GOING_HOME, player);
1534 }
1535 break;
1536 }
1537
1538 default:
1539 break;
1540 }
1541 }
1542
1543 void UpdateAI(uint32 diff) override
1544 {
1545 _events.Update(diff);
1546
1547 while (uint32 eventId = _events.ExecuteEvent())
1548 {
1549 switch (eventId)
1550 {
1552 {
1554 {
1556 player->CastSpell(me, SPELL_GO_HOME, true);
1557 else
1559 }
1560 break;
1561 }
1562
1563 default:
1564 break;
1565 }
1566 }
1567 }
1568
1570 {
1572 me->m_spells[1] = 0;
1573 }
1574
1580
1582 {
1583 me->m_spells[0] = 0;
1584 me->m_spells[1] = 0;
1585 }
1586
1587private:
1590};
1591
1598
1599// 205143 - Abandoned Outhouse
1601{
1603
1604 void OnQuestAccept(Player* player, Quest const* quest) override
1605 {
1607 player->CastSpell(player, SPELL_SUMMON_DEATHSTALKER_YORICK, true);
1608 }
1609
1610 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
1611 {
1612 player->CastSpell(player, SPELL_SUMMON_DEATHSTALKER_YORICK, true);
1613 CloseGossipMenuFor(player);
1614 return false;
1615 }
1616};
1617
1618Position const YorickReadyPosition = { 1313.7f, 1211.99f, 58.5f, 4.564474f };
1619
1653
1654// 44882 - Deathstalker Rane Yorick
1656{
1658
1659 void JustAppeared() override
1660 {
1663 me->SetPower(POWER_ENERGY, 100, true);
1664 }
1665
1666 void IsSummonedBy(WorldObject* summoner) override
1667 {
1668 me->SetFacingToObject(summoner);
1669
1671 }
1672
1673 void WaypointReached(uint32 waypointId, uint32 pathId) override
1674 {
1675 if (pathId == PATH_YORICK_UP && waypointId == WAYPOINT_CLOSE_TO_ARMOIRE)
1677
1678 if (pathId == PATH_YORICK_HIDE && waypointId == WAYPOINT_HIDDEN_NEXT_TO_ARMOIRE)
1679 {
1680 me->SetFacingTo(4.6425757f);
1681
1683
1684 me->SetUninteractible(true);
1685
1686 _playerSkipped = true;
1687 }
1688 }
1689
1690 void DoAction(int32 param) override
1691 {
1692 switch (param)
1693 {
1695 me->SetDisableGravity(true);
1697 break;
1698
1700 me->PauseMovement();
1701 me->GetMotionMaster()->Clear();
1702 _events.Reset();
1704 break;
1705
1706 default:
1707 break;
1708 }
1709 }
1710
1711 void UpdateAI(uint32 diff) override
1712 {
1713 TempSummon* tempSummon = me->ToTempSummon();
1714 if (!tempSummon)
1715 return;
1716
1717 _events.Update(diff);
1718
1719 if (Unit* summoner = tempSummon->GetSummonerUnit())
1720 {
1721 // Note: SummonPropertiesFlags::DespawnWhenExpired is NYI.
1722 if (!summoner->HasAura(SPELL_SUMMON_YORICK))
1724 }
1725
1726 if (!_playerSkipped)
1727 {
1728 if (Unit* summoner = tempSummon->GetSummonerUnit())
1729 {
1730 if (summoner->HasAura(SPELL_HIDDEN_IN_ARMOIRE))
1731 {
1732 _playerSkipped = true;
1733
1735 }
1736 }
1737 }
1738
1739 while (uint32 eventId = _events.ExecuteEvent())
1740 {
1741 switch (eventId)
1742 {
1744 {
1745 if (Unit* summoner = tempSummon->GetSummonerUnit())
1746 {
1748
1750 }
1751 break;
1752 }
1753
1756 break;
1757
1759 {
1760 if (Unit* summoner = tempSummon->GetSummonerUnit())
1761 {
1762 if (summoner->GetDistance2d(me) <= 5.0f && !_playerArrived)
1763 {
1765 _playerArrived = true;
1766 }
1767 else
1769 }
1770 break;
1771 }
1772
1774 {
1775 if (Unit* summoner = tempSummon->GetSummonerUnit())
1776 {
1778
1781 }
1782 break;
1783 }
1784
1785 case EVENT_RANE_HIDE:
1787 break;
1788
1790 {
1791 if (Unit* summoner = tempSummon->GetSummonerUnit())
1792 {
1793 if (!_bloodfangGUID)
1794 {
1796 {
1797 if (bloodfang->GetOwnerGUID() == summoner->GetGUID())
1798 _bloodfangGUID = bloodfang->GetGUID();
1799 }
1800 }
1801
1802 if (!_armoireGUID)
1803 {
1804 if (Creature* armoire = me->FindNearestCreature(NPC_ARMOIRE_SUMMONED, 30.0f))
1805 {
1806 if (armoire->GetOwnerGUID() == summoner->GetGUID())
1807 {
1808 _armoireGUID = armoire->GetGUID();
1809
1810 if (armoire->IsAIEnabled())
1811 armoire->GetAI()->SetGUID(me->GetGUID(), me->GetEntry());
1812 }
1813 }
1814 }
1815 }
1816
1819 break;
1820 }
1821
1825 break;
1826
1827 case EVENT_RANE_LAST_MOVE + 1:
1828 me->SetDisableGravity(false);
1829 break;
1830
1834 break;
1835
1836 case EVENT_RANE_SKIPS_PATH + 1:
1838 me->SetUninteractible(true);
1840 break;
1841
1842 default:
1843 break;
1844 }
1845 }
1846 }
1847
1848private:
1854};
1855
1857{
1860
1868
1874
1894
1900 PATH_CROWLEY_EXIT = 3590648
1902
1903// 44893 - Armoire
1905{
1906 npc_silverpine_armoire(Creature* creature) : VehicleAI(creature) { }
1907
1908 void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override
1909 {
1910 if (apply)
1911 {
1912 if (Player* player = passenger->ToPlayer())
1913 {
1914 if (player->GetQuestStatus(QUEST_WAITING_TO_EXSANGUINATE) == QUEST_STATUS_INCOMPLETE)
1916 }
1917 }
1918 else
1919 {
1921 crowley->DespawnOrUnsummon();
1922
1924 bloodfang->DespawnOrUnsummon();
1925
1927 yorick->CastSpell(nullptr, SPELL_CANCEL_SUMMON_YORICK, true);
1928
1929 me->DespawnOrUnsummon(1s);
1930 }
1931 }
1932
1933 void SetGUID(ObjectGuid const& guid, int32 id) override
1934 {
1935 switch (id)
1936 {
1938 _yorickGUID = guid;
1939 break;
1940
1942 _crowleyGUID = guid;
1943 break;
1944
1946 _bloodfangGUID = guid;
1947 break;
1948
1949 default:
1950 break;
1951 }
1952 }
1953
1954 void UpdateAI(uint32 diff) override
1955 {
1956 TempSummon* tempSummon = me->ToTempSummon();
1957 if (!tempSummon)
1958 return;
1959
1960 _events.Update(diff);
1961
1962 while (uint32 eventId = _events.ExecuteEvent())
1963 {
1964 switch (eventId)
1965 {
1967 {
1968 if (Unit* summoner = tempSummon->GetSummonerUnit())
1969 {
1970 summoner->CastSpell(summoner, SPELL_SUMMON_CROWLEY_BLOODFANG_MASTER, true);
1971
1973 }
1974 break;
1975 }
1976
1978 {
1980 {
1981 crowley->GetMotionMaster()->MovePath(PATH_CROWLEY_ENTER, false);
1982
1984 {
1985 bloodfang->GetMotionMaster()->MovePath(PATH_BLOODFANG_ENTER, false);
1986
1988 }
1989 }
1990 break;
1991 }
1992
1994 {
1996 {
1998 {
1999 crowley->SetFacingToObject(bloodfang);
2000
2001 bloodfang->SetFacingToObject(crowley);
2002
2004 }
2005 }
2006 break;
2007 }
2008
2010 {
2011 if (Unit* summoner = tempSummon->GetSummonerUnit())
2012 {
2014 {
2015 if (crowley->IsAIEnabled())
2016 crowley->AI()->Talk(TALK_CROWLEY_EXSANGUINATE_0, summoner);
2017
2019 }
2020 }
2021 break;
2022 }
2023
2025 {
2026 if (Unit* summoner = tempSummon->GetSummonerUnit())
2027 {
2028 summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_BLOODFANG, true);
2029
2031 }
2032 break;
2033 }
2034
2036 {
2037 if (Unit* summoner = tempSummon->GetSummonerUnit())
2038 {
2040 {
2041 if (bloodfang->IsAIEnabled())
2042 bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_0, summoner);
2043
2045 }
2046 }
2047 break;
2048 }
2049
2051 {
2053 {
2054 bloodfang->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
2055
2057 }
2058 break;
2059 }
2060
2062 {
2063 if (Unit* summoner = tempSummon->GetSummonerUnit())
2064 {
2065 summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_CROWLEY, true);
2066
2068 }
2069 break;
2070 }
2071
2073 {
2074 if (Unit* summoner = tempSummon->GetSummonerUnit())
2075 {
2077 {
2078 if (crowley->IsAIEnabled())
2079 crowley->AI()->Talk(TALK_CROWLEY_EXSANGUINATE_1, summoner);
2080
2082 }
2083 }
2084 break;
2085 }
2086
2088 {
2090 {
2091 crowley->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
2092
2094 }
2095 break;
2096 }
2097
2099 {
2100 if (Unit* summoner = tempSummon->GetSummonerUnit())
2101 {
2103 {
2104 if (crowley->IsAIEnabled())
2105 crowley->AI()->Talk(TALK_CROWLEY_EXSANGUINATE_2, summoner);
2106
2108 }
2109 }
2110 break;
2111 }
2112
2114 {
2116 {
2117 crowley->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
2118
2120 }
2121 break;
2122 }
2123
2125 {
2126 if (Unit* summoner = tempSummon->GetSummonerUnit())
2127 {
2128 summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_BLOODFANG, true);
2129
2131 }
2132 break;
2133 }
2134
2136 {
2137 if (Unit* summoner = tempSummon->GetSummonerUnit())
2138 {
2140 {
2141 if (bloodfang->IsAIEnabled())
2142 bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_1, summoner);
2143
2145 }
2146 }
2147 break;
2148 }
2149
2151 {
2152 if (Unit* summoner = tempSummon->GetSummonerUnit())
2153 {
2155 {
2156 if (bloodfang->IsAIEnabled())
2157 bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_2, summoner);
2158
2160 }
2161 }
2162 break;
2163 }
2164
2166 {
2167 if (Unit* summoner = tempSummon->GetSummonerUnit())
2168 {
2170 {
2171 if (bloodfang->IsAIEnabled())
2172 bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_3, summoner);
2173
2175 }
2176 }
2177 break;
2178 }
2179
2181 {
2183 {
2184 bloodfang->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
2185
2187 }
2188 break;
2189 }
2190
2192 {
2193 if (Unit* summoner = tempSummon->GetSummonerUnit())
2194 {
2195 summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_CROWLEY, true);
2196
2198 }
2199 break;
2200 }
2201
2203 {
2204 if (Unit* summoner = tempSummon->GetSummonerUnit())
2205 {
2207 {
2208 if (crowley->IsAIEnabled())
2209 crowley->AI()->Talk(TALK_CROWLEY_EXSANGUINATE_3, summoner);
2210
2212 }
2213 }
2214 break;
2215 }
2216
2218 {
2219 if (Unit* summoner = tempSummon->GetSummonerUnit())
2220 {
2221 summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_BLOODFANG, true);
2222
2224 }
2225 break;
2226 }
2227
2229 {
2230 if (Unit* summoner = tempSummon->GetSummonerUnit())
2231 {
2233 {
2234 if (bloodfang->IsAIEnabled())
2235 bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_4, summoner);
2236
2238 }
2239 }
2240 break;
2241 }
2242
2244 {
2246 {
2247 bloodfang->SetFacingTo(0.6457718f);
2248
2250 }
2251 break;
2252 }
2253
2255 {
2256 if (Unit* summoner = tempSummon->GetSummonerUnit())
2257 {
2259 {
2260 if (bloodfang->IsAIEnabled())
2261 bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_5, summoner);
2262
2264 }
2265 }
2266 break;
2267 }
2268
2270 {
2271 if (Unit* summoner = tempSummon->GetSummonerUnit())
2272 {
2274 {
2275 if (bloodfang->IsAIEnabled())
2276 bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_6, summoner);
2277
2279 }
2280 }
2281 break;
2282 }
2283
2285 {
2287 {
2288 bloodfang->HandleEmoteCommand(EMOTE_ONESHOT_YES);
2289
2291 }
2292 break;
2293 }
2294
2296 {
2298 {
2299 bloodfang->GetMotionMaster()->MovePath(PATH_BLOODFANG_NEAR_YORICK, false);
2300
2302 }
2303 break;
2304 }
2305
2307 {
2309 {
2310 bloodfang->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
2311
2313 }
2314 break;
2315 }
2316
2318 {
2319 if (Unit* summoner = tempSummon->GetSummonerUnit())
2320 {
2322 {
2323 if (bloodfang->IsAIEnabled())
2324 bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_7, summoner);
2325
2327 }
2328 }
2329 break;
2330 }
2331
2333 {
2335 {
2337 {
2338 yorick->RemoveAura(SPELL_STEALTH);
2339
2340 yorick->SetUninteractible(false);
2341
2342 bloodfang->CastSpell(yorick, SPELL_RIDE_REVERSE_CAST_EXSANGUINATE, true);
2343
2345 }
2346 }
2347 break;
2348 }
2349
2351 {
2353 {
2354 bloodfang->GetMotionMaster()->MovePath(PATH_BLOODFANG_WITH_YORICK, false);
2355
2357 }
2358 break;
2359 }
2360
2362 {
2363 if (Unit* summoner = tempSummon->GetSummonerUnit())
2364 {
2366 {
2367 bloodfang->SetFacingTo(3.054326f);
2368
2369 if (bloodfang->IsAIEnabled())
2370 bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_8, summoner);
2371
2373 }
2374 }
2375 break;
2376 }
2377
2379 {
2380 if (Unit* summoner = tempSummon->GetSummonerUnit())
2381 {
2383 {
2384 if (yorick->IsAIEnabled())
2385 yorick->AI()->Talk(TALK_YORICK_EXSANGUINATE_DEATH, summoner);
2386
2388 }
2389 }
2390 break;
2391 }
2392
2394 {
2395 if (Unit* summoner = tempSummon->GetSummonerUnit())
2396 {
2398 {
2400 {
2401 bloodfang->CastSpell(yorick, SPELL_EJECT_PASSENGER_01, false);
2402
2403 if (yorick->IsAIEnabled())
2404 yorick->AI()->DoAction(ACTION_RANE_JUMP_DEATH);
2405
2406 if (bloodfang->IsAIEnabled())
2407 bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_9, summoner);
2408
2410 }
2411 }
2412 }
2413 break;
2414 }
2415
2417 {
2419 {
2420 bloodfang->SetFacingTo(0.0f);
2421
2423 }
2424 break;
2425 }
2426
2428 {
2429 if (Unit* summoner = tempSummon->GetSummonerUnit())
2430 {
2432 {
2433 if (bloodfang->IsAIEnabled())
2434 bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_10, summoner);
2435
2437 }
2438 }
2439 break;
2440 }
2441
2443 {
2445 {
2446 bloodfang->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
2447
2449 }
2450 break;
2451 }
2452
2454 {
2455 if (Unit* summoner = tempSummon->GetSummonerUnit())
2456 {
2457 summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_CROWLEY, true);
2458
2460 {
2461 bloodfang->SetWalk(false);
2462 bloodfang->GetMotionMaster()->MovePath(PATH_BLOODFANG_EXIT, false);
2463
2465 }
2466 }
2467 break;
2468 }
2469
2471 {
2473 {
2474 crowley->GetMotionMaster()->MovePath(PATH_CROWLEY_EXIT, false);
2475
2477 }
2478 break;
2479 }
2480
2482 {
2483 if (Unit* summoner = tempSummon->GetSummonerUnit())
2484 {
2486 crowley->CastSpell(summoner, SPELL_KILL_CREDIT_YORICK, false);
2487
2489 yorick->CastSpell(summoner, SPELL_CANCEL_SUMMON_YORICK, true);
2490
2491 summoner->GetMotionMaster()->Clear();
2492
2493 summoner->RemoveAura(SPELL_HIDE_IN_ARMOIRE);
2494
2495 summoner->ExitVehicle();
2496 }
2497 break;
2498 }
2499
2500 default:
2501 break;
2502 }
2503 }
2504 }
2505
2506private:
2511};
2512
2517
2518// 44883 - Lord Darius Crowley
2520{
2522
2523 void JustAppeared() override
2524 {
2526 }
2527
2528 void IsSummonedBy(WorldObject* /*summoner*/) override
2529 {
2530 if (Creature* armoire = me->FindNearestCreature(NPC_ARMOIRE_SUMMONED, 100.0f))
2531 {
2532 if (armoire->IsAIEnabled())
2533 armoire->GetAI()->SetGUID(me->GetGUID(), me->GetEntry());
2534 }
2535 }
2536
2537 void WaypointReached(uint32 waypointId, uint32 pathId) override
2538 {
2539 if (pathId == PATH_CROWLEY_EXIT && waypointId == WAYPOINT_ON_CROWLEY_DESPAWN)
2541 }
2542};
2543
2548
2549// 44884 - Packleader Ivar Bloodfang
2551{
2553
2554 void JustAppeared() override
2555 {
2557 }
2558
2559 void IsSummonedBy(WorldObject* /*summoner*/) override
2560 {
2561 if (Creature* armoire = me->FindNearestCreature(NPC_ARMOIRE_SUMMONED, 30.0f))
2562 {
2563 if (armoire->IsAIEnabled())
2564 armoire->GetAI()->SetGUID(me->GetGUID(), me->GetEntry());
2565 }
2566 }
2567
2568 void WaypointReached(uint32 waypointId, uint32 pathId) override
2569 {
2570 if (pathId == PATH_BLOODFANG_EXIT && waypointId == WAYPOINT_ON_BLOODFANG_DESPAWN)
2572 }
2573};
2574
2601
2602// 45498 - "Salty" Rocka
2604{
2606
2607 void JustAppeared() override
2608 {
2610 }
2611
2612 void Reset() override
2613 {
2615 _events.Reset();
2616 }
2617
2618 void MoveInLineOfSight(Unit* who) override
2619 {
2620 if (who->GetTypeId() == TYPEID_PLAYER && who->GetDistance2d(me) < 20.0f)
2622 }
2623
2624 void UpdateAI(uint32 diff) override
2625 {
2626 _events.Update(diff);
2627
2628 while (uint32 eventId = _events.ExecuteEvent())
2629 {
2630 switch (eventId)
2631 {
2634 return;
2638 break;
2639
2641 _events.ScheduleEvent(EVENT_ROCKA_TALK + (urand(0, 4) * 10), 750ms);
2642 break;
2643
2644 case EVENT_ROCKA_TALK:
2647 break;
2648
2649 case EVENT_ROCKA_TALK + 1:
2650 {
2652 {
2653 if (gorgar->IsAIEnabled())
2654 gorgar->AI()->Talk(TALK_GORGAR_0);
2655 }
2657 break;
2658 }
2659
2660 case EVENT_ROCKA_TALK + 2:
2662 break;
2663
2664 case EVENT_ROCKA_TALK + 10:
2667 break;
2668
2669 case EVENT_ROCKA_TALK + 11:
2670 {
2672 {
2673 if (gorgar->IsAIEnabled())
2674 gorgar->AI()->Talk(TALK_GORGAR_1);
2675 }
2677 break;
2678 }
2679
2680 case EVENT_ROCKA_TALK + 12:
2682 break;
2683
2684 case EVENT_ROCKA_TALK + 20:
2687 break;
2688
2689 case EVENT_ROCKA_TALK + 21:
2690 {
2692 {
2693 if (gorgar->IsAIEnabled())
2694 gorgar->AI()->Talk(TALK_GORGAR_2);
2695 }
2697 break;
2698 }
2699
2700 case EVENT_ROCKA_TALK + 22:
2702 break;
2703
2704 case EVENT_ROCKA_TALK + 30:
2707 break;
2708
2709 case EVENT_ROCKA_TALK + 31:
2710 {
2712 {
2713 if (gorgar->IsAIEnabled())
2714 gorgar->AI()->Talk(TALK_GORGAR_3);
2715 }
2717 break;
2718 }
2719
2720 case EVENT_ROCKA_TALK + 32:
2722 break;
2723
2724 case EVENT_ROCKA_TALK + 40:
2727 break;
2728
2729 case EVENT_ROCKA_TALK + 41:
2730 {
2732 {
2733 if (gorgar->IsAIEnabled())
2734 gorgar->AI()->Talk(TALK_GORGAR_4);
2735 }
2737 break;
2738 }
2739
2740 case EVENT_ROCKA_TALK + 42:
2742 break;
2743
2745 Reset();
2746 break;
2747
2748 default:
2749 break;
2750 }
2751 }
2752 }
2753
2755 {
2756 if (!_gorgarGUID)
2757 {
2758 if (Creature* gorgar = me->FindNearestCreature(NPC_SALTY_GORGAR, 50.0f))
2759 _gorgarGUID = gorgar->GetGUID();
2760 }
2761 }
2762
2763private:
2767};
2768
2781
2782// 6222 - Forsaken Rear Guard
2784{
2785public:
2786 at_silverpine_forsaken_rear_guard() : AreaTriggerScript("at_silverpine_forsaken_rear_guard") { }
2787
2788 bool OnTrigger(Player* player, AreaTriggerEntry const* /*at*/) override
2789 {
2790 if (player->IsAlive())
2791 {
2794 {
2795 if (Creature* hatchet = player->FindNearestCreature(NPC_ADMIRAL_HATCHET, 50.0f))
2796 {
2797 if (hatchet->IsAIEnabled())
2798 hatchet->AI()->DoAction(ACTION_HATCHET_START_CONVERSATION);
2799 }
2800 }
2802 {
2803 if (Creature* wormcrud = player->FindNearestCreature(NPC_APOTHECARY_WORMCRUD, 50.0f))
2804 {
2805 if (wormcrud->IsAIEnabled())
2806 wormcrud->AI()->DoAction(ACTION_WORMCRUD_START_CONVERSATION);
2807 }
2808 }
2809 }
2810
2811 return true;
2812 }
2813};
2814
2829
2830// 44912 - Apothecary Wormcrud
2832{
2834
2835 void JustAppeared() override
2836 {
2838 }
2839
2840 void Reset() override
2841 {
2842 _events.Reset();
2843
2845 }
2846
2847 void DoAction(int32 param) override
2848 {
2850 {
2852 return;
2853
2855
2858 }
2859 }
2860
2861 void UpdateAI(uint32 diff) override
2862 {
2863 _events.Update(diff);
2864
2865 while (uint32 eventId = _events.ExecuteEvent())
2866 {
2867 switch (eventId)
2868 {
2870 {
2872 {
2873 if (orcsea1->IsAIEnabled())
2874 orcsea1->AI()->Talk(TALK_ORCSEA_0);
2875 }
2877 break;
2878 }
2879
2880 case EVENT_WORMCRUD_TALK + 1:
2881 {
2883 {
2884 if (orcsea2->IsAIEnabled())
2885 orcsea2->AI()->Talk(TALK_ORCSEA_1);
2886 }
2888 break;
2889 }
2890
2891 case EVENT_WORMCRUD_TALK + 2:
2892 {
2894 {
2895 if (orcsea3->IsAIEnabled())
2896 orcsea3->AI()->Talk(TALK_ORCSEA_2);
2897 }
2899 break;
2900 }
2901
2902 case EVENT_WORMCRUD_TALK + 3:
2904 break;
2905
2907 Reset();
2908 break;
2909
2910 default:
2911 break;
2912 }
2913 }
2914 }
2915
2917 {
2918 std::vector<Creature*> orcSeaDogList;
2920
2921 if (orcSeaDogList.size() < 3)
2922 return;
2923
2924 for (uint32 i = 0; i < orcSeaDogList.size(); i++)
2925 _drunkenOrcSeaDog[i] = orcSeaDogList[i]->GetGUID();
2926 }
2927
2928private:
2930 std::array<ObjectGuid, 3> _drunkenOrcSeaDog;
2932};
2933
2956
2957// 44916 - Admiral Hatchet
2959{
2961
2962 void JustAppeared() override
2963 {
2964 CheckForTorok();
2965 }
2966
2967 void OnQuestAccept(Player* player, Quest const* quest) override
2968 {
2969 if (quest->GetQuestId() == QUEST_STEEL_THUNDER)
2970 player->CastSpell(player, SPELL_SUMMON_ORC_SEA_PUP);
2971 }
2972
2973 void OnQuestReward(Player* player, Quest const* quest, LootItemType /*type*/, uint32 /*opt*/) override
2974 {
2975 if (quest->GetQuestId() == QUEST_STEEL_THUNDER)
2976 player->CastSpell(player, SPELL_SEA_PUP_TRIGGER, true);
2977 else if (quest->GetQuestId() == QUEST_LOST_IN_THE_DARKNESS)
2979 }
2980
2981 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
2982 {
2984 player->CastSpell(player, SPELL_SUMMON_ORC_SEA_PUP);
2985
2986 CloseGossipMenuFor(player);
2987 return false;
2988 }
2989
2990 void Reset() override
2991 {
2992 _events.Reset();
2994 }
2995
2996 void DoAction(int32 param) override
2997 {
2999 {
3001 return;
3002
3004
3007 }
3008 }
3009
3010 void UpdateAI(uint32 diff) override
3011 {
3012 _events.Update(diff);
3013
3014 while (uint32 eventId = _events.ExecuteEvent())
3015 {
3016 switch (eventId)
3017 {
3018 case EVENT_HATCHET_TALK:
3021 break;
3022
3023 case EVENT_HATCHET_TALK + 1:
3024 {
3026 {
3027 if (torok->IsAIEnabled())
3028 torok->AI()->Talk(TALK_TOROK_0);
3029 }
3031 break;
3032 }
3033
3034 case EVENT_HATCHET_TALK + 2:
3037 break;
3038
3039 case EVENT_HATCHET_TALK + 3:
3040 {
3042 {
3043 torok->PlayOneShotAnimKitId(ANIMKIT_TOROK);
3044
3045 if (torok->IsAIEnabled())
3046 torok->AI()->Talk(TALK_TOROK_1);
3047 }
3048 break;
3049 }
3050
3052 Reset();
3053 break;
3054
3055 default:
3056 break;
3057 }
3058 }
3059 }
3060
3062 {
3063 if (!_torokGUID)
3064 {
3065 if (Creature* torok = me->FindNearestCreature(NPC_WARLORD_TOROK, 30.0f))
3066 _torokGUID = torok->GetGUID();
3067 }
3068 }
3069
3070private:
3074};
3075
3093
3094// 44913 - Orc Sea Dog
3096{
3098
3099 void JustAppeared() override
3100 {
3102 {
3107 break;
3110 break;
3114 break;
3115 default:
3116 break;
3117 }
3118 }
3119
3120 void UpdateAI(uint32 diff) override
3121 {
3122 _events.Update(diff);
3123
3124 while (uint32 eventId = _events.ExecuteEvent())
3125 {
3126 switch (eventId)
3127 {
3130 _events.Repeat(6s, 20s);
3131 break;
3132 case EVENT_SEA_DOG_ROAM:
3134 break;
3135 default:
3136 break;
3137 }
3138 }
3139 }
3140
3141private:
3143};
3144
3146{
3148
3149 void JustAppeared() override
3150 {
3152
3154 }
3155
3156 void UpdateAI(uint32 diff) override
3157 {
3158 _events.Update(diff);
3159
3160 while (uint32 eventId = _events.ExecuteEvent())
3161 {
3162 switch (eventId)
3163 {
3165 DoCastSelf(SPELL_SICK, false);
3166 _events.Repeat(25s, 50s);
3167 break;
3168 default:
3169 break;
3170 }
3171 }
3172 }
3173
3174private:
3176};
3177
3178// Note: we're not using the generic spell for this one because Orc Sea Pup is unsummoned 3s later.
3179// 83840 - Despawn All Summons
3181{
3183 {
3184 if (Unit* caster = GetCaster())
3185 {
3186 Creature* target = GetHitCreature();
3187
3188 if (target->GetOwner() == caster)
3189 target->DespawnOrUnsummon(3s);
3190 }
3191 }
3192
3197};
3198
3217
3218// 44914 - Orc Sea Pup
3220{
3222
3223 void JustAppeared() override
3224 {
3226 }
3227
3228 void IsSummonedBy(WorldObject* summoner) override
3229 {
3230 if (Player* player = summoner->ToPlayer())
3231 {
3233
3234 // Note: SummonPropertiesFlags::JoinSummonerSpawnGroup is NYI.
3235 me->GetMotionMaster()->MoveFollow(player, 2.0f, float(M_PI / 2.0f));
3236
3237 if (player->GetQuestStatus(QUEST_STEEL_THUNDER) == QUEST_STATUS_INCOMPLETE)
3238 {
3242
3243 int c = player->GetReqKillOrCastCurrentCount(QUEST_STEEL_THUNDER, NPC_ORC_CRATE);
3244
3245 for (int i = 0; i < c; i++)
3247 }
3248 }
3249 }
3250
3251 void PassengerBoarded(Unit* passenger, int8 seatId, bool apply) override
3252 {
3253 TempSummon* tempSummon = me->ToTempSummon();
3254 if (!tempSummon)
3255 return;
3256
3257 Creature* passengerCreature = passenger->ToCreature();
3258 if (!passengerCreature)
3259 return;
3260
3261 if (passenger->GetEntry() != NPC_ORC_CRATE)
3262 return;
3263
3264 if (apply)
3265 {
3266 if (_isJustSummoned)
3267 return;
3268
3269 if (Unit* summoner = tempSummon->GetSummonerUnit())
3270 Talk(seatId + 1, summoner);
3271 }
3272 else
3273 passengerCreature->DespawnOrUnsummon(3s);
3274 }
3275
3276 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
3277 {
3278 TempSummon* tempSummon = me->ToTempSummon();
3279 if (!tempSummon)
3280 return;
3281
3282 switch (spellInfo->Id)
3283 {
3285 {
3286 if (Unit* summoner = tempSummon->GetSummonerUnit())
3287 {
3289
3290 summoner->CastSpell(nullptr, SPELL_DESPAWN_ALL_SUMMONS_STEEL_THUNDER, true);
3291
3293 }
3294 break;
3295 }
3296
3299 break;
3300 default:
3301 break;
3302 }
3303 }
3304
3305 void UpdateAI(uint32 diff) override
3306 {
3307 TempSummon* tempSummon = me->ToTempSummon();
3308 if (!tempSummon)
3309 return;
3310
3311 _events.Update(diff);
3312
3313 while (uint32 eventId = _events.ExecuteEvent())
3314 {
3315 switch (eventId)
3316 {
3318 if (Unit* summoner = tempSummon->GetSummonerUnit())
3319 Talk(TALK_ORC_PUP_SUMMONED, summoner);
3320 break;
3321
3322 case EVENT_ORC_PUP_TALK:
3323 {
3324 if (Vehicle* vehicle = me->GetVehicleKit())
3325 {
3326 if (vehicle->IsVehicleInUse())
3327 {
3328 if (Unit* summoner = tempSummon->GetSummonerUnit())
3329 Talk(TALK_ORC_PUP_WORN_OFF, summoner);
3330 }
3331 }
3333 break;
3334 }
3335
3337 _isJustSummoned = false;
3338 break;
3339
3344 break;
3345
3346 default:
3347 break;
3348 }
3349 }
3350 }
3351
3352private:
3355};
3356
3358{
3359 NPC_ORC_SEA_PUP = 44914
3361
3362// 44915 - Orc Crate
3364{
3366
3367 void IsSummonedBy(WorldObject* summoner) override
3368 {
3369 if (summoner->GetEntry() == NPC_ORC_SEA_PUP)
3370 {
3371 me->SetUninteractible(true);
3372
3373 me->EnterVehicle(summoner->ToUnit());
3374 }
3375 }
3376};
3377
3382
3383// 83838 - Pick Up Orc Crate
3406
3434
3435// 44367 - Forest Ettin
3437{
3439
3440 void JustAppeared() override
3441 {
3443 }
3444
3445 void Reset() override
3446 {
3447 _events.Reset();
3448
3449 _isGrabbingBushChicken = false;
3450
3451 me->ResumeMovement();
3452
3455 }
3456
3457 void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
3458 {
3459 if (spellInfo->Id == SPELL_RELEASE_BUSH_CHICKEN)
3460 _playerGUID = caster->GetGUID();
3461 }
3462
3463 void SetGUID(ObjectGuid const& guid, int32 id) override
3464 {
3465 switch (id)
3466 {
3468 _chickenGUID = guid;
3469 break;
3470 default:
3471 break;
3472 }
3473 }
3474
3475 void PassengerBoarded(Unit* /*passenger*/, int8 seatId, bool apply) override
3476 {
3478 return;
3479
3480 if (apply)
3481 {
3482 if (seatId == SEAT_ETTIN_ARM)
3484 else if (seatId == SEAT_ETTIN_MOUTH)
3486 }
3487 }
3488
3489 void DoAction(int32 param) override
3490 {
3491 switch (param)
3492 {
3494 {
3495 if (Creature* mutantBushChicken = ObjectAccessor::GetCreature(*me, _chickenGUID))
3496 {
3497 me->PauseMovement();
3498
3499 me->SetFacingToObject(mutantBushChicken);
3500
3502 }
3503 break;
3504 }
3505
3506 default:
3507 break;
3508 }
3509 }
3510
3511 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* spellInfo /*= nullptr*/) override
3512 {
3513 if (!spellInfo)
3514 return;
3515
3516 // HACKFIX: according to BasePoints damage is around 90k, which is wrong. On retail, it deals 80% of its health points only.
3517 // Also, Mutant Bush Chicken is summoned as not player-controlled (not blue-taped), though it uses the same summonProperties's
3518 // Control and Slot as some other summoning spells from this zone.
3519 if (spellInfo->Id == SPELL_BUSH_EXPLOSION)
3520 damage = 0;
3521 }
3522
3523 void JustEngagedWith(Unit* /*who*/) override
3524 {
3527 }
3528
3529 void UpdateAI(uint32 diff) override
3530 {
3531 _events.Update(diff);
3532
3533 while (uint32 eventId = _events.ExecuteEvent())
3534 {
3535 switch (eventId)
3536 {
3537 case EVENT_BONK:
3539 _events.Repeat(9s, 11s);
3540 break;
3541
3542 case EVENT_LOG_SMASH:
3544 _events.Repeat(15s, 16s);
3545 break;
3546
3548 {
3549 if (Creature* mutantBushChicken = ObjectAccessor::GetCreature(*me, _chickenGUID))
3550 {
3552
3553 me->CastSpell(mutantBushChicken, SPELL_RIDE_REVERSE_CAST_ITS_POISONOUS, true);
3554
3556 }
3557 break;
3558 }
3559
3561 me->ResumeMovement();
3563 break;
3564
3566 {
3567 if (Creature* mutantBushChicken = ObjectAccessor::GetCreature(*me, _chickenGUID))
3568 {
3569 mutantBushChicken->CastSpell(me, SPELL_ETTIN_MOUTH, true);
3570
3572 {
3574 mutantBushChicken->PlayDirectSound(SOUND_CHICKEN_MOUNT_WOUND, player);
3575 }
3576 }
3577 break;
3578 }
3579
3581 {
3582 if (Creature* mutantBushChicken = ObjectAccessor::GetCreature(*me, _chickenGUID))
3583 {
3584 mutantBushChicken->CastSpell(me, SPELL_BUSH_EXPLOSION, true);
3585
3587 AttackStart(player);
3588 }
3589 break;
3590 }
3591
3592 case EVENT_RESET:
3593 Reset();
3594 break;
3595
3596 default:
3597 break;
3598 }
3599 }
3600
3601 if (!UpdateVictim())
3602 return;
3603 }
3604
3605private:
3610};
3611
3620
3621// 44935 - Mutant Bush Chicken
3623{
3625
3626 void JustAppeared() override
3627 {
3628 me->SetImmuneToAll(true);
3629 }
3630
3631 void IsSummonedBy(WorldObject* summoner) override
3632 {
3633 if (Player* player = summoner->ToPlayer())
3634 {
3637 }
3638 }
3639
3640 void MovementInform(uint32 type, uint32 id) override
3641 {
3642 if (type != POINT_MOTION_TYPE)
3643 return;
3644
3645 if (id == POINT_NEAR_FOREST_ETTIN)
3646 {
3648 {
3649 if (forestEttin->IsAIEnabled())
3650 forestEttin->AI()->DoAction(ACTION_NOTICE_CHICKEN);
3651 }
3652 }
3653 }
3654
3655 void UpdateAI(uint32 diff) override
3656 {
3657 TempSummon* tempSummon = me->ToTempSummon();
3658 if (!tempSummon)
3659 return;
3660
3661 if (Unit* summoner = tempSummon->GetSummonerUnit())
3662 {
3663 // Note: SummonPropertiesFlags::DespawnOnSummonerLogout is NYI.
3664 if (!summoner->IsInWorld())
3666 }
3667
3668 _events.Update(diff);
3669
3670 while (uint32 eventId = _events.ExecuteEvent())
3671 {
3672 switch (eventId)
3673 {
3676 me->GetMotionMaster()->MovePoint(POINT_NEAR_FOREST_ETTIN, forestEttin->GetPosition(), false);
3677 break;
3678 default:
3679 break;
3680 }
3681 }
3682 }
3683
3684 void CheckForForestEttin(Unit* forestEttin)
3685 {
3686 _forestEttinGUID = forestEttin->GetGUID();
3687
3688 me->SetFacingToObject(forestEttin);
3689
3691 }
3692
3693private:
3696};
3697
3698// 83902 - Release Diseased Mutant Bush Chicken
3700{
3701 void HandleHit(SpellEffIndex /*effIndex*/)
3702 {
3703 Unit* target = GetHitUnit();
3704
3705 if (Unit* caster = GetCaster())
3706 {
3707 std::vector<Creature*> chickens;
3708 caster->GetCreatureListWithEntryInGrid(chickens, NPC_MUTANT_BUSH_CHICKEN, 5.0f);
3709 for (Creature* mutantBushChicken : chickens)
3710 {
3711 if (mutantBushChicken->GetOwner() != caster)
3712 continue;
3713
3714 if (target->IsAIEnabled())
3715 target->GetAI()->SetGUID(mutantBushChicken->GetGUID(), NPC_MUTANT_BUSH_CHICKEN);
3716
3717 if (npc_silverpine_mutant_bush_chicken* mutantBushChickenAI = CAST_AI(npc_silverpine_mutant_bush_chicken, mutantBushChicken->AI()))
3718 mutantBushChickenAI->CheckForForestEttin(target);
3719 }
3720 }
3721 }
3722
3727};
3728
3734
3735// 44941 - Webbed Victim
3737{
3739
3740 void JustAppeared() override
3741 {
3743 }
3744
3745 void JustDied(Unit* killer) override
3746 {
3747 if (Player* player = killer->ToPlayer())
3748 {
3749 if (player->GetQuestStatus(QUEST_LOST_IN_THE_DARKNESS) == QUEST_STATUS_INCOMPLETE)
3751 }
3752 }
3753};
3754
3766
3767// 83919 - Free Webbed Victim
3769{
3770 void HandleHit(SpellEffIndex /*effIndex*/)
3771 {
3772 if (Unit* caster = GetCaster())
3773 {
3774 uint32 randomCreature = 0;
3775
3776 /*
3777 * Note: this spell is always cast when there's nothing in the web or there's a foe. Also,
3778 * there are 4 serverside spells for this, but we're unable to know which one does what exactly:
3779 * 83922 - (Serverside/Non-DB2) Free Webbed Victim, 83923 - (Serverside/Non-DB2) Free Webbed Victim,
3780 * 83924 - (Serverside/Non-DB2) Free Webbed Victim, 83925 - (Serverside/Non-DB2) Free Webbed Victim.
3781 * It is safe to assume that each summons one of the three foes, and the other summons nothing.
3782 * 83927 - Free Webbed Victim summons orcs. We could try finding summonProperties, but it is hard.
3783 */
3784
3786 {
3787 case DATA_RANDOM_0:
3788 randomCreature = NPC_BLOODFANG_SCAVENGER;
3789 break;
3790 case DATA_RANDOM_1:
3791 randomCreature = NPC_RABID_DOG;
3792 break;
3793 case DATA_RANDOM_2:
3794 randomCreature = NPC_GIANT_RABBID_BEAR;
3795 break;
3796 case DATA_RANDOM_3:
3797 randomCreature = 0;
3798 break;
3799 default:
3800 break;
3801 }
3802
3803 if (randomCreature != 0)
3804 {
3805 if (Creature* randomAggresiveCreature = caster->SummonCreature(randomCreature, GetHitUnit()->GetPosition()))
3806 randomAggresiveCreature->Attack(caster, true);
3807 }
3808 }
3809 }
3810
3815};
3816
3829
3830// 44942 - Orc Sea Dog
3832{
3834
3835 void JustAppeared() override
3836 {
3839 me->SetPower(POWER_ENERGY, 100, true);
3840
3841 // Note: SummonPropertiesFlags::HelpWhenSummonedInCombat is NYI.
3843 }
3844
3845 void IsSummonedBy(WorldObject* summoner) override
3846 {
3847 if (Player* player = summoner->ToPlayer())
3848 {
3849 player->KilledMonsterCredit(NPC_ORC_SEA_DOG);
3850
3851 // Note: SummonPropertiesFlags::JoinSummonerSpawnGroup is NYI. They should be faned around the back of the player depending on how many summons they have (Pets and Guardians included).
3852 me->GetMotionMaster()->MoveFollow(player, 5.0f, frand(1.57f, 4.71f));
3853
3856 }
3857 }
3858
3859 void Reset() override
3860 {
3862 }
3863
3864 void JustEngagedWith(Unit* /*who*/) override
3865 {
3867 }
3868
3869 void UpdateAI(uint32 diff) override
3870 {
3871 TempSummon* tempSummon = me->ToTempSummon();
3872 if (!tempSummon)
3873 return;
3874
3875 if (Unit* summoner = tempSummon->GetSummonerUnit())
3876 {
3877 // Note: SummonPropertiesFlags::DespawnOnSummonerDeath and SummonPropertiesFlags::DespawnOnSummonerLogout are NYI.
3878 if (!summoner->IsAlive() || !summoner->IsInWorld())
3880 }
3881
3882 _events.Update(diff);
3883
3884 while (uint32 eventId = _events.ExecuteEvent())
3885 {
3886 switch (eventId)
3887 {
3889 if (Unit* summoner = tempSummon->GetSummonerUnit())
3890 Talk(TALK_WEBBEB_ORC_FREED, summoner);
3891 break;
3892
3895 _events.Repeat(6s, 8s);
3896 break;
3897
3898 default:
3899 break;
3900 }
3901 }
3902
3903 if (!UpdateVictim())
3904 return;
3905 }
3906
3907private:
3909};
3910
3928
3929// 44906 - Skitterweb Matriarch
3931{
3933
3934 void JustAppeared() override
3935 {
3936 me->SetDisableGravity(true);
3937
3939
3941
3942 me->CastSpell(nullptr, SPELL_SKITTERWEB, true);
3943 }
3944
3945 void Reset() override
3946 {
3947 _events.Reset();
3948 }
3949
3950 void JustReachedHome() override
3951 {
3952 me->SetFacingTo(0.820305f);
3953
3955 }
3956
3957 void JustSummoned(Creature* summon) override
3958 {
3959 if (Unit* victim = me->GetVictim())
3960 summon->Attack(victim, true);
3961 }
3962
3963 void JustEngagedWith(Unit* who) override
3964 {
3965 _attackerGUID = who->GetGUID();
3966
3967 me->AttackStop();
3968
3971
3973 }
3974
3975 void UpdateAI(uint32 diff) override
3976 {
3977 _events.Update(diff);
3978
3979 while (uint32 eventId = _events.ExecuteEvent())
3980 {
3981 switch (eventId)
3982 {
3984 me->SetDisableGravity(false);
3987 break;
3988
3989 case EVENT_MATRIARCH_AGGRO + 1:
3990 me->CastStop();
3993 break;
3994
3995 case EVENT_MATRIARCH_AGGRO + 2:
3996 if (Unit* attacker = ObjectAccessor::GetUnit(*me, _attackerGUID))
3997 ScheduleCombatEvents(attacker);
3998 break;
3999
4001 me->SetDisableGravity(true);
4004 me->CastSpell(nullptr, SPELL_SKITTERWEB, true);
4006 break;
4007
4010 break;
4011
4012 case EVENT_VENOM_SPLASH:
4014 _events.Repeat(15s, 18s);
4015 break;
4016
4017 default:
4018 break;
4019 }
4020 }
4021
4022 if (!UpdateVictim())
4023 return;
4024 }
4025
4027 {
4028 me->Attack(who, true);
4029
4032 }
4033
4034private:
4038};
4039
4044
4045// 83979 - Bond of the Val'kyr
4069
4070Position const AgathaBackFrontyardPos = { 982.57f, 671.04f, 77.298f };
4071
4108
4109// 44951 - Agatha
4111{
4113
4114 void JustAppeared() override
4115 {
4116 // Note: SummonPropertiesFlags::HelpWhenSummonedInCombat is NYI.
4118
4120
4121 // Note: SummonPropertiesFlags::JoinSummonerSpawnGroup is NYI.
4122 me->GetMotionMaster()->Clear();
4123 me->GetMotionMaster()->MoveFollow(me->GetOwner(), 3.0f, float(M_PI / 2.0f));
4124
4126 }
4127
4128 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
4129 {
4130 TempSummon* tempSummon = me->ToTempSummon();
4131 if (!tempSummon)
4132 return;
4133
4134 switch (spellInfo->Id)
4135 {
4137 {
4138 if (_isSceneStarted)
4139 return;
4140
4141 if (Unit* summoner = tempSummon->GetSummonerUnit())
4142 Talk(TALK_AGATHA_BROADCAST, summoner);
4143 break;
4144 }
4145
4147 {
4148 if (!_isSceneStarted)
4150 break;
4151 }
4152
4154 if (Unit* summoner = tempSummon->GetSummonerUnit())
4155 me->CastSpell(summoner, SPELL_ARMORE_CAMERA_1, true);
4156 break;
4157
4160 break;
4161
4164 break;
4165
4168 break;
4169
4170 default:
4171 break;
4172 }
4173 }
4174
4175 void WaypointReached(uint32 waypointId, uint32 pathId) override
4176 {
4177 if (pathId == PATH_AGATHA_TO_FORSAKEN)
4178 {
4179 if (waypointId == WAYPOINT_SPEED_UP)
4180 me->SetSpeed(MOVE_RUN, 15.880999f);
4181 else if (waypointId == WAYPOINT_ARRIVED_TO_FORSAKEN)
4183 }
4184 }
4185
4186 void Reset() override
4187 {
4190
4191 // Note: SummonPropertiesFlags::JoinSummonerSpawnGroup is NYI.
4192 me->GetMotionMaster()->Clear();
4193 me->GetMotionMaster()->MoveFollow(me->GetOwner(), 3.0f, float(M_PI / 2.0f));
4194 }
4195
4196 void JustEngagedWith(Unit* /*who*/) override
4197 {
4200 }
4201
4202 void UpdateAI(uint32 diff) override
4203 {
4204 TempSummon* tempSummon = me->ToTempSummon();
4205 if (!tempSummon)
4206 return;
4207
4208 // Note: SummonPropertiesFlags::DespawnOnSummonerDeath, SummonPropertiesFlags::DespawnOnSummonerLogout and SummonPropertiesFlags::DespawnWhenExpired are NYI.
4209 if (Unit* summoner = tempSummon->GetSummonerUnit())
4210 {
4211 if (!summoner->IsAlive() || !summoner->IsInWorld() || !summoner->HasAura(SPELL_SUMMON_AGATHA_FENRIS))
4213 }
4214
4215 _events.Update(diff);
4216
4217 while (uint32 eventId = _events.ExecuteEvent())
4218 {
4219 switch (eventId)
4220 {
4222 {
4223 if (Unit* summoner = tempSummon->GetSummonerUnit())
4224 {
4225 if (!me->HasUnitState(UNIT_STATE_CASTING) && summoner->GetHealthPct() < 75.0f)
4226 me->CastSpell(summoner, SPELL_UNHOLY_DARKNESS, false);
4227
4228 _events.Repeat(1s);
4229 }
4230 break;
4231 }
4232
4233 case EVENT_DOOMHOWL:
4235 _events.Repeat(14s, 18s);
4236 break;
4237
4238 case EVENT_UNHOLY_SMITE:
4240 _events.Repeat(4s, 6s);
4241 break;
4242
4243 case EVENT_FLEE_FROM_FENRIS + 1:
4244 {
4245 if (Unit* summoner = tempSummon->GetSummonerUnit())
4246 {
4247 me->SetFacingTo(3.159046f);
4248
4249 Talk(TALK_AGATHA_POST_EVENT1, summoner);
4250 }
4251 break;
4252 }
4253
4254 case EVENT_FLEE_FROM_FENRIS + 2:
4255 {
4256 if (Unit* summoner = tempSummon->GetSummonerUnit())
4257 {
4259
4260 Talk(TALK_AGATHA_POST_EVENT2, summoner);
4261
4262 if (Player* player = summoner->ToPlayer())
4263 player->KilledMonsterCredit(NPC_AGATHA_FENRIS);
4264
4265 me->SetDisableGravity(true);
4266 me->SetCanFly(true);
4267
4268 me->SetSpeed(MOVE_RUN, 7.7937083f);
4269 me->GetMotionMaster()->Clear();
4271 }
4272 break;
4273 }
4274
4275 case EVENT_FLEE_FROM_FENRIS + 3:
4276 {
4277 if (Unit* summoner = tempSummon->GetSummonerUnit())
4278 {
4279 summoner->ExitVehicle();
4280
4281 _isSceneStarted = false;
4282
4283 me->SetSpeed(MOVE_RUN, 1.14286f);
4284
4285 // Note: SummonPropertiesFlags::JoinSummonerSpawnGroup is NYI.
4286 me->GetMotionMaster()->Clear();
4287 me->GetMotionMaster()->MoveFollow(summoner, 3.0f, float(M_PI / 2.0f));
4288
4289 me->SetImmuneToAll(false);
4290
4292 }
4293 break;
4294 }
4295
4296 default:
4297 break;
4298 }
4299 }
4300
4301 if (!UpdateVictim())
4302 return;
4303 }
4304
4306 {
4307 TempSummon* tempSummon = me->ToTempSummon();
4308 if (!tempSummon)
4309 return;
4310
4311 if (_isSceneStarted)
4312 return;
4313
4314 _isSceneStarted = true;
4315
4316 me->SetImmuneToAll(false);
4317
4319
4320 me->GetMotionMaster()->Clear();
4322
4323 if (Unit* summoner = tempSummon->GetSummonerUnit())
4324 Talk(TALK_AGATHA_PRE_EVENT, summoner);
4325 }
4326
4327private:
4330};
4331
4336
4337// 83990 - Notify Agatha
4339{
4340 bool Validate(SpellInfo const* /*spellInfo*/) override
4341 {
4343 }
4344
4346 {
4347 Unit* caster = GetCaster();
4348 Unit* target = GetExplTargetUnit();
4349
4350 if (caster)
4351 {
4352 if (Creature* agatha = target->FindNearestCreature(NPC_AGATHA_FENRIS, 50.0f, true))
4353 {
4354 if (agatha->GetOwner() == target)
4355 {
4356 agatha->CastSpell(caster, SPELL_RISE_FORSAKEN_FENRIS, true);
4357
4358 if (Player* player = target->ToPlayer())
4359 {
4360 if (roll_chance(50))
4361 {
4362 if (agatha->IsAIEnabled())
4363 agatha->AI()->Talk(TALK_AGATHA_RISE_FORSAKEN, player);
4364 }
4365 }
4366 }
4367 }
4368 }
4369 }
4370
4375};
4376
4397
4398// 83997 - Forsaken Trooper Master Script (Fenris Isle)
4400{
4415
4417 {
4418 Unit* unit = GetCaster();
4419
4420 if (Creature* hillsbradRefugee = unit->ToCreature())
4421 {
4423
4424 switch (hillsbradRefugee->GetDisplayId())
4425 {
4426 case DISPLAY_MALE_01_F:
4428 break;
4429 case DISPLAY_MALE_02_F:
4431 break;
4432 case DISPLAY_MALE_03_F:
4434 break;
4435 case DISPLAY_MALE_04_F:
4437 break;
4440 break;
4443 break;
4446 break;
4449 break;
4450 default:
4451 break;
4452 }
4453
4454 hillsbradRefugee->CastSpell(hillsbradRefugee, spellId, true);
4455 }
4456 }
4457
4462};
4463
4474
4475// 44954, 44966 - Hillsbrad Refugee
4477{
4479
4480 void Reset() override
4481 {
4482 _events.Reset();
4483 }
4484
4485 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
4486 {
4487 switch (spellInfo->Id)
4488 {
4491 me->DespawnOrUnsummon(2s);
4492 break;
4493 default:
4494 break;
4495 }
4496 }
4497
4498 void JustDied(Unit* killer) override
4499 {
4500 if (Player* player = killer->ToPlayer())
4501 {
4502 if (player->GetQuestStatus(QUEST_RISE_FORSAKEN) == QUEST_STATUS_INCOMPLETE)
4503 me->CastSpell(player, SPELL_NOTIFY_AGATHA_FENRIS, true);
4504 }
4505 }
4506
4507 void JustEngagedWith(Unit* /*who*/) override
4508 {
4510 }
4511
4512 void UpdateAI(uint32 diff) override
4513 {
4514 _events.Update(diff);
4515
4516 if (!UpdateVictim())
4517 return;
4518
4519 while (uint32 eventId = _events.ExecuteEvent())
4520 {
4521 switch (eventId)
4522 {
4525 _events.Repeat(15s, 18s);
4526 break;
4527 default:
4528 break;
4529 }
4530 }
4531 }
4532
4533private:
4535};
4536
4552
4553// 44958, 44959, 44960, 44961 - Forsaken Trooper (Male)
4554// 44962, 44963, 44964, 44965 - Forsaken Trooper (Female)
4556{
4558
4559 void IsSummonedBy(WorldObject* summoner) override
4560 {
4561 if (!summoner->IsCreature())
4562 return;
4563
4564 me->SetImmuneToAll(true);
4565
4567
4569
4570 switch (summoner->ToCreature()->GetDisplayId())
4571 {
4572 case DISPLAY_MALE_01_F:
4573 displayId = DISPLAY_MALE_01_D_F;
4574 break;
4575 case DISPLAY_MALE_02_F:
4576 displayId = DISPLAY_MALE_02_D_F;
4577 break;
4578 case DISPLAY_MALE_03_F:
4579 displayId = DISPLAY_MALE_03_D_F;
4580 break;
4581 case DISPLAY_MALE_04_F:
4582 displayId = DISPLAY_MALE_04_D_F;
4583 break;
4585 displayId = DISPLAY_FEMALE_01_D_F;
4586 break;
4588 displayId = DISPLAY_FEMALE_02_D_F;
4589 break;
4591 displayId = DISPLAY_FEMALE_03_D_F;
4592 break;
4594 displayId = DISPLAY_FEMALE_04_D_F;
4595 break;
4596 default:
4597 break;
4598 }
4599
4600 me->SetDisplayId(displayId);
4601
4603
4604 me->DespawnOrUnsummon(4s);
4605 }
4606
4607 void Reset() override
4608 {
4609 _events.Reset();
4610 }
4611
4612 void UpdateAI(uint32 diff) override
4613 {
4614 _events.Update(diff);
4615
4616 while (uint32 eventId = _events.ExecuteEvent())
4617 {
4618 switch (eventId)
4619 {
4622 break;
4623 default:
4624 break;
4625 }
4626 }
4627 }
4628
4629private:
4631};
4632
4642
4643// 44987 - Worgen Sentry
4645{
4647
4648 void Reset() override
4649 {
4650 _events.Reset();
4651 }
4652
4653 void JustDied(Unit* /*killer*/) override
4654 {
4656 }
4657
4658 void JustEngagedWith(Unit* /*who*/) override
4659 {
4661
4663 }
4664
4665 void UpdateAI(uint32 diff) override
4666 {
4667 _events.Update(diff);
4668
4669 if (!UpdateVictim())
4670 return;
4671
4672 while (uint32 eventId = _events.ExecuteEvent())
4673 {
4674 switch (eventId)
4675 {
4678 _events.Repeat(10s, 12s);
4679 break;
4680 default:
4681 break;
4682 }
4683 }
4684 }
4685
4686private:
4688};
4689
4690Position const NoEscapeStartPos = { 981.782f, 670.953f, 74.898f, 3.1887f };
4691
4696
4697// 45032 - Fenris Keep Stalker
4699{
4701
4702 void Reset() override
4703 {
4704 eventIsTriggered = false;
4705 }
4706
4707 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
4708 {
4709 switch (spellInfo->Id)
4710 {
4712 Reset();
4713 break;
4714 default:
4715 break;
4716 }
4717 }
4718
4720 {
4721 if (eventIsTriggered)
4722 return;
4723
4724 if (Player* player = ObjectAccessor::GetPlayer(*me, playerGuid))
4725 {
4726 eventIsTriggered = true;
4727
4729
4730 player->NearTeleportTo(NoEscapeStartPos, true);
4731 }
4732 }
4733
4734private:
4736};
4737
4742
4743// 6230 - No Escape
4745{
4746public:
4747 at_silverpine_no_escape() : AreaTriggerScript("at_silverpine_no_escape") { }
4748
4749 bool OnTrigger(Player* player, AreaTriggerEntry const* /*at*/) override
4750 {
4751 if (!player->IsAlive() || player->GetQuestStatus(QUEST_NO_ESCAPE) != QUEST_STATUS_INCOMPLETE)
4752 return true;
4753
4754 if (Creature* agatha = player->FindNearestCreature(NPC_AGATHA_FENRIS, 10.0f, true))
4755 {
4756 if (agatha->GetOwner() == player)
4757 {
4758 if (Creature* fenrisStalker = player->FindNearestCreature(NPC_FENRIS_KEEP_STALKER, 50.0f, true))
4759 {
4760 if (npc_silverpine_fenris_keep_stalker* fenrisKeepStalkerAI = CAST_AI(npc_silverpine_fenris_keep_stalker, fenrisStalker->AI()))
4761 fenrisKeepStalkerAI->OnTriggerNoEscape(player->GetGUID());
4762 }
4763 }
4764 }
4765
4766 return true;
4767 }
4768};
4769
4781
4782// 84053 - Summon Fenris Actors
4784{
4799
4801 {
4802 Unit* target = GetHitUnit();
4803
4804 target->CastSpell(target, SPELL_SUMMON_BLOODFANG_FENRIS, true);
4805 target->CastSpell(target, SPELL_SUMMON_CROWLEY_FENRIS, true);
4806 target->CastSpell(target, SPELL_SUMMON_PHIN_ODELIC, true);
4807 target->CastSpell(target, SPELL_SUMMON_BARTOLO_GINSETTI, true);
4808 target->CastSpell(target, SPELL_SUMMON_LOREMASTER_DIBBS, true);
4809 target->CastSpell(target, SPELL_SUMMON_MAGISTRATE_HENRY, true);
4810 target->CastSpell(target, SPELL_SUMMON_CARETAKER_SMITHERS, true);
4811 target->CastSpell(target, SPELL_SUMMON_SOPHIA, true);
4812 }
4813
4818};
4819
4820Position const CameraFrontyardPos = { 980.7f, 689.14f, 76.9f };
4821
4839
4840// 45003 - Fenris Keep Camera
4842{
4844
4845 void IsSummonedBy(WorldObject* summoner) override
4846 {
4847 if (Unit* unit = summoner->ToUnit())
4848 unit->EnterVehicle(me, SEAT_FENRIS_CAMERA);
4849
4850 me->SetImmuneToAll(true);
4851
4853 }
4854
4855 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
4856 {
4857 switch (spellInfo->Id)
4858 {
4861 break;
4862 default:
4863 break;
4864 }
4865 }
4866
4867 void PassengerBoarded(Unit* passenger, int8 seatId, bool apply) override
4868 {
4869 if (apply)
4870 {
4871 if (seatId == SEAT_FENRIS_CAMERA)
4872 {
4874
4875 me->CastSpell(passenger, SPELL_SUMMON_FENRIS_ACTORS, true);
4876 }
4877 else if (seatId == SEAT_FENRIS_CAMERA_FORCE)
4878 passenger->SetFacingTo(0.0f);
4879 }
4880 else
4881 {
4882 if (seatId == SEAT_FENRIS_CAMERA_FORCE)
4884 }
4885 }
4886
4887 void MovementInform(uint32 type, uint32 id) override
4888 {
4889 if (type == POINT_MOTION_TYPE && id == POINT_CAMERA_FRONTYARD)
4891 }
4892
4893 void UpdateAI(uint32 diff) override
4894 {
4895 TempSummon* summon = me->ToTempSummon();
4896 if (!summon)
4897 return;
4898
4899 Unit* summoner = summon->GetSummonerUnit();
4900 if (!summoner)
4901 return;
4902
4903 _events.Update(diff);
4904
4905 while (uint32 eventId = _events.ExecuteEvent())
4906 {
4907 switch (eventId)
4908 {
4911 break;
4912
4914 me->CastSpell(summoner, SPELL_FORCE_SEAT_2, true);
4916 break;
4917
4919 summoner->CastSpell(summoner, SPELL_GENERAL_TRIGGER_84102, true);
4920 break;
4921
4923 if (Creature* agatha = me->FindNearestCreature(NPC_AGATHA_FENRIS, 60.0f))
4925 me->SetFacingTo(0.08278348f);
4927 break;
4928
4931 break;
4932
4933 default:
4934 break;
4935 }
4936 }
4937 }
4938
4939private:
4941};
4942
4961
4962// 44989 - Lord Darius Crowley, 44990 - Packleader Ivar Bloodfang
4964{
4966
4967 void JustAppeared() override
4968 {
4969 me->SetImmuneToAll(true);
4970
4972 }
4973
4974 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
4975 {
4976 TempSummon* tempSummon = me->ToTempSummon();
4977 if (!tempSummon)
4978 return;
4979
4980 if (me->GetEntry() != NPC_CROWLEY_FENRIS)
4981 return;
4982
4983 switch (spellInfo->Id)
4984 {
4986 {
4987 if (Unit* summoner = tempSummon->GetSummonerUnit())
4988 {
4989 me->CastSpell(summoner, SPELL_ARMORE_CAMERA_FENRIS, true);
4990
4991 Talk(TALK_CROWLEY_NO_ESCAPE_6, summoner);
4992
4994 }
4995 break;
4996 }
4997
4998 default:
4999 break;
5000 }
5001 }
5002
5003 void UpdateAI(uint32 diff) override
5004 {
5005 TempSummon* tempSummon = me->ToTempSummon();
5006 if (!tempSummon)
5007 return;
5008
5009 Unit* summoner = tempSummon->GetSummonerUnit();
5010 if (!summoner)
5011 return;
5012
5013 _events.Update(diff);
5014
5015 if (me->GetEntry() != NPC_CROWLEY_FENRIS)
5016 return;
5017
5018 while (uint32 eventId = _events.ExecuteEvent())
5019 {
5020 switch (eventId)
5021 {
5023 Talk(TALK_CROWLEY_NO_ESCAPE_0, summoner);
5025 break;
5026
5028 Talk(TALK_CROWLEY_NO_ESCAPE_1, summoner);
5030 break;
5031
5033 Talk(TALK_CROWLEY_NO_ESCAPE_2, summoner);
5035 break;
5036
5038 Talk(TALK_CROWLEY_NO_ESCAPE_3, summoner);
5040 break;
5041
5043 Talk(TALK_CROWLEY_NO_ESCAPE_4, summoner);
5045 break;
5046
5048 Talk(TALK_CROWLEY_NO_ESCAPE_5, summoner);
5050 break;
5051
5055 break;
5056
5057 default:
5058 break;
5059 }
5060 }
5061 }
5062
5063private:
5065};
5066
5096
5097// 44993 - Phin Odelic, 44994 - Bartolo Ginsetti, 44995 - Loremaster Dibbs, 44996 - Magistrate Henry Maleb, 44997 - Caretaker Smithers, 45002 - Sophia Zwoski
5099{
5101
5102 void JustAppeared() override
5103 {
5104 if (Creature* fenrisStalker = me->FindNearestCreature(NPC_FENRIS_KEEP_STALKER, 50.0f, true))
5105 me->SetFacingToObject(fenrisStalker);
5106
5107 me->SetImmuneToAll(true);
5108
5110 }
5111
5112 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
5113 {
5114 TempSummon* tempSummon = me->ToTempSummon();
5115 if (!tempSummon)
5116 return;
5117
5118 switch (spellInfo->Id)
5119 {
5121 if (Unit* summoner = tempSummon->GetSummonerUnit())
5122 me->CastSpell(summoner, SPELL_ARMORE_CAMERA_2, true);
5123 break;
5124
5127 break;
5128
5131 break;
5132
5133 default:
5134 break;
5135 }
5136 }
5137
5138 void UpdateAI(uint32 diff) override
5139 {
5140 TempSummon* tempSummon = me->ToTempSummon();
5141 if (!tempSummon)
5142 return;
5143
5144 _events.Update(diff);
5145
5146 while (uint32 eventId = _events.ExecuteEvent())
5147 {
5148 switch (eventId)
5149 {
5151 if (Unit* summoner = tempSummon->GetSummonerUnit())
5152 Talk(TALK_HENRY_NO_ESCAPE_0, summoner);
5154 break;
5155
5157 if (Unit* summoner = tempSummon->GetSummonerUnit())
5158 Talk(TALK_HENRY_NO_ESCAPE_1, summoner);
5160 break;
5161
5164 break;
5165
5168 break;
5169
5171 {
5172 _isWorgen = true;
5173
5174 uint32 spellId = 0;
5175
5176 switch (me->GetEntry())
5177 {
5178 case NPC_PHIN_ODELIC:
5179 spellId = SPELL_BLOOD_ODELIC;
5180 break;
5182 spellId = SPELL_BLOOD_BARTOLO;
5183 break;
5185 spellId = SPELL_BLOOD_DIBBS;
5186 break;
5188 spellId = SPELL_BLOOD_HENRY;
5189 break;
5191 spellId = SPELL_BLOOD_SMITHERS;
5192 break;
5193 case NPC_SOPHIA_ZWOSKI:
5194 spellId = SPELL_BLOOD_ZWOSKI;
5196 break;
5197 default:
5198 break;
5199 }
5200
5201 DoCastSelf(spellId);
5202
5204 break;
5205 }
5206
5207 case EVENT_ACTOR_FENRIS_MORPH + 1:
5211 break;
5212
5213 case EVENT_ACTOR_FENRIS_MORPH + 2:
5214 if (Creature* agatha = me->FindNearestCreature(NPC_AGATHA_FENRIS, 60.0f))
5216 break;
5217
5218 default:
5219 break;
5220 }
5221 }
5222 }
5223
5224private:
5227};
5228
5230{
5231 /* Vehicles */
5232
5235
5236 /* Forsaken High Command */
5237
5249
5250 /* Ivar Patch */
5251
5257
5258 /* Forsaken Rear Guard */
5259
5266
5267 /* North Tide's Beachhead */
5268
5276
5277 /* The Skittering Dark */
5278
5283
5284 /* Fenris Isle */
5285
5299}
#define M_PI
Definition Common.h:118
int8_t int8
Definition Define.h:152
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
LootItemType
@ POINT_MOTION_TYPE
@ TEMPSUMMON_TIMED_DESPAWN
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
@ QUEST_STATUS_REWARDED
Definition QuestDef.h:153
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:150
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:148
float frand(float min, float max)
Definition Random.cpp:55
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
bool roll_chance(T chance)
Definition Random.h:55
#define RegisterCreatureAI(ai_name)
Definition ScriptMgr.h:1392
#define RegisterGameObjectAI(ai_name)
Definition ScriptMgr.h:1410
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
void AddGossipItemFor(Player *player, GossipOptionNpc optionNpc, std::string text, uint32 sender, uint32 action)
void SendGossipMenuFor(Player *player, uint32 npcTextID, ObjectGuid const &guid)
void CloseGossipMenuFor(Player *player)
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ GENDER_MALE
@ EMOTE_ONESHOT_POINT
@ EMOTE_ONESHOT_YES
@ EMOTE_ONESHOT_EXCLAMATION
@ EMOTE_STATE_READY_UNARMED
@ EMOTE_ONESHOT_ROAR
@ EMOTE_ONESHOT_SALUTE
@ EMOTE_ONESHOT_TALK
@ EVENT_JUMP
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ POWER_ENERGY
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_DUMMY
@ SPELL_AURA_PERIODIC_DUMMY
#define SpellEffectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraEffectRemoveFn(F, I, N, M)
#define CAST_AI(a, b)
Definition UnitAI.h:29
@ MOVE_RUN
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ REACT_ASSIST
@ UNIT_STAND_STATE_DEAD
Definition UnitDefines.h:49
@ UNIT_NPC_FLAG_QUESTGIVER
@ UNIT_NPC_FLAG_SPELLCLICK
DamageEffectType
@ UNIT_FLAG3_UNTARGETABLE_FROM_UI
@ UNIT_STATE_CASTING
Definition Unit.h:276
HookList< EffectPeriodicHandler > OnEffectPeriodic
SpellInfo const * GetSpellInfo() const
AuraEffect * GetEffect(uint8 effIndex) const
Unit * GetTarget() const
HookList< EffectApplyHandler > OnEffectRemove
HookList< EffectApplyHandler > OnEffectApply
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
bool IsCreature() const
Definition BaseEntity.h:172
bool IsPlayer() const
Definition BaseEntity.h:173
TypeID GetTypeId() const
Definition BaseEntity.h:166
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:386
uint32 m_spells[MAX_CREATURE_SPELLS]
Definition Creature.h:324
void SetReactState(ReactStates st)
Definition Creature.h:174
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void SetImmuneToAll(bool apply) override
Definition Creature.h:181
void SetDisplayId(uint32 displayId, bool setNative=false) override
uint32 ExecuteEvent()
Definition EventMap.cpp:77
void Update(uint32 time)
Definition EventMap.h:61
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:40
void CancelEvent(uint32 eventId)
Definition EventMap.cpp:135
void Reset()
Definition EventMap.cpp:25
void MoveFall(uint32 id=0, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void MoveFollow(Unit *target, float dist, Optional< ChaseAngle > angle={}, Optional< Milliseconds > duration={}, bool ignoreTargetWalk=false, MovementSlot slot=MOTION_SLOT_ACTIVE, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={}, Optional< MovementFadeObject > fadeObject={}, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount, Optional< Milliseconds > duration={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void MovePath(uint32 pathId, bool repeatable, Optional< Milliseconds > duration={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< std::pair< Milliseconds, Milliseconds > > waitTimeRangeAtPathEnd={}, Optional< float > wanderDistanceAtPathEnds={}, Optional< bool > followPathBackwardsFromEndToStart={}, Optional< bool > exactSplinePath={}, bool generatePath=true, Optional< MovementFadeObject > fadeObject={}, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void Clear()
Definition ObjectGuid.h:329
Player * ToPlayer()
Definition Object.h:126
uint32 GetEntry() const
Definition Object.h:89
Creature * ToCreature()
Definition Object.h:121
Unit * ToUnit()
Definition Object.h:116
WorldSession * GetSession() const
Definition Player.h:2272
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition Player.cpp:15962
uint32 GetGossipTextId(uint32 menuId, WorldObject *source)
Definition Player.cpp:14269
std::unique_ptr< PlayerMenu > PlayerTalkClass
Definition Player.h:2570
uint32 GetQuestId() const
Definition QuestDef.h:637
uint32 const Id
Definition SpellInfo.h:328
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:588
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Creature * GetHitCreature() const
Unit * GetCaster() const
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
Unit * GetExplTargetUnit() const
void Summon(Creature const *summon)
Unit * GetSummonerUnit() const
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:160
virtual void SetGUID(ObjectGuid const &guid, int32 id)
Definition UnitAI.h:76
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:180
virtual ObjectGuid GetGUID(int32 id) const
Definition UnitAI.h:77
Definition Unit.h:635
void EnterVehicle(Unit *base, int8 seatId=-1)
Definition Unit.cpp:12749
void CastStop(uint32 except_spellid=0)
Definition Unit.cpp:1186
void SetUnitFlag3(UnitFlags3 flags)
Definition Unit.h:856
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3828
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition Unit.cpp:10731
void PlayOneShotAnimKitId(uint16 animKitId)
Definition Unit.cpp:11160
void SetSpeed(UnitMoveType mtype, float newValue)
Definition Unit.cpp:8937
void SetPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:10046
MotionMaster * GetMotionMaster()
Definition Unit.h:1723
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition Unit.cpp:13307
void ResumeMovement(uint32 timer=0, uint8 slot=0)
Definition Unit.cpp:10707
void PauseMovement(uint32 timer=0, uint8 slot=0, bool forced=true)
Definition Unit.cpp:10695
bool IsAlive() const
Definition Unit.h:1185
void RemoveNpcFlag(NPCFlags flags)
Definition Unit.h:998
TempSummon * ToTempSummon()
Definition Unit.h:1828
UnitAI * GetAI() const
Definition Unit.h:668
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition Unit.cpp:13361
void SetUninteractible(bool apply)
Definition Unit.cpp:8564
bool IsTaxi() const
Definition Unit.h:1011
Gender GetGender() const
Definition Unit.h:767
uint32 GetDisplayId() const
Definition Unit.h:1610
bool IsAIEnabled() const
Definition Unit.h:666
bool Attack(Unit *victim, bool meleeAttack)
Definition Unit.cpp:5853
bool SetCanFly(bool enable)
Definition Unit.cpp:13459
bool IsSummon() const
Definition Unit.h:749
bool SetWalk(bool enable)
Definition Unit.cpp:13343
Unit * GetVictim() const
Definition Unit.h:726
void SetFacingTo(float const ori, bool force=true)
Definition Unit.cpp:13289
void NearTeleportTo(TeleportLocation const &target, bool casting=false)
Definition Unit.cpp:12958
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4804
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition Unit.cpp:1657
void SetMaxPower(Powers power, int32 val)
Definition Unit.cpp:10083
Vehicle * GetVehicleKit() const
Definition Unit.h:1782
bool AttackStop()
Definition Unit.cpp:5965
void SetPowerType(Powers power, bool sendUpdate=true, bool onInit=false)
Definition Unit.cpp:5697
void SetAIAnimKitId(uint16 animKitId)
Definition Unit.cpp:11174
void RemoveAllPassengers()
Removes all current and pending passengers from the vehicle.
Definition Vehicle.cpp:238
void PlayDirectSound(uint32 soundId, Player const *target=nullptr, uint32 broadcastTextId=0) const
Definition Object.cpp:2938
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition Object.cpp:2658
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
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:1398
Unit * GetOwner() const
Definition Object.cpp:1598
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:450
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:1517
void SendTaxiMenu(Creature *unit)
bool OnTrigger(Player *player, AreaTriggerEntry const *) override
bool OnTrigger(Player *player, AreaTriggerEntry const *) override
void OnApply(AuraEffect const *, AuraEffectHandleModes)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *spellInfo) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
void OnApply(AuraEffect const *, AuraEffectHandleModes)
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)
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
constexpr float GetPositionZ() const
Definition Position.h:89
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
void OnQuestAccept(Player *player, Quest const *quest) override
bool OnGossipSelect(Player *player, uint32, uint32) override
bool OnGossipSelect(Player *player, uint32, uint32) override
void OnQuestAccept(Player *player, Quest const *quest) override
void OnQuestReward(Player *player, Quest const *quest, LootItemType, uint32) override
void WaypointReached(uint32 waypointId, uint32 pathId) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
std::array< ObjectGuid, 3 > _drunkenOrcSeaDog
void UpdateAI(uint32 diff) override
void PassengerBoarded(Unit *passenger, int8, bool apply) override
== Fields =======================================
void SetGUID(ObjectGuid const &guid, int32 id) override
npc_silverpine_armoire(Creature *creature)
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void WaypointReached(uint32 waypointId, uint32 pathId) override
void IsSummonedBy(WorldObject *summoner) override
npc_silverpine_deathstalker(Creature *creature)
npc_silverpine_fallen_human(Creature *creature)
void UpdateAI(uint32 diff) override
void DoAction(int32 action) override
void MovementInform(uint32 type, uint32 id) override
void IsSummonedBy(WorldObject *summoner) override
void PassengerBoarded(Unit *passenger, int8 seatId, bool apply) override
== Fields =======================================
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void OnTriggerNoEscape(ObjectGuid playerGuid)
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
npc_silverpine_forest_ettin(Creature *creature)
void SetGUID(ObjectGuid const &guid, int32 id) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *spellInfo) override
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
void DoAction(int32 param) override
void PassengerBoarded(Unit *, int8 seatId, bool apply) override
== Fields =======================================
void UpdateAI(uint32 diff) override
npc_silverpine_forsaken_bat(Creature *creature)
void DoAction(int32 param) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void IsSummonedBy(WorldObject *summoner) override
void PassengerBoarded(Unit *passenger, int8, bool apply) override
== Fields =======================================
void UpdateAI(uint32 diff) override
void WaypointReached(uint32 waypointId, uint32 pathId) override
void IsSummonedBy(WorldObject *summoner) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void OnQuestAccept(Player *, Quest const *quest) override
void JustSummoned(Creature *summon) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void UpdateAI(uint32 diff) override
npc_silverpine_horde_hauler(Creature *creature)
void WaypointReached(uint32 waypointId, uint32 pathId) override
void PassengerBoarded(Unit *passenger, int8 seatId, bool apply) override
== Fields =======================================
void WaypointReached(uint32 waypointId, uint32 pathId) override
void IsSummonedBy(WorldObject *summoner) override
void MovementInform(uint32 type, uint32 id) override
void IsSummonedBy(WorldObject *summoner) override
npc_silverpine_orc_crate(Creature *creature)
npc_silverpine_orc_sea_dog(Creature *creature)
void IsSummonedBy(WorldObject *summoner) override
void UpdateAI(uint32 diff) override
npc_silverpine_orc_sea_pup(Creature *creature)
void PassengerBoarded(Unit *passenger, int8 seatId, bool apply) override
== Fields =======================================
void UpdateAI(uint32 diff) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void IsSummonedBy(WorldObject *summoner) override
void WaypointReached(uint32 waypointId, uint32 pathId) override
npc_silverpine_salty_rocka(Creature *creature)
void UpdateAI(uint32 diff) override
void MoveInLineOfSight(Unit *who) override
void JustSummoned(Creature *summon) override
void OnQuestReward(Player *player, Quest const *quest, LootItemType, uint32) override
void JustDied(Unit *killer) override
void UpdateAI(uint32 diff) override
Position const YorickReadyPosition
@ EVENT_MOVE_TO_FOREST_ETTIN
@ POINT_NEAR_FOREST_ETTIN
Position const AgathaPreRisePos
Position const GarroshJumpPos
@ TALK_REFUGEE_JUST_RISEN
@ EVENT_REFUGEE_JUST_RISEN
@ WAYPOINT_CLOSE_TO_ARMOIRE
@ TALK_YORICK_EXSANGUINATE_HIDE
@ EVENT_SET_GUID_FOR_ARMOIRE
@ SPELL_CANCEL_SUMMON_YORICK
@ PHASE_WAITING_TO_EXSANGUINATE
@ TALK_YORICK_EXSANGUINATE_SUMMON
@ WAYPOINT_HIDDEN_NEXT_TO_ARMOIRE
@ NPC_PACKLEADER_IVAR_BLOODFANG
@ SPELL_HIDDEN_IN_ARMOIRE
@ EVENT_RANE_TALK_TO_PLAYER
@ EVENT_START_QUEST_EXSANGUINATE
@ EVENT_WAIT_FOR_PLAYER_EXSANGUINATE
@ SPELL_PERMANENT_FEIGN_DEATH
@ SPELL_COSMETIC_NOT_FEELING_SICK
@ COSMETIC_SIT_ON_THE_FLOOR
@ SPELL_COSMETIC_FEELING_SICK
@ COSMETIC_SIT_ON_THE_FLOOR_TWICE
@ COSMETIC_START_TO_FEEL_UNEASY
void AddSC_silverpine_forest()
Position const NoEscapeStartPos
SpellForsakenTrooperMasterScriptCometh
@ SPELL_FORSAKEN_TROOPER_MALE_02_HC
@ SPELL_FORSAKEN_TROOPER_MALE_03_HC
@ SPELL_FORSAKEN_TROOPER_FEMALE_03_HC
@ SPELL_FORSAKEN_TROOPER_MALE_01_HC
@ SPELL_FORSAKEN_TROOPER_FEMALE_02_HC
@ SPELL_FORSAKEN_TROOPER_FEMALE_04_HC
@ SPELL_FORSAKEN_TROOPER_MALE_04_HC
@ SPELL_FORSAKEN_TROOPER_FEMALE_01_HC
@ WAYPOINT_ON_TROOPER_DESPAWN
@ WAYPOINT_ON_FORSAKEN_FRONT
@ SEAT_HAULER_TROOPER_4
@ NPC_HORDE_ENGINEER_HAULER
@ SEAT_HAULER_TROOPER_3
@ WAYPOINT_ON_DESPAWN_POINT_SOUTH
@ SEAT_HAULER_TROOPER_1
@ WAYPOINT_ON_SEPULCHER
@ SEAT_HAULER_TROOPER_5
@ SPELL_EJECT_PASSENGERS_3_8
@ EVENT_YELL_ON_FORSAKEN_HIGH
@ NPC_FORSAKEN_TROOPER_F
@ EVENT_YELL_ON_FORSAKEN_FRONT
@ NPC_FORSAKEN_TROOPER_M
@ TALK_ON_FORSAKEN_HIGH
@ PATH_FROM_NORTH_TO_SOUTH
@ TALK_ON_FORSAKEN_FRONT
@ SEAT_HAULER_TROOPER_2
@ EVENT_YELL_ON_SEPULCHER
@ NPC_SUBDUED_FOREST_ETTIN_HAULER
@ TALK_HAULER_BOARDED
@ WAYPOINT_ON_FORSAKEN_HIGH
@ SPELL_SUMMON_CROWLEY_FENRIS
@ SPELL_SUMMON_LOREMASTER_DIBBS
@ SPELL_SUMMON_BLOODFANG_FENRIS
@ SPELL_SUMMON_PHIN_ODELIC
@ SPELL_SUMMON_CARETAKER_SMITHERS
@ SPELL_SUMMON_MAGISTRATE_HENRY
@ SPELL_SUMMON_BARTOLO_GINSETTI
@ EVENT_AGATHA_CHECK_PLAYER_HEALTH
@ WAYPOINT_ARRIVED_TO_FORSAKEN
@ TALK_AGATHA_POST_EVENT2
@ TALK_AGATHA_RISE_FORSAKEN
@ PATH_AGATHA_TO_FORSAKEN
@ SPELL_RIDE_REVERSE_CAST_NO_ESCAPE
@ POINT_AGATHA_BACK_FRONTYARD
@ SPELL_GENERAL_TRIGGER_84079
@ SPELL_GENERAL_TRIGGER_84107
@ SPELL_GENERAL_TRIGGER_84114
@ SPELL_BOND_OF_THE_VALKYR
@ TALK_AGATHA_POST_EVENT1
@ SPELL_MARK_MASTER_AS_DESUMMONED
@ EVENT_ACTOR_FENRIS_MORPH
@ SPELL_CONVERSATION_TRIGGER_84077
@ EVENT_MAGISTRATE_ANIMATION
@ EVENT_ACTOR_FENRIS_DRINK
@ EVENT_ROCKA_CHOOSE_CONVERSATION
@ EVENT_ROCKA_CONVERSATION_COOLDOWN
@ EVENT_ROCKA_CHECK_CONVERSATION
@ SPELL_RISE_FORSAKEN_FENRIS
@ NPC_MUTANT_BUSH_CHICKEN
@ EVENT_GRAB_BUSH_CHICKEN
@ EVENT_BUSH_CHICKEN_CHANGE_SITS
@ SOUND_CHICKEN_MOUNT_WOUND
@ SPELL_RELEASE_BUSH_CHICKEN
@ EVENT_BUSH_CHICKEN_BLASTS
@ SPELL_RIDE_REVERSE_CAST_ITS_POISONOUS
@ EVENT_AFTER_GRABBING_BUSH_CHICKEN
@ ACTION_DESCEND_AFTER_RAISE
@ ACTION_RISE_DURING_RAISE
@ WAYPOINT_ON_CROWLEY_DESPAWN
@ SPELL_DESPAWN_ALL_SUMMONS_STEEL_THUNDER
@ EVENT_ORC_PUP_DELIVER_CRATES
@ EVENT_ORC_PUP_JUST_SUMMONED
@ EVENT_ORC_PUP_REMOVE_PROTECTION
@ TALK_ORC_PUP_DELIVER_CRATES
@ SPELL_EJECT_ALL_PASSENGERS
@ NPC_BLOODFANG_SCAVENGER
@ NPC_MAGISTRATE_HENRY_MALEB
@ TALK_CROWLEY_NO_ESCAPE_2
@ TALK_CROWLEY_NO_ESCAPE_0
@ TALK_CROWLEY_NO_ESCAPE_6
@ TALK_CROWLEY_NO_ESCAPE_5
@ EVENT_CROWLEY_ANIMATION_FENRIS
@ SPELL_ARMORE_CAMERA_FENRIS
@ TALK_CROWLEY_NO_ESCAPE_4
@ SPELL_CONVERSATION_TRIGGER_84076
@ TALK_CROWLEY_NO_ESCAPE_1
@ TALK_CROWLEY_NO_ESCAPE_3
@ SPELL_KILL_CREDIT_YORICK
@ SPELL_EJECT_PASSENGER_01
@ PATH_BLOODFANG_WITH_YORICK
@ TALK_CROWLEY_EXSANGUINATE_3
@ TALK_CROWLEY_EXSANGUINATE_0
@ SPELL_SUMMON_CROWLEY_BLOODFANG_MASTER
@ TALK_BLOODFANG_EXSANGUINATE_7
@ TALK_CROWLEY_EXSANGUINATE_6
@ TALK_BLOODFANG_EXSANGUINATE_2
@ TALK_CROWLEY_EXSANGUINATE_2
@ NPC_DEATHSTALKER_RANE_YORICK
@ TALK_BLOODFANG_EXSANGUINATE_1
@ TALK_BLOODFANG_EXSANGUINATE_6
@ TALK_BLOODFANG_EXSANGUINATE_0
@ TALK_CROWLEY_EXSANGUINATE_4
@ SPELL_ARMOIRE_CAMERA_ON_BLOODFANG
@ EVENT_ACTION_SCENE_EXSANGUINATE
@ TALK_CROWLEY_EXSANGUINATE_5
@ NPC_LORD_DARIUS_CROWLEY
@ TALK_BLOODFANG_EXSANGUINATE_5
@ TALK_CROWLEY_EXSANGUINATE_1
@ EVENT_FINISH_SCENE_EXSANGUINATE
@ TALK_YORICK_EXSANGUINATE_DEATH
@ TALK_BLOODFANG_EXSANGUINATE_10
@ TALK_BLOODFANG_EXSANGUINATE_9
@ PATH_BLOODFANG_NEAR_YORICK
@ EVENT_SWITCH_SCENE_CAMERA
@ EVENT_START_SCENE_EXSANGUINATE
@ EVENT_TALK_SCENE_EXSANGUINATE
@ SPELL_ARMOIRE_CAMERA_ON_CROWLEY
@ TALK_BLOODFANG_EXSANGUINATE_4
@ SPELL_RIDE_REVERSE_CAST_EXSANGUINATE
@ TALK_BLOODFANG_EXSANGUINATE_8
@ TALK_BLOODFANG_EXSANGUINATE_3
@ SPELL_DESPAWN_ALL_SUMMONS_AGATHA
@ NPC_FORSAKEN_WARHORSE_SERVERSIDE
@ SPELL_SUMMON_FORSAKEN_WARHORSE_SERVERSIDE
@ SPELL_APPLY_INVIS_ZONE_1
@ SPELL_APPLY_INVIS_ZONE_4
@ SPELL_NOTIFY_AGATHA_FENRIS
@ SPELL_TROOPER_MASTERSCRIPT_FENRIS
@ SPELL_SUMMON_AGATHA_FENRIS
@ SPELL_FORCE_CAST_FENRIS_CAMERA
@ NPC_FENRIS_KEEP_STALKER
Position const AgathaPreResetPos
@ TALK_SYLVANAS_COMETH_7
@ POINT_AGATHA_PRE_RESET
@ QUEST_THE_WARCHIEF_COMETH
@ SPELL_RAISE_FORSAKEN_COMETH
@ EVENT_SUMMON_PORTAL_COMETH
@ TALK_SYLVANAS_COMETH_8
@ ACTION_START_SCENE_COMETH
@ TALK_SYLVANAS_COMETH_4
@ TALK_GARROSH_COMETH_3
@ TALK_SYLVANAS_COMETH_10
@ TALK_GARROSH_COMETH_9
@ TALK_SYLVANAS_COMETH_3
@ TALK_SYLVANAS_COMETH_1
@ TALK_SYLVANAS_COMETH_6
@ SPELL_SIMPLE_TELEPORT
@ SPELL_WELCOME_TO_SILVERPINE_CREDIT
@ TALK_SYLVANAS_COMETH_0
@ TALK_GARROSH_COMETH_7
@ NPC_GRAND_EXECUTOR_MORTUUS
@ POINT_AGATHA_PRE_RISE
@ EVENT_SUMMON_GARROSH_COMETH
@ SPELL_AIR_REVENANT_ENTRANCE
@ TALK_SYLVANAS_COMETH_9
@ EVENT_START_SCENE_COMETH
@ EVENT_SCENE_TALK_COMETH
@ TALK_CROMUSH_COMETH_0
@ TALK_GARROSH_COMETH_0
@ NPC_HIGH_WARLORD_CROMUSH_COMETH
@ NPC_PORTAL_FROM_ORGRIMMAR
@ NPC_FORSAKEN_WARHORSE_UNPHASED
@ TALK_SYLVANAS_COMETH_2
@ NPC_QUEST_MONSTER_CREDIT
@ TALK_CROMUSH_COMETH_1
@ TALK_GARROSH_COMETH_8
@ TALK_GARROSH_COMETH_1
@ NPC_FEMALE_FALLEN_HUMAN
@ TALK_GARROSH_COMETH_6
@ NPC_MALE_FALLEN_HUMAN
@ NPC_GARROSH_HELLSCREAM
@ TALK_SYLVANAS_COMETH_5
@ TALK_GARROSH_COMETH_10
@ TALK_GARROSH_COMETH_4
@ NPC_LADY_SYLVANAS_WINDRUNNER_COMETH
@ TALK_GARROSH_COMETH_5
@ NPC_HELLSCREAM_ELITE_COMETH
@ EVENT_AGATHA_RAISE_FORSAKEN
@ TALK_GARROSH_COMETH_2
@ SPELL_KILL_CREDIT_SEA_DOG_CRATE
Position const CameraFrontyardPos
Position const HellscreamElitePos[16]
@ EVENT_WEBBEB_ORC_CHECK_PLAYER
@ ANIMKIT_MATRIARCH_INTERACT
@ EVENT_SUMMON_SPIDERLINGS
@ ANIMKIT_MATRIARCH_HANGING_BY_WEB
@ ANIMKIT_MATRIARCH_LURKING_ON_CEILING
@ SPELL_SUMMNON_SPIDERLINGS
@ QUEST_LOST_IN_THE_DARKNESS
@ ACTION_WORMCRUD_START_CONVERSATION
@ QUEST_DEEPER_INTO_DARKNESS
@ ACTION_HATCHET_START_CONVERSATION
@ QUEST_ITS_ONLY_POISONOUS_IF_YOU_INGEST_IT
@ NPC_APOTHECARY_WORMCRUD
@ WAYPOINT_LAST_POINT_AROUND_LAKE
@ WAYPOINT_LAST_POINT_TO_HOME
@ SPELL_BLIGHT_CONCOCTION
@ EVENT_CHECK_FINISH_ITERATING
@ DATA_ITERATING_UPON_SUCCESS_QUEST_REQ
@ WAYPOINT_LAST_POINT_TO_LAKE
@ TALK_BAT_ARRIVED_TO_ISLE
@ NPC_BAT_HANDLER_MAGGOTBREATH
@ EVENT_START_MOVEMENT_ITERATING
@ EVENT_GO_HOME_ITERATING
@ SPELL_SUMMON_FORSAKEN_BAT
@ QUEST_ITERATING_UPON_SUCCESS
@ TALK_MAGGOTHBREATH_ITERATING_UPON_SUCCESS
@ DATA_GOSSIP_MENU_MAGGOT
@ SPELL_CHAIN_LEFT_HAULER
@ SPELL_CHAIN_RIGHT_HAULER
@ SPELL_SUMMON_FENRIS_ACTORS
@ SPELL_GENERAL_TRIGGER_84102
@ EVENT_MOVE_TO_START_POINT
@ SPELL_DESPAWN_ALL_SUMMONS_FENRIS
@ SEAT_FENRIS_CAMERA_FORCE
@ EVENT_SCENE_FINISH_FENRIS
Position const AgathaResetPos
SpellForsakenTrooperMasterScriptFenrisIsle
@ SPELL_FORSAKEN_TROOPER_MALE_04_F
@ SPELL_FORSAKEN_TROOPER_MALE_03_F
@ SPELL_FORSAKEN_TROOPER_MALE_01_F
@ SPELL_FORSAKEN_TROOPER_FEMALE_03_F
@ SPELL_FORSAKEN_TROOPER_MALE_02_F
@ SPELL_FORSAKEN_TROOPER_FEMALE_01_F
@ SPELL_FORSAKEN_TROOPER_FEMALE_02_F
@ SPELL_FORSAKEN_TROOPER_FEMALE_04_F
@ EVENT_FACE_TOWARDS_SYLVANAS
@ EVENT_EMOTE_TO_SYLVANAS
@ EVENT_TRANSFORM_INTO_FORSAKEN
@ SPELL_FORSAKEN_TROOPER_MS_COMETH
@ EVENT_HATCHET_CONVERSATION_COOLDOWN
@ SPELL_DESPAWN_ALL_SUMMONS_LOST_IN_DARKNESS
@ SPELL_SUMMON_ORC_SEA_PUP
@ EVENT_HATCHET_CHECK_CONVERSATION
@ SPELL_SUMMON_DEATHSTALKER_YORICK
@ QUEST_WAITING_TO_EXSANGUINATE
@ WAYPOINT_ON_BLOODFANG_DESPAWN
@ SPELL_FREE_WEBBED_VICTIM_RANDOM
@ SPELL_FREE_WEBBED_VICTIM
@ NPC_DRUNKEN_ORC_SEA_DOG
@ EVENT_WORMCRUD_CHOOSE_CONVERSATION
@ EVENT_WORMCRUD_CHECK_CONVERSATION
@ EVENT_WORMCRUD_CONVERSATION_COOLDOWN
Position const GarroshPos
Position const CromushPos
Position const AgathaBackFrontyardPos
Position const AgathaRisePos
Position const OrgrimmarPortalPos[3]