TrinityCore
Loading...
Searching...
No Matches
boss_kaelthas.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/*
19 * Spells SPELL_ROOT_SELF and SPELL_PACIFY_SELF are guessed, based on effects received in packets
20 * Phoenix's on-death sequence requires sniff verification, partially based on a movie and MGT version
21 * The way Telonicus casts shoot and bomb requires additional research, can't figure out how exactly both are used
22 * Shock Barrier reflect damage calculation requires re-check, current formula may be wrong, based almost on nothing
23 * What does Script Effect of the Banish spell?
24 * Phoenix behavior during Gravity Lapse requires research. While in banish, they don't cast the Burn spell but
25 how it is implemented remains unknown. What happens to eggs and invisible phoenixes is unknown
26 * Combat timers requires to be revisited, especially in ground phase 5
27 * The way we change spells and stages requires additional research, current behavior is not entrirely correct but
28 correct approach remains unknown
29 * Spell 39254 probably is used to despawn advisors in case of wipe and death, currently we despawn them by despawning spawn groups
30 * What does Script Effect of spell 35879?
31 * Before some patch, doors were closed when first advisor was engaged, allowing players to kite advisors and Kael'thas through whole
32 instance. We close doors when encounter starts
33 * Nether Vapor's movement requires research, they send almost no move packets but they move. Currently we force them to move randomly but
34 on retail that doesn't look like random movement
35 * Visual effect of Pure Nether Beam doesn't stop. Looks like client bug, saw same in WoTLK classic
36 * Drowned emote during transition doesn't trigger, not set manually in sniffs (doesn't work if set manually either way). From my observation this boss has
37 different bugs in different expansions. Something is fixed in one and is broken in another
38 */
39
40#include "ScriptMgr.h"
41#include "Containers.h"
42#include "DBCStores.h"
43#include "GameObject.h"
44#include "InstanceScript.h"
45#include "Map.h"
46#include "MotionMaster.h"
47#include "ObjectMgr.h"
48#include "ScriptedCreature.h"
49#include "SpellAuraEffects.h"
50#include "SpellInfo.h"
51#include "SpellScript.h"
52#include "the_eye.h"
53
90
92{
93 // Phase 1
96
101
102 // Phase 2
104
105 // Phase 3
107
108 // Phase 4
116
117 // Transition
132
133 // Phase 5
138
139 // Generic spells
142
143 // Thaladred the Darkener
145 SPELL_REND = 36965,
147
148 // Lord Sanguinar
150
151 // Grand Astromancer Capernian
155
156 // Master Engineer Telonicus
157 SPELL_SHOOT = 16496,
158 SPELL_BOMB = 37036,
160
161 // Flame Strike Trigger (Kael)
163
164 // Phoenix
172
173 // Nether Vapor
177
178 // Scripts
179 // Mind Control
181
182 // Shock Barrier
184
185 // Remote Toy
187
188 // Gravity Lapse
214
217
219
220 // Flame Strike
222
223 // Summon Weapons
231
232 // Remove Enchanted Weapons
240
241 // Kael Gaining Power
245
246 // Pure Nether Beam
250
251 // Summon Nether Vapor
256
257 // Nether Beam
260
315
323
332
340
350
357
368
374
382
383static constexpr std::array<uint32, 4> AdvisorsSpawnGroupsData =
384{
389};
390
401
412
441
449
450Position const TransitionStartPos = { 796.641f, -0.588817f, 48.728474f, 0.0f };
451Position const TransitionUpPos = { 795.007f, -0.471827f, 75.000000f, 0.0f };
452Position const TransitionDownPos = { 792.419f, -0.504778f, 50.050500f, 0.0f };
453
454// 19622 - Kael'thas Sunstrider
455struct boss_kaelthas : public BossAI
456{
459
460 void JustAppeared() override
461 {
463 me->SetRegenerateHealth(false);
464
466
467 for (uint32 group : AdvisorsSpawnGroupsData)
468 me->GetMap()->SpawnGroupSpawn(group, true);
469 }
470
471 void JustEngagedWith(Unit* who) override
472 {
474
475 if (_phase == PHASE_NONE)
477 }
478
479 void MoveInLineOfSight(Unit* who) override
480 {
481 if (_phase == PHASE_NONE && me->IsValidAttackTarget(who) && me->IsWithinDistInMap(who, 30.0f) && who->GetTypeId() == TYPEID_PLAYER)
483 }
484
491
492 void AttackStart(Unit* who) override
493 {
495 }
496
497 void DoAction(int32 action) override
498 {
499 if (action == ACTION_ENGAGE_COMBAT)
500 if (_phase == PHASE_3_ADVANCE)
502 }
503
504 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
505 {
506 switch (spellInfo->Id)
507 {
510 break;
513 break;
516 break;
519 break;
523 break;
524 default:
525 break;
526 }
527 }
528
529 void OnSpellStart(SpellInfo const* spellInfo) override
530 {
531 if (spellInfo->Id == SPELL_GRAVITY_LAPSE)
533 }
534
535 void OnSpellCast(SpellInfo const* spellInfo) override
536 {
537 switch (spellInfo->Id)
538 {
541 break;
544 break;
546 if (_phase == PHASE_4_ENGAGED)
547 {
549 _pyroblastCount = 0;
552 }
553 break;
556 break;
557 default:
558 break;
559 }
560 }
561
562 void OnSpellFailed(SpellInfo const* spellInfo) override
563 {
564 if (spellInfo->Id == SPELL_PYROBLAST)
565 {
568 }
569 }
570
572 {
573 switch (stage)
574 {
583 break;
587 break;
598 break;
607 break;
608 default:
609 break;
610 }
611 }
612
613 void MovementInform(uint32 type, uint32 point) override
614 {
615 if (type != POINT_MOTION_TYPE)
616 return;
617
618 switch (point)
619 {
622 break;
625 break;
626 default:
627 break;
628 }
629 }
630
631 void JustSummoned(Creature* summon) override
632 {
633 // Do not engage summons, handled manually in each script
634 summons.Summon(summon);
635 }
636
637 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
638 {
640 {
643 }
644 }
645
646 void EnterEvadeMode(EvadeReason /*why*/) override
647 {
649
651 statue->ResetDoorOrButton();
652
654 statue->ResetDoorOrButton();
655
657 window->ResetDoorOrButton();
658
659 for (uint32 group : AdvisorsSpawnGroupsData)
660 me->GetMap()->SpawnGroupDespawn(group);
661
662 if (Creature* controller = me->FindNearestCreatureWithOptions(250.0f, { .StringId = "KaelthasControllerTrigger" }))
663 controller->AI()->DoAction(ACTION_RESET_CONTROLLER);
664
666 _DespawnAtEvade(15s);
667 }
668
669 void KilledUnit(Unit* /*victim*/) override
670 {
671 Talk(SAY_SLAY);
672 }
673
674 void JustDied(Unit* /*killer*/) override
675 {
677 _JustDied();
678
679 for (uint32 group : AdvisorsSpawnGroupsData)
680 me->GetMap()->SpawnGroupDespawn(group);
681 }
682
683 void UpdateAI(uint32 diff) override
684 {
685 if (!UpdateVictim())
686 return;
687
688 specialEvents.Update(diff);
689
690 while (uint32 eventId = specialEvents.ExecuteEvent())
691 {
692 switch (eventId)
693 {
694 // Phase 4
695 case EVENT_PYROBLAST:
696 if (_pyroblastCount < 3)
697 {
701 }
702 else
704 break;
705
706 // Transition
708 me->AttackStop();
712 events.Reset();
713 break;
715 me->SetFacingTo(3.176499128341674804f);
719 break;
723 break;
725 me->SetWalk(true);
726 me->SetDisableGravity(true);
727 me->SetHover(true);
729
730 if (Creature* trigger = me->FindNearestCreatureWithOptions(100.0f, { .StringId = "KaelthasNetherbeamChannelTrigger1" }))
731 trigger->CastSpell(trigger, SPELL_NETHERBEAM_CHANNEL_1);
732
733 if (Creature* trigger = me->FindNearestCreatureWithOptions(100.0f, { .StringId = "KaelthasNetherbeamChannelTrigger2" }))
734 trigger->CastSpell(trigger, SPELL_NETHERBEAM_CHANNEL_2);
735
738 break;
740 if (Creature* trigger = me->FindNearestCreatureWithOptions(100.0f, { .StringId = "KaelthasNetherbeamChannelTrigger3" }))
741 trigger->CastSpell(trigger, SPELL_NETHERBEAM_CHANNEL_1);
742
743 if (Creature* trigger = me->FindNearestCreatureWithOptions(100.0f, { .StringId = "KaelthasNetherbeamChannelTrigger4" }))
744 trigger->CastSpell(trigger, SPELL_NETHERBEAM_CHANNEL_2);
745
747 break;
749 if (Creature* trigger = me->FindNearestCreatureWithOptions(100.0f, { .StringId = "KaelthasNetherbeamChannelTrigger5" }))
750 trigger->CastSpell(trigger, SPELL_NETHERBEAM_CHANNEL_1);
751
752 if (Creature* trigger = me->FindNearestCreatureWithOptions(100.0f, { .StringId = "KaelthasNetherbeamChannelTrigger6" }))
753 trigger->CastSpell(trigger, SPELL_NETHERBEAM_CHANNEL_2);
754
756 break;
759 object->UseDoorOrButton();
760
762 object->UseDoorOrButton();
763
765 break;
767 {
772
773 std::vector<Creature*> triggers;
774 GetCreatureListWithOptionsInGrid(triggers, me, 150.0f, { .StringId = "KaelthasExplosionTrigger" });
775 for (Creature* trigger : triggers)
776 trigger->CastSpell(trigger, SPELL_KAEL_EXPLODES_4);
777
779 object->UseDoorOrButton();
780
783 break;
784 }
789 break;
793 break;
796 me->SetDisableGravity(false);
797 me->SetHover(false);
802 break;
803
804 // Transition: Explosion
806 {
807 std::vector<Creature*> triggers;
808 GetCreatureListWithOptionsInGrid(triggers, me, 150.0f, { .StringId = "KaelthasExplosionTrigger" });
809 for (Creature* trigger : triggers)
810 trigger->CastSpell(trigger, SPELL_KAEL_EXPLODES_1);
811
813 break;
814 }
816 {
817 std::vector<Creature*> triggers;
818 GetCreatureListWithOptionsInGrid(triggers, me, 150.0f, { .StringId = "KaelthasExplosionTrigger" });
819 for (Creature* trigger : triggers)
820 trigger->CastSpell(trigger, SPELL_KAEL_EXPLODES_2);
821
823 break;
824 }
826 {
827 std::vector<Creature*> triggers;
828 GetCreatureListWithOptionsInGrid(triggers, me, 150.0f, { .StringId = "KaelthasExplosionTrigger" });
829 for (Creature* trigger : triggers)
830 trigger->CastSpell(trigger, SPELL_KAEL_EXPLODES_3);
831 break;
832 }
833
834 // Transition: Pure Nether Beam
836 {
837 std::vector<Creature*> triggersGroup1;
838 GetCreatureListWithOptionsInGrid(triggersGroup1, me, 150.0f, { .StringId = "KaelthasPureNetherBeamTriggerGroup1" });
839 for (Creature* trigger : triggersGroup1)
840 if (roll_chance_i(30))
841 trigger->CastSpell(trigger, SPELL_PURE_NETHER_BEAM_SCRIPT_1);
842
843 std::vector<Creature*> triggersGroup2;
844 GetCreatureListWithOptionsInGrid(triggersGroup2, me, 150.0f, { .StringId = "KaelthasPureNetherBeamTriggerGroup2" });
845 for (Creature* trigger : triggersGroup2)
846 if (roll_chance_i(20))
847 trigger->CastSpell(trigger, SPELL_PURE_NETHER_BEAM_SCRIPT_2);
848
849 std::vector<Creature*> triggersGroup3;
850 GetCreatureListWithOptionsInGrid(triggersGroup3, me, 150.0f, { .StringId = "KaelthasPureNetherBeamTriggerGroup3" });
851 for (Creature* trigger : triggersGroup3)
852 if (roll_chance_i(30))
853 trigger->CastSpell(trigger, SPELL_PURE_NETHER_BEAM_SCRIPT_3);
854
855 specialEvents.Repeat(400ms);
856 break;
857 }
858 default:
859 break;
860 }
861 }
862
863 events.Update(diff);
864
866 return;
867
868 while (uint32 eventId = events.ExecuteEvent())
869 {
870 switch (eventId)
871 {
872 // Phase 1
877 break;
883 break;
886 advisor->AI()->DoAction(ACTION_ADVISOR_ENGAGED);
888 break;
889
890 // Phase 1, 2, 3: Special
891 case EVENT_SET_FACING:
892 // This is quite tricky event. What is known and verified:
893 // 1. This event starts when first advisor is engaged
894 // 2. Event stops when phase 4 begins
895 // 3. This is not SetTarget since boss constantly sends unit field target with 0 as value
896 // 4. This is pure SetFacingTo
897 // 5. Minimal delay between events is exactly 400ms
898 // 6. Event triggers even if player's position was changed a little (result FaceDirection: 3.00765 > FaceDirection: 3.00557)
899 // What remains unknown or not implemented:
900 // 1. Looks like event doesn't trigger if boss already faces that direction
901 // 2. Is delay between events random or always 400ms?
902 // 3. What happens if target dies remains unknown
903 // 4. Looks like he switches target every x second, we use max threat for now, maybe it's correct
905 {
907 events.Repeat(400ms);
908 }
909 break;
910
911 // Phase 2
917 break;
918
919 // Phase 3
924 break;
928 break;
938 break;
939
940 // Phase 4
941 case EVENT_FIREBALL:
943 events.Repeat(2400ms);
944 break;
946 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 200.0f, true))
947 DoCast(target, SPELL_FLAME_STRIKE);
948 events.Repeat(30s, 40s);
949 break;
952 events.Repeat(20s, 30s);
953 break;
956 events.Repeat(45s, 55s);
957 break;
960 events.Repeat(30s, 45s);
961 break;
964 events.Repeat(_phase == PHASE_4_ENGAGED ? 60s : 7s);
965 break;
966
967 // Phase 5
970 break;
973 break;
976 break;
979 break;
982 events.Repeat(3600ms);
983 break;
984 default:
985 break;
986 }
987
989 return;
990 }
991
993 }
994
995private:
1001};
1002
1004{
1005 AdvisorBaseAI(Creature* creature) : ScriptedAI(creature), HasRessurrected(false), IsFeigningDeath(false) { }
1006
1007 void InitializeAI() override
1008 {
1009 me->SetImmuneToPC(true);
1010
1011 Scheduler.SetValidator([this]
1012 {
1014 });
1015 }
1016
1017 void Reset() override
1018 {
1020 }
1021
1022 void JustEngagedWith(Unit* /*who*/) override
1023 {
1025 }
1026
1027 virtual void ScheduleEvents() = 0;
1028
1029 void DoAction(int32 action) override
1030 {
1031 if (action == ACTION_ADVISOR_ENGAGED)
1032 {
1033 me->SetImmuneToPC(false);
1035 }
1036 }
1037
1039 {
1040 if (Creature* controller = me->FindNearestCreatureWithOptions(250.0f, { .StringId = "KaelthasControllerTrigger" }))
1041 controller->AI()->DoAction(ACTION_ADVISOR_DEFEATED);
1042 }
1043
1044 bool IsEnemyInRange(float distance)
1045 {
1047 if (me->GetDistance2d(ref->GetVictim()) < distance)
1048 return true;
1049
1050 return false;
1051 }
1052
1053 void DamageTaken(Unit* /*who*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1054 {
1055 if (HasRessurrected)
1056 return;
1057
1058 if (damage >= me->GetHealth())
1059 {
1060 damage = me->GetHealth() -1;
1061
1062 if (!IsFeigningDeath)
1063 {
1064 IsFeigningDeath = true;
1065
1066 Scheduler.Schedule(0s, [this](TaskContext /*task*/)
1067 {
1069
1074 });
1075 }
1076 }
1077 }
1078
1079 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
1080 {
1081 if (spellInfo->Id == SPELL_RESSURECTION)
1082 {
1083 Scheduler.Schedule(0s, [this](TaskContext task)
1084 {
1085 switch (task.GetRepeatCounter())
1086 {
1087 case 0:
1088 me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
1089 me->SetReactState(REACT_PASSIVE);
1090 task.Repeat(2500ms);
1091 break;
1092 case 1:
1093 me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
1094 me->SetReactState(REACT_AGGRESSIVE);
1095 ResetThreatList();
1096 ScheduleEvents();
1097 HasRessurrected = true;
1098 IsFeigningDeath = false;
1099 break;
1100 default:
1101 break;
1102 }
1103 });
1104 }
1105 }
1106
1107 void JustDied(Unit* /*killer*/) override
1108 {
1110 }
1111
1112 void UpdateAI(uint32 diff) override
1113 {
1114 if (!UpdateVictim())
1115 return;
1116
1117 Scheduler.Update(diff);
1118
1120 }
1121
1122protected:
1126};
1127
1128// 20064 - Thaladred the Darkener
1130{
1132
1133 void ScheduleEvents() override
1134 {
1135 Scheduler
1136 .Schedule(2s, 3s, [this](TaskContext task)
1137 {
1138 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
1139 {
1141 AddThreat(target, 1000000.0f);
1142 Talk(EMOTE_THALADRED_GAZE, target);
1143 }
1144 task.Repeat(8s, 18s);
1145 })
1146 .Schedule(0s, [this](TaskContext task)
1147 {
1148 if (IsEnemyInRange(10.0f))
1150 task.Repeat(5s);
1151 })
1152 .Schedule(0s, 5s, [this](TaskContext task)
1153 {
1155 task.Repeat(3s, 5s);
1156 })
1157 .Schedule(0s, 5s, [this](TaskContext task)
1158 {
1160 task.Repeat(15s, 20s);
1161 });
1162 }
1163
1164 void JustEngagedWith(Unit* who) override
1165 {
1168 }
1169
1170 void JustDied(Unit* killer) override
1171 {
1174 }
1175};
1176
1177// 20060 - Lord Sanguinar
1179{
1180 boss_lord_sanguinar(Creature* creature) : AdvisorBaseAI(creature) { }
1181
1182 void ScheduleEvents() override
1183 {
1184 Scheduler
1185 .Schedule(0s, 5s, [this](TaskContext task)
1186 {
1187 if (IsEnemyInRange(35.0f))
1189 task.Repeat(30s, 45s);
1190 });
1191 }
1192
1193 void JustEngagedWith(Unit* who) override
1194 {
1197 }
1198
1199 void JustDied(Unit* killer) override
1200 {
1203 }
1204};
1205
1206// 20062 - Grand Astromancer Capernian
1208{
1210
1211 void ScheduleEvents() override
1212 {
1213 Scheduler
1214 .Schedule(0s, [this](TaskContext task)
1215 {
1217 task.Repeat(2400ms);
1218 })
1219 .Schedule(0s, 20s, [this](TaskContext task)
1220 {
1221 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f))
1222 DoCast(target, SPELL_CONFLAGRATION);
1223 task.Repeat(15s);
1224 })
1225 .Schedule(0s, [this](TaskContext task)
1226 {
1227 if (IsEnemyInRange(10.0f))
1229 task.Repeat(1200ms);
1230 });
1231 }
1232
1233 void AttackStart(Unit* who) override
1234 {
1236 }
1237
1238 void JustEngagedWith(Unit* who) override
1239 {
1242 }
1243
1244 void JustDied(Unit* killer) override
1245 {
1248 }
1249};
1250
1251// 20063 - Master Engineer Telonicus
1253{
1255
1256 void ScheduleEvents() override
1257 {
1258 Scheduler
1259 .Schedule(0s, [this](TaskContext task)
1260 {
1262 task.Repeat(2400ms);
1263 })
1264 .Schedule(0s, [this](TaskContext task)
1265 {
1267 task.Repeat(3600ms);
1268 })
1269 .Schedule(0s, 10s, [this](TaskContext task)
1270 {
1271 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, false, true, -SPELL_REMOTE_TOY))
1272 DoCast(target, SPELL_REMOTE_TOY);
1273 task.Repeat(15s, 18s);
1274 });
1275 }
1276
1277 void AttackStart(Unit* who) override
1278 {
1280 }
1281
1282 void JustEngagedWith(Unit* who) override
1283 {
1286 }
1287
1288 void JustDied(Unit* killer) override
1289 {
1292 }
1293};
1294
1295// 22515 - World Trigger
1297{
1299 _instance(creature->GetInstanceScript()), _defeatedAdvisorCounter(0) { }
1300
1301 // The reasons why this script exists:
1302 // 1. We know that specific AIGroup actions autotargets invoker of event and this creature is receiver
1303 // of Kael'thas' texts in phase 1, 2 and 3, meaning this creature is invoker of those events
1304 // 2. This creature casts non-serverside spell (Kael Phase Two) that starts phase 2. Other spells are
1305 // serverside and are guessed but perfectly satisfies our needs
1306 void Reset() override
1307 {
1310 }
1311
1312 void DoAction(int32 action) override
1313 {
1314 switch (action)
1315 {
1317 {
1319
1321 {
1322 case ADVISOR_THALADRED:
1324 _scheduler.Schedule(12500ms, [this](TaskContext /*task*/)
1325 {
1327 advisor->AI()->DoAction(ACTION_ADVISOR_ENGAGED);
1328 });
1329 break;
1330 case ADVISOR_SANGUINAR:
1332 _scheduler.Schedule(7s, [this](TaskContext /*task*/)
1333 {
1335 advisor->AI()->DoAction(ACTION_ADVISOR_ENGAGED);
1336 });
1337 break;
1338 case ADVISOR_CAPERNIAN:
1340 _scheduler.Schedule(8s, [this](TaskContext /*task*/)
1341 {
1343 advisor->AI()->DoAction(ACTION_ADVISOR_ENGAGED);
1344 });
1345 break;
1346 case ADVISOR_TELONICUS:
1348 break;
1350 if (Creature* kaelthas = _instance->GetCreature(DATA_KAELTHAS))
1351 kaelthas->AI()->DoAction(ACTION_ENGAGE_COMBAT);
1352 break;
1353 default:
1354 break;
1355 }
1356 break;
1357 }
1359 Reset();
1360 break;
1361 default:
1362 break;
1363 }
1364 }
1365
1366 void UpdateAI(uint32 diff) override
1367 {
1368 _scheduler.Update(diff);
1369 }
1370
1371private:
1375};
1376
1377// 21369 - Flame Strike Trigger (Kael)
1379{
1381
1382 void InitializeAI() override
1383 {
1385 }
1386
1387 void JustAppeared() override
1388 {
1390 me->DespawnOrUnsummon(15s);
1391 }
1392};
1393
1394// 21362 - Phoenix
1396{
1397 npc_phoenix_the_eye(Creature* creature) : ScriptedAI(creature), _isDepleted(false), _summons(me) { }
1398
1399 void InitializeAI() override
1400 {
1402 }
1403
1404 void JustAppeared() override
1405 {
1408
1409 _scheduler.Schedule(3s, [this](TaskContext /*task*/)
1410 {
1413 });
1414 }
1415
1416 void OnSpellCast(SpellInfo const* spellInfo) override
1417 {
1418 if (spellInfo->Id == SPELL_BURN_TRIGGER)
1420 }
1421
1422 void JustSummoned(Creature* summon) override
1423 {
1424 _summons.Summon(summon);
1425 }
1426
1427 void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override
1428 {
1430 }
1431
1432 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1433 {
1434 if (damage >= me->GetHealth())
1435 {
1436 damage = me->GetHealth() - 1;
1437
1438 if (!_isDepleted)
1439 {
1440 _isDepleted = true;
1441
1448
1449 _scheduler.Schedule(15s, [this](TaskContext task)
1450 {
1451 switch (task.GetRepeatCounter())
1452 {
1453 case 0:
1454 _summons.DespawnAll();
1455 me->RemoveAurasDueToSpell(SPELL_EMBER_BLAST);
1456 me->RemoveAurasDueToSpell(SPELL_SUMMON_PHOENIX_EGG);
1457 task.Repeat(2s);
1458 break;
1459 case 1:
1460 me->SetStandState(UNIT_STAND_STATE_STAND);
1461 DoCastSelf(SPELL_REBIRTH_RESPAWN);
1462 task.Repeat(3s);
1463 break;
1464 case 2:
1465 _isDepleted = false;
1466 DoCastSelf(SPELL_FULL_HEAL);
1467 DoCastSelf(SPELL_BURN_PERIODIC);
1468 me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
1469 task.Repeat(2s);
1470 break;
1471 case 3:
1472 me->SetReactState(REACT_AGGRESSIVE);
1473 break;
1474 default:
1475 break;
1476 }
1477 });
1478 }
1479 }
1480 }
1481
1482 void UpdateAI(uint32 diff) override
1483 {
1484 _scheduler.Update(diff);
1485
1486 if (UpdateVictim())
1488 }
1489
1490private:
1494};
1495
1496// 21364 - Phoenix Egg
1498{
1499 npc_phoenix_egg_the_eye(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
1500
1501 void InitializeAI() override
1502 {
1503 me->SetCorpseDelay(5, true);
1505 }
1506
1507 void JustAppeared() override
1508 {
1509 if (Creature* kaelthas = _instance->GetCreature(DATA_KAELTHAS))
1510 kaelthas->AI()->JustSummoned(me);
1511 }
1512
1513private:
1515};
1516
1517// 21002 - Nether Vapor
1519{
1520 npc_nether_vapor(Creature* creature) : ScriptedAI(creature) { }
1521
1522 void InitializeAI() override
1523 {
1525 }
1526
1535};
1536
1537// 36797 - Mind Control
1539{
1541
1542 bool Load() override
1543 {
1544 return GetCaster()->IsUnit();
1545 }
1546
1547 void FilterTargets(std::list<WorldObject*>& targets)
1548 {
1549 targets.remove(GetCaster()->GetVictim());
1551 }
1552
1557};
1558
1584
1585// 36815 - Shock Barrier
1587{
1589
1590 bool Validate(SpellInfo const* /*spellInfo*/) override
1591 {
1593 }
1594
1595 void OnAbsorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)
1596 {
1598 .SetTriggerFlags(TRIGGERED_FULL_MASK)
1599 .AddSpellMod(SPELLVALUE_BASE_POINT0, absorbAmount / 15));
1600 }
1601
1606};
1607
1608// 36819 - Pyroblast
1610{
1612
1613 void FilterTargets(std::list<WorldObject*>& targets)
1614 {
1615 if (targets.empty())
1616 return;
1617
1618 if (WorldObject* target = GetCaster()->GetVictim())
1619 {
1620 targets.clear();
1621 targets.push_back(target);
1622 }
1623 }
1624
1629};
1630
1631// 37027 - Remote Toy
1633{
1635
1636 bool Validate(SpellInfo const* /*spellInfo*/) override
1637 {
1639 }
1640
1641 void HandlePeriodic(AuraEffect const* /*aurEff*/)
1642 {
1643 if (roll_chance_i(50))
1645 }
1646
1651};
1652
1653// 35941 - Gravity Lapse
1655{
1657
1658public:
1663
1668
1669 void HandleScript(SpellEffIndex /*effIndex*/)
1670 {
1671 Unit* caster = GetCaster();
1672 Unit* target = GetHitUnit();
1673
1674 caster->CastSpell(target, GravityLapseSpells[std::min(_targetCount, GravityLapseSpells.size() - 1)], true);
1675 target->CastSpell(target, SPELL_GRAVITY_LAPSE_FLIGHT_AURA, true);
1676 target->CastSpell(target, SPELL_GRAVITY_LAPSE_PERIODIC, true);
1677 _targetCount++;
1678 }
1679
1684
1685private:
1686 std::size_t _targetCount;
1687};
1688
1689// 34480 - Gravity Lapse
1691{
1693
1694 bool Validate(SpellInfo const* /*spellInfo*/) override
1695 {
1697 }
1698
1699 void OnPeriodic(AuraEffect const* /*aurEff*/)
1700 {
1701 Unit* target = GetTarget();
1702 if (!target->IsFlying() || std::abs(target->GetPositionZ() - target->GetFloorZ()) < 0.5f)
1703 target->CastSpell(target, SPELL_GRAVITY_LAPSE_KNOCK_BACK, true);
1704 }
1705
1710};
1711
1712// 36730 - Flame Strike
1732
1733// 36976 - Summon Weapons
1735{
1737
1738 bool Validate(SpellInfo const* /*spellInfo*/) override
1739 {
1741 }
1742
1743 void HandleScript(SpellEffIndex /*effIndex*/)
1744 {
1745 Unit* caster = GetCaster();
1746 for (uint32 spell : SummonWeaponsSpells)
1747 caster->CastSpell(caster, spell, true);
1748 }
1749
1754};
1755
1756// 39497 - Remove Enchanted Weapons
1758{
1760
1761 bool Validate(SpellInfo const* /*spellInfo*/) override
1762 {
1764 }
1765
1766 void HandleScript(SpellEffIndex /*effIndex*/)
1767 {
1768 Unit* target = GetHitUnit();
1769 for (uint32 spell : RemoveWeaponsSpells)
1771 }
1772
1777};
1778
1779// 36091 - Kael Gaining Power
1781{
1783
1784 bool Validate(SpellInfo const* /*spellInfo*/) override
1785 {
1789 }
1790
1791 void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1792 {
1793 Unit* target = GetTarget();
1796 }
1797
1798 void OnPeriodic(AuraEffect const* aurEff)
1799 {
1800 Unit* target = GetTarget();
1801
1802 switch (aurEff->GetTickNumber())
1803 {
1804 case 1:
1805 target->CastSpell(target, SPELL_NETHERBEAM_1, true);
1808 break;
1809 case 2:
1811 target->CastSpell(target, SPELL_NETHERBEAM_2, true);
1814 break;
1815 case 3:
1817 target->CastSpell(target, SPELL_NETHERBEAM_3, true);
1820 break;
1821 default:
1822 break;
1823 }
1824 }
1825
1831};
1832
1833// 36092 - Kael Explodes
1861
1862// 36201, 36290, 36291 - Pure Nether Beam
1893
1894// 36196, 36197, 36198 - Pure Nether Beam
1910
1911// 35865 - Summon Nether Vapor
1913{
1915
1916 bool Validate(SpellInfo const* /*spellInfo*/) override
1917 {
1919 }
1920
1921 void HandleScript(SpellEffIndex /*effIndex*/)
1922 {
1923 Unit* caster = GetCaster();
1924 for (uint32 spell : SummonNetherVaporSpells)
1925 caster->CastSpell(caster, spell, true);
1926 }
1927
1932};
1933
1934// 35861, 35862, 35863, 35864 - Summon Nether Vapor
1965
1966// 45960 - Nether Vapor Lightning
1968{
1970
1971 bool Validate(SpellInfo const* spellInfo) override
1972 {
1973 return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
1974 }
1975
1976 void OnPeriodic(AuraEffect const* aurEff)
1977 {
1978 GetTarget()->CastSpell(GetTarget()->GetNearPosition(10.0f, frand(0.0f, 2.0f * float(M_PI))), aurEff->GetAmount());
1979 }
1980
1985};
1986
1987// 35869 - Nether Beam
1989{
1991
1992 bool Validate(SpellInfo const* /*spellInfo*/) override
1993 {
1995 }
1996
1997 void HandleScript(SpellEffIndex /*effIndex*/)
1998 {
1999 if (Creature* caster = GetCaster()->ToCreature())
2000 {
2001 std::vector<Unit*> targets;
2002 for (ThreatReference const* ref : caster->GetThreatManager().GetUnsortedThreatList())
2003 targets.push_back(ref->GetVictim());
2004
2006
2007 for (Unit* target : targets)
2008 caster->CastSpell(target, SPELL_NETHER_BEAM_CHAIN, true);
2009 }
2010 }
2011
2016};
2017
2019{
2047}
#define M_PI
Definition Common.h:72
First const & RAND(First const &first, Second const &second, Rest const &... rest)
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
@ POINT_MOTION_TYPE
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
float frand(float min, float max)
Definition Random.cpp:55
bool roll_chance_i(int chance)
Definition Random.h:59
#define RegisterSpellAndAuraScriptPair(script_1, script_2)
Definition ScriptMgr.h:1130
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
void GetCreatureListWithOptionsInGrid(Container &container, WorldObject *source, float maxSearchRange, FindCreatureOptions const &options)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ TARGET_DEST_CASTER_FRONT
@ TARGET_DEST_CASTER_LEFT
@ TARGET_UNIT_SRC_AREA_ENTRY
@ TARGET_DEST_CASTER_RIGHT
@ TARGET_DEST_CASTER_BACK
@ TARGET_UNIT_SRC_AREA_ENEMY
#define EFFECT_ALL
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_DUMMY
@ SPELL_AURA_AOE_CHARM
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
@ SPELLVALUE_BASE_POINT0
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define SpellDestinationTargetSelectFn(F, I, N)
#define AuraEffectAbsorbFn(F, I)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraEffectRemoveFn(F, I, N, M)
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_STAND_STATE_DEAD
Definition UnitDefines.h:41
@ UNIT_FLAG_UNINTERACTIBLE
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
@ NODAMAGE
Definition Unit.h:357
KaelthasSounds
@ SOUND_FIRE_WARD_TARGET
@ SOUND_PRECAST_FROST_HIGH
@ SOUND_HOLY_BOLT
@ SOUND_EXORCISM
@ SOUND_GHOSTLY_STRIKE_IMPACT
@ SOUND_ARCANE_EXPLOSION
@ SOUND_PRECAST_NATURE_LOW
Position const TransitionStartPos
KaelthasSpawnGroups
@ SPAWN_GROUP_SANGUINAR
@ SPAWN_GROUP_CAPERNIAN
@ SPAWN_GROUP_TELONICUS
@ SPAWN_GROUP_THALADRED
Position const TransitionDownPos
@ PHASE_3_ADVANCE
@ PHASE_4_ENGAGED
@ PHASE_NONE
@ PHASE_5_TRUE_POWER
@ PHASE_2_WEAPONS
@ PHASE_1_INTRO
@ SAY_DEATH
@ SAY_THALADRED_DEATH
@ SAY_SANGUINAR_AGGRO
@ SAY_INTRO_SANGUINAR
@ SAY_PHASE_3_ADVANCE
@ SAY_TELONICUS_AGGRO
@ SAY_PHASE_5_NUTS
@ SAY_INTRO_TELONICUS
@ SAY_CAPERNIAN_AGGRO
@ SAY_THALADRED_AGGRO
@ SAY_PHASE_4_INTRO_2
@ SAY_SLAY
@ SAY_CAPERNIAN_DEATH
@ SAY_SUMMON_PHOENIX
@ EMOTE_PYROBLAST
@ SAY_GRAVITY_LAPSE
@ SAY_MIND_CONTROL
@ EMOTE_THALADRED_GAZE
@ SAY_INTRO_THALADRED
@ SAY_INTRO_CAPERNIAN
@ SAY_INTRO
@ SAY_SANGUINAR_DEATH
@ SAY_TELONICUS_DEATH
@ SAY_PHASE_2_WEAPONS
static constexpr std::array< uint32, 4 > SummonNetherVaporSpells
KaelthasSpellVisualKits
@ SPELL_VISUAL_KIT_2
@ SPELL_VISUAL_KIT_1
KaelthasCombatStages
@ COMBAT_STAGE_PHASE_5_GRAVITY
@ COMBAT_STAGE_PHASE_5_INITIAL
@ COMBAT_STAGE_PHASE_5_GROUND
@ COMBAT_STAGE_PHASE_4
KaelthasAdvisors
@ ADVISOR_CAPERNIAN
@ MAX_DEFEATED_ADVISORS
@ ADVISOR_SANGUINAR
@ ADVISOR_TELONICUS
@ ADVISOR_THALADRED
static constexpr std::array< uint32, 7 > RemoveWeaponsSpells
@ SPELL_SUMMON_NETHER_VAPOR_3
@ SPELL_CAPERNIAN_FIREBALL
@ SPELL_REMOVE_WEAPON_C
@ SPELL_PURE_NETHER_BEAM_SCRIPT_3
@ SPELL_GRAVITY_LAPSE_TELE_BACK
@ SPELL_SUMMON_WEAPON_A
@ SPELL_REBIRTH_SPAWN
@ SPELL_PURE_NETHER_BEAM_2
@ SPELL_KAEL_TELONICUS
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_RIGHT
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_RIGHT3
@ SPELL_REMOVE_WEAPONS
@ SPELL_SHOOT
@ SPELL_KAEL_STUNNED
@ SPELL_FLAME_STRIKE_DAMAGE
@ SPELL_KAEL_EXPLODES_1
@ SPELL_SUMMON_WEAPON_F
@ SPELL_MIND_CONTROL
@ SPELL_GRAVITY_LAPSE_FLIGHT_AURA
@ SPELL_NETHERBEAM_1
@ SPELL_GRAVITY_LAPSE_TELE_BACK_LEFT
@ SPELL_GRAVITY_LAPSE_PERIODIC
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_RIGHT
@ SPELL_BELLOWING_ROAR
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_RIGHT2
@ SPELL_SHOCK_BARRIER
@ SPELL_SILENCE
@ SPELL_NETHERBEAM_2
@ SPELL_NETHER_BEAM_CHAIN
@ SPELL_NETHERBEAM_3
@ SPELL_REMOTE_TOY
@ SPELL_BOMB
@ SPELL_CONFLAGRATION
@ SPELL_GRAVITY_LAPSE_TELE_FRONT_RIGHT
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_LEFT
@ SPELL_SUMMON_WEAPON_E
@ SPELL_SUMMON_NETHER_VAPOR
@ SPELL_REMOVE_WEAPON_E
@ SPELL_PURE_NETHER_BEAM_SCRIPT_1
@ SPELL_ARCANE_DISRUPTION
@ SPELL_GRAVITY_LAPSE_TELE_FRONT_LEFT
@ SPELL_REMOVE_WEAPON_A
@ SPELL_KAEL_GROW
@ SPELL_REMOTE_TOY_STUN
@ SPELL_SUMMON_WEAPON_G
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT2
@ SPELL_SUMMON_NETHER_VAPOR_4
@ SPELL_GRAVITY_LAPSE_TELE_FRONT_LEFT3
@ SPELL_SUMMON_NETHER_VAPOR_1
@ SPELL_SUMMON_WEAPONS
@ SPELL_NETHER_VAPOR_SCRIPT
@ SPELL_REMOVE_WEAPON_B
@ SPELL_KAEL_EXPLODES_2
@ SPELL_SUMMON_WEAPON_B
@ SPELL_NETHER_BEAM
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_LEFT2
@ SPELL_KAEL_CAPERNIAN
@ SPELL_KAEL_FULL_POWER
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT_RIGHT
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_LEFT
@ SPELL_FIREBALL
@ SPELL_NETHERBEAM_CHANNEL_1
@ SPELL_ROOT_SELF
@ SPELL_SUMMON_NETHER_VAPOR_2
@ SPELL_SUMMON_WEAPON_C
@ SPELL_GRAVITY_LAPSE
@ SPELL_SHOCK_BARRIER_DAMAGE
@ SPELL_MIND_CONTROL_2
@ SPELL_ARCANE_BURST
@ SPELL_GRAVITY_LAPSE_KNOCK_BACK
@ SPELL_PSYCHIC_BLOW
@ SPELL_GRAVITY_LAPSE_TELE_FRONT
@ SPELL_PACIFY_SELF
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT
@ SPELL_BANISH
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_LEFT2
@ SPELL_NETHER_VAPOR_DAMAGE
@ SPELL_NETHER_VAPOR_LIGHTNING
@ SPELL_GRAVITY_LAPSE_TELE_TO_CASTER
@ SPELL_SUMMON_PHOENIX
@ SPELL_KAEL_PHASE_TWO
@ SPELL_PURE_NETHER_BEAM_1
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK
@ SPELL_GRAVITY_LAPSE_TELE_FRONT_RIGHT2
@ SPELL_BURN_TRIGGER
@ SPELL_REND
@ SPELL_FULL_HEAL
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_RIGHT2
@ SPELL_GRAVITY_LAPSE_TELE_FRONT_LEFT2
@ SPELL_SUMMON_WEAPON_D
@ SPELL_KAEL_EXPLODES_3
@ SPELL_REMOVE_WEAPON_F
@ SPELL_REBIRTH_RESPAWN
@ SPELL_PURE_NETHER_BEAM_3
@ SPELL_PERMANENT_FEIGN_DEATH
@ SPELL_BURN_PERIODIC
@ SPELL_SUMMON_PHOENIX_EGG
@ SPELL_PURE_NETHER_BEAM_SCRIPT_2
@ SPELL_PYROBLAST
@ SPELL_FLAME_STRIKE
@ SPELL_EMBER_BLAST
@ SPELL_KAEL_EXPLODES_4
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT_LEFT
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK2
@ SPELL_REMOVE_WEAPON_D
@ SPELL_KAEL_EXPLODES
@ SPELL_KAEL_GAINING_POWER
@ SPELL_NETHERBEAM_CHANNEL_2
@ SPELL_RESSURECTION
@ SPELL_KAEL_SANGUINAR
@ SPELL_GRAVITY_LAPSE_TELE_CASTER_LEFT3
@ SPELL_FLAME_STRIKE_DUMMY
@ SPELL_REMOVE_WEAPON_G
void AddSC_boss_kaelthas()
Position const TransitionUpPos
KaelthasMovementPoints
@ POINT_TRANSITION_UP
@ POINT_TRANSITION_DOWN
@ POINT_TRANSITION_START
static constexpr std::array< uint32, 4 > AdvisorsSpawnGroupsData
KaelthasActions
@ ACTION_RESET_CONTROLLER
@ ACTION_ADVISOR_ENGAGED
@ ACTION_ADVISOR_DEFEATED
@ ACTION_ENGAGE_COMBAT
@ EVENT_TRANSITION_4
@ EVENT_START_ENCOUNTER_1
@ EVENT_STAGE_GROUND
@ EVENT_TRANSITION_5
@ EVENT_FIREBALL
@ EVENT_NETHER_BEAM
@ EVENT_SUMMON_NETHER_VAPOR
@ EVENT_TRANSITION_7
@ EVENT_GRAVITY_LAPSE
@ EVENT_TRANSITION_11
@ EVENT_EXPLOSION_1
@ EVENT_SUMMON_PHOENIX
@ EVENT_ARCANE_DISRUPTION
@ EVENT_STAGE_GRAVITY
@ EVENT_ENGAGE_COMBAT
@ EVENT_TRANSITION_9
@ EVENT_SET_FACING
@ EVENT_PURE_NETHER_BEAM
@ EVENT_TRANSITION_1
@ EVENT_SUMMON_WEAPONS
@ EVENT_EXPLOSION_2
@ EVENT_MIND_CONTROL
@ EVENT_TRANSITION_6
@ EVENT_EXPLOSION_3
@ EVENT_REVIVE_ADVISORS_2
@ EVENT_TRANSITION_8
@ EVENT_REVIVE_ADVISORS_1
@ EVENT_TRANSITION_2
@ EVENT_FLAME_STRIKE
@ EVENT_SHOCK_BARRIER
@ EVENT_PYROBLAST
@ EVENT_START_ENCOUNTER_3
@ EVENT_START_ENCOUNTER_2
@ EVENT_TRANSITION_3
@ EVENT_TRANSITION_10
static constexpr std::array< uint32, 25 > GravityLapseSpells
static constexpr std::array< uint32, 7 > SummonWeaponsSpells
uint32 GetTickNumber() const
int32 GetAmount() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
HookList< EffectApplyHandler > AfterEffectApply
HookList< EffectAbsorbHandler > AfterEffectAbsorb
Unit * GetTarget() const
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
void _DespawnAtEvade(Seconds delayToRespawn=30s, Creature *who=nullptr)
SummonList summons
EventMap events
void DoZoneInCombat(Creature *creature=nullptr)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
void SetImmuneToPC(bool apply) override
Definition Creature.h:129
void SetReactState(ReactStates st)
Definition Creature.h:119
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void SetRegenerateHealth(bool value)
Definition Creature.h:285
void SetCorpseDelay(uint32 delay, bool ignoreCorpseDecayRatio=false)
Definition Creature.h:89
Unit * GetAttacker() const
Definition Unit.h:458
void Update(uint32 time)
Definition EventMap.h:67
void Repeat(Milliseconds time)
Definition EventMap.cpp:63
EventId ExecuteEvent()
Definition EventMap.cpp:73
void RescheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:52
void CancelEvent(EventId eventId)
Definition EventMap.cpp:151
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
void Reset()
Definition EventMap.cpp:21
Creature * GetCreature(uint32 type)
GameObject * GetGameObject(uint32 type)
bool SpawnGroupSpawn(uint32 groupId, bool ignoreRespawn=false, bool force=false, std::vector< WorldObject * > *spawnedObjects=nullptr)
Definition Map.cpp:3382
bool SpawnGroupDespawn(uint32 groupId, bool deleteRespawnTimes=false, size_t *count=nullptr)
Definition Map.cpp:3458
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={})
void MoveRandom(float wanderDistance=0.0f)
bool IsUnit() const
Definition Object.h:191
TypeID GetTypeId() const
Definition Object.h:93
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr) const
uint32 Id
Definition SpellInfo.h:289
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:483
Unit * GetCaster() const
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
HookList< EffectHandler > OnEffectHit
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
HookList< EffectHandler > OnEffectLaunchTarget
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
void Summon(Creature const *summon)
TaskContext & Repeat(std::chrono::duration< _Rep, _Period > const &duration)
TaskScheduler::repeated_t GetRepeatCounter() const
Returns the repeat counter which increases every time the task is repeated.
TaskScheduler & CancelAll()
TaskScheduler & Schedule(std::chrono::duration< _Rep, _Period > const &time, task_handler_t const &task)
TaskScheduler & Update(success_t const &callback=EmptyCallback)
TaskScheduler & SetValidator(P &&predicate)
Sets a validator which is asked if tasks are allowed to be executed.
Trinity::IteratorPair< ThreatListIterator, std::nullptr_t > GetUnsortedThreatList() const
void AttackStartCaster(Unit *victim, float dist)
Definition UnitAI.cpp:48
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:241
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:96
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true)
Definition Unit.cpp:716
ThreatManager & GetThreatManager()
Definition Unit.h:1155
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3093
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool SetHover(bool enable, bool updateAnimTier=true)
Definition Unit.cpp:13503
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition Unit.cpp:13286
uint32 GetHealth() const
Definition Unit.h:913
void SendPlaySpellVisualKit(uint32 id, uint32 type) const
Definition Unit.cpp:12019
bool SetWalk(bool enable)
Definition Unit.cpp:13268
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
void SetFacingTo(float ori, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13250
uint32 CountPctFromMaxHealth(int32 pct) const
Definition Unit.h:922
void SetStandState(UnitStandStateType state)
Definition Unit.cpp:10363
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition Unit.h:918
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
bool IsFlying() const
Definition Unit.h:1762
bool AttackStop()
Definition Unit.cpp:5645
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:955
Map * GetMap() const
Definition Object.h:449
Creature * FindNearestCreatureWithOptions(float range, FindCreatureOptions const &options) const
Definition Object.cpp:2108
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2856
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1141
float GetFloorZ() const
Definition Object.cpp:3586
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1192
void PlayDirectSound(uint32 soundId, Player *target=nullptr)
Definition Object.cpp:3433
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
uint32 m_scriptSpellId
void HandleScript(SpellEffIndex)
PrepareSpellScript(spell_kaelthas_explodes)
bool Validate(SpellInfo const *) override
void AfterRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_kaelthas_flame_strike)
PrepareAuraScript(spell_kaelthas_gaining_power)
void AfterApply(AuraEffect const *, AuraEffectHandleModes)
void OnPeriodic(AuraEffect const *aurEff)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_kaelthas_gravity_lapse_periodic)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_kaelthas_gravity_lapse)
bool Validate(SpellInfo const *) override
void HandleScript(SpellEffIndex)
void AfterRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_kaelthas_mind_control_aura)
bool Validate(SpellInfo const *) override
void AfterApply(AuraEffect const *, AuraEffectHandleModes)
PrepareSpellScript(spell_kaelthas_mind_control)
void FilterTargets(std::list< WorldObject * > &targets)
PrepareSpellScript(spell_kaelthas_nether_beam)
bool Validate(SpellInfo const *) override
void HandleScript(SpellEffIndex)
PrepareAuraScript(spell_kaelthas_nether_vapor_lightning)
bool Validate(SpellInfo const *spellInfo) override
void OnPeriodic(AuraEffect const *aurEff)
PrepareSpellScript(spell_kaelthas_pure_nether_beam_visual)
PrepareSpellScript(spell_kaelthas_pure_nether_beam)
void FilterTargets(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_kaelthas_pyroblast)
void FilterTargets(std::list< WorldObject * > &targets)
PrepareAuraScript(spell_kaelthas_remote_toy)
void HandlePeriodic(AuraEffect const *)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_kaelthas_remove_weapons)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void OnAbsorb(AuraEffect *aurEff, DamageInfo &dmgInfo, uint32 &absorbAmount)
PrepareAuraScript(spell_kaelthas_shock_barrier)
PrepareSpellScript(spell_kaelthas_summon_nether_vapor_effect)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_kaelthas_summon_nether_vapor)
PrepareSpellScript(spell_kaelthas_summon_weapons)
bool Validate(SpellInfo const *) override
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:66
bool IsEnemyInRange(float distance)
void Reset() override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
TaskScheduler Scheduler
void InitializeAI() override
void JustEngagedWith(Unit *) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
AdvisorBaseAI(Creature *creature)
void JustDied(Unit *) override
void DoAction(int32 action) override
virtual void ScheduleEvents()=0
void UpdateAI(uint32 diff) override
float GetPositionZ() const
Definition Position.h:81
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:128
void ResetThreatList(Unit *who=nullptr)
void AddThreat(Unit *victim, float amount, Unit *who=nullptr)
void RelocateOffset(Position const &offset)
Definition Spell.cpp:110
boss_grand_astromancer_capernian(Creature *creature)
void AttackStart(Unit *who) override
void JustDied(Unit *killer) override
void JustEngagedWith(Unit *who) override
void JustAppeared() override
void JustEngagedWith(Unit *who) override
void ScheduleCombatEventsForStage(uint8 stage)
boss_kaelthas(Creature *creature)
void KilledUnit(Unit *) override
void JustDied(Unit *) override
void OnSpellStart(SpellInfo const *spellInfo) override
void MoveInLineOfSight(Unit *who) override
void JustSummoned(Creature *summon) override
void UpdateAI(uint32 diff) override
void OnSpellFailed(SpellInfo const *spellInfo) override
void EnterEvadeMode(EvadeReason) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void MovementInform(uint32 type, uint32 point) override
void AttackStart(Unit *who) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void DoAction(int32 action) override
void OnSpellCast(SpellInfo const *spellInfo) override
void ScheduleEvents() override
boss_lord_sanguinar(Creature *creature)
void JustEngagedWith(Unit *who) override
void JustDied(Unit *killer) override
void JustDied(Unit *killer) override
void JustEngagedWith(Unit *who) override
boss_master_engineer_telonicus(Creature *creature)
void AttackStart(Unit *who) override
void JustEngagedWith(Unit *who) override
void JustDied(Unit *killer) override
boss_thaladred_the_darkener(Creature *creature)
npc_flame_strike_trigger_kael(Creature *creature)
void DoAction(int32 action) override
void UpdateAI(uint32 diff) override
npc_kaelthas_controller(Creature *creature)
void InitializeAI() override
npc_nether_vapor(Creature *creature)
void JustAppeared() override
npc_phoenix_egg_the_eye(Creature *creature)
void JustSummoned(Creature *summon) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
npc_phoenix_the_eye(Creature *creature)
void SummonedCreatureDies(Creature *, Unit *) override
void InitializeAI() override
void OnSpellCast(SpellInfo const *spellInfo) override
void UpdateAI(uint32 diff) override
void JustAppeared() override
#define RegisterTheEyeCreatureAI(ai_name)
Definition the_eye.h:74
@ DATA_KAEL_STATUE_RIGHT
Definition the_eye.h:43
@ DATA_TEMPEST_BRIDGE_WINDOW
Definition the_eye.h:44
@ DATA_SANGUINAR
Definition the_eye.h:38
@ DATA_TELONICUS
Definition the_eye.h:39
@ DATA_KAELTHAS
Definition the_eye.h:34
@ DATA_KAEL_STATUE_LEFT
Definition the_eye.h:42
@ DATA_CAPERNIAN
Definition the_eye.h:37
@ DATA_THALADRED
Definition the_eye.h:40