TrinityCore
Loading...
Searching...
No Matches
boss_anduin_wrynn.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 "AreaTrigger.h"
19#include "AreaTriggerAI.h"
20#include "Containers.h"
21#include "Conversation.h"
22#include "CreatureAI.h"
23#include "CreatureAIImpl.h"
24#include "DB2Structure.h"
25#include "G3DPosition.hpp"
26#include "GameObject.h"
27#include "GameObjectAI.h"
28#include "GridNotifiers.h"
29#include "InstanceScript.h"
30#include "Map.h"
31#include "MapUtils.h"
32#include "MotionMaster.h"
33#include "ObjectAccessor.h"
34#include "PathGenerator.h"
35#include "Player.h"
36#include "ScriptMgr.h"
37#include "ScriptedCreature.h"
38#include "SpellAuraEffects.h"
39#include "SpellAuras.h"
40#include "SpellMgr.h"
41#include "SpellScript.h"
42#include "TemporarySummon.h"
44
46{
47 // Pre-Introduction
49
50 // Generic Spells
60
61 // Dark Zeal
64
65 // Hopebreaker
71
72 // Domination Word: Pain
74
75 // Befouled Barrier
83
84 // Blasphemy
96
97 // Kingsmourne Hungers
115
116 // Rain of Despair (Big add)
122
123 // Wicked Star
132
133 // Empowered Wicked Star
138
139 // Force of Will
142
143 // Fiendish Soul
149
150 // Monstrous Soul
154
155 // Grim Reflections
163
164 // Beacon of Hope
167
168 // Fragment of Hope
172
173 // Purging Light
175
176 // Hopelessness
181
182 // Empowered Hopebreaker
185
186 // Anduin's Soul
189
190 // Anduin's Hope
192 SPELL_GLOOM = 364031,
193
194 // Anduin's Doubt
196
197 // Remnant of a Fallen King
209
210 // Remorseless Winter
215
216 // Army of the Dead
221
222 // March of the Damned
228
229 // Soul Reaper
235
236 // Finish Encounter
240
241 // Berserk
243
244 // Jaina Spells
245 SPELL_BLINK = 362844,
248
249 // Sylvanas Spells
251 SPELL_TUMBLE = 364069,
252
253 // Uther Spells
256
257 // Translocators Teleport
260};
261
268
321
345
364
373
378
386
396
401
403{
404 { -3826.9548f, -2626.2761f, 78.9296f, 4.644121f }, // Jaina
405 { -3831.6807f, -2626.2761f, 78.9296f, 5.460620f }, // Uther
406 { -3818.7300f, -2626.2800f, 78.9296f, 4.558697f }, // Sylvanas
407};
408
409//constexpr Position FirimOutroductionPos = { -3830.0156f, -2676.7969f, 91.56402f };
410constexpr Position QuartermasterRahmPos = { -3824.9565f, -2673.0190f, 91.44697f, 4.7163963f };
411constexpr Position LeftKnightPosition = { -3815.4097f, -2677.1824f, 91.44697f, 4.742376f };
412constexpr Position RightKnightPosition = { -3834.6807f, -2677.42360f, 91.44697f, 4.6956997f };
413
414constexpr Position DominationGraspCenter = { -3825.0601f, -2715.4600f, 91.3567f, 1.6260f };
415
417{
418 { -3828.472f, -2688.191f, 91.2652f, 1.9153f }, // Sylvanas
419 { -3819.519f, -2687.170f, 91.2652f, 2.1812f }, // Uther
420 { -3824.960f, -2692.550f, 91.2652f, 1.5733f }, // Jaina
421};
422
423constexpr Position AnduinsDespairSpawnPosition = { -3828.355957f, -2704.1875f, 91.350716f, 4.982021f };
424
425constexpr Position AnduinsSoulSpawnPosition = { -3825.060059f, -2715.459961f, 91.356697f, 1.626040f };
426
428{
429 { -3852.638916f, -2687.373291f, 91.348526f, 5.560700f }, // Right of Uther
430 { -3852.845459f, -2742.732666f, 91.348534f, 0.961583f }, // Next Right
431 { -3797.704834f, -2686.685791f, 91.348526f, 3.804689f }, // Left of Sylvanas
432 { -3799.805664f, -2740.925293f, 91.348541f, 2.247305f }, // Next Left
433};
434
436{
437 { -3825.149414f, -2711.508789f, 91.354919f, 1.463445f }, // In front of Anduin
438 { -3828.751709f, -2715.171875f, 91.354919f, 3.221487f }, // Left of Anduin
439 { -3821.041748f, -2715.296875f, 91.354889f, 0.046978f }, // Right of Anduin
440 { -3825.180664f, -2719.208252f, 91.354820f, 4.741285f }, // Behind Anduin
441};
442
443constexpr Position RemnantOfAFallenKingSpawnPosition = { -3825.2466f, -2700.0486f, 91.3650f, 1.3762f };
444
446{
447 { -3825.389f, -2739.4202f, 91.431305f, 4.8445f}, // back side of Anduin
448 { -3849.8438f, -2715.0574f, 91.40953f, 2.9961f}, // left side of Anduin
449 { -3825.4966f, -2692.6199f, 91.487495f, 1.4654f}, // in front of Anduin
450 { -3800.6980f, -2715.4340f, 91.390780f, 6.2769f}, // right side of Anduin
451};
452
454{
455 { -3839.8489f, -2679.7708f, 91.53031f, 5.1081f }, // First right
456 { -3860.8940f, -2701.0051f, 91.53032f, 5.9010f }, // Second Right
457 { -3860.5696f, -2729.7344f, 91.53032f, 0.3886f }, // Third Right
458 { -3839.6390f, -2750.8890f, 91.53032f, 1.1935f }, // Fourth Right
459 { -3811.0625f, -2679.6528f, 91.53031f, 4.3362f }, // First left
460 { -3789.8125f, -2700.5088f, 91.53032f, 3.5383f }, // Second Left
461 { -3789.2812f, -2729.3160f, 91.53032f, 2.7669f }, // Third Left
462 { -3810.4290f, -2751.0903f, 91.53032f, 1.9584f } // Fourth Left
463};
464
465constexpr Position BeaconOfHopeSpawnPosition = { -3825.0417f, -2715.3923f, 91.3568f, 0.0f };
466
467constexpr Position ChestLootSpawnPosition = { -3840.9915f, -2741.7847f, 91.26521f, 1.334929f };
468
470{
471public:
473 : _summonerGuid(summoner->GetGUID()), _owner(owner) { }
474
475 bool Execute(uint64 /*time*/, uint32 /*diff*/) override
476 {
478 {
479 if (Unit* target = _summoner->AI()->SelectTarget(SelectTargetMethod::Random, 0))
480 {
482 _owner->AI()->AttackStart(target);
483 }
484 }
485 return true;
486 }
487
488private:
491};
492
493// 181954 - Anduin Wrynn
495{
498
515
517 {
519 {
521 sylvanas->AttackStop();
522 sylvanas->SetSheath(SHEATH_STATE_RANGED);
523 sylvanas->SetEmoteState(EMOTE_STATE_READY_BOW);
524 }
525
527 {
529 uther->AttackStop();
530 uther->SetSheath(SHEATH_STATE_MELEE);
531 uther->SetEmoteState(EMOTE_STATE_READY2H);
532 }
533
535 {
537 jaina->AttackStop();
538 jaina->SetSheath(SHEATH_STATE_RANGED);
539 jaina->SetEmoteState(EMOTE_STATE_READY2H);
540 }
541 }
542
544 {
546 if (!remnant)
547 return;
548
549 auto forceAttack = [this, remnant](uint32 data)
550 {
551 Creature* creature = instance->GetCreature(data);
552 if (!creature)
553 return;
554
555 creature->AI()->AttackStart(remnant);
557 };
558
561 forceAttack(DATA_JAINA_PROUDMOORE_ANDUIN);
562 }
563
565 {
567 rahm->NearTeleportTo(QuartermasterRahmPos);
568
569 std::list<Creature*> knights;
570 me->GetCreatureListWithOptionsInGrid(knights, 150.0f, { .CreatureId = NPC_KNIGHT_OF_EBON_BLADE_ANDUIN });
571
572 for (Creature* knight : knights)
573 {
574 if (knight->HasStringId("left_knight"))
575 knight->NearTeleportTo(LeftKnightPosition);
576 else
577 knight->NearTeleportTo(RightKnightPosition);
578 }
579 }
580
596
609
622
623 void Reset() override
624 {
625 _Reset();
628
629 _slayTextOnCooldown = false;
631 _encounterEnded = false;
632 }
633
634 void KilledUnit(Unit* victim) override
635 {
636 if (_slayTextOnCooldown == false && !victim->IsPlayer())
637 {
638 Talk(SAY_SLAY);
639 _slayTextOnCooldown = true;
640 scheduler.Schedule(3s, [this](TaskContext const& /*task*/)
641 {
642 _slayTextOnCooldown = false;
643 });
644 }
645 }
646
647 void JustSummoned(Creature* summon) override
648 {
649 summons.Summon(summon);
650
651 switch (summon->GetEntry())
652 {
654 {
656 summon->CastSpell(summon, SPELL_BEFOULED_ERUPTION, true);
658 summon->CastSpell(summon, SPELL_BEFOULED_BARRIER_BLACK_RING, true);
659 break;
660 }
661
663 {
665 summon->SetUninteractible(true);
666 summon->CastSpell(summon, SPELL_REMNANT_SPAWN);
667 break;
668 }
669
671 {
672 float marchSpeed = 0.0f;
673 switch (me->GetMap()->GetDifficultyID())
674 {
678 marchSpeed = 0.40f;
679 break;
681 marchSpeed = 0.60f;
682 break;
683 default:
684 marchSpeed = 0.40f;
685 break;
686 }
687
688 summon->SetSpeedRate(MOVE_RUN, marchSpeed);
691 scheduler.Schedule(1s, [summon](TaskContext const& /*task*/)
692 {
693 Position exitPlatform = summon->GetFirstCollisionPosition(100.0f, summon->GetAbsoluteAngle(summon));
694 summon->GetMotionMaster()->MovePoint(POINT_MARCH_OF_THE_DAMNED, exitPlatform, false, summon->GetOrientation());
695 });
696 break;
697 }
698
700 {
703 break;
704 }
705
706 default:
707 break;
708 }
709 }
710
711 void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
712 {
713 if (summon->GetEntry() == NPC_GRIM_REFLECTION)
714 summon->DespawnOrUnsummon(3s);
715 }
716
725
726 void DoAction(int32 action) override
727 {
728 switch (action)
729 {
731 {
732 auto teleportNamed = [this](uint32 data, Position const& position)
733 {
734 Creature* creature = instance->GetCreature(data);
735 if (!creature)
736 return;
737
738 creature->NearTeleportTo(position);
739 creature->CastSpell(creature, SPELL_BROKER_SPAWN, true);
740 };
741
745 break;
746 }
748 {
749 auto castBrokerSpawn = [this](uint32 data)
750 {
751 Creature* creature = instance->GetCreature(data);
752 if (!creature)
753 return;
754
755 creature->CastSpell(creature, SPELL_BROKER_SPAWN, true);
756 };
757
758 castBrokerSpawn(DATA_UTHER_THE_LIGHTBRINGER_ANDUIN);
759 castBrokerSpawn(DATA_SYLVANAS_WINDRUNNER_ANDUIN);
760 castBrokerSpawn(DATA_JAINA_PROUDMOORE_ANDUIN);
761 break;
762 }
764 {
766 scheduler.Schedule(1ms, [this](TaskContext const& /*task*/)
767 {
769 if (!uther)
770 return;
771
773 if (!sylvanas)
774 return;
775
777 if (!jaina)
778 return;
779
781 if (!conversation)
782 return;
783
784 conversation->AddActor(NPC_UTHER_THE_LIGHTBRINGER_ANDUIN, 1, uther->GetGUID());
785 conversation->AddActor(NPC_SYLVANAS_WINDRUNNER_ANDUIN, 2, sylvanas->GetGUID());
786 conversation->AddActor(NPC_LADY_JAINA_PROUDMOORE_ANDUIN, 3, jaina->GetGUID());
787 conversation->Start();
788 });
789
790 scheduler.Schedule(35s, [this](TaskContext const& /*task*/)
791 {
794 });
795 break;
796 }
798 {
800 bolvar->GetMotionMaster()->MovePath(PATH_OUTRODUCTION_BOLVAR, false);
801
803 thrall->GetMotionMaster()->MovePath(PATH_OUTRODUCTION_THRALL, false);
804
805 scheduler.Schedule(10s, [this](TaskContext const& /*task*/)
806 {
808 });
809 break;
810 }
812 {
814 if (!uther)
815 break;
816
818 if (!sylvanas)
819 break;
820
822 if (!jaina)
823 break;
824
826 if (!firim)
827 break;
828
830
832 if (!conversation)
833 break;
834
835 conversation->AddActor(NPC_LADY_JAINA_PROUDMOORE_ANDUIN, 1, jaina->GetGUID());
836 conversation->AddActor(NPC_SYLVANAS_WINDRUNNER_ANDUIN, 2, sylvanas->GetGUID());
837 conversation->AddActor(NPC_UTHER_THE_LIGHTBRINGER_ANDUIN, 3, uther->GetGUID());
838 conversation->AddActor(NPC_FIRIM_ANDUIN, 4, firim->GetGUID());
839 conversation->Start();
840 break;
841 }
843 {
846 {
848 {
849 conversation->AddActor(NPC_UTHER_THE_LIGHTBRINGER_ANDUIN, 1, uther->GetGUID());
850 conversation->Start();
851 }
852 }
853 break;
854 }
856 {
859 {
861 {
862 conversation->AddActor(NPC_SYLVANAS_WINDRUNNER_ANDUIN, 1, sylvanas->GetGUID());
863 conversation->Start();
864 }
865 }
866 break;
867 }
869 {
870 if (_intermissionsDone == 0)
871 {
873 scheduler.Schedule(3s, [this](TaskContext const& /*task*/)
874 {
876 });
877 }
878 else if (_intermissionsDone == 1)
879 {
881 scheduler.Schedule(6s, [this](TaskContext const& /*task*/)
882 {
884 });
885 }
886 break;
887 }
889 {
890 EndEncounter();
891 break;
892 }
893 default:
894 break;
895 }
896 }
897
898 void UpdateAI(uint32 diff) override
899 {
900 scheduler.Update(diff);
901
902 if (!UpdateVictim())
903 return;
904
905 Unit* victim = me->GetVictim();
906 if (victim && !victim->IsPlayer())
907 {
909 return;
910 }
911
912 events.Update(diff);
913
915 return;
916
917 while (uint32 eventId = events.ExecuteEvent())
918 {
919 switch (eventId)
920 {
922 {
925 break;
926 }
928 {
931 if (IsMythic())
932 events.Repeat(65500ms);
933 else
934 events.Repeat(58400ms);
935 break;
936 }
938 {
940 break;
941 }
943 {
946 break;
947 }
948 case EVENT_BLASPHEMY:
949 {
953 break;
954 }
956 {
959 if (IsMythic())
960 events.Repeat(65500ms);
961 else
962 events.Repeat(58500ms);
963 break;
964 }
966 {
970 events.Repeat(58500ms);
971 break;
972 }
974 {
977 if (IsMythic())
978 events.Repeat(65500ms);
979 else
980 events.Repeat(58500ms);
981 break;
982 }
984 {
988 break;
989 }
991 {
994 break;
995 }
997 {
999 break;
1000 }
1002 {
1004 break;
1005 }
1007 {
1009 break;
1010 }
1011 case EVENT_BERSERK:
1012 {
1014 break;
1015 }
1016 default:
1017 break;
1018 }
1019
1021 return;
1022 }
1023 }
1024
1025 void StartIntermission(uint8 intermissionNum)
1026 {
1027 auto SpawnRemnant = [this](TaskContext const& /*task*/)
1028 {
1031 };
1032
1033 Seconds timeOffset = intermissionNum * 1s;
1034
1035 scheduler.Schedule(1ms, [this](TaskContext const& /*task*/)
1036 {
1040 });
1041
1042 scheduler.Schedule(1204ms + timeOffset, [this, intermissionNum](TaskContext const& /*task*/)
1043 {
1045 });
1046
1047 scheduler.Schedule(2204ms + timeOffset, [this](TaskContext const& /*task*/)
1048 {
1049 me->SetFacingTo(1.626040f);
1050 });
1051
1052 scheduler.Schedule(4s + timeOffset, [this](TaskContext const& /*task*/)
1053 {
1057
1059 {
1062 }
1063 });
1064
1065 scheduler.Schedule(5s + timeOffset, SpawnRemnant);
1066
1067 scheduler.Schedule(6s + timeOffset, SpawnRemnant);
1068
1069 scheduler.Schedule(7s + timeOffset, SpawnRemnant);
1070
1071 scheduler.Schedule(8s + timeOffset, [this, intermissionNum](TaskContext const& /*task*/)
1072 {
1073 if (intermissionNum == 1 || IsMythic())
1075
1077 {
1079 arthas->SetImmuneToAll(false);
1081 }
1082 });
1083 }
1084
1085 void PhaseEvents(uint8 phase)
1086 {
1087 events.Reset();
1088
1089 switch (phase)
1090 {
1091 case PHASE_ONE:
1092 {
1094 events.ScheduleEventSeries(EVENT_HOPEBREAKER, { 5s, 31900ms, 28s, 29900ms, 29900ms });
1095 events.ScheduleEventSeries(EVENT_BEFOULED_BARRIER, { 17s, 51900ms, 48s });
1096 events.ScheduleEventSeries(EVENT_BLASPHEMY, { 30s, 49900ms, 54900ms });
1097 events.ScheduleEventSeries(EVENT_WICKED_STAR, { 55s, 35s, 30s });
1098 events.ScheduleEventSeries(EVENT_DOMINATION_WORD_PAIN, { 7s, 13s, 13s, 10s, 15s, 13100ms, 12900ms, 13s, 13900ms, 12200ms, 14800ms });
1101
1102 if (IsLFR())
1104 else
1106 break;
1107 }
1108
1109 case PHASE_TWO:
1110 {
1112 me->ModifyPower(me->GetPowerType(), 0);
1117
1118 if (!IsMythic())
1119 {
1120 events.ScheduleEventSeries(EVENT_DOMINATION_WORD_PAIN, { 11500ms, 13s, 13s, 17700ms, 8100ms, 13s, 13s, 14400ms, 11200ms, 12200ms });
1121 events.ScheduleEventSeries(EVENT_HOPEBREAKER, { 13600ms, 22s, 33300ms, 29s, 29s });
1122 events.ScheduleEventSeries(EVENT_WICKED_STAR, { 18500ms, 39s, 26s, 30500ms, 19s });
1123 }
1124 else
1125 {
1126 events.ScheduleEventSeries(EVENT_DOMINATION_WORD_PAIN, { 10700ms, 13s, 13s, 17700ms, 8100ms, 13s, 13s, 14400ms, 11200ms, 12200ms });
1127 events.ScheduleEventSeries(EVENT_HOPEBREAKER, { 13600ms, 25s, 33s, 29s, 29100ms });
1128 events.ScheduleEventSeries(EVENT_WICKED_STAR, { 18500ms, 39s, 26s, 30900ms, 19100ms });
1129 }
1130
1131 if (IsLFR())
1133 else
1135 break;
1136 }
1137
1138 case PHASE_THREE:
1139 {
1141 me->ModifyPower(me->GetPowerType(), 0);
1147
1148 if (!IsMythic())
1150 else
1152 break;
1153 }
1154 default:
1155 break;
1156 }
1157 }
1158
1159 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1160 {
1161 if (_intermissionsDone < 2 && me->HealthBelowPctDamaged(10, damage))
1162 {
1165 scheduler.Schedule(6s, [this](TaskContext const& /*task*/)
1166 {
1168 });
1169
1173
1174 std::list<Creature*> fiendishSouls;
1175 GetCreatureListWithEntryInGrid(fiendishSouls, me, NPC_FIENDISH_SOUL, 50.0f);
1176
1177 for (Creature* fiends : fiendishSouls)
1178 {
1179 fiends->CastSpell(fiends, SPELL_SOUL_DESPAWN);
1180 fiends->DespawnOrUnsummon(500ms);
1181 }
1182
1183 std::list<Creature*> marches;
1185
1186 for (Creature* march : marches)
1187 march->DespawnOrUnsummon();
1188
1190 remnant->GetAI()->DoAction(ACTION_DESPAWN_REMNANT);
1191 }
1192 }
1193
1224
1225private:
1229};
1230
1231// 184830 - Beacon of Hope
1233{
1235
1236 void JustUnregisteredAreaTrigger(AreaTrigger* areaTrigger) override
1237 {
1238 switch (areaTrigger->GetSpellId())
1239 {
1241 {
1242 if (!areaTrigger->GetInsideUnits().empty())
1243 break;
1244
1245 InstanceScript* instance = me->GetInstanceScript();
1246 if (!instance)
1247 break;
1248
1249 if (Creature* beacon = instance->GetCreature(DATA_BEACON_OF_HOPE))
1250 beacon->CastSpell(beacon, SPELL_FRAGMENT_OF_HOPE_DAMAGE, true);
1251 break;
1252 }
1253 default:
1254 break;
1255 }
1256 }
1257};
1258
1259// 183452 - Empty Vessel
1261{
1263
1264 void JustAppeared() override
1265 {
1267 }
1268
1269 void IsSummonedBy(WorldObject* summoner) override
1270 {
1271 if (!summoner->IsPlayer())
1272 return;
1273
1274 summoner->CastSpell(me, SPELL_MIRROR_IMAGE);
1276 }
1277};
1278
1279// 185607 - Lost Soul
1281{
1283
1284 void JustAppeared() override
1285 {
1288 }
1289
1290 void IsSummonedBy(WorldObject* summoner) override
1291 {
1292 if (!summoner->IsPlayer())
1293 return;
1294
1296 }
1297
1298 void JustDied(Unit* /*killer*/) override
1299 {
1300 TempSummon* summon = me->ToTempSummon();
1301 if (!summon)
1302 return;
1303
1304 if (Unit* summoner = summon->GetSummonerUnit())
1305 {
1307 summoner->NearTeleportTo(me->GetPosition());
1308 }
1309 me->DespawnOrUnsummon(2s);
1310 }
1311
1312 void Reset() override
1313 {
1314 _events.Reset();
1315 }
1316
1317 void UpdateAI(uint32 diff) override
1318 {
1319 UpdateVictim();
1320
1321 _events.Update(diff);
1322
1324 return;
1325
1326 while (uint32 eventId = _events.ExecuteEvent())
1327 {
1328 switch (eventId)
1329 {
1330 case EVENT_BANISH_SOUL:
1331 {
1333 _events.Repeat(1ms);
1334 break;
1335 }
1336 default:
1337 break;
1338 }
1339 }
1340 }
1341
1342private:
1344};
1345
1346// 184519 - Anduin's Soul
1348{
1351
1353 {
1354 if (_hopeRestored == 4 && _doubtGone == 4 && _despairGone == 1)
1355 {
1357 _hopeRestored = 0;
1358 _doubtGone = 0;
1359 _despairGone = 0;
1360 }
1361 }
1362
1363 void JustAppeared() override
1364 {
1365 me->SetDisableGravity(true, true);
1366 me->SetHoverHeight(1.0);
1368 }
1369
1370 void Reset() override
1371 {
1374 }
1375
1376 void JustSummoned(Creature* who) override
1377 {
1378 _summons.Summon(who);
1379 }
1380
1381 void JustDied(Unit* /*killer*/) override
1382 {
1384 }
1385
1386 void EnterEvadeMode(EvadeReason /*why*/) override
1387 {
1390 }
1391
1392 void DoAction(int32 action) override
1393 {
1394 InstanceScript* instance = me->GetInstanceScript();
1395 if (!instance)
1396 return;
1397
1398 Creature* anduin = instance->GetCreature(DATA_ANDUIN_SOUL);
1399 if (!anduin)
1400 return;
1401
1402 switch (action)
1403 {
1405 {
1407 for (uint8 i = 0; i < 4; i++)
1408 {
1411 }
1412 break;
1413 }
1415 _despairGone++;
1417 break;
1418
1419 case ACTION_DOUBT_GONE:
1420 _doubtGone++;
1422 break;
1423
1425 _hopeRestored++;
1427 break;
1428
1429 default:
1430 break;
1431 }
1432 }
1433
1434public:
1439};
1440
1441// 184520 - Anduin's Despair
1443{
1445 _instance(creature->GetInstanceScript()) { }
1446
1452
1453 void JustDied(Unit* /*killer*/) override
1454 {
1456
1458 soul->GetAI()->DoAction(ACTION_DESPAIR_GONE);
1459 }
1460
1461private:
1463};
1464
1465// 184494 - Anduin's Doubt
1467{
1469
1477
1478 void JustDied(Unit* /*killer*/) override
1479 {
1482
1484 soul->GetAI()->DoAction(ACTION_DOUBT_GONE);
1485 }
1486
1487 void UpdateAI(uint32 /*diff*/) override
1488 {
1489 UpdateVictim();
1490 }
1491};
1492
1493// 184493 - Anduin's Hope
1495{
1497 _instance(creature->GetInstanceScript()) { }
1498
1499 void Reset() override
1500 {
1501 me->SetRegenerateHealth(false);
1502 me->SetHealth(1);
1504 }
1505
1506 void JustAppeared() override
1507 {
1509 me->SetWalk(true);
1511 if (IsHeroic() || IsMythic())
1513
1514 _scheduler.Schedule(2s, [this](TaskContext const& /*task*/)
1515 {
1516 Position exitPlatform = me->GetFirstCollisionPosition(100.0f, 0);
1517 me->GetMotionMaster()->MovePoint(POINT_ESCAPE_PLATFORM, exitPlatform, false, me->GetOrientation());
1518 });
1519 me->SetHealth(1);
1520
1521 _scheduler.Schedule(40s, [this](TaskContext const& /*task*/)
1522 {
1524 });
1525 }
1526
1527 void UpdateAI(uint32 diff) override
1528 {
1529 UpdateVictim();
1530
1531 _scheduler.Update(diff);
1532 }
1533
1534 void HealReceived(Unit* /*healer*/, uint32& heal) override
1535 {
1536 if (me->HealthAbovePctHealed(100, heal))
1537 {
1541
1543 soul->GetAI()->DoAction(ACTION_HOPE_RESTORED);
1544 }
1545 }
1546
1547 void MovementInform(uint32 type, uint32 pointId) override
1548 {
1549 if (type != POINT_MOTION_TYPE)
1550 return;
1551
1552 switch (pointId)
1553 {
1555 {
1557 break;
1558 }
1559 default:
1560 break;
1561 }
1562 }
1563
1564private:
1567};
1568
1569// 183669 - Fiendish Soul
1571{
1573
1574 void JustEngagedWith(Unit* /*who*/) override
1575 {
1578 }
1579
1580 void JustDied(Unit* /*killer*/) override
1581 {
1582 if (IsHeroic() || IsMythic())
1584
1586 }
1587
1588 void EnterEvadeMode(EvadeReason /*why*/) override
1589 {
1591 }
1592
1593 void UpdateAI(uint32 diff) override
1594 {
1595 if (!UpdateVictim())
1596 return;
1597
1598 _events.Update(diff);
1599
1601 return;
1602
1603 while (uint32 eventId = _events.ExecuteEvent())
1604 {
1605 switch (eventId)
1606 {
1607 case EVENT_GHOUL_LEAP:
1608 {
1609 std::list<Player*> targetList;
1610 GetPlayerListInGrid(targetList, me, 50.0f);
1611 if (!targetList.empty())
1613 _events.Repeat(10s);
1614 break;
1615 }
1617 {
1619 _events.Repeat(5s, 10s);
1620 break;
1621 }
1622 default:
1623 break;
1624 }
1625 }
1626 }
1627
1628private:
1630};
1631
1632// 183671 - Monstrous Soul
1634{
1636
1642
1643 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1644 {
1645 if (me->HealthBelowPctDamaged(35, damage))
1647 }
1648
1649 void Reset() override
1650 {
1651 _events.Reset();
1652 }
1653
1654 void DoAction(int32 action) override
1655 {
1656 switch (action)
1657 {
1659 {
1662 break;
1663 }
1664 default:
1665 break;
1666 }
1667 }
1668
1669 void JustDied(Unit* /*killer*/) override
1670 {
1672 }
1673
1679
1680 void UpdateAI(uint32 diff) override
1681 {
1682 if (!UpdateVictim())
1683 return;
1684
1685 _events.Update(diff);
1686
1688 return;
1689
1690 while (uint32 eventId = _events.ExecuteEvent())
1691 {
1692 switch (eventId)
1693 {
1695 {
1698 break;
1699 }
1700 default:
1701 break;
1702 }
1703 }
1704 }
1705
1706private:
1708};
1709
1710// 183463 - Remnant of a Fallen King
1712{
1713 boss_remnant_of_a_fallen_king(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _summons(creature) { }
1714
1715 void JustAppeared() override
1716 {
1719 me->ModifyPower(me->GetPowerType(), 0);
1720 me->SetPower(me->GetPowerType(), 0);
1721 for (MapReference const& players : me->GetMap()->GetPlayers())
1722 {
1723 if (Player* player = players.GetSource())
1724 me->CastSpell(player, SPELL_WEATHER_COSMETIC, true);
1725 }
1728 }
1729
1743
1745 {
1747 sylvanas->GetAI()->AttackStartCaster(me, 25.0f);
1748
1750 uther->GetAI()->AttackStart(me);
1751
1753 jaina->GetAI()->AttackStartCaster(me, 25.0f);
1754 }
1755
1756 void JustSummoned(Creature* summon) override
1757 {
1758 _summons.Summon(summon);
1759
1760 switch (summon->GetEntry())
1761 {
1762 case NPC_FIENDISH_SOUL:
1763 case NPC_MONSTROUS_SOUL:
1765 summon->m_Events.AddEvent(new ActivateGhouls(me, summon), summon->m_Events.CalculateTime(5s));
1766 break;
1767 default:
1768 break;
1769 }
1770 }
1771
1772 void DoAction(int32 action) override
1773 {
1774 switch (action)
1775 {
1777 {
1780
1781 _scheduler.Schedule(1500ms, [this](TaskContext const& /*task*/)
1782 {
1784 me->SetUninteractible(false);
1785 });
1786
1787 _scheduler.Schedule(2s, [this](TaskContext const& /*task*/)
1788 {
1795 });
1796 break;
1797 }
1799 {
1801 _scheduler.Schedule(500ms, [this](TaskContext const& /*task*/)
1802 {
1804 });
1805 break;
1806 }
1807 default:
1808 break;
1809 }
1810 }
1811
1812 void UpdateAI(uint32 diff) override
1813 {
1814 _scheduler.Update(diff);
1815
1816 if (!UpdateVictim())
1817 return;
1818
1819 _events.Update(diff);
1820
1822 return;
1823
1824 while (uint32 eventId = _events.ExecuteEvent())
1825 {
1826 switch (eventId)
1827 {
1829 {
1831 me->AttackStop();
1834 break;
1835 }
1837 {
1840 if (!IsLFR())
1841 _events.Repeat(36900ms);
1842 break;
1843 }
1844 case EVENT_SOUL_REAPER:
1845 {
1847 _events.Repeat(12s);
1848 break;
1849 }
1850 default:
1851 break;
1852 }
1853
1855 return;
1856 }
1857 }
1858
1859private:
1864};
1865
1866// 183033 - Grim Reflection
1868{
1870
1871 void Reset() override
1872 {
1873 _events.Reset();
1874 }
1875
1887
1888 void JustDied(Unit* /*killer*/) override
1889 {
1890 if (IsMythic())
1892 }
1893
1894 void UpdateAI(uint32 diff) override
1895 {
1896 if (!UpdateVictim())
1897 return;
1898
1899 _events.Update(diff);
1900
1902 return;
1903
1904 while (uint32 eventId = _events.ExecuteEvent())
1905 {
1906 switch (eventId)
1907 {
1909 {
1911 _events.Repeat(2s);
1912 break;
1913 }
1915 {
1917 _events.Repeat(1s);
1918 break;
1919 }
1920 default:
1921 break;
1922 }
1923
1925 return;
1926 }
1927 }
1928
1929private:
1931};
1932
1933// 183666 - Sylvanas Windrunner
1935{
1937
1938 void JustAppeared() override
1939 {
1941 me->SetCanMelee(false); // DoSpellAttackIfReady
1942 }
1943
1944 void Reset() override
1945 {
1946 _events.Reset();
1947 }
1948
1949 void JustEngagedWith(Unit* /*who*/) override
1950 {
1952 }
1953
1954 bool CanAIAttack(Unit const* target) const override
1955 {
1957 }
1958
1959 void UpdateAI(uint32 diff) override
1960 {
1961 if (!UpdateVictim())
1962 return;
1963
1964 _events.Update(diff);
1965
1967 return;
1968
1969 while (uint32 eventId = _events.ExecuteEvent())
1970 {
1971 switch (eventId)
1972 {
1973 case EVENT_TUMBLE:
1974 {
1976 _events.Repeat(10s);
1977 break;
1978 }
1979 default:
1980 break;
1981 }
1982 }
1983
1985 }
1986
1987private:
1989};
1990
1991// 183664 - Jaina Proudmoore
1993{
1994 npc_anduin_wrynn_jaina(Creature* creature) : ScriptedAI(creature) { }
1995
1996 void JustAppeared() override
1997 {
1999 me->SetCanMelee(false); // DoSpellAttackIfReady
2000 }
2001
2002 void Reset() override
2003 {
2004 _events.Reset();
2005 }
2006
2007 void JustEngagedWith(Unit* /*who*/) override
2008 {
2010 }
2011
2012 bool CanAIAttack(Unit const* target) const override
2013 {
2015 }
2016
2017 void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override
2018 {
2019 if (pathId != PATH_INTRODUCTION_JAINA)
2020 return;
2021
2023 anduin->GetAI()->DoAction(ACTION_START_INTRODUCTION);
2024 }
2025
2026 void UpdateAI(uint32 diff) override
2027 {
2028 if (!UpdateVictim())
2029 return;
2030
2031 _events.Update(diff);
2032
2034 return;
2035
2036 while (uint32 eventId = _events.ExecuteEvent())
2037 {
2038 switch (eventId)
2039 {
2041 {
2043 break;
2044 }
2045 case EVENT_BLINK:
2046 {
2048 _events.Repeat(60s);
2049 break;
2050 }
2051 default:
2052 break;
2053 }
2054 }
2055
2057 }
2058
2059private:
2061};
2062
2063// 183665 - Uther the Lightbringer
2065{
2066 npc_anduin_wrynn_uther(Creature* creature) : ScriptedAI(creature) { }
2067
2068 void JustAppeared() override
2069 {
2071 }
2072
2073 void Reset() override
2074 {
2075 _events.Reset();
2076 }
2077
2078 void JustEngagedWith(Unit* who) override
2079 {
2082 }
2083
2084 bool CanAIAttack(Unit const* target) const override
2085 {
2087 }
2088
2089 void UpdateAI(uint32 diff) override
2090 {
2091 if (!UpdateVictim())
2092 return;
2093
2094 _events.Update(diff);
2095
2097 return;
2098
2099 while (uint32 eventId = _events.ExecuteEvent())
2100 {
2101 switch (eventId)
2102 {
2104 {
2106 break;
2107 }
2109 {
2111 _events.Repeat(10s);
2112 break;
2113 }
2114 default:
2115 break;
2116 }
2117 }
2118 }
2119
2120private:
2122};
2123
2124// 367524 - Spawn Pre-Introduction
2126{
2127 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
2128 {
2129 Unit* caster = GetCaster();
2130 if (!caster)
2131 return;
2132
2133 switch (caster->GetEntry())
2134 {
2137 break;
2140 break;
2143 break;
2144 default:
2145 break;
2146 }
2147 }
2148
2149 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
2150 {
2151 Unit* caster = GetCaster();
2152 if (!caster)
2153 return;
2154
2155 uint32 pathId = 0;
2156 switch (caster->GetEntry())
2157 {
2159 pathId = PATH_INTRODUCTION_JAINA;
2160 break;
2162 pathId = PATH_INTRODUCTION_UTHER;
2163 break;
2166 break;
2167 default:
2168 break;
2169 }
2170 caster->GetMotionMaster()->MovePath(pathId, false);
2171 }
2172
2178};
2179
2180// 369317 - Anduin Progression Aura (Can't be reduced < 1 hp)
2182{
2183 bool Validate(SpellInfo const* /*spellInfo*/) override
2184 {
2186 }
2187
2188 void CalculateAmount(AuraEffect const* /*aurEff*/, SpellEffectValue& amount, bool& canBeRecalculated)
2189 {
2190 amount = -1;
2191 canBeRecalculated = true;
2192 }
2193
2194 void Trigger(AuraEffect* /*aurEff*/, DamageInfo const& dmgInfo, uint32& absorbAmount)
2195 {
2197 return;
2198
2199 if (dmgInfo.GetDamage() <= GetTarget()->GetHealth())
2200 return;
2201
2202 if (dmgInfo.GetDamage() >= GetTarget()->GetHealth())
2203 {
2204 absorbAmount = dmgInfo.GetDamage();
2205 if (_triggered)
2206 return;
2207
2208 GetTarget()->SetHealth(1);
2211 _triggered = true;
2212 }
2213 }
2214
2220
2221private:
2222 bool _triggered = false;
2223};
2224
2225// 366848 - Anduin Willpower Periodic (Only LFR)
2227{
2228 static constexpr std::array<int32, 22> AnduinRegenCycle =
2229 { 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1 }; // 0.681 willpower per second on Retail
2230
2231 void HandlePeriodic(AuraEffect const* /*aurEff*/)
2232 {
2233 Unit* target = GetTarget();
2235
2236 if (_powerRegenCycle >= 22)
2237 _powerRegenCycle = 0;
2238
2239 target->ModifyPower(target->GetPowerType(), _powerGained);
2240 }
2241
2246
2249};
2250
2251// 364247 - Dark Zeal
2253{
2254 bool Validate(SpellInfo const* /*spellInfo*/) override
2255 {
2257 }
2258
2259 void OnProc(AuraEffect* /*aurEff*/, ProcEventInfo const& eventInfo)
2260 {
2261 Unit* actionTarget = eventInfo.GetActionTarget();
2262 if (!actionTarget)
2263 return;
2264
2265 Unit* target = GetTarget();
2266 target->CastSpell(target, SPELL_DARK_ZEAL_BUFF, true);
2267
2268 if (actionTarget->GetGUID() == _currentTank)
2269 return;
2270
2272 _currentTank = actionTarget->GetGUID();
2273 }
2274
2279
2280private:
2282};
2283
2284// 361815 - Hopebreaker
2285// 365806 - Empowered Hopebreaker
2304
2305// 361817 - Hopebreaker Periodic
2307{
2308 bool Validate(SpellInfo const* /*spellInfo*/) override
2309 {
2311 }
2312
2313 void OnPeriodic(AuraEffect const* /*aurEff*/) const
2314 {
2315 if (!GetCaster())
2316 return;
2317
2319 }
2320
2325};
2326
2327// 361818 - Hopebreaker Damage
2329{
2330 bool Validate(SpellInfo const* /*spellInfo*/) override
2331 {
2333 }
2334
2335 void HandleDamage(SpellEffIndex /*effIndex*/)
2336 {
2337 Unit* target = GetHitUnit();
2338
2339 Aura* hopebreaker = target->GetAura(SPELL_HOPEBREAKER_DEBUFF);
2340 if (!hopebreaker)
2341 return;
2342
2343 uint8 hopebreakerStacks = hopebreaker->GetStackAmount();
2344 SetHitDamage(GetHitDamage() * hopebreakerStacks);
2345 }
2346
2351};
2352
2353// 363133 - March of the Damned, CreatePropertiesId - 24093
2355{
2357
2358 void OnUnitEnter(Unit* unit) override
2359 {
2360 if (!unit->IsPlayer())
2361 return;
2362
2363 Unit* caster = at->GetCaster();
2364 if (!caster)
2365 return;
2366
2367 caster->CastSpell(unit, SPELL_MARCH_OF_THE_DAMNED_DAMAGE, true);
2368 }
2369};
2370
2371float constexpr BEFOULED_BARRIER_MAX_RADIUS = 12.0f;
2372float constexpr BEFOULED_BARRIER_MIN_RADIUS = 4.0f;
2373
2374// 365173 - Befouled Barrier - CreatePropertiesId: 24332
2376{
2378
2379 void OnInitialize() override
2380 {
2381 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_BEFOULED_BARRIER_DEBUFF, at->GetMap()->GetDifficultyID()))
2382 _absorbRequired = spellInfo->GetEffect(EFFECT_0).CalcValueAsInt(at->GetCaster());
2383
2384 at->SetTimeToTargetScale(30000);
2385
2386 // The aura is handling it automatically
2387 at->SetDuration(-1);
2388 }
2389
2390 void OnCreate(Spell const* /*creatingSpell*/) override
2391 {
2392 _scheduler.Schedule(500ms, [this](TaskContext& task)
2393 {
2394 float startRadius = 1.0f;
2395
2398
2400 {
2401 UpdateSizeBasedOnAbsorb();
2402 task.Repeat();
2403 });
2404 });
2405 }
2406
2407 void UpdateSize(float radius, float targetRadius) const
2408 {
2409 std::array<DBCPosition2D, 2> points =
2410 { {
2411 { 0.0f, radius },
2412 { 1.0f, targetRadius }
2413 } };
2414
2415 at->SetOverrideScaleCurve(points);
2416 }
2417
2419 {
2420 Unit* target = at->GetTarget();
2421 if (!target)
2422 return;
2423
2424 float radiusMod = 1.0f - (_absorbDone / (float)_absorbRequired);
2425 float targetRadius = BEFOULED_BARRIER_MAX_RADIUS * radiusMod;
2426 float currentRadius = at->GetMaxSearchRadius();
2427
2428 if (G3D::fuzzyEq(currentRadius, targetRadius))
2429 return;
2430
2431 // Players need to be able to actually enter the AT to heal it no sniff has a value lower than 4.0f
2432 if (targetRadius <= BEFOULED_BARRIER_MIN_RADIUS)
2433 return;
2434
2435 UpdateSize(currentRadius, targetRadius);
2436 }
2437
2438 void OnUpdate(uint32 diff) override
2439 {
2440 _scheduler.Update(diff);
2441 }
2442
2443 void OnUnitEnter(Unit* unit) override
2444 {
2445 Unit* caster = at->GetCaster();
2446 if (!caster)
2447 return;
2448
2449 caster->CastSpell(unit, SPELL_BEFOULED_BARRIER_DEBUFF, true);
2450 }
2451
2452 void OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) override
2453 {
2455 }
2456
2457 void Absorb(uint32 absorbAmount)
2458 {
2459 _absorbDone += absorbAmount;
2460
2462 return;
2463
2464 Unit* target = at->GetTarget();
2465 if (!target)
2466 return;
2467
2468 // remove barrier, we're done healing
2469 if (Creature* creature = target->ToCreature())
2470 {
2471 creature->CastSpell(creature, SPELL_BEFOULED_BARRIER_CLEAR, true);
2472 creature->DespawnOrUnsummon(1s);
2473 }
2474 }
2475
2477 {
2479 }
2480
2481private:
2485};
2486
2487float constexpr BEACON_OF_HOPE_MAX_RADIUS = 12.0f;
2488float constexpr BEACON_OF_HOPE_MIN_RADIUS = 4.0f;
2489
2490// 362702 - Beacon of Hope - CreatePropertiesId: 25025 / 24247
2492{
2494 _instance(at->GetInstanceScript()), _entries(0), _chargesRemaining(40) { }
2495
2496 void OnInitialize() override
2497 {
2498 _entries = 0;
2499 _chargesRemaining = 40;
2500 }
2501
2502 void OnCreate(Spell const* /*creatingSpell*/) override
2503 {
2504 _scheduler.Schedule(500ms, [this](TaskContext& task)
2505 {
2506 float startRadius = 1.0f;
2507 float targetRadius = BEACON_OF_HOPE_MAX_RADIUS;
2508
2509 UpdateSize(startRadius, targetRadius);
2511
2513 {
2514 UpdateSizeBasedOnCharges();
2515 task.Repeat();
2516 });
2517 });
2518 }
2519
2520 void UpdateSize(float radius, float targetRadius) const
2521 {
2522 std::array<DBCPosition2D, 2> points =
2523 { {
2524 { 0.0f, radius },
2525 { 1.0f, targetRadius }
2526 } };
2527
2528 at->SetOverrideScaleCurve(points);
2529 }
2530
2532 {
2533 float radiusMod = 0.205129f * _entries;
2534 float targetRadius = BEACON_OF_HOPE_MAX_RADIUS - radiusMod;
2535
2536 if (targetRadius <= BEACON_OF_HOPE_MIN_RADIUS || _chargesRemaining <= 0)
2537 at->Remove();
2538
2539 float currentRadius = at->GetMaxSearchRadius();
2540 if (G3D::fuzzyEq(currentRadius, targetRadius))
2541 return;
2542
2543 UpdateSize(currentRadius, targetRadius);
2544 }
2545
2546 void OnUpdate(uint32 diff) override
2547 {
2548 _scheduler.Update(diff);
2549 }
2550
2551 void OnUnitEnter(Unit* unit) override
2552 {
2553 if (!unit->IsPlayer())
2554 return;
2555
2556 if (!at->GetCaster())
2557 return;
2558
2560 if (!beacon)
2561 return;
2562
2563 beacon->CastSpell(beacon, SPELL_PURGING_LIGHT, true);
2565
2566 if (at->GetMap()->IsMythic())
2567 {
2568 _entries++;
2570 beacon->CastSpell(unit, SPELL_FRAGMENT_OF_HOPE_AREATRIGGER, true);
2571 }
2572 }
2573
2574private:
2579};
2580
2581// 365816 - Fragment of Hope
2583{
2584 void SetDest(SpellDestination& destination) const
2585 {
2586 Unit* caster = GetCaster();
2587 Position dest = caster->GetPosition();
2588
2590 beacon->MovePositionToFirstCollision(dest, 30.0f, beacon->GetAbsoluteAngle(GetExplTargetWorldObject()) - beacon->GetOrientation());
2591
2592 destination.Relocate(dest);
2593 }
2594
2599};
2600
2601// 365293 - Befouled Barrier
2603{
2604 bool Validate(SpellInfo const* spellInfo) override
2605 {
2607 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_2 } });
2608 }
2609
2610 void OnHealAbsorb(AuraEffect* /*aurEff*/, HealInfo const& healInfo, uint32& absorbAmount) const
2611 {
2612 absorbAmount = CalculatePct(healInfo.GetHeal(), GetEffectInfo(EFFECT_2).CalcValueAsInt());
2613
2614 Unit* caster = GetCaster();
2615 if (!caster)
2616 return;
2617
2619 if (!barrier)
2620 return;
2621
2622 at_anduin_wrynn_befouled_barrier* barrierScript = dynamic_cast<at_anduin_wrynn_befouled_barrier*>(barrier->AI());
2623 if (!barrierScript)
2624 return;
2625
2626 barrierScript->Absorb(absorbAmount);
2627 }
2628
2633};
2634
2635// 365173 - Befouled Barrier Expire
2637{
2638 bool Validate(SpellInfo const* /*spellInfo*/) override
2639 {
2641 }
2642
2643 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
2644 {
2645 Unit* target = GetTarget();
2646 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
2647 {
2649 if (!barrier)
2650 return;
2651
2652 at_anduin_wrynn_befouled_barrier* barrierScript = dynamic_cast<at_anduin_wrynn_befouled_barrier*>(barrier->AI());
2653 if (!barrierScript)
2654 return;
2655
2657 }
2658
2659 if (Creature* creatureTarget = target->ToCreature())
2660 creatureTarget->DespawnOrUnsummon();
2661 }
2662
2667};
2668
2669// 361989 - Blasphemy
2671{
2676
2677 void OnPrecast() override
2678 {
2680 }
2681
2682 void FilterTargets(std::list<WorldObject*>& targets)
2683 {
2684 int64 hopelessnessAffected = targets.size() / 2;
2685 int64 maxAffected = hopelessnessAffected * 2;
2686 Trinity::Containers::RandomResize(targets, maxAffected);
2687
2688 for (WorldObject* target : targets)
2689 {
2690 if (hopelessnessAffected > 0)
2691 {
2693 hopelessnessAffected--;
2694 }
2695 else
2697 }
2698 }
2699
2700 void HandleDebuff(SpellEffIndex /*effIndex*/)
2701 {
2703 if (!spellId)
2704 return;
2705
2706 GetCaster()->CastSpell(GetHitUnit(), *spellId, true);
2707 }
2708
2714
2715private:
2716 std::unordered_map<ObjectGuid /*player*/, uint32 /*spell*/> _spellAssignments;
2717};
2718
2719// 361992 - Overconfidence CreatePropertiesId: 24616
2720// 361993 - Hopelessness CreatePropertiesId: 24616
2722{
2723 at_anduin_wrynn_blasphemy(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
2724
2725 void OnUnitEnter(Unit* unit) override
2726 {
2727 if (!unit->IsPlayer() || unit->HasAura(SPELL_BLASPHEMY_PRE_HIT))
2728 return;
2729
2730 if (!unit->IsAlive())
2731 at->Remove();
2732
2733 if (unit->HasAura(at->GetSpellId()))
2734 {
2735 uint32 explodeSpellId = SPELL_BLASPHEMY_EXPLODE;
2736 if (at->GetMap()->IsLFR() || at->GetMap()->IsNormal())
2737 explodeSpellId = SPELL_BLASPHEMY_EXPLODE_LFR_NORMAL;
2738
2739 unit->CastSpell(unit, explodeSpellId, true);
2741 if (Unit* target = at->GetTarget())
2742 {
2743 target->CastSpell(target, explodeSpellId, true);
2744 target->RemoveAurasDueToSpell(at->GetSpellId());
2745 }
2746 }
2748 {
2751 unit->CastSpell(unit, SPELL_BLASPHEMY_SUCCESS, true);
2752 if (Unit* target = at->GetTarget())
2753 {
2754 target->RemoveAurasDueToSpell(SPELL_BLASPHEMY_HOPELESSNESS);
2755 target->RemoveAurasDueToSpell(SPELL_BLASPHEMY_HOPELESSNESS_AREATRIGGER);
2756 target->CastSpell(target, SPELL_BLASPHEMY_SUCCESS, true);
2757 }
2758 }
2760 {
2763 unit->CastSpell(unit, SPELL_BLASPHEMY_SUCCESS, true);
2764 if (Unit* target = at->GetTarget())
2765 {
2766 target->RemoveAurasDueToSpell(SPELL_BLASPHEMY_OVERCONFIDENCE);
2767 target->RemoveAurasDueToSpell(SPELL_BLASPHEMY_OVERCONFIDENCE_AREATRIGGER);
2768 target->CastSpell(target, SPELL_BLASPHEMY_SUCCESS, true);
2769 }
2770 }
2771 else
2772 {
2773 // On Mythic players walking in with no debuff also trigger explosion
2774 if (!at->GetMap()->IsMythic())
2775 return;
2776
2778 {
2779 if (Unit* target = at->GetTarget())
2780 target->CastSpell(target, SPELL_BLASPHEMY_EXPLODE, true);
2781 }
2782 }
2783 }
2784};
2785
2786// 361992 - Overconfidence
2787// 361993 - Hopelessness
2789{
2790 bool Validate(SpellInfo const* /*spell*/) override
2791 {
2792 return ValidateSpellInfo(
2793 {
2796 });
2797 }
2798
2799 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
2800 {
2801 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
2802 {
2803 Unit* target = GetTarget();
2804 uint32 explodeSpellId = SPELL_BLASPHEMY_EXPLODE;
2805 if (target->GetMap()->IsLFR() || target->GetMap()->IsNormal())
2806 explodeSpellId = SPELL_BLASPHEMY_EXPLODE_LFR_NORMAL;
2807
2808 target->CastSpell(target, explodeSpellId, true);
2809 }
2810 }
2811
2816};
2817
2818// 365021 - Wicked Star
2820{
2821 void FilterTargets(std::list<WorldObject*>& targets)
2822 {
2823 uint32 rangedDpsCount = 0;
2824 for (WorldObject* target : targets)
2825 {
2826 Player* targetPlayer = target->ToPlayer();
2827 if (!targetPlayer)
2828 continue;
2829
2830 ChrSpecializationEntry const* spec = targetPlayer->GetPrimarySpecializationEntry();
2831 if (!spec)
2832 continue;
2833
2834 if (!targetPlayer->IsAlive())
2835 continue;
2836
2837 if ((spec->GetRole() == ChrSpecializationRole::Dps && spec->GetFlags().HasFlag(ChrSpecializationFlag::Caster)) ||
2839 rangedDpsCount++;
2840 }
2841
2842 targets.remove_if([rangedDpsCount](WorldObject* target) -> bool
2843 {
2844 Player* player = target->ToPlayer();
2845 if (!player || player->HasAura(SPELL_WICKED_STAR_TARGETED))
2846 return true;
2847
2849 return true;
2850
2851 if (rangedDpsCount >= 3)
2852 {
2854 return true;
2855
2857 return true;
2858 }
2859 return false;
2860 });
2861 }
2862
2867};
2868
2869// 365021 - Wicked Star
2871{
2872 bool Validate(SpellInfo const* /*spellInfo*/) override
2873 {
2875 }
2876
2878 {
2880 }
2881
2883 {
2885 }
2886
2887 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
2888 {
2889 Unit* caster = GetCaster();
2890 Unit* target = GetTarget();
2891 if (!caster)
2892 return;
2893
2894 caster->CastSpell(target, SPELL_WICKED_STAR_TARGETED, true);
2895
2896 if (Creature* creature = caster->ToCreature())
2897 if (CreatureAI* anduinAI = creature->AI())
2898 anduinAI->Talk(GetAnnounceGroupID(), target);
2899 }
2900
2901 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
2902 {
2903 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
2904 return;
2905
2906 Unit* caster = GetCaster();
2907 if (!caster)
2908 return;
2909
2910 float angle = caster->GetAbsoluteAngle(GetTarget());
2911 Position spellDest(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), angle);
2912
2913 if (InstanceScript* instance = GetTarget()->GetInstanceScript())
2914 if (Creature* anduin = instance->GetCreature(DATA_ANDUIN_WRYNN))
2915 anduin->CastSpell(spellDest, GetAreaTriggerSpellID(), true);
2916 }
2917
2923};
2924
2925// 365017 - Wicked Star CreatePropertiesId: 24322
2926// 365017 - Wicked Star CreatePropertiesId: 24740
2927// 365017 - Wicked Star CreatePropertiesId: 24741
2929{
2931
2932 void OnInitialize() override
2933 {
2934 if (Unit* caster = at->GetCaster())
2935 {
2936 at->SetOrientation(caster->GetOrientation());
2937
2938 Position destPos = caster->GetPosition();
2939 at->MovePositionToFirstCollision(destPos, 100.0f, 0.0f);
2940
2941 std::vector<G3D::Vector3> splinePoints;
2942 splinePoints.push_back(PositionToVector3(at->GetPosition()));
2943 splinePoints.push_back(PositionToVector3(destPos));
2944 splinePoints.push_back(PositionToVector3(at->GetPosition()));
2945
2946 at->InitSplines(splinePoints);
2947 }
2948 }
2949
2950 void OnUnitEnter(Unit* unit) override
2951 {
2954 return;
2955
2956 Unit* caster = at->GetCaster();
2957 if (!caster)
2958 return;
2959
2960 if (caster->IsValidAttackTarget(unit))
2962 else if (caster->IsValidAssistTarget(unit))
2964 }
2965
2966 void OnDestinationReached() override
2967 {
2968 at->Remove();
2969 }
2970};
2971
2972// 367632 - Empowered Wicked Star
2985
2986// 367621 - Empowered Wicked Star CreatePropertiesId: 24599
2988{
2990
2991 void HandleMovement(float angle) const
2992 {
2993 Unit* caster = at->GetCaster();
2994 if (!caster)
2995 return;
2996
2997 // hack: when reflection is implemented use at position instead of center; due to mmaps we are causing infinite loop if using at position after dest reach
2999 at->MovePositionToFirstCollision(destPos, 100.0f, angle);
3000
3001 std::vector<G3D::Vector3> splinePoints;
3002 splinePoints.push_back(PositionToVector3(at->GetPosition()));
3003 splinePoints.push_back(PositionToVector3(destPos));
3004
3005 at->InitSplines(splinePoints);
3006 }
3007
3008 void OnInitialize() override
3009 {
3010 HandleMovement(0);
3011 }
3012
3013 void OnDestinationReached() override
3014 {
3015 // hack: angle should use physical laws for reflection
3016 HandleMovement(frand(0, 2.0f * float(M_PI)));
3017 }
3018};
3019
3020// 362405 - Kingsmourne Hungers
3022{
3023 bool Validate(SpellInfo const* /*spellInfo*/) override
3024 {
3025 return ValidateSpellInfo(
3026 {
3031 });
3032 }
3033
3034 void HandleDummyEffect(SpellEffIndex /*effIndex*/) const
3035 {
3036 Unit* caster = GetCaster();
3037 Unit* hitUnit = GetHitUnit();
3038 caster->CastSpell(hitUnit, SPELL_KINGSMOURNE_HUNGERS_DAMAGE, true);
3039 if (caster->GetMap()->IsMythic())
3040 hitUnit->CastSpell(hitUnit, SPELL_SEVERED_SOUL, true);
3041 caster->CastSpell(hitUnit, SPELL_LOST_SOUL_DIMENSION);
3042 hitUnit->CastSpell(hitUnit, SPELL_LOST_SOUL, true);
3043 }
3044
3045 void OnCast() const
3046 {
3048 if (!instance)
3049 return;
3050
3051 if (Creature* anduinSoul = instance->GetCreature(DATA_ANDUIN_SOUL))
3052 anduinSoul->GetAI()->DoAction(ACTION_SUMMON_KINGSMOURNE_SOULS);
3053 }
3054
3060};
3061
3062// 362055 - Lost Soul
3064{
3065 bool Validate(SpellInfo const* /*spellInfo*/) override
3066 {
3067 return ValidateSpellInfo(
3068 {
3071 });
3072 }
3073
3074 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
3075 {
3076 Unit* target = GetTarget();
3077 _lostSoulPosition = target->GetPosition();
3078 target->CastSpell(target, SPELL_LOST_SOUL_GRACE, true);
3079 }
3080
3081 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3082 {
3083 Unit* target = GetTarget();
3084 switch (GetTargetApplication()->GetRemoveMode())
3085 {
3088 target->CastSpell(target, SPELL_SCARRED_SOUL, true);
3089 break;
3091 {
3092 if (target->GetMap()->IsMythic())
3093 {
3094 target->KillSelf();
3096 }
3097 break;
3098 }
3100 {
3101 target->CastSpell(target, SPELL_SCARRED_SOUL, true);
3102 if (target->GetMap()->IsMythic())
3104 break;
3105 }
3106 default:
3107 break;
3108 }
3109 }
3110
3116
3118};
3119
3120// 362392 - Rain of Despair
3133
3134// 362766 - Soul Despawn
3136{
3137 void OnCast() const
3138 {
3139 if (Creature* creature = GetCaster()->ToCreature())
3140 if (creature->GetEntry() == NPC_ANDUIN_HOPE || creature->GetEntry() == NPC_ANDUIN_DOUBT)
3141 creature->DespawnOrUnsummon(3s);
3142 }
3143
3148};
3149
3150// 368913 - Force of Will
3152{
3153 void RecalculateHook(AuraEffect const* /*aurEffect*/, SpellEffectValue& amount, bool& canBeRecalculated) const
3154 {
3155 Unit* caster = GetCaster();
3156 if (!caster)
3157 return;
3158
3159 // at 100 will power = 200% Damage Done increase
3160 int32 powerValue = caster->GetPower(caster->GetPowerType());
3161 amount = 2 * powerValue;
3162 canBeRecalculated = false;
3163 }
3164
3165 void RecalculateHookDamageTaken(AuraEffect const* /*aurEffect*/, SpellEffectValue& amount, bool& canBeRecalculated) const
3166 {
3167 Unit* caster = GetCaster();
3168 if (!caster)
3169 return;
3170
3171 // Damage Taken reduction can only be capped to 90%
3172 int32 powerValue = caster->GetPower(caster->GetPowerType());
3173 amount = -std::min(powerValue, 90);
3174 canBeRecalculated = false;
3175 }
3176
3177 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3178 {
3179 Unit* caster = GetCaster();
3180 if (!caster)
3181 return;
3182
3183 caster->SetPower(caster->GetPowerType(), 0);
3184 }
3185
3193};
3194
3195// 363233 - March of the Damned
3197{
3198 void OnPeriodic(AuraEffect const* aurEff)
3199 {
3200 Unit* caster = GetCaster();
3201 if (!caster)
3202 return;
3203
3204 Seconds raidDifficulty = 0s;
3205
3206 switch (GetCaster()->GetMap()->GetDifficultyID())
3207 {
3208 case DIFFICULTY_LFR_NEW:
3211 raidDifficulty = 28s;
3212 break;
3214 raidDifficulty = 21s;
3215 break;
3216 default:
3217 raidDifficulty = 28s;
3218 break;
3219 }
3220
3221 // Don't summon the wall on aura granted
3222 if (aurEff->GetTickNumber() == 1)
3223 return;
3224
3225 if (_availableSpawnPositions.empty())
3226 return;
3227
3229 auto it = std::find(_availableSpawnPositions.begin(), _availableSpawnPositions.end(), chosenPosition);
3230 _availableSpawnPositions.erase(it);
3231
3232 GetCaster()->SummonCreature(NPC_MARCH_OF_THE_DAMNED, chosenPosition, TEMPSUMMON_TIMED_DESPAWN, raidDifficulty);
3233 }
3234
3239
3241};
3242
3243// 362500 - Shade Spawn Ceremony
3257
3258// 365652 - Lost Soul
3260{
3261 void FilterTargets(std::list<WorldObject*>& unitList) const
3262 {
3263 unitList.remove_if([this](WorldObject const* target)
3264 {
3265 if (target->GetEntry() == NPC_ANDUIN_DOUBT && target->IsWithinDistInMap(GetCaster(), 0.2f))
3266 return false;
3267 return true;
3268 });
3269 }
3270
3271 void HandleDummy(SpellEffIndex /*effIndex*/) const
3272 {
3273 if (Creature* creature = GetHitUnit()->ToCreature())
3274 creature->DespawnOrUnsummon();
3275 }
3276
3282};
3283
3284// 367769 - Severed Soul
3286{
3287 bool Validate(SpellInfo const* /*spellInfo*/) override
3288 {
3290 }
3291
3292 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
3293 {
3294 if (Unit* caster = GetCaster())
3295 _soulPosition = caster->GetPosition();
3296 }
3297
3298 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3299 {
3300 Unit* caster = GetCaster();
3301 if (!caster)
3302 return;
3303
3304 caster->CastSpell(caster, SPELL_CANCEL_LOST_SOUL, true);
3305
3306 if (TempSummon* summon = GetTarget()->ToTempSummon())
3307 if (summon->GetSummonerUnit() == caster)
3309 }
3310
3316
3318};
3319
3320// 362402 - Lost Soul Mirror Image
3322{
3323 void FilterTargets(std::list<WorldObject*>& targets) const
3324 {
3325 Unit* caster = GetCaster();
3326 if (!caster)
3327 return;
3328
3329 ObjectGuid casterGuid = caster->GetGUID();
3330
3331 targets.remove_if([casterGuid](WorldObject const* target) -> bool
3332 {
3333 Unit const* unit = target->ToUnit();
3334 if (!unit)
3335 return true;
3336
3337 TempSummon const* summon = unit->ToTempSummon();
3338 if (!summon)
3339 return true;
3340
3341 if (summon->GetSummonerGUID() != casterGuid)
3342 return true;
3343
3344 return false;
3345 });
3346 }
3347
3355};
3356
3357// 363029 - Soul Explosion
3359{
3360 bool Validate(SpellInfo const* /*spellInfo*/) override
3361 {
3363 }
3364
3365 void FilterTargets(std::list<WorldObject*>& targets) const
3366 {
3367 if (targets.empty())
3368 return;
3369
3370 targets.remove_if(Trinity::ObjectTypeIdCheck(TYPEID_PLAYER, false));
3371
3372 std::vector<WorldObject*> rangedTargets;
3373 for (WorldObject* target : targets)
3374 {
3375 if (target->GetDistance(GetCaster()) >= 5.0f)
3376 {
3377 rangedTargets.push_back(target);
3378 break;
3379 }
3380 }
3381
3382 if (!rangedTargets.empty())
3383 {
3384 targets.clear();
3385 targets.push_back(Trinity::Containers::SelectRandomContainerElement(rangedTargets));
3386 }
3387 }
3388
3389 void HandleMissile(SpellEffIndex /*effIndex*/) const
3390 {
3392 }
3393
3399};
3400
3401// 363022 - Return to Kingsmourne
3403{
3404 bool Validate(SpellInfo const* /*spellInfo*/) override
3405 {
3407 }
3408
3409 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3410 {
3411 Unit* caster = GetCaster();
3412 if (!caster)
3413 return;
3414
3416 }
3417
3422};
3423
3424// 363021 - Return to Kingsmourne
3426{
3427 bool Validate(SpellInfo const* /*spellInfo*/) override
3428 {
3429 return ValidateSpellInfo(
3430 {
3433 });
3434 }
3435
3436 void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3437 {
3438 Unit* caster = GetCaster();
3439 if (!caster)
3440 return;
3441
3442 InstanceScript* instance = caster->GetInstanceScript();
3443 if (!instance)
3444 return;
3445
3446 if (Creature* arthas = instance->GetCreature(DATA_REMNANT_OF_A_FALLEN_KING))
3447 arthas->AI()->EnterEvadeMode(EvadeReason::Other);
3448
3449 if (Creature* anduin = instance->GetCreature(DATA_ANDUIN_WRYNN))
3450 {
3451 anduin->RemoveAurasDueToSpell(SPELL_DOMINATION_GRASP_ROOT_AREATRIGGER);
3454 if (anduin->IsAIEnabled())
3455 {
3456 anduin->AI()->DoAction(ACTION_EXIT_INTERMISSION);
3457 anduin->AI()->DoCastSelf(SPELL_CANCEL_FORCE_OF_WILL);
3458 }
3459 }
3460 }
3461
3466};
3467
3468// 365120 - Grim Reflections
3470{
3471 bool Validate(SpellInfo const* /*spellInfo*/) override
3472 {
3474 }
3475
3476 void HandleCast() const
3477 {
3478 uint8 reflectionsNumber = GetCaster()->GetMap()->IsMythic() ? 4 : 3;
3479 std::vector<Position> grimReflectionPositions(std::begin(GrimReflectionsSpawnPositions), std::end(GrimReflectionsSpawnPositions));
3480 Trinity::Containers::RandomResize(grimReflectionPositions, reflectionsNumber);
3481
3482 for (uint8 i = 0; i < reflectionsNumber; i++)
3483 GetCaster()->CastSpell(grimReflectionPositions[i], SPELL_GRIM_REFLECTIONS_SUMMON, true);
3484 }
3485
3490};
3491
3492// 365872 - Beacon of Hope
3505
3506// 365958 - Hopelessness
3508{
3509 bool Validate(SpellInfo const* /*spellInfo*/) override
3510 {
3511 return ValidateSpellInfo(
3512 {
3515 });
3516 }
3517
3518 void OnPrecast() override
3519 {
3521 }
3522
3523 void HandleDebuff(SpellEffIndex /*effIndex*/) const
3524 {
3526 }
3527
3532};
3533
3534// 365966 - Hopelessness CreatePropertiesId 24443
3536{
3538
3539 void OnUnitEnter(Unit* unit) override
3540 {
3541 if (!unit->IsPlayer() || unit->HasAura(SPELL_BLASPHEMY_PRE_HIT))
3542 return;
3543
3544 if (!unit->IsAlive())
3545 {
3546 at->Remove();
3547 return;
3548 }
3549
3550 if (unit->HasAura(at->GetSpellId()))
3551 {
3552 unit->CastSpell(unit, SPELL_BLASPHEMY_EXPLODE, true);
3553 if (Unit* target = at->GetTarget())
3554 target->CastSpell(target, SPELL_BLASPHEMY_EXPLODE, true);
3555 }
3556 }
3557
3558 void OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) override
3559 {
3560 if (!unit->IsAlive() && unit->HasAura(at->GetSpellId()))
3562 }
3563};
3564
3565// 365966 - Hopelessness
3567{
3568 bool Validate(SpellInfo const* /*spell*/) override
3569 {
3571 }
3572
3573 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3574 {
3575 switch (GetTargetApplication()->GetRemoveMode())
3576 {
3581 break;
3582 default:
3583 break;
3584 }
3585 }
3586
3591};
3592
3593// 365291 - Remnant Timer
3595{
3596 static constexpr std::array<int32, 3> RemnantRegenCycle = { 1, 1, 2 };
3597
3598 void HandlePeriodic(AuraEffect const* /*aurEff*/)
3599 {
3600 Unit* target = GetTarget();
3601 int32 powerGained = RemnantRegenCycle[_powerRegenCycle++];
3602
3603 if (_powerRegenCycle > 2)
3604 _powerRegenCycle = 1;
3605
3606 target->ModifyPower(target->GetPowerType(), powerGained);
3607 }
3608
3613
3615};
3616
3617// 362862 - Army of the Dead
3619{
3620 bool Validate(SpellInfo const* /*spell*/) override
3621 {
3623 }
3624
3625 void HandleAfterCast() const
3626 {
3627 if (GetCaster()->GetMap()->IsLFR())
3628 return;
3629
3630 Position monstrousSoulSpawnPosition = GetCaster()->GetNearPosition(frand(30.0f, 50.0f), frand(0.0f, 3.5f));
3631 GetCaster()->CastSpell(monstrousSoulSpawnPosition, SPELL_ECHOES_OF_ANDORHAL_MONSTROUS_SOUL, true);
3632 }
3633
3638};
3639
3640// 362543 - Remorseless Winter
3657
3658// 362545 - Remorseless Winter
3660{
3661 void HandleDamage(SpellEffIndex /*effIndex*/)
3662 {
3663 Unit* caster = GetCaster();
3664 if (!caster)
3665 return;
3666
3668 if (!remorselessWinter)
3669 return;
3670
3671 SetHitDamage(int32(GetHitDamage() * remorselessWinter->GetStackAmount()));
3672 }
3673
3678};
3679
3680// 362771 - Soul Reaper
3682{
3693
3694 void HandleDummyEffect(SpellEffIndex /*effIndex*/) const
3695 {
3696 Unit* caster = GetCaster();
3697 Unit* hitUnit = GetHitUnit();
3698 caster->CastSpell(hitUnit, SPELL_SOUL_REAPER_PHYSICAL_DAMAGE, true);
3699 caster->CastSpell(hitUnit, SPELL_SOUL_REAPER_SHADOWFROST_DAMAGE, true);
3700 caster->CastSpell(hitUnit, SPELL_SOUL_REAPER_DEBUFF, true);
3701 caster->CastSpell(caster, SPELL_SOUL_REAPER_ATTACK_SPEED, true);
3703 }
3704
3709};
3710
3711// Anduin Wrynn Introduction Custom AT
3713{
3715
3716 void OnUnitEnter(Unit* unit) override
3717 {
3718 Player* player = unit->ToPlayer();
3719 if (!player || player->IsGameMaster())
3720 return;
3721
3722 InstanceScript* instance = at->GetInstanceScript();
3723 if (!instance)
3724 return;
3725
3726 if (Creature* anduin = instance->GetCreature(DATA_ANDUIN_WRYNN))
3727 anduin->GetAI()->DoAction(ACTION_START_PRE_INTRODUCTION);
3728
3729 at->Remove();
3730 }
3731};
3732
3733// 956 - Anduin End Movie
3735{
3736public:
3737 movie_anduin_final() : PlayerScript("movie_anduin_final") { }
3738
3740 {
3741 _skippedPlayers.insert(playerId);
3742 }
3743
3744 void OnMovieComplete(Player* player, uint32 /*movieId*/) override
3745 {
3746 InstanceScript* instance = player->GetInstanceScript();
3747 if (!instance)
3748 return;
3749
3750 Creature* anduin = instance->GetCreature(DATA_ANDUIN_WRYNN);
3751 if (!anduin)
3752 return;
3753
3754 MarkPlayerAsSkipped(static_cast<uint32>(player->GetGUID().GetCounter()));
3756
3757 // Outroduction must start once every player skips or completes the movie
3758 if (_skippedPlayers.size() == player->GetMap()->GetPlayersCountExceptGMs())
3760 }
3761
3762private:
3763 std::unordered_set<uint32> _skippedPlayers;
3764};
3765
3767{
3783
3820
3829
3830 new movie_anduin_final();
3831}
AreaTriggerExitReason
Definition AreaTrigger.h:69
#define M_PI
Definition Common.h:118
@ DIFFICULTY_MYTHIC_RAID
Definition DBCEnums.h:947
@ DIFFICULTY_NORMAL_RAID
Definition DBCEnums.h:945
@ DIFFICULTY_HEROIC_RAID
Definition DBCEnums.h:946
@ DIFFICULTY_LFR_NEW
Definition DBCEnums.h:948
uint8_t uint8
Definition Define.h:156
int64_t int64
Definition Define.h:149
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
uint32_t uint32
Definition Define.h:154
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:28
@ IN_PROGRESS
@ DONE
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_ENGAGE
@ POINT_MOTION_TYPE
@ TEMPSUMMON_MANUAL_DESPAWN
@ TEMPSUMMON_TIMED_DESPAWN
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
float frand(float min, float max)
Definition Random.cpp:55
#define RegisterSpellAndAuraScriptPair(script_1, script_2)
Definition ScriptMgr.h:1381
#define RegisterAreaTriggerAI(ai_name)
Definition ScriptMgr.h:1428
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
#define RegisterSpellAndAuraScriptPairWithArgs(script_1, script_2, script_name,...)
Definition ScriptMgr.h:1380
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
void GetPlayerListInGrid(Container &container, WorldObject *source, float maxSearchRange, bool alive=true)
SpellEffIndex
@ EFFECT_3
@ EFFECT_1
@ EFFECT_0
@ EFFECT_2
@ TARGET_UNIT_SRC_AREA_ENTRY
@ TARGET_DEST_DEST
@ TARGET_UNIT_SRC_AREA_ENEMY
@ EMOTE_STATE_READY_BOW
@ EMOTE_STATE_READY2H
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCHOOL_DAMAGE
@ BASE_ATTACK
@ POWER_ENERGY
@ FACTION_FRIENDLY
@ GO_STATE_ACTIVE
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ AURA_REMOVE_BY_DEFAULT
@ AURA_REMOVE_BY_DEATH
@ AURA_REMOVE_BY_EXPIRE
@ AURA_REMOVE_BY_ENEMY_SPELL
@ SPELL_AURA_TRIGGER_SPELL_ON_EXPIRE
@ SPELL_AURA_LINKED_SUMMON
@ SPELL_AURA_DUMMY
@ SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
@ SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
@ SPELL_AURA_MOD_ROOT
@ SPELL_AURA_PHASE
@ SPELL_AURA_SCHOOL_ABSORB
@ SPELL_AURA_MOD_SCALE
@ SPELL_AURA_MOD_SUMMON_DAMAGE
@ SPELL_AURA_AREA_TRIGGER
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_SCREEN_EFFECT
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ SPELL_AURA_MOD_STUN
double SpellEffectValue
This is a double instead of float to be able to store full range of int32.
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will not check if a current cast is in progress.
@ TRIGGERED_IGNORE_GCD
Will ignore GCD.
@ SPELLVALUE_BASE_POINT1
#define sSpellMgr
Definition SpellMgr.h:812
#define AuraEffectProcFn(F, I, N)
#define SpellEffectFn(F, I, N)
#define AuraEffectAbsorbHealFn(F, I)
#define AuraEffectCalcAmountFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define SpellCastFn(F)
#define SpellDestinationTargetSelectFn(F, I, N)
#define AuraEffectAbsorbFn(F, I)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraEffectRemoveFn(F, I, N, M)
EvadeReason
@ MOVE_RUN
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
DamageEffectType
@ SHEATH_STATE_MELEE
Definition UnitDefines.h:83
@ SHEATH_STATE_RANGED
Definition UnitDefines.h:84
@ UNIT_FLAG_NOT_ATTACKABLE_1
@ UNIT_STATE_CASTING
Definition Unit.h:276
T CalculatePct(T base, U pct)
Definition Util.h:72
constexpr Position AnduinsDespairSpawnPosition
constexpr Position RightKnightPosition
constexpr Position QuartermasterRahmPos
float constexpr BEACON_OF_HOPE_MAX_RADIUS
constexpr Position AnduinsHopeSpawnPosition[4]
constexpr Position LeftKnightPosition
constexpr Position AnduinsSoulSpawnPosition
constexpr Position PreIntroductionAssistersPositions[3]
constexpr Position GrimReflectionsSpawnPositions[4]
AnduinWrynnSpellVisuals
@ SPELL_VISUAL_CHEST_LOOT
Position const MarchOfTheDamnedSpawnPositions[8]
@ SAY_ANNOUNCE_BLASPHEMY
@ SAY_EMPOWERED_HOPEBREAKER
@ SAY_BEFOULED_BARRIER
@ SAY_KINGSMOURNE_HUNGERS
@ SAY_DISENGAGE
@ SAY_ANNOUNCE_WICKED_STAR
@ SAY_BLASPHEMY
@ SAY_GRIM_REFLECTIONS
@ SAY_ANNOUNCE_KINGSMOURNE_HUNGERS
@ SAY_WICKED_STAR
@ SAY_HOPEBREAKER
@ SAY_NECROTIC_DETONATION
@ SAY_ANNOUNCE_EMPOWERED_WICKED_STAR
void AddSC_boss_anduin_wrynn()
AnduinWrynnSpawnGroups
@ SPAWN_GROUP_INITIAL
@ PATH_INTRODUCTION_SYLVANAS
@ PATH_INTRODUCTION_UTHER
@ PATH_OUTRODUCTION_FIRIM
@ PATH_INTRODUCTION_JAINA
@ PATH_OUTRODUCTION_THRALL
@ PATH_OUTRODUCTION_BOLVAR
constexpr Position RemnantOfAFallenKingSpawnPosition
AnduinWrynnPhases
@ PHASE_THREE
float constexpr BEFOULED_BARRIER_MIN_RADIUS
constexpr Position ChestLootSpawnPosition
constexpr Position IntermissionAssistersTeleportPosition[3]
float constexpr BEFOULED_BARRIER_MAX_RADIUS
AnduinWrynnSpells
@ SPELL_BLINK
@ SPELL_SOUL_EXPLOSION_TRIGGER_MISSILE
@ SPELL_ANDUIN_WILLPOWER_PERIODIC
@ SPELL_HOPEBREAKER_DAMAGE
@ SPELL_PURGING_LIGHT
@ SPELL_BLASPHEMY
@ SPELL_DARK_PRESENCE
@ SPELL_BEFOULED_BARRIER_EXPLODE
@ SPELL_LOST_SOUL_CLEAR
@ SPELL_REMORSELESS_WINTER_PERIODIC
@ SPELL_EMPOWERED_WICKED_STAR_POINTER
@ SPELL_KINGSMOURNE_HUNGERS_DAMAGE
@ SPELL_FROSTBOLT
@ SPELL_RETURN_TO_KINGSMOURNE
@ SPELL_ECHOES_OF_ANDORHAL_FIENDISH_GHOULS
@ SPELL_LOST_SOUL_MIRROR_IMAGE
@ SPELL_WICKED_STAR_PROTECTION
@ SPELL_HOPEBREAKER_CLEAR
@ SPELL_DARK_ZEAL_BUFF
@ SPELL_BLASPHEMY_OVERCONFIDENCE
@ SPELL_BLASPHEMY_PRE_HIT
@ SPELL_POWER_ENERGIZE_WILLPOWER_LARGE
@ SPELL_SOUL_DESPAWN
@ SPELL_EMPOWERED_HOPEBREAKER_EXPLOSION
@ SPELL_DOMINATION_GRASP_ROOT_AREATRIGGER
@ SPELL_BLASPHEMY_IMMUNE
@ SPELL_BEFOULED_ERUPTION
@ SPELL_SHADESTEP
@ SPELL_MIRROR_IMAGE
@ SPELL_BEFOULED_BARRIER_DEBUFF
@ SPELL_BLASPHEMY_HOPELESSNESS
@ SPELL_UNRAVELING_FRENZY_PERIODIC
@ SPELL_MARCH_OF_THE_DAMNED
@ SPELL_PSYCHIC_TERROR
@ SPELL_DESPAWN_WALLS
@ SPELL_FRAGMENT_OF_HOPE_DAMAGE
@ SPELL_WICKED_STAR_POINTER
@ SPELL_UNRAVELING_FRENZY
@ SPELL_SHOOT_BOW
@ SPELL_BLASPHEMY_EXPLODE_LFR_NORMAL
@ SPELL_FRAGMENT_OF_HOPE_AREATRIGGER
@ SPELL_AWARD_ANDUIN_KILL
@ SPELL_ARMY_OF_THE_DEAD
@ SPELL_DOMINATION_WORD_PAIN
@ SPELL_WICKED_STAR_EMPOWERMENT
@ SPELL_ANDUIN_PROGRESSION_AURA
@ SPELL_SEVERED_SOUL
@ SPELL_WICKED_STAR_DAMAGE_SILENCE
@ SPELL_BEACON_OF_HOPE
@ SPELL_GHOST_VISUAL_COSMETIC
@ SPELL_TELEPORT_DOMINATIONS_GRASP
@ SPELL_BEACON_OF_HOPE_AREATRIGGER
@ SPELL_SPAWN_REMNANT
@ SPELL_BEFOULED_BARRIER
@ SPELL_BROKER_SPAWN
@ SPELL_ECHOES_OF_ANDORHAL_MONSTROUS_SOUL
@ SPELL_KINGSMOURNE_HUNGERS
@ SPELL_ANDUIN_SLOW
@ SPELL_TUMBLE
@ SPELL_SOUL_REAPER_DEBUFF
@ SPELL_LOST_SOUL_CONSUME
@ SPELL_DOMINATION_GRASP
@ SPELL_EMPOWERED_WICKED_STAR
@ SPELL_FRAGMENT_OF_HOPE_CLEAR_DEBUFF
@ SPELL_BLASPHEMY_EXPLODE
@ SPELL_WICKED_STAR_IDK
@ SPELL_GRIM_REFLECTIONS
@ SPELL_ANDUIN_LOST_SOUL_TRACKER
@ SPELL_MARCH_OF_THE_DAMNED_DAMAGE
@ SPELL_SHADE_VISUAL
@ SPELL_ANDUIN_PLUNGE_KINGSMOURNE
@ SPELL_ANDUIN_SOUL_DESPAIR
@ SPELL_LOST_SOUL_MYTHIC
@ SPELL_GENERIC_BLINK
@ SPELL_RAIN_OF_DESPAIR
@ SPELL_BLASPHEMY_OVERCONFIDENCE_AREATRIGGER
@ SPELL_RETURN_TO_KINGSMOURNE_VISUALS
@ SPELL_FEIGN_DEATH
@ SPELL_SOUL_REAPER
@ SPELL_LOST_SOUL
@ SPELL_REMNANT_SPAWN
@ SPELL_EMPOWERED_HOPEBREAKER
@ SPELL_GRIM_REFLECTIONS_DEST_SUMMON
@ SPELL_POWER_ENERGIZE_WILLPOWER_SMALL
@ SPELL_POWER_DISPLAY_WILLPOWER
@ SPELL_HOPELESSNESS_HOPELESSNESS_AREATRIGGER
@ SPELL_NECROTIC_CLAWS_LEAP
@ SPELL_LOST_SOUL_DIMENSION
@ SPELL_ECHOES_OF_ANDORHAL
@ SPELL_GLOOM
@ SPELL_REMORSELESS_WINTER_DEBUFF_DAMAGE
@ SPELL_BANISH_SOUL
@ SPELL_BEFOULED_BARRIER_SPHERE_AREATRIGGER
@ SPELL_KINGSMOURNE_HUNGERS_DAMAGE_IDK
@ SPELL_SOUL_EXPLOSION_TARGET
@ SPELL_CANCEL_LOST_SOUL
@ SPELL_LOST_SOUL_GRACE
@ SPELL_REMORSELESS_WINTER_CLEAR
@ SPELL_SOUL_REAPER_PHYSICAL_DAMAGE
@ SPELL_WICKED_STAR_AREATRIGGER
@ SPELL_FINAL_MOVIE
@ SPELL_BEFOULED_BARRIER_CLEAR
@ SPELL_UTHER_CHARGE
@ SPELL_WICKED_STAR
@ SPELL_MARCH_OF_THE_DAMNED_AREATRIGGER
@ SPELL_REMORSELESS_WINTER
@ SPELL_CALAMITY_STATE_VISUAL
@ SPELL_ANDUIN_SOUL_GHOST
@ SPELL_WICKED_STAR_TARGETED
@ SPELL_GRIM_REFLECTIONS_SUMMON
@ SPELL_SOUL_REAPER_SHADOWFROST_DAMAGE
@ SPELL_SOUL_REAPER_ATTACK_SPEED
@ SPELL_HOPELESSNESS_EXPLODE
@ SPELL_HOPEBREAKER_DEBUFF
@ SPELL_EMPOWERED_WICKED_STAR_DAMAGE_SILENCE
@ SPELL_BLADE_OF_JUSTICE
@ SPELL_CANCEL_FORCE_OF_WILL
@ SPELL_NECROTIC_DETONATION
@ SPELL_FORCE_OF_WILL
@ SPELL_HOPEBREAKER
@ SPELL_LOST_SOUL_PERIODIC
@ SPELL_REMNANT_TIMER
@ SPELL_GRIM_FATE
@ SPELL_CANCEL_BLASPHEMY
@ SPELL_SCARRED_SOUL
@ SPELL_EMPOWERED_WICKED_STAR_AREATRIGGER
@ SPELL_ANDUIN_KNEEL_POSE
@ SPELL_BERSERK
@ SPELL_RAIN_OF_DESPAIR_MELEE
@ SPELL_MARCH_OF_THE_DAMNED_PERIODIC
@ SPELL_RAIN_OF_DESPAIR_RANGED
@ SPELL_BLASPHEMY_SUCCESS
@ SPELL_RAIN_OF_DESPAIR_EXPLOSION
@ SPELL_SOUL_EXPLOSION_DAMAGE
@ SPELL_WEATHER_COSMETIC
@ SPELL_HOPELESSNESS_MISSILE
@ SPELL_WICKED_STAR_IDK_3
@ SPELL_NECROTIC_CLAWS_DEBUFF
@ SPELL_BLASPHEMY_HOPELESSNESS_AREATRIGGER
@ SPELL_SHADE_DESPAWN_CEREMONY
@ SPELL_MIRROR_IMAGE_IGNORE_PHASE_SHIFT
@ SPELL_HOPEBREAKER_DEBUFF_DAMAGE
@ SPELL_BEFOULED_BARRIER_BLACK_RING
@ SPELL_TELEPORT_COSMIC_HUB
@ SPELL_DARK_ZEAL_AURA
@ SPELL_HOPELESSNESS
constexpr Position AnduinsDoubtSpawnPositions[4]
float constexpr BEACON_OF_HOPE_MIN_RADIUS
AnduinWrynnEvents
@ EVENT_BLINK
@ EVENT_BLADE_OF_JUSTICE
@ EVENT_UPDATE_BEFOULED_BARRIER
@ EVENT_CANCEL_SYLVANAS_EVENTS
@ EVENT_BLASPHEMY
@ EVENT_BEFOULED_BARRIER
@ EVENT_GRIM_REFLECTIONS
@ EVENT_DOMINATION_WORD_PAIN
@ EVENT_NECROTIC_CLAWS
@ EVENT_EMPOWERED_WICKED_STAR
@ EVENT_ARMY_OF_THE_DEAD
@ EVENT_HOPEBREAKER
@ EVENT_INTERMISSION_ONE
@ EVENT_UNRAVELING_FRENZY
@ EVENT_ANDUIN_SOUL
@ EVENT_HOPELESSNESS
@ EVENT_INTERMISSION_TWO
@ EVENT_BANISH_SOUL
@ EVENT_BERSERK
@ EVENT_TUMBLE
@ EVENT_KINGSMOURNE_HUNGERS
@ EVENT_EMPOWERED_HOPEBREAKER
@ EVENT_RETURN_TO_KINGSMOURNE
@ EVENT_WICKED_STAR
@ EVENT_NECROTIC_DETONATION
@ EVENT_GRIM_REFLECTION_IMMUNITY
@ EVENT_BEACON_OF_HOPE
@ EVENT_SOUL_REAPER
@ EVENT_GHOUL_LEAP
@ EVENT_CANCEL_UTHER_EVENTS
@ EVENT_CANCEL_JAINA_EVENTS
@ EVENT_PSYCHIC_TERROR
AnduinWrynnActions
@ ACTION_END_ENCOUNTER
@ ACTION_NECROTIC_DETONATION
@ ACTION_START_INTRODUCTION
@ ACTION_HOPE_RESTORED
@ ACTION_DESPAWN_REMNANT
@ ACTION_EXIT_INTERMISSION
@ ACTION_SUMMON_KINGSMOURNE_SOULS
@ ACTION_ARTHAS_INTERMISSION_SYLVANAS
@ ACTION_ACTIVATE_REMNANT
@ ACTION_MOVE_NPCS_ON_PLATFORM
@ ACTION_DESPAIR_GONE
@ ACTION_START_PRE_INTRODUCTION
@ ACTION_DOUBT_GONE
@ ACTION_ARTHAS_INTERMISSION_UTHER
@ ACTION_START_OUTRODUCTION
@ ACTION_START_MOVEMENT
constexpr Position DominationGraspCenter
AnduinWrynnConversations
@ CONVERSATION_ANDUIN_OUTRODUCTION
@ CONVERSATION_ANDUIN_PHASE_THREE
@ CONVERSATION_INTRO
@ CONVERSATION_ARTHAS_UTHER
@ CONVERSATION_ARTHAS_SYLVANAS
constexpr Position BeaconOfHopeSpawnPosition
AnduinWrynnPoints
@ POINT_ANDUIN_SOUL
@ POINT_MARCH_OF_THE_DAMNED
@ POINT_ESCAPE_PLATFORM
@ POINT_START_INTRODUCTION
ActivateGhouls(Creature *summoner, Creature *owner)
bool Execute(uint64, uint32) override
AreaTrigger *const at
GuidUnorderedSet const & GetInsideUnits() const
AreaTriggerAI * AI()
float GetMaxSearchRadius() const
void InitSplines(std::vector< G3D::Vector3 > const &splinePoints, Optional< float > overrideSpeed={}, Optional< bool > speedIsTimeInSeconds={})
uint32 GetSpellId() const
uint32 GetTimeToTargetScale() const
Unit * GetTarget() const
void SetTimeToTargetScale(uint32 timeToTargetScale)
void SetOverrideScaleCurve(float overrideScale)
void SetDuration(int32 newDuration)
Unit * GetCaster() const
uint32 GetTickNumber() const
HookList< EffectAbsorbHealHandler > OnEffectAbsorbHeal
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
HookList< EffectCalcAmountHandler > DoEffectCalcAmount
Unit * GetCaster() const
SpellEffectInfo const & GetEffectInfo(SpellEffIndex effIndex) const
HookList< EffectAbsorbHandler > OnEffectAbsorb
Aura * GetAura() const
Unit * GetTarget() const
HookList< EffectApplyHandler > OnEffectRemove
HookList< EffectProcHandler > OnEffectProc
HookList< AuraProcHandler > OnProc
HookList< EffectApplyHandler > OnEffectApply
uint8 GetStackAmount() const
Definition SpellAuras.h:238
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
bool IsPlayer() const
Definition BaseEntity.h:173
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
void _DespawnAtEvade(Seconds delayToRespawn=30s, Creature *who=nullptr)
TaskScheduler scheduler
SummonList summons
EventMap events
void AddActor(int32 actorId, uint32 actorIdx, ObjectGuid const &actorGuid)
static Conversation * CreateConversation(uint32 conversationEntry, Unit *creator, Position const &pos, ObjectGuid privateObjectOwner, SpellInfo const *spellInfo=nullptr, bool autoStart=true)
void DoZoneInCombat()
Definition CreatureAI.h:169
bool _EnterEvadeMode(EvadeReason why=EvadeReason::Other)
bool UpdateVictim()
void AttackStart(Unit *victim) override
== Triggered Actions Requested ==================
Creature *const me
Definition CreatureAI.h:63
void SetCanMelee(bool canMelee, bool fleeFromMelee=false)
void SetReactState(ReactStates st)
Definition Creature.h:174
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void SetRegenerateHealth(bool value)
Definition Creature.h:373
void SetImmuneToAll(bool apply) override
Definition Creature.h:181
CreatureAI * AI() const
Definition Creature.h:228
uint32 GetDamage() const
Definition Unit.h:452
uint32 ExecuteEvent()
Definition EventMap.cpp:77
void ScheduleEventSeries(uint32 eventId, uint8 group, uint8 phase, std::initializer_list< Milliseconds > timeSeries)
Definition EventMap.cpp:202
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
bool IsInPhase(uint8 phase) const
Definition EventMap.h:222
void CancelEvent(uint32 eventId)
Definition EventMap.cpp:135
void SetPhase(uint8 phase)
Definition EventMap.cpp:32
void Reset()
Definition EventMap.cpp:25
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
Milliseconds CalculateTime(Milliseconds t_offset) const
uint32 GetHeal() const
Definition Unit.h:482
virtual bool SetBossState(uint32 id, EncounterState state)
void DoRemoveAurasDueToSpellOnPlayers(uint32 spell, bool includePets=false, bool includeControlled=false)
void DoCastSpellOnPlayers(uint32 spell, bool includePets=false, bool includeControlled=false)
Creature * GetCreature(uint32 type)
void DoUpdateWorldState(int32 worldStateId, int32 value)
void SendEncounterUnit(EncounterFrameType type, Unit const *unit, Optional< int32 > param1={}, Optional< int32 > param2={})
bool IsNormal() const
Definition Map.cpp:3295
bool IsLFR() const
Definition Map.cpp:3282
Difficulty GetDifficultyID() const
Definition Map.h:360
uint32 GetPlayersCountExceptGMs() const
Definition Map.cpp:2679
PlayerList const & GetPlayers() const
Definition Map.h:403
bool IsMythic() const
Definition Map.cpp:3332
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 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={})
LowType GetCounter() const
Definition ObjectGuid.h:336
static ObjectGuid const Empty
Definition ObjectGuid.h:314
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
bool IsGameMaster() const
Definition Player.h:1309
ChrSpecializationEntry const * GetPrimarySpecializationEntry() const
Definition Player.cpp:30819
Unit * GetActionTarget() const
Definition Unit.h:500
uint32 const Id
Definition SpellInfo.h:328
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
HookList< CastHandler > AfterCast
int32 GetHitDamage() const
Unit * GetCaster() const
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
Unit * GetHitUnit() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
HookList< CastHandler > OnCast
WorldObject * GetExplTargetWorldObject() const
HookList< EffectHandler > OnEffectLaunchTarget
void SetHitDamage(int32 damage)
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition Spell.h:277
void Summon(Creature const *summon)
TaskContext & Schedule(TaskScheduler::duration_t time, TaskScheduler::task_handler_t task)
TaskScheduler & CancelAll()
TaskScheduler & Schedule(duration_t time, task_handler_t task)
TaskScheduler & ClearValidator()
Clears the validator which is asked if tasks are allowed to be executed.
TaskScheduler & Update()
Update the scheduler to the current time.
ObjectGuid GetSummonerGUID() const
Unit * GetSummonerUnit() const
bool DoSpellAttackIfReady(uint32 spellId)
Definition UnitAI.cpp:61
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:160
virtual void DoAction(int32 param)
Definition UnitAI.h:73
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:180
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:162
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:89
Definition Unit.h:635
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:8697
void SetHealth(uint64 val)
Definition Unit.cpp:9973
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3828
void SetHoverHeight(float hoverHeight)
Definition Unit.h:1147
void SetFaction(uint32 faction) override
Definition Unit.h:872
bool HealthAbovePctHealed(float pct, uint32 heal) const
Definition Unit.h:795
void SetSpeed(UnitMoveType mtype, float newValue)
Definition Unit.cpp:8937
void SetPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:10046
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3231
MotionMaster * GetMotionMaster()
Definition Unit.h:1723
Powers GetPowerType() const
Definition Unit.h:811
bool IsAlive() const
Definition Unit.h:1185
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
void SetEmoteState(Emote emote)
Definition Unit.h:865
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4700
bool SetWalk(bool enable)
Definition Unit.cpp:13343
bool HealthBelowPctDamaged(float pct, uint32 damage) const
Definition Unit.h:793
Unit * GetVictim() const
Definition Unit.h:726
int32 GetPower(Powers power) const
Definition Unit.cpp:10028
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition Unit.cpp:8942
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 SetUnitFlag(UnitFlags flags)
Definition Unit.h:846
void KillSelf(bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition Unit.h:936
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition Unit.cpp:665
bool AttackStop()
Definition Unit.cpp:5965
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3974
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:847
AreaTrigger * GetAreaTrigger(uint32 spellId) const
Definition Unit.cpp:5469
Map * GetMap() const
Definition Object.h:411
InstanceScript * GetInstanceScript() const
Definition Object.cpp:396
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2324
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
Position GetNearPosition(float dist, float angle)
Definition Object.cpp:2755
GameObject * SummonGameObject(uint32 entry, Position const &pos, QuaternionData const &rot, Seconds respawnTime, GOSummonType summonType=GO_SUMMON_TIMED_OR_CORPSE_DESPAWN)
Definition Object.cpp:1441
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:501
bool IsValidAssistTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2482
EventProcessor m_Events
Definition Object.h:561
void MovePositionToFirstCollision(Position &pos, float dist, float angle) const
Definition Object.cpp:2828
Position GetFirstCollisionPosition(float dist, float angle)
Definition Object.cpp:2762
void GetCreatureListWithOptionsInGrid(Container &creatureContainer, float maxSearchRange, FindCreatureOptions const &options) const
Definition Object.cpp:2666
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=nullptr)
Definition Object.cpp:1507
virtual void DoAction(uint32 actionId, WorldObject *source=nullptr, WorldObject *target=nullptr)
Definition ZoneScript.h:104
virtual uint32 GetData(uint32) const
Definition ZoneScript.h:99
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:100
std::unordered_set< uint32 > _skippedPlayers
void OnMovieComplete(Player *player, uint32) override
void MarkPlayerAsSkipped(uint32 playerId)
void HandleDespair(SpellEffIndex effIndex) const
void FilterTargets(std::list< WorldObject * > &unitList) const
void HandleDummy(SpellEffIndex) const
bool Validate(SpellInfo const *spellInfo) override
void OnHealAbsorb(AuraEffect *, HealInfo const &healInfo, uint32 &absorbAmount) const
void OnRemove(AuraEffect const *, AuraEffectHandleModes) const
bool Validate(SpellInfo const *) override
std::unordered_map< ObjectGuid, uint32 > _spellAssignments
bool Validate(SpellInfo const *) override
void FilterTargets(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *) override
void OnProc(AuraEffect *, ProcEventInfo const &eventInfo)
static constexpr std::array< int32, 22 > AnduinRegenCycle
void RecalculateHookDamageTaken(AuraEffect const *, SpellEffectValue &amount, bool &canBeRecalculated) const
void RecalculateHook(AuraEffect const *, SpellEffectValue &amount, bool &canBeRecalculated) const
void OnApply(AuraEffect const *, AuraEffectHandleModes) const
void SetDest(SpellDestination &destination) const
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void OnPeriodic(AuraEffect const *) const
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleHit(SpellEffIndex) const
void OnRemove(AuraEffect const *, AuraEffectHandleModes) const
bool Validate(SpellInfo const *) override
void OnRemove(AuraEffect const *, AuraEffectHandleModes) const
void HandleDebuff(SpellEffIndex) const
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void FilterTargets(std::list< WorldObject * > &targets) const
void OnApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void OnRemove(AuraEffect const *, AuraEffectHandleModes) const
void OnPeriodic(AuraEffect const *aurEff)
void OnRemove(AuraEffect const *, AuraEffectHandleModes) const
void OnApply(AuraEffect const *, AuraEffectHandleModes) const
void CalculateAmount(AuraEffect const *, SpellEffectValue &amount, bool &canBeRecalculated)
bool Validate(SpellInfo const *) override
void Trigger(AuraEffect *, DamageInfo const &dmgInfo, uint32 &absorbAmount)
void OnRemove(AuraEffect const *, AuraEffectHandleModes) const
void OnApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void OnRemove(AuraEffect const *, AuraEffectHandleModes) const
void OnApply(AuraEffect const *, AuraEffectHandleModes) const
void FilterTargets(std::list< WorldObject * > &targets)
void FilterTargets(std::list< WorldObject * > &targets) const
bool Validate(SpellInfo const *) override
void HandleMissile(SpellEffIndex) const
static constexpr std::array< int32, 3 > RemnantRegenCycle
void OnApply(AuraEffect const *, AuraEffectHandleModes) const
void AfterRemove(AuraEffect const *, AuraEffectHandleModes) const
bool Validate(SpellInfo const *) override
void OnRemove(AuraEffect const *, AuraEffectHandleModes) const
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
auto SelectRandomContainerElement(C const &container) -> std::add_const_t< decltype(*std::ranges::begin(container))> &
Definition Containers.h:110
auto MapGetValuePtr(M &map, typename M::key_type const &key)
Definition MapUtils.h:37
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:67
@ WORLD_STATE_ANDUIN_ENCOUNTER_STARTED
@ WORLD_STATE_ANDUIN_ENCOUNTER_COMPLETED
@ WORLD_STATE_ANDUIN_INTERMISSION
#define RegisterSepulcherOfTheFirstOnesCreatureAI(ai_name)
@ BOSS_REMNANT_OF_A_FALLEN_KING
@ NPC_LADY_JAINA_PROUDMOORE_ANDUIN
@ NPC_KNIGHT_OF_EBON_BLADE_ANDUIN
@ NPC_SYLVANAS_WINDRUNNER_ANDUIN
@ NPC_UTHER_THE_LIGHTBRINGER_ANDUIN
@ DATA_QUARTERMASTER_RAHM_ANDUIN
@ DATA_BOLVAR_FORDRAGON_ANDUIN
@ DATA_SYLVANAS_WINDRUNNER_ANDUIN
@ DATA_UTHER_THE_LIGHTBRINGER_ANDUIN
@ DATA_ANDUIN_WRYNN_INTRODUCTION
@ DATA_JAINA_PROUDMOORE_ANDUIN
@ DATA_REMNANT_OF_A_FALLEN_KING
@ GAMEOBJECT_ANDUIN_CHEST_LOOT
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
EnumFlag< ChrSpecializationFlag > GetFlags() const
ChrSpecializationRole GetRole() const
constexpr void SetOrientation(float orientation)
Definition Position.h:82
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:136
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
constexpr float GetOrientation() const
Definition Position.h:90
constexpr float GetPositionZ() const
Definition Position.h:89
static QuaternionData fromEulerAnglesZYX(float Z, float Y, float X)
bool IsHeroic() const
bool IsNormal() const
bool IsMythic() const
void SetCombatMovement(bool allowMovement)
bool IsLFR() const
void Relocate(Position const &pos)
Definition Spell.cpp:82
void OnCreate(Spell const *) override
void OnUpdate(uint32 diff) override
at_anduin_wrynn_beacon_of_hope(AreaTrigger *areatrigger)
void UpdateSize(float radius, float targetRadius) const
void OnUnitEnter(Unit *unit) override
void OnUpdate(uint32 diff) override
void OnUnitEnter(Unit *unit) override
void OnCreate(Spell const *) override
at_anduin_wrynn_befouled_barrier(AreaTrigger *areatrigger)
void OnUnitExit(Unit *unit, AreaTriggerExitReason) override
void UpdateSize(float radius, float targetRadius) const
at_anduin_wrynn_blasphemy(AreaTrigger *areatrigger)
void OnUnitEnter(Unit *unit) override
at_anduin_wrynn_empowered_wicked_star(AreaTrigger *areatrigger)
void OnUnitExit(Unit *unit, AreaTriggerExitReason) override
at_anduin_wrynn_hopelessness(AreaTrigger *areatrigger)
void OnUnitEnter(Unit *unit) override
at_anduin_wrynn_march_of_the_damned(AreaTrigger *areatrigger)
at_anduin_wrynn_pre_introduction(AreaTrigger *areatrigger)
void OnUnitEnter(Unit *unit) override
void OnUnitEnter(Unit *unit) override
at_anduin_wrynn_wicked_star(AreaTrigger *areatrigger)
void JustAppeared() override
void ForceAssistersToAttackRemnant() const
void JustSummoned(Creature *summon) override
void DoAction(int32 action) override
void KilledUnit(Unit *victim) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void PhaseEvents(uint8 phase)
boss_anduin_wrynn(Creature *creature)
void PrepareAssistersForIntermission() const
void UpdateAI(uint32 diff) override
void MoveKnightsOnPlatform() const
void JustEngagedWith(Unit *who) override
void StartIntermission(uint8 intermissionNum)
void SummonedCreatureDies(Creature *summon, Unit *) override
void EnterEvadeMode(EvadeReason) override
void EnterEvadeMode(EvadeReason) override
boss_remnant_of_a_fallen_king(Creature *creature)
void UpdateAI(uint32 diff) override
void DoAction(int32 action) override
void JustSummoned(Creature *summon) override
npc_anduin_wrynn_anduin_despair(Creature *creature)
npc_anduin_wrynn_anduin_doubt(Creature *creature)
void MovementInform(uint32 type, uint32 pointId) override
void HealReceived(Unit *, uint32 &heal) override
void UpdateAI(uint32 diff) override
npc_anduin_wrynn_anduin_hope(Creature *creature)
void JustSummoned(Creature *who) override
void DoAction(int32 action) override
npc_anduin_wrynn_anduin_soul(Creature *creature)
void EnterEvadeMode(EvadeReason) override
void JustUnregisteredAreaTrigger(AreaTrigger *areaTrigger) override
npc_anduin_wrynn_beacon_of_hope(Creature *creature)
void IsSummonedBy(WorldObject *summoner) override
npc_anduin_wrynn_empty_vessel(Creature *creature)
void UpdateAI(uint32 diff) override
npc_anduin_wrynn_fiendish_soul(Creature *creature)
void EnterEvadeMode(EvadeReason) override
void UpdateAI(uint32 diff) override
npc_anduin_wrynn_grim_reflection(Creature *creature)
void UpdateAI(uint32 diff) override
bool CanAIAttack(Unit const *target) const override
void WaypointPathEnded(uint32, uint32 pathId) override
void JustEngagedWith(Unit *) override
npc_anduin_wrynn_jaina(Creature *creature)
void IsSummonedBy(WorldObject *summoner) override
npc_anduin_wrynn_lost_soul(Creature *creature)
void UpdateAI(uint32 diff) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void EnterEvadeMode(EvadeReason) override
npc_anduin_wrynn_monstrous_soul(Creature *creature)
void UpdateAI(uint32 diff) override
void DoAction(int32 action) override
npc_anduin_wrynn_sylvanas(Creature *creature)
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *) override
bool CanAIAttack(Unit const *target) const override
void UpdateAI(uint32 diff) override
bool CanAIAttack(Unit const *target) const override
npc_anduin_wrynn_uther(Creature *creature)
void JustEngagedWith(Unit *who) override