TrinityCore
Loading...
Searching...
No Matches
boss_illidan.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ScriptMgr.h"
19#include "black_temple.h"
20#include "Containers.h"
21#include "GridNotifiersImpl.h"
22#include "InstanceScript.h"
23#include "Map.h"
24#include "MotionMaster.h"
25#include "ObjectAccessor.h"
26#include "PassiveAI.h"
27#include "Player.h"
28#include "ScriptedCreature.h"
29#include "ScriptedGossip.h"
30#include "SpellAuraEffects.h"
31#include "SpellInfo.h"
32#include "SpellScript.h"
33#include "TemporarySummon.h"
34
36{
37 // Illidan
53
54 // Maiev Shadowsong
63
64 // Flame of Azzinoth
66
67 // Akama
77
78 // Spirits
80
81 // Direct Sounds
90};
91
93{
94 // Akama
101
102 // Spirits
104
105 // Door Trigger
107
108 // Blade of Azzinoth
109 SPELL_BIRTH = 40031,
113
114 // Flame of Azzinoth
119
120 // Maiev
126
127 // Cage Trap Disturb Trigger
129
130 // Shadow Demon
135
136 // Player
139
140 // Illidan DB Target
142
143 // Cage Trap Summon Spells
152
153 // Glaive Target
156
157 // Illidan
159 SPELL_SHEAR = 41032,
180 SPELL_KNEEL = 39656,
187 SPELL_DEATH = 41218,
194
195 // Blaze
196 SPELL_BLAZE = 40610,
197
198 // Demon Fire
200
201 // Flame Crash
204
214
231
242
253
269
279
281{
282 // Akama
312
313 // Illidan Stormrage
354
355 // Flame of Azzinoth
359
360 // Maiev
374
376{
377 { 609.7720f, 308.4560f, 271.826f }, // Illidari Council Position
378 { 752.2771f, 369.9401f, 353.1584f } // Minions Position
379};
380
382{
383 { 745.2552f, 322.1574f, 310.4596f, 6.038839f },
384 { 747.0576f, 326.4268f, 309.0688f, 0.0f },
385 { 743.9686f, 289.6447f, 311.1807f, 6.056293f },
386 { 748.8422f, 288.0620f, 310.9782f, 1.884956f },
387 { 751.0878f, 327.6505f, 309.4576f, 6.178465f },
388 { 750.0472f, 282.3274f, 309.4353f, 3.071779f },
389 { 754.0332f, 325.8136f, 310.3195f, 2.9147f },
390 { 753.8425f, 286.562f, 310.9353f, 1.029744f },
391 { 745.3237f, 283.986f, 309.2765f, 0.6283185f },
392 { 750.0322f, 323.6064f, 310.2757f, 5.497787f }
393};
394
396{
397 { 705.921997f, 337.145996f, 370.083008f, 3.961900f },
398 { 706.226990f, 273.264008f, 370.083008f, 2.251072f },
399 { 658.830017f, 265.098999f, 370.083008f, 0.850345f },
400 { 656.859009f, 344.071991f, 370.083008f, 5.235990f }
401};
402
403Position const IllidanMiddlePoint = { 676.6479f, 304.7606f, 354.1909f , 6.230825f };
404
406{
407 { 710.8815f, 306.4028f, 353.5962f, 2.391101f },
408 { 652.105f, 259.5127f, 353.0794f, 0.122173f },
409 { 642.7164f, 305.2436f, 353.5596f, 3.438299f },
410 { 710.8815f, 306.4028f, 353.5962f, 2.391101f }
411};
412
414{
415 { 660.3492f, 345.5749f, 353.2961f },
416 { 701.6755f, 297.3358f, 354.041f },
417 { 706.7507f, 269.4593f, 353.2778f },
418 { 660.3492f, 345.5749f, 353.2961f }
419};
420
422{
423 { 676.226013f, 325.230988f },
424 { 678.059998f, 285.220001f }
425};
426
438
440{
441public:
443
444 bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override
445 {
448 return true;
449 }
450
451private:
453};
454
456{
457public:
459
460 bool operator()(Unit* unit) const
461 {
462 return unit->GetTypeId() == TYPEID_PLAYER
463 && unit->GetDistance2d(BladesPositions[0].GetPositionX(), BladesPositions[0].GetPositionY()) > 25.0f
464 && unit->GetDistance2d(BladesPositions[1].GetPositionX(), BladesPositions[1].GetPositionY()) > 25.0f;
465 }
466};
467
468// 22917 - Illidan Stormrage
470{
473
474 void Reset() override
475 {
476 _Reset();
479 me->LoadEquipment(1, true);
482 me->SetDisableGravity(false);
483 _dead = false;
484 _minionsCount = 0;
485 _flameCount = 0;
486 _phase = PHASE_1;
487 _isDemon = false;
490 akama->AI()->DoAction(ACTION_ACTIVE_AKAMA_INTRO);
491 }
492
504
505 void JustSummoned(Creature* summon) override
506 {
507 if (summon->GetEntry() == NPC_PARASITIC_SHADOWFIEND)
508 summons.Summon(summon);
509 else
510 BossAI::JustSummoned(summon);
511 }
512
513 void ChangeOrientation(float orientation)
514 {
515 _orientation = orientation;
517 }
518
519 void KilledUnit(Unit* victim) override
520 {
521 if (victim->GetTypeId() == TYPEID_PLAYER)
523 }
524
525 void ScheduleEvents(uint8 phase, uint8 group)
526 {
527 switch (phase)
528 {
529 case GROUP_PHASE_1:
532 events.ScheduleEvent(EVENT_SHEAR, 10s, group);
534 break;
535 case GROUP_PHASE_2:
536 events.ScheduleEvent(EVENT_FIREBALL, 1s, 8s, group);
537 events.ScheduleEvent(EVENT_EYE_BLAST, 1s, 30s, group);
538 if (roll_chance(50))
539 events.ScheduleEvent(EVENT_DARK_BARRAGE, 1s, 20s, group);
540 break;
541 case GROUP_PHASE_3:
544 events.ScheduleEvent(EVENT_DEMON, 60s, group);
545 break;
549 events.ScheduleEvent(EVENT_SHADOW_DEMON, 18s, 30s, group);
550 break;
551 case GROUP_PHASE_4:
553 events.ScheduleEvent(EVENT_FRENZY, 40s, group);
554 break;
555 default:
556 break;
557 }
558 }
559
560 void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
561 {
562 if (summon->GetEntry() == NPC_ILLIDARI_ELITE)
564 }
565
566 void EnterEvadeMode(EvadeReason /*why*/) override
567 {
571 }
572
573 void DoAction(int32 actionId) override
574 {
575 switch (actionId)
576 {
583 akama->AI()->DoAction(ACTION_FREE);
584 break;
587 break;
591 akama->AI()->DoAction(ACTION_START_MINIONS);
592 break;
595 break;
597 {
599 me->AttackStop();
600 me->SetUninteractible(true);
602 me->SetDisableGravity(true);
606 break;
607 }
609 _flameCount++;
610 if (_flameCount == 2)
611 {
612 _flameCount = 0;
614 }
615 break;
620 _phase = PHASE_3;
623 break;
629 me->AttackStop();
630 me->SetUninteractible(true);
632 break;
634 for (uint32 summonSpell : SummonCageTrapSpells)
635 DoCastSelf(summonSpell, true);
637 break;
639 me->AttackStop();
640 events.Reset();
642 DoCastSelf(SPELL_DEATH, true);
643 me->SetUninteractible(true);
645 break;
646 default:
647 break;
648 }
649 }
650
651 void JustDied(Unit* /*killer*/) override
652 {
653 me->SetUninteractible(false);
655 events.Reset();
656 }
657
658 void MovementInform(uint32 type, uint32 pointId) override
659 {
660 if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
661 return;
662
663 switch (pointId)
664 {
669 break;
671 {
673 ChangeOrientation(orientation);
675 break;
676 }
678 {
679 float orientation = IllidanMiddlePoint.GetOrientation();
680 ChangeOrientation(orientation);
681
682 std::list<Creature*> triggers;
684 for (Creature* trigger : triggers)
685 trigger->CastSpell(trigger, SPELL_GLAIVE_RETURNS, true);
686
688 break;
689 }
690 default:
691 break;
692 }
693 }
694
696 {
697 Map::PlayerList const& players = me->GetMap()->GetPlayers();
698 for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
699 if (Player* player = i->GetSource())
700 if (player->IsAlive() && !player->IsGameMaster() && IsInBoundary(player))
701 return;
702
704 }
705
707 {
709 for (uint8 i = 0; i < needSummon; ++i)
710 {
713 }
714 }
715
716 void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
717 {
718 if (damage >= me->GetHealth() && (!who || who->GetGUID() != me->GetGUID()))
719 {
720 damage = me->GetHealth() - 1;
721 if (!_dead)
722 {
723 if (_isDemon)
724 {
725 events.Reset();
728 return;
729 }
730 _dead = true;
735 maiev->AI()->DoAction(ACTION_START_OUTRO);
736 }
737 }
738 else if (me->HealthBelowPct(90) && _phase < PHASE_MINIONS)
739 {
742 }
743 else if (me->HealthBelowPct(65) && _phase < PHASE_2)
744 {
745 _phase = PHASE_2;
747 }
748 else if (me->HealthBelowPct(30) && _phase < PHASE_4)
749 {
750 _phase = PHASE_4;
751
752 if (_isDemon)
753 {
754 _isDemon = false;
760 }
761 else
763 }
764 }
765
767 {
768 while (uint32 eventId = specialEvents.ExecuteEvent())
769 {
770 switch (eventId)
771 {
772 case EVENT_BERSERK:
775 break;
782 _isDemon = false;
783 break;
787 break;
788 default:
789 break;
790 }
791 }
792 }
793
794 void UpdateAI(uint32 diff) override
795 {
797 return;
798
799 specialEvents.Update(diff);
800
802
804 return;
805
806 events.Update(diff);
807
808 while (uint32 eventId = events.ExecuteEvent())
809 {
810 switch (eventId)
811 {
814 break;
818 break;
819 case EVENT_PREPARED:
823 break;
825 me->SetImmuneToAll(false);
828 akama->AI()->DoAction(ACTION_START_ENCOUNTER);
829 break;
832 events.Repeat(30s);
833 break;
834 case EVENT_DRAW_SOUL:
836 events.Repeat(34s);
837 break;
838 case EVENT_SHEAR:
840 events.Repeat(12s);
841 break;
843 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
845 events.Repeat(30s);
846 break;
848 if (_dead)
849 return;
851 events.Repeat(30s);
852 break;
854 {
855 Position pos;
856 std::list<Creature*> triggers;
858 triggers.remove_if([](WorldObject* unit)
859 {
860 return unit->GetPositionZ() < 355.0f || unit->GetPositionZ() > 365.0f;
861 });
862
863 if (triggers.empty())
864 break;
865
866 triggers.sort(Trinity::ObjectDistanceOrderPred(me));
867 pos.Relocate(triggers.front());
868 pos.SetOrientation(0.0f);
871 musicController->PlayDirectMusic(EVENT_BT_STORM_WALK_HERO_2_SOUND_ID);
872 break;
873 }
877 break;
882 break;
885 break;
886 case EVENT_FLY:
887 ChangeOrientation(3.137039f);
889 break;
891 {
893 _pillarIndex = urand(0, 3);
895 events.Repeat(30s);
896 break;
897 }
899 {
900 float angle = me->GetAbsoluteAngle(IllidanMiddlePoint);
901 me->SetFacingTo(angle);
902 break;
903 }
904 case EVENT_EYE_BLAST:
905 {
909 {
911 DoCast(dbTarget, SPELL_EYE_BLAST);
912 dbTarget->GetMotionMaster()->MovePoint(POINT_DB_TARGET, IllidanDBTargetPoints[_pillarIndex]);
913 }
914 break;
915 }
917 {
918 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 150.0f, true))
919 DoCast(target, SPELL_DARK_BARRAGE);
923 break;
924 }
925 case EVENT_FIREBALL:
926 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 150.0f, true))
927 DoCast(target, SPELL_FIREBALL);
928 events.Repeat(2s, 4s);
929 break;
931 me->SetDisableGravity(false);
935 break;
937 me->SetUninteractible(false);
941 musicController->PlayDirectMusic(EVENT_BT_STORM_WALK_UNI_3_SOUND_ID);
942 break;
945 events.Repeat(53s);
946 break;
947 case EVENT_DEMON:
949 _isDemon = true;
951 me->LoadEquipment(0, true);
956 break;
960 break;
961 case EVENT_DEMON_TEXT:
963 break;
965 {
968 ScheduleEvents(group, group);
969 me->LoadEquipment(1, true);
970 break;
971 }
974 events.Repeat(22s);
975 break;
978 break;
981 events.Repeat(2s);
982 break;
985 break;
989 break;
993 me->SetFacingToObject(maiev);
995 break;
999 break;
1001 me->SetUninteractible(false);
1005 break;
1006 case EVENT_FRENZY:
1009 events.Repeat(40s);
1010 break;
1011 case EVENT_TAUNT:
1013 events.Repeat(30s, 60s);
1014 break;
1018 musicController->PlayDirectMusic(EVENT_BT_ARRIVAL_WALK_HERO_1_SOUND_ID);
1020 break;
1022 {
1024 if (Creature* akama = instance->GetCreature(DATA_AKAMA))
1025 akama->AI()->DoAction(ACTION_START_OUTRO);
1028 summons.DespawnIf([_akamaGUID, _maievGUID](ObjectGuid unitGuid)
1029 {
1030 return unitGuid != _akamaGUID && unitGuid != _maievGUID;
1031 });
1032 break;
1033 }
1034 default:
1035 break;
1036 }
1037
1039 return;
1040 }
1041 }
1042
1043private:
1049 bool _dead;
1052};
1053
1054// 23089 - Akama
1056{
1057 npc_akama_illidan(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()),
1058 _orientation(0.0f), _isTeleportToMinions(false) { }
1059
1060 void Reset() override
1061 {
1062 _events.Reset();
1065 _isTeleportToMinions = false;
1066 }
1067
1068 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
1069 {
1070 if (gossipListId == GOSSIP_START_INTRO)
1071 {
1076 illidan->AI()->DoAction(ACTION_INTRO_DONE);
1077 CloseGossipMenuFor(player);
1078
1079 }
1080 else if (gossipListId == GOSSIP_START_FIGHT)
1081 {
1085 CloseGossipMenuFor(player);
1086 }
1087 return false;
1088 }
1089
1090 bool CanAIAttack(Unit const* who) const override
1091 {
1093 return false;
1094 return ScriptedAI::CanAIAttack(who);
1095 }
1096
1097 uint32 GetData(uint32 /*data*/) const override
1098 {
1099 return _isTeleportToMinions ? 1 : 0;
1100 }
1101
1102 void EnterEvadeMode(EvadeReason /*why*/) override { }
1103
1104 void JustSummoned(Creature* summon) override
1105 {
1106 if (summon->GetEntry() == NPC_SPIRIT_OF_UDALO)
1107 {
1108 _spiritOfUdaloGUID = summon->GetGUID();
1110 }
1111 else if (summon->GetEntry() == NPC_SPIRIT_OF_OLUM)
1112 {
1113 _spiritOfOlumGUID = summon->GetGUID();
1115 }
1116 }
1117
1118 void DoAction(int32 actionId) override
1119 {
1120 switch (actionId)
1121 {
1128 break;
1129 case ACTION_OPEN_DOOR:
1132 break;
1133 case ACTION_FREE:
1135 break;
1139 break;
1142 break;
1143 case ACTION_START_OUTRO:
1145 me->AttackStop();
1146 _events.Reset();
1148 break;
1149 default:
1150 break;
1151 }
1152 }
1153
1154 void ChangeOrientation(float orientation)
1155 {
1156 _orientation = orientation;
1158 }
1159
1160 void MovementInform(uint32 type, uint32 pointId) override
1161 {
1162 if (type != POINT_MOTION_TYPE && type != SPLINE_CHAIN_MOTION_TYPE)
1163 return;
1164
1165 switch (pointId)
1166 {
1170 break;
1171 case POINT_STAIRS:
1172 ChangeOrientation(6.265732f);
1174 break;
1175 case POINT_ILLIDAN_ROOM:
1176 ChangeOrientation(2.129302f);
1179 break;
1180 case POINT_FACE_ILLIDAN:
1181 ChangeOrientation(3.140537f);
1183 break;
1184 case POINT_TELEPORT:
1187 break;
1188 case POINT_MINIONS:
1190 me->SetImmuneToNPC(false);
1193 illidan->AI()->DoAction(ACTION_START_MINIONS_WEAVE);
1195 break;
1196 case POINT_MOVE_BACK:
1198 break;
1199 case POINT_ILLIDAN:
1201 break;
1202 default:
1203 break;
1204 }
1205 }
1206
1207 void DamageTaken(Unit* /*who*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1208 {
1209 if (damage >= me->GetHealth())
1210 damage = me->GetHealth() - 1;
1211 }
1212
1213 void UpdateAI(uint32 diff) override
1214 {
1216 return;
1217
1218 _events.Update(diff);
1219
1221 return;
1222
1223 while (uint32 eventId = _events.ExecuteEvent())
1224 {
1225 switch (eventId)
1226 {
1227 case EVENT_TELEPORT:
1229 break;
1232 break;
1236 break;
1240 break;
1244 break;
1248 break;
1249 case EVENT_SPIRIT_SAY_1:
1251 undalo->AI()->Talk(SAY_SPIRIT_ALONE);
1253 break;
1254 case EVENT_SPIRIT_SAY_2:
1256 olum->AI()->Talk(SAY_SPIRIT_ALONE);
1258 break;
1262 undalo->CastSpell((Unit*) nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL);
1264 olum->CastSpell((Unit*) nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL);
1266 break;
1269 musicController->PlayDirectMusic(EVENT_BT_SUMMIT_WALK_SOUND_ID);
1270 break;
1271 case EVENT_AKAMA_THANKS:
1275 break;
1278 {
1279 undalo->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
1280 undalo->DespawnOrUnsummon(7s);
1281 }
1283 {
1284 olum->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
1285 olum->DespawnOrUnsummon(7s);
1286 }
1287 break;
1290 break;
1293 illidan->AI()->DoAction(ACTION_START_ENCOUNTER);
1294 break;
1295 case EVENT_FREE:
1298 break;
1302 break;
1303 case EVENT_ROAR:
1306 break;
1309 break;
1311 if (me->HealthBelowPct(20))
1313 _events.Repeat(1s);
1314 break;
1318 break;
1321 me->AttackStop();
1323 me->SetImmuneToNPC(true);
1325 break;
1327 _isTeleportToMinions = true;
1329 break;
1332 break;
1335 _events.Repeat(8s + 500ms);
1336 break;
1339 break;
1343 break;
1347 break;
1348 case EVENT_FINAL_SALUTE:
1351 break;
1354 break;
1355 default:
1356 break;
1357 }
1358
1360 return;
1361 }
1362 }
1363
1364private:
1371};
1372
1373// 23498 - Parasitic Shadowfiend
1375{
1376 npc_parasitic_shadowfiend(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
1377
1378 void Reset() override
1379 {
1381 {
1383 return;
1384 }
1385
1387 illidan->AI()->JustSummoned(me);
1389 _scheduler.Schedule(2s, [this](TaskContext const& /*context*/)
1390 {
1393 });
1394 }
1395
1396 void DoAction(int32 action) override
1397 {
1398 if (action == ACTION_START_PHASE_4)
1399 {
1401 me->AttackStop();
1402 }
1403 else if (action == ACTION_RESUME_COMBAT)
1404 _scheduler.Schedule(2s, [this](TaskContext const& /*context*/)
1405 {
1408 });
1409 }
1410
1411 void UpdateAI(uint32 diff) override
1412 {
1413 _scheduler.Update(diff);
1414
1415 if (!UpdateVictim())
1416 return;
1417 }
1418
1419private:
1422};
1423
1424// 22996 - Blade of Azzinoth
1426{
1427 npc_blade_of_azzinoth(Creature* creature) : NullCreatureAI(creature), _instance(creature->GetInstanceScript()) { }
1428
1429 void Reset() override
1430 {
1432 {
1434 return;
1435 }
1436
1438 illidan->AI()->JustSummoned(me);
1439 _flameGuid.Clear();
1441 DoCastSelf(SPELL_BIRTH, true);
1442 _scheduler.Schedule(3s, [this](TaskContext const& /*context*/)
1443 {
1445 _scheduler.Schedule(500ms, [this](TaskContext const& /*context*/)
1446 {
1449 });
1450 });
1451 }
1452
1453 void JustSummoned(Creature* summon) override
1454 {
1455 if (summon->GetEntry() == NPC_FLAME_OF_AZZINOTH)
1456 _flameGuid = summon->GetGUID();
1457 }
1458
1459 void UpdateAI(uint32 diff) override
1460 {
1461 _scheduler.Update(diff);
1462 }
1463
1464private:
1468};
1469
1470// 22997 - Flame of Azzinoth
1472{
1473 npc_flame_of_azzinoth(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
1474 {
1476 }
1477
1478 void Reset() override
1479 {
1481 {
1483 return;
1484 }
1485
1487 illidan->AI()->JustSummoned(me);
1488 DoCastSelf(SPELL_FLAME_TEAR_OF_AZZINOTH, true); // Idk what this spell should do
1492 }
1493
1494 void UpdateAI(uint32 diff) override
1495 {
1496 if (!UpdateVictim())
1497 return;
1498
1500 return;
1501
1502 _events.Update(diff);
1503
1504 while (uint32 eventId = _events.ExecuteEvent())
1505 {
1506 switch (eventId)
1507 {
1508 case EVENT_ENGAGE:
1512 break;
1513 case EVENT_FLAME_CHARGE:
1515 {
1516 DoCast(target, SPELL_CHARGE);
1517 _events.Repeat(5s);
1518 }
1519 else
1520 _events.Repeat(1s);
1521 break;
1522 case EVENT_FLAME_BLAST:
1524 _events.Repeat(12s);
1525 break;
1526 default:
1527 break;
1528 }
1529
1531 return;
1532 }
1533 }
1534
1535 void JustDied(Unit* /*killer*/) override
1536 {
1538 illidan->AI()->DoAction(ACTION_FLAME_DEAD);
1539 }
1540
1541private:
1544};
1545
1546// 23070 - Illidan DB Target
1548{
1550
1551 void Reset() override
1552 {
1554 }
1555
1556 void JustSummoned(Creature* summon) override
1557 {
1558 if (summon->GetEntry() == NPC_DEMON_FIRE)
1560 }
1561
1562 void MovementInform(uint32 type, uint32 pointId) override
1563 {
1564 if (type == POINT_MOTION_TYPE && pointId == POINT_DB_TARGET)
1565 {
1568 }
1569 }
1570};
1571
1572// 23375 - Shadow Demon
1574{
1575 npc_shadow_demon(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
1576
1577 void Reset() override
1578 {
1580 {
1582 return;
1583 }
1584
1587 _scheduler.Schedule(1s, [this](TaskContext& checkTarget)
1588 {
1589 if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID))
1590 {
1591 if (!target->IsAlive())
1593 else if (me->IsWithinMeleeRange(target))
1594 {
1595 me->InterruptNonMeleeSpells(false);
1596 DoCast(target, SPELL_CONSUME_SOUL, true);
1597 }
1598 }
1599 checkTarget.Repeat();
1600 });
1601 }
1602
1603 void SetGUID(ObjectGuid const& guid, int32 /*id*/) override
1604 {
1605 _targetGUID = guid;
1606 if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID))
1607 me->GetMotionMaster()->MoveChase(target);
1608 }
1609
1610 void UpdateAI(uint32 diff) override
1611 {
1612 _scheduler.Update(diff);
1613 }
1614
1615private:
1619};
1620
1621// 23197 - Maiev Shadowsong
1622struct npc_maiev : public ScriptedAI
1623{
1624 npc_maiev(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _canDown(true) { }
1625
1638
1646
1647 void DoAction(int32 actionId) override
1648 {
1649 if (actionId == ACTION_START_OUTRO)
1650 {
1651 _events.Reset();
1654 me->AttackStop();
1656 me->SetFacingToObject(illidan);
1659 }
1660 else if (actionId == ACTION_MAIEV_DOWN_FADE)
1661 _canDown = true;
1662 }
1663
1664 void DamageTaken(Unit* /*who*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1665 {
1666 if (damage >= me->GetHealth() && _canDown)
1667 {
1668 damage = me->GetHealth() - 1;
1669 _canDown = false;
1672 }
1673 }
1674
1675 void UpdateAI(uint32 diff) override
1676 {
1678 return;
1679
1681 return;
1682
1683 _events.Update(diff);
1684
1685 while (uint32 eventId = _events.ExecuteEvent())
1686 {
1687 switch (eventId)
1688 {
1689 case EVENT_MAIEV_APPEAR:
1691 break;
1694 break;
1698 break;
1699 case EVENT_MAIEV_YES:
1702 break;
1703 case EVENT_MAIEV_ROAR:
1706 break;
1707 case EVENT_MAIEV_COMBAT:
1710 AttackStart(illidan);
1711 break;
1712 case EVENT_CAGE_TRAP:
1714 illidan->CastSpell(illidan, SPELL_CAGED_TRAP_TELEPORT, true);
1717 _events.Repeat(30s);
1718 break;
1721 _events.Repeat(50s);
1722 break;
1723 case EVENT_THROW_DAGGER:
1724 if (Unit* target = me->GetVictim())
1725 if (!me->IsWithinMeleeRange(target))
1726 {
1728 _events.Repeat(5s);
1729 break;
1730 }
1731 _events.Repeat(1s);
1732 break;
1733 case EVENT_TAUNT:
1735 _events.Repeat(30s, 60s);
1736 break;
1740 break;
1744 break;
1747 me->DespawnOrUnsummon(1s);
1748 break;
1749 default:
1750 break;
1751 }
1752
1754 return;
1755 }
1756 }
1757
1758private:
1762};
1763
1764// 23304 - Cage Trap Disturb Trigger
1766{
1767 npc_cage_trap_trigger(Creature* creature) : PassiveAI(creature) { }
1768
1769 void Reset() override
1770 {
1771 _scheduler.Schedule(1s, [this](TaskContext& checkTarget)
1772 {
1774 checkTarget.Repeat();
1775 });
1776 }
1777
1778 void UpdateAI(uint32 diff) override
1779 {
1780 _scheduler.Update(diff);
1781 }
1782
1783private:
1785};
1786
1787// 23226 - Illidari Elite
1789{
1790 npc_illidari_elite(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
1791
1792 void Reset() override
1793 {
1795 {
1796 AttackStart(akama);
1797 AddThreat(akama, 1000.0f);
1798 }
1799 }
1800
1801 bool CanAIAttack(Unit const* who) const override
1802 {
1803 if (who->GetEntry() == NPC_AKAMA)
1804 return true;
1805 return false;
1806 }
1807
1808private:
1810};
1811
1812// 23069 - Demon Fire
1813// 23259 - Blaze
1814// 23336 - Flame Crash
1816{
1817 npc_illidan_generic_fire(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
1818 {
1819 SetCombatMovement(false);
1820 }
1821
1822 void Reset() override
1823 {
1825 illidan->AI()->JustSummoned(me);
1826
1828 switch (me->GetEntry())
1829 {
1830 case NPC_DEMON_FIRE:
1832 break;
1833 case NPC_BLAZE:
1834 DoCastSelf(SPELL_BLAZE, true);
1835 DoCastSelf(SPELL_BIRTH, true);
1836 break;
1837 case NPC_FLAME_CRASH:
1839 break;
1840 default:
1841 break;
1842 }
1843 }
1844
1845 void UpdateAI(uint32 /*diff*/) override { }
1846
1847private:
1849};
1850
1851// 41077 - Akama Teleport
1853{
1855 {
1856 if (Creature* caster = GetCaster()->ToCreature())
1857 {
1858 uint32 destination = caster->AI()->GetData(DATA_AKAMA_TELEPORT_POSITION);
1859 dest.Relocate(AkamaTeleportPositions[destination]);
1860 }
1861 }
1862
1867};
1868
1869// 41268 - Quest - Black Temple - Akama - Door Open
1871{
1872 bool Validate(SpellInfo const* /*spell*/) override
1873 {
1875 }
1876
1877 void OnRemoveDummy(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1878 {
1879 Unit* target = GetTarget();
1880 target->CastSpell(target, SPELL_ARCANE_EXPLOSION, true);
1881
1882 if (InstanceScript* instance = target->GetInstanceScript())
1883 if (Creature* akama = instance->GetCreature(DATA_AKAMA))
1884 akama->AI()->DoAction(ACTION_OPEN_DOOR);
1885 }
1886
1891};
1892
1893// 40904 - Draw Soul
1895{
1896 bool Validate(SpellInfo const* /*spellInfo*/) override
1897 {
1899 }
1900
1902 {
1903 PreventHitDefaultEffect(effIndex);
1905 }
1906
1911};
1912
1913/* 41917 - Parasitic Shadowfiend
1914 41914 - Parasitic Shadowfiend */
1916{
1917 bool Validate(SpellInfo const* /*spellInfo*/) override
1918 {
1920 }
1921
1922 void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1923 {
1925 if (removeMode != AURA_REMOVE_BY_EXPIRE && removeMode != AURA_REMOVE_BY_DEATH)
1926 return;
1927
1928 Unit* target = GetTarget();
1929 target->CastSpell(target, SPELL_SUMMON_PARASITIC_SHADOWFIENDS, true);
1930 }
1931
1936};
1937
1938// 41913 - Parasitic Shadowfiend Passive
1940{
1941 bool Validate(SpellInfo const* /*spellInfo*/) override
1942 {
1944 }
1945
1946 bool CheckProc(ProcEventInfo& eventInfo)
1947 {
1948 Unit* target = eventInfo.GetActionTarget();
1950 }
1951
1956};
1957
1958// 41923 - Remove Parasitic Shadowfiends (SERVERSIDE)
1977
1978/* 39635 - Throw Glaive
1979 39849 - Throw Glaive */
1981{
1982 void HandleDummy(SpellEffIndex /*effIndex*/)
1983 {
1984 Unit* target = GetHitUnit();
1985 target->m_Events.AddEvent(new SummonWarglaiveEvent(target), target->m_Events.CalculateTime(1s));
1986 }
1987
1992};
1993
1994// 39857 - Tear of Azzinoth Summon Channel
1996{
1997 bool Validate(SpellInfo const* /*spellInfo*/) override
1998 {
2000 }
2001
2002 void OnPeriodic(AuraEffect const* /*aurEff*/)
2003 {
2005 if (Unit* caster = GetCaster())
2006 {
2007 Unit* target = GetTarget();
2008 if (caster->GetDistance2d(target) > 25.0f)
2009 {
2010 target->CastSpell(target, SPELL_UNCAGED_WRATH, true);
2011 Remove();
2012 }
2013 }
2014 }
2015
2020};
2021
2022// 40631 - Flame Blast
2024{
2025 bool Validate(SpellInfo const* /*spellInfo*/) override
2026 {
2028 }
2029
2030 void HandleBlaze(SpellEffIndex /*effIndex*/)
2031 {
2032 Unit* target = GetHitUnit();
2033 if (target->GetTypeId() == TYPEID_PLAYER)
2034 target->CastSpell(target, SPELL_BLAZE_SUMMON, true);
2035 }
2036
2041};
2042
2043// 39873 - Glaive Returns
2045{
2047 {
2049 if (Creature* caster = GetCaster()->ToCreature())
2050 caster->DespawnOrUnsummon();
2051 }
2052
2057};
2058
2059// 40834 - Agonizing Flames
2061{
2062 bool Validate(SpellInfo const* /*spellInfo*/) override
2063 {
2065 }
2066
2067 void FilterTargets(std::list<WorldObject*>& targets)
2068 {
2069 if (targets.empty())
2070 return;
2071
2073 targets.clear();
2074 targets.push_back(target);
2075 }
2076
2077 void HandleScript(SpellEffIndex /*effIndex*/)
2078 {
2080 }
2081
2087};
2088
2089// 40511 - Demon Transform 1
2091{
2092 bool Validate(SpellInfo const* /*spellInfo*/) override
2093 {
2095 }
2096
2097 void OnPeriodic(AuraEffect const* /*aurEff*/)
2098 {
2101 Remove();
2102 }
2103
2108};
2109
2110// 40398 - Demon Transform 2
2112{
2113 bool Validate(SpellInfo const* /*spellInfo*/) override
2114 {
2116 }
2117
2118 void OnPeriodic(AuraEffect const* aurEff)
2119 {
2121 Unit* target = GetTarget();
2122
2123 if (aurEff->GetTickNumber() == 1)
2124 {
2125 if (target->GetDisplayId() == target->GetNativeDisplayId())
2126 target->CastSpell(target, SPELL_DEMON_FORM, true);
2127 else
2129 }
2130 else if (aurEff->GetTickNumber() == 2)
2131 {
2132 target->CastSpell(target, SPELL_DEMON_TRANSFORM_3, true);
2134 aura->SetDuration(4300);
2135 Remove();
2136 }
2137 }
2138
2143};
2144
2145// 41126 - Flame Burst
2147{
2148 bool Validate(SpellInfo const* /*spellInfo*/) override
2149 {
2151 }
2152
2157
2162};
2163
2164// 41081 - Find Target
2166{
2167 bool Validate(SpellInfo const* /*spellInfo*/) override
2168 {
2170 }
2171
2172 void FilterTargets(std::list<WorldObject*>& targets)
2173 {
2174 targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_PARALYZE));
2175
2176 if (targets.empty())
2177 return;
2178
2180 targets.clear();
2181 targets.push_back(target);
2182 }
2183
2184 void HandleScript(SpellEffIndex /*effIndex*/)
2185 {
2186 Unit* target = GetHitUnit();
2187 if (Creature* caster = GetCaster()->ToCreature())
2188 {
2189 caster->CastSpell(target, SPELL_PARALYZE, true);
2190 caster->AI()->SetGUID(target->GetGUID(), 0);
2191 }
2192 }
2193
2199};
2200
2201// 39908 - Eye Blast
2203{
2204 void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2205 {
2206 if (Creature* target = GetTarget()->ToCreature())
2207 target->DespawnOrUnsummon();
2208 }
2209
2214};
2215
2216// 40761 - Cage Trap
2218{
2220 {
2221 Creature* target = GetHitCreature();
2222 Creature* caster = GetCaster()->ToCreature();
2223
2224 if (!target || !caster)
2225 return;
2226
2227 if (caster->GetDistance2d(target) < 4.0f)
2228 {
2229 target->AI()->DoAction(ACTION_ILLIDAN_CAGED);
2230 caster->DespawnOrUnsummon();
2231 if (GameObject* trap = target->FindNearestGameObject(GO_ILLIDAN_CAGE_TRAP, 10.0f))
2232 trap->UseDoorOrButton();
2233 }
2234 }
2235
2240};
2241
2242// 40760 - Cage Trap
2244{
2245 bool Validate(SpellInfo const* /*spellInfo*/) override
2246 {
2248 }
2249
2250 void OnPeriodic(AuraEffect const* /*aurEff*/)
2251 {
2253 Unit* target = GetTarget();
2254 target->CastSpell(target, SPELL_CAGED_DEBUFF, true);
2255 Remove();
2256 }
2257
2262};
2263
2264// 40409 - Maiev Down
2289
2290// 40693 - Cage Trap
2292{
2294 {
2295 Position offset = { 0.0f, 0.0f, GetCaster()->GetPositionZ(), 0.0f };
2296 dest.RelocateOffset(offset);
2297 }
2298
2303};
2304
2305// 41242 - Akama Despawn
2307{
2308 void HandleDummy(SpellEffIndex /*effIndex*/)
2309 {
2310 if (Creature* target = GetHitCreature())
2311 target->DespawnOrUnsummon(1s);
2312 }
2313
2318};
2319
2321{
2354}
uint8_t uint8
Definition Define.h:156
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
@ IN_PROGRESS
@ DONE
@ SPLINE_CHAIN_MOTION_TYPE
@ POINT_MOTION_TYPE
@ EFFECT_MOTION_TYPE
@ TEMPSUMMON_MANUAL_DESPAWN
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
@ TYPEID_UNIT
Definition ObjectGuid.h:43
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
bool roll_chance(float chance, PseudoRandomDistributionState &state)
Definition Random.cpp:131
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:43
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
void CloseGossipMenuFor(Player *player)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SCHOOL_DAMAGE
@ TARGET_DEST_CASTER_RADIUS
@ TARGET_DEST_NEARBY_ENTRY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ EMOTE_STATE_READY1H
@ EMOTE_ONESHOT_YES
@ EMOTE_ONESHOT_EXCLAMATION
@ EMOTE_ONESHOT_LAND
@ EMOTE_ONESHOT_ROAR
@ EMOTE_ONESHOT_SALUTE
@ EMOTE_ONESHOT_LIFTOFF
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
AuraRemoveMode
@ AURA_REMOVE_BY_DEATH
@ AURA_REMOVE_BY_EXPIRE
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ SPELL_AURA_MOD_STUN
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define SpellDestinationTargetSelectFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraCheckProcFn(F)
#define AuraEffectRemoveFn(F, I, N, M)
EvadeReason
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_NPC_FLAG_GOSSIP
DamageEffectType
@ SHEATH_STATE_UNARMED
Definition UnitDefines.h:82
@ SHEATH_STATE_MELEE
Definition UnitDefines.h:83
@ UNIT_STATE_ROOT
Definition Unit.h:285
@ UNIT_STATE_CASTING
Definition Unit.h:290
@ AKAMA_FIGHT
@ ACTION_OPEN_DOOR
@ ACTION_ACTIVE_AKAMA_INTRO
#define RegisterBlackTempleCreatureAI(ai_name)
@ DATA_AKAMA
@ DATA_ILLIDARI_COUNCIL
@ DATA_ILLIDAN_STORMRAGE
@ DATA_ILLIDAN_MUSIC_CONTROLLER
@ DATA_AKAMA_ILLIDAN_INTRO
@ DATA_MAIEV
@ NPC_SPIRIT_OF_UDALO
@ NPC_AKAMA
@ NPC_SPIRIT_OF_OLUM
@ NPC_FLAME_OF_AZZINOTH
@ NPC_ILLIDAN_STORMRAGE
@ NPC_FLAME_CRASH
@ NPC_ILLIDARI_ELITE
@ NPC_DEMON_FIRE
@ NPC_BLAZE
@ NPC_BLADE_OF_AZZINOTH
@ NPC_PARASITIC_SHADOWFIEND
@ NPC_GLAIVE_WORLD_TRIGGER
@ NPC_ILLIDAN_DB_TARGET
@ GO_ILLIDAN_CAGE_TRAP
Position const IllidanMiddlePoint
IllidanPoints
@ POINT_RANDOM_PILLAR
@ POINT_ILLIDAN_MIDDLE
@ POINT_TELEPORT
@ POINT_ILLIDAN
@ POINT_ILLIDARI_COUNCIL
@ POINT_THROW_GLAIVE
@ POINT_DB_TARGET
@ POINT_STAIRS
@ POINT_FACE_ILLIDAN
@ POINT_MOVE_BACK
@ POINT_ILLIDAN_ROOM
@ POINT_MINIONS
Position const BladesPositions[2]
Position const MinionsSpawnPositions[10]
IllidanActions
@ ACTION_START_OUTRO
@ ACTION_FINALIZE_AIR_PHASE
@ ACTION_START_MINIONS_WEAVE
@ ACTION_FREE
@ ACTION_RESUME_COMBAT
@ ACTION_ILLIDAN_CAGED
@ ACTION_START_PHASE_2
@ ACTION_FLAME_DEAD
@ ACTION_START_ENCOUNTER
@ ACTION_START_MINIONS
@ ACTION_START_PHASE_4
@ ACTION_INTRO_DONE
@ ACTION_MAIEV_DOWN_FADE
IllidanMisc
@ SUMMON_GROUP
@ GOSSIP_START_FIGHT
@ DATA_AKAMA_TELEPORT_POSITION
@ MAX_MINIONS_NUMBER
@ SPELL_GLAIVE_VISUAL_KIT
@ GOSSIP_START_INTRO
uint32 const SummonCageTrapSpells[8]
IllidanSplineMovement
@ SPLINE_MOVE_BACK
@ SPLINE_ILLIDAN_ROOM
@ SPLINE_STAIRS
@ SPLINE_FACE_ILLIDAN
@ SPLINE_MINIONS
@ SPLINE_ILLIDARI_COUNCIL
@ SPLINE_TELEPORT
Position const IllidanPhase2Positions[4]
void AddSC_boss_illidan()
IllidanEvents
@ EVENT_CHAIN_LIGHTNING
@ EVENT_FLY
@ EVENT_ENCOUNTER_START
@ EVENT_MINIONS_WEAVE
@ EVENT_PHASE_4_DELAYED
@ EVENT_MOVE_TO_ILLIDARI_ROOM
@ EVENT_START_ILLIDAN
@ EVENT_SHADOW_BLAST
@ EVENT_DEMON_TEXT
@ EVENT_MAIEV_FAREWELL_TEXT
@ EVENT_CONFRONT_MAIEV_TEXT
@ EVENT_DEMON
@ EVENT_FIREBALL
@ EVENT_AKAMA_MINIONS_MOVE_2
@ EVENT_MAIEV_OUTRO_TEXT
@ EVENT_PARASITIC_SHADOWFIEND
@ EVENT_AKAMA_MINIONS_EMOTE
@ EVENT_AKAMA_LIGHT_TEXT
@ EVENT_THROW_DAGGER
@ EVENT_THROW_WARGLAIVE_2
@ EVENT_FREE
@ EVENT_GLAIVE_EMOTE
@ EVENT_SPIRIT_SALUTE
@ EVENT_FINAL_SALUTE
@ EVENT_THROW_WARGLAIVE
@ EVENT_UNCONVINCED
@ EVENT_PREPARED
@ EVENT_CAGE_TRAP
@ EVENT_RESUME_COMBAT_PHASE_4
@ EVENT_SHADOW_PRISON_TEXT
@ EVENT_AKAMA_SAY_ALONE
@ EVENT_MAIEV_JUSTICE_TEXT
@ EVENT_TELEPORT
@ EVENT_START_INTRO
@ EVENT_QUIET_SUICIDE
@ EVENT_SPIRIT_SAY_2
@ EVENT_TAUNT
@ EVENT_EVADE_CHECK
@ EVENT_CHANGE_ORIENTATION
@ EVENT_SHADOW_STRIKE
@ EVENT_SHEAR
@ EVENT_MAIEV_ROAR
@ EVENT_FLAME_BLAST
@ EVENT_MAIEV_EXCLAMATION
@ EVENT_FACE_MIDDLE
@ EVENT_HEALING_POTION
@ EVENT_AKAMA_THANKS
@ EVENT_SCHEDULE_DEMON_SPELLS
@ EVENT_RUN_FROM_ILLIDAN_ROOM
@ EVENT_BERSERK
@ EVENT_AKAMA_DOOR_SUCCESS
@ EVENT_SHADOW_DEMON
@ EVENT_AKAMA_MINIONS_MOVE
@ EVENT_ROAR
@ EVENT_ENGAGE
@ EVENT_TIME_HAS_COME
@ EVENT_CANCEL_DEMON_FORM
@ EVENT_MOVE_TO_WARGLAIVE_POINT
@ EVENT_RESUME_COMBAT_DEMON
@ EVENT_AGONIZING_FLAMES
@ EVENT_EYE_BLAST
@ EVENT_MAIEV_TELEPORT_DESPAWN
@ EVENT_AKAMA_MOVE_BACK
@ EVENT_DARK_BARRAGE
@ EVENT_AKAMA_DESPAWN
@ EVENT_AKAMA_MINIONS
@ EVENT_DRAW_SOUL
@ EVENT_FLY_TO_RANDOM_PILLAR
@ EVENT_AKAMA_START_SOUND
@ EVENT_FLAME_BURST
@ EVENT_AKAMA_MOVE_TO_ILLIDAN
@ EVENT_FLAME_CHARGE
@ EVENT_FRENZY
@ EVENT_DEFEATED_TEXT
@ EVENT_AKAMA_SAY_DOOR
@ EVENT_SUMMON_SPIRITS
@ EVENT_AKAMA_DOOR_FAIL
@ EVENT_MAIEV_COMBAT
@ EVENT_RESUME_COMBAT
@ EVENT_MAIEV_YES
@ EVENT_SPIRIT_SAY_1
@ EVENT_MAIEV_APPEAR
@ EVENT_SUMMON_MAIEV
@ EVENT_FLAME_CRASH
Position const IllidanDBTargetSpawnPositions[4]
IllidanEventGroup
@ GROUP_PHASE_2
@ GROUP_PHASE_DEMON
@ GROUP_PHASE_1
@ GROUP_PHASE_ALL
@ GROUP_PHASE_3
@ GROUP_PHASE_4
IllidanPhases
@ PHASE_3
@ PHASE_INTRO
@ PHASE_4
@ PHASE_OUTRO
@ PHASE_MINIONS
@ PHASE_2
@ PHASE_1
IllidanSpells
@ SPELL_BIRTH
@ SPELL_AKAMA_DESPAWN
@ SPELL_DRAW_SOUL_HEAL
@ SPELL_FIND_TARGET
@ SPELL_CLEAR_ALL_DEBUFFS
@ SPELL_CAGED_DEBUFF
@ SPELL_EMOTE_TALK_QUESTION
@ SPELL_SHADOW_PRISON
@ SPELL_DRAW_SOUL
@ SPELL_SHEAR
@ SPELL_HEALING_POTION
@ SPELL_CAGE_TRAP_PERIODIC
@ SPELL_SHADOW_BLAST
@ SPELL_SUMMON_CAGE_TRAP_6
@ SPELL_AGONIZING_FLAMES
@ SPELL_UNCAGED_WRATH
@ SPELL_GLAIVE_RETURNS
@ SPELL_CONSUME_SOUL
@ SPELL_FLAME_CRASH
@ SPELL_SUMMON_CAGE_TRAP_1
@ SPELL_CHARGE
@ SPELL_THROW_DAGGER
@ SPELL_KNEEL
@ SPELL_RANGE_MARKER
@ SPELL_SUMMON_CAGE_TRAP_7
@ SPELL_AURA_OF_DREAD
@ SPELL_AZZINOTH_CHANNEL
@ SPELL_FLAME_BURST_EFFECT
@ SPELL_FLAME_BURST
@ SPELL_PARASITIC_SHADOWFIEND_2
@ SPELL_SUMMON_CAGE_TRAP_8
@ SPELL_DEATHSWORN_DOOR_CHANNEL
@ SPELL_AKAMA_DOOR_CHANNEL
@ SPELL_ARCANE_EXPLOSION
@ SPELL_SUMMON_PARASITIC_SHADOWFIENDS
@ SPELL_TELEPORT_VISUAL
@ SPELL_AGONIZING_FLAMES_SELECTOR
@ SPELL_THROW_GLAIVE
@ SPELL_DARK_BARRAGE
@ SPELL_THROW_GLAIVE2
@ SPELL_SHADOW_STRIKE
@ SPELL_CAGE_TRAP
@ SPELL_FIREBALL
@ SPELL_FLAME_CRASH_GROUND
@ SPELL_DEMON_FORM
@ SPELL_SUMMON_CAGE_TRAP_4
@ SPELL_MAIEV_DOWN
@ SPELL_SHADOW_DEMON_PASSIVE
@ SPELL_DEMON_TRANSFORM_1
@ SPELL_BLAZE_SUMMON
@ SPELL_SUMMON_MAIEV
@ SPELL_REMOVE_PARASITIC_SHADOWFIEND
@ SPELL_FLAME_BLAST
@ SPELL_DEMON_TRANSFORM_2
@ SPELL_SUMMON_CAGE_TRAP_2
@ SPELL_SUMMON_CAGE_TRAP_3
@ SPELL_EYE_BLAST_TRIGGER
@ SPELL_TELEPORT_MAIEV
@ SPELL_PARASITIC_SHADOWFIEND
@ SPELL_FLAME_TEAR_OF_AZZINOTH
@ SPELL_FRENZY
@ SPELL_PARALYZE
@ SPELL_CHAIN_LIGHTNING
@ SPELL_CAGED_TRAP_TELEPORT
@ SPELL_BERSERK
@ SPELL_DEATH
@ SPELL_QUIET_SUICIDE
@ SPELL_CAGE_TRAP_SUMMON
@ SPELL_AKAMA_TELEPORT
@ SPELL_AKAMA_DOOR_FAIL
@ SPELL_SUMMON_GLAIVE
@ SPELL_EYE_BLAST
@ SPELL_DEMON_FIRE
@ SPELL_SUMMON_CAGE_TRAP_5
@ SPELL_SUMMON_TEAR_OF_AZZINOTH
@ SPELL_SUMMON_SHADOWDEMON
@ SPELL_BLAZE
@ SPELL_DEMON_TRANSFORM_3
Position const IllidanDBTargetPoints[4]
Position const AkamaTeleportPositions[2]
IllidanTexts
@ EMOTE_AZZINOTH_GAZE
@ SAY_MAIEV_SHADOWSONG_FAREWELL
@ EVENT_BT_SUMMIT_WALK_SOUND_ID
@ SAY_ILLIDAN_TAKEOFF
@ SAY_ILLIDAN_KILL
@ SAY_AKAMA_TIME_HAS_COME
@ SAY_AKAMA_LIGHT
@ ILLIDAN_WARGLAIVE_SOUND_ID
@ SAY_ILLIDAN_UNCONVINCED
@ EVENT_BT_STORM_WALK_UNI_3_SOUND_ID
@ SAY_AKAMA_SALUTE
@ SAY_ILLIDAN_MINION
@ EVENT_BT_STORM_WALK_HERO_2_SOUND_ID
@ SAY_MAIEV_SHADOWSONG_TRAP
@ SAY_ILLIDAN_CONFRONT_MAIEV
@ SAY_AKAMA_DOOR
@ SAY_AKAMA_ALONE
@ SAY_MAIEV_SHADOWSONG_OUTRO
@ SAY_ILLIDAN_DUPLICITY
@ SAY_AKAMA_MINIONS
@ SAY_ILLIDAN_FRENZY
@ SAY_ILLIDAN_EYE_BLAST
@ EVENT_BT_SUMMIT_WALK_3_SOUND_ID
@ SAY_SPIRIT_ALONE
@ SAY_ILLIDAN_SUMMONFLAMES
@ SAY_ILLIDAN_TAUNT
@ ILLIDAN_TAKEOFF_SOUND_ID
@ SAY_MAIEV_SHADOWSONG_FINISHED
@ SAY_AKAMA_FINISH
@ SAY_ILLIDAN_PREPARED
@ WARGLAIVE_SPAWN_SOUND_ID
@ SAY_ILLIDAN_SHADOW_PRISON
@ SAY_MAIEV_SHADOWSONG_DOWN
@ SAY_MAIEV_SHADOWSONG_APPEAR
@ SAY_AKAMA_FREE
@ SAY_AKAMA_BETRAYER
@ SAY_MAIEV_SHADOWSONG_TAUNT
@ SAY_ILLIDAN_DEFEATED
@ SAY_MAIEV_SHADOWSONG_JUSTICE
@ SAY_ILLIDAN_MORPH
@ SAY_ILLIDAN_ENRAGE
@ EVENT_BT_ARRIVAL_WALK_HERO_1_SOUND_ID
AuraRemoveMode GetRemoveMode() const
Definition SpellAuras.h:96
uint32 GetTickNumber() const
void PreventDefaultAction()
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
HookList< EffectApplyHandler > AfterEffectApply
Unit * GetCaster() const
Aura * GetAura() const
Unit * GetTarget() const
HookList< CheckProcHandler > DoCheckProc
Unit * GetUnitOwner() const
HookList< EffectApplyHandler > OnEffectApply
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
TypeID GetTypeId() const
Definition BaseEntity.h:166
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
void JustSummoned(Creature *summon) override
void _DespawnAtEvade(Seconds delayToRespawn=30s, Creature *who=nullptr)
SummonList summons
EventMap events
bool operator()(Unit *unit) const
void DoZoneInCombat()
Definition CreatureAI.h:169
bool IsInBoundary(Position const *who=nullptr) const
bool UpdateVictim()
void SetBoundary(CreatureBoundary const *boundary, bool negativeBoundaries=false)
Creature *const me
Definition CreatureAI.h:63
void LoadEquipment(int8 id=1, bool force=false)
void SetReactState(ReactStates st)
Definition Creature.h:180
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void SetImmuneToNPC(bool apply) override
Definition Creature.h:193
void SetImmuneToAll(bool apply) override
Definition Creature.h:187
void SetCanDualWield(bool value) override
CreatureAI * AI() const
Definition Creature.h:235
void Update(uint32 time)
Definition EventMap.h:77
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
Milliseconds GetTimeUntilEvent(EventId eventId) const
Definition EventMap.cpp:200
EventId ExecuteEvent()
Definition EventMap.cpp:77
bool IsInPhase(PhaseIndex phase) const
Definition EventMap.h:246
void RescheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:56
void CancelEvent(EventId eventId)
Definition EventMap.cpp:156
void SetPhase(PhaseIndex phase)
Definition EventMap.cpp:32
void CancelEventGroup(GroupIndex group)
Definition EventMap.cpp:178
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:40
void Reset()
Definition EventMap.cpp:25
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
Milliseconds CalculateTime(Milliseconds t_offset) const
virtual bool SetBossState(uint32 id, EncounterState state)
Creature * GetCreature(uint32 type)
virtual ObjectGuid GetGuidData(uint32 type) const override
CreatureBoundary const * GetBossBoundary(uint32 id) const
EncounterState GetBossState(uint32 id) const
GameObject * GetGameObject(uint32 type)
PlayerList const & GetPlayers() const
Definition Map.h:408
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk)
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 MoveCloserAndStop(uint32 id, Unit *target, float distance)
void Clear()
Definition ObjectGuid.h:329
uint32 GetEntry() const
Definition Object.h:89
Creature * ToCreature()
Definition Object.h:121
Unit * GetActionTarget() const
Definition Unit.h:514
iterator end()
Definition RefManager.h:36
iterator begin()
Definition RefManager.h:35
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Creature * GetHitCreature() const
Unit * GetCaster() const
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
void DespawnEntry(uint32 entry)
void DespawnIf(T const &predicate)
void Summon(Creature const *summon)
void DoAction(int32 info, Predicate &&predicate, uint16 max=0)
SummonWarglaiveEvent(Unit *owner)
bool Execute(uint64, uint32) override
TaskContext & Repeat(TaskScheduler::duration_t duration)
TaskScheduler & Schedule(duration_t time, task_handler_t task)
TaskScheduler & Update()
Update the scheduler to the current time.
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:160
virtual bool CanAIAttack(Unit const *) const
Definition UnitAI.h:58
virtual void DoAction(int32 param)
Definition UnitAI.h:73
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:172
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:71
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:162
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:81
Definition Unit.h:647
bool IsWithinMeleeRange(Unit const *obj) const
Definition Unit.h:722
void SetControlled(bool apply, UnitState state)
Definition Unit.cpp:11631
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3253
MotionMaster * GetMotionMaster()
Definition Unit.h:1750
void RemoveNpcFlag(NPCFlags flags)
Definition Unit.h:1013
UnitAI * GetAI() const
Definition Unit.h:680
void SetUninteractible(bool apply)
Definition Unit.cpp:8583
void SetSheath(SheathState sheathed)
Definition Unit.cpp:5832
void SetFacingToObject(WorldObject const *object, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13394
void SetEmoteState(Emote emote)
Definition Unit.h:880
uint32 GetDisplayId() const
Definition Unit.h:1637
uint32 GetNativeDisplayId() const
Definition Unit.h:1640
uint64 GetHealth() const
Definition Unit.h:800
void SetNpcFlag(NPCFlags flags)
Definition Unit.h:1012
Unit * GetVictim() const
Definition Unit.h:738
bool HealthBelowPct(float pct) const
Definition Unit.h:804
bool HasUnitState(const uint32 f) const
Definition Unit.h:755
void SendPlaySpellVisualKit(uint32 id, uint32 type, uint32 duration) const
Definition Unit.cpp:12437
void SetFacingTo(float ori, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13385
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4822
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition Unit.cpp:1662
bool SetDisableGravity(bool disable, bool updateAnimTier=true, bool updatePlayHoverAnim=true)
Definition Unit.cpp:13440
bool AttackStop()
Definition Unit.cpp:5984
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3992
void PlayDirectSound(uint32 soundId, Player const *target=nullptr, uint32 broadcastTextId=0) const
Definition Object.cpp:2941
GameObject * FindNearestGameObject(uint32 entry, float range, bool spawnedOnly=true) const
Definition Object.cpp:1544
Map * GetMap() const
Definition Object.h:411
InstanceScript * GetInstanceScript() const
Definition Object.cpp:394
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2222
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:1403
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:448
EventProcessor m_Events
Definition Object.h:561
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=nullptr)
Definition Object.cpp:1512
virtual uint32 GetData(uint32) const
Definition ZoneScript.h:99
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:100
void FilterTargets(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *) override
void OnRemoveDummy(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void SetDest(SpellDestination &dest)
void SetDest(SpellDestination &dest)
void HandleScriptEffect(SpellEffIndex)
void Register() override
void OnPeriodic(AuraEffect const *)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void OnPeriodic(AuraEffect const *)
void OnPeriodic(AuraEffect const *aurEff)
bool Validate(SpellInfo const *) override
void HandleDummy(SpellEffIndex)
void HandleScriptEffect(SpellEffIndex effIndex)
bool Validate(SpellInfo const *) override
void HandleEffectRemove(AuraEffect const *, AuraEffectHandleModes)
void FilterTargets(std::list< WorldObject * > &targets)
void HandleScript(SpellEffIndex)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleBlaze(SpellEffIndex)
bool Validate(SpellInfo const *) override
void HandleScriptEffect(SpellEffIndex)
bool CheckProc(ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
void HandleEffectRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void HandleApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void HandleScriptEffect(SpellEffIndex)
bool Validate(SpellInfo const *) override
void HandleDummy(SpellEffIndex)
bool Load() override
void HandleEffectRemove(AuraEffect const *, AuraEffectHandleModes)
void HandleEffectApply(AuraEffect const *, AuraEffectHandleModes)
void Register() override
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
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
constexpr void SetOrientation(float orientation)
Definition Position.h:82
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:136
constexpr void Relocate(float x, float y)
Definition Position.h:74
constexpr float GetOrientation() const
Definition Position.h:90
constexpr float GetPositionZ() const
Definition Position.h:89
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
void SetCombatMovement(bool allowMovement)
void ResetThreatList(Unit *who=nullptr)
void DoPlaySoundToSet(WorldObject *source, uint32 soundId)
void AddThreat(Unit *victim, float amount, Unit *who=nullptr)
void RelocateOffset(Position const &offset)
Definition Spell.cpp:90
void Relocate(Position const &pos)
Definition Spell.cpp:82
void KilledUnit(Unit *victim) override
void SummonedCreatureDies(Creature *summon, Unit *) override
void JustSummoned(Creature *summon) override
void ChangeOrientation(float orientation)
void DamageTaken(Unit *who, uint32 &damage, DamageEffectType, SpellInfo const *) override
boss_illidan_stormrage(Creature *creature)
void JustDied(Unit *) override
void JustEngagedWith(Unit *who) override
void EnterEvadeMode(EvadeReason) override
void MovementInform(uint32 type, uint32 pointId) override
void UpdateAI(uint32 diff) override
void DoAction(int32 actionId) override
void ScheduleEvents(uint8 phase, uint8 group)
void DoAction(int32 actionId) override
void UpdateAI(uint32 diff) override
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
void MovementInform(uint32 type, uint32 pointId) override
void JustSummoned(Creature *summon) override
void EnterEvadeMode(EvadeReason) override
ObjectGuid _spiritOfOlumGUID
uint32 GetData(uint32) const override
bool CanAIAttack(Unit const *who) const override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
ObjectGuid _spiritOfUdaloGUID
void Reset() override
InstanceScript * _instance
void ChangeOrientation(float orientation)
npc_akama_illidan(Creature *creature)
void JustSummoned(Creature *summon) override
npc_blade_of_azzinoth(Creature *creature)
InstanceScript * _instance
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
npc_cage_trap_trigger(Creature *creature)
InstanceScript * _instance
void UpdateAI(uint32 diff) override
void JustDied(Unit *) override
npc_flame_of_azzinoth(Creature *creature)
npc_illidan_db_target(Creature *creature)
void JustSummoned(Creature *summon) override
void MovementInform(uint32 type, uint32 pointId) override
npc_illidan_generic_fire(Creature *creature)
void UpdateAI(uint32) override
InstanceScript * _instance
void Reset() override
npc_illidari_elite(Creature *creature)
bool CanAIAttack(Unit const *who) const override
npc_maiev(Creature *creature)
EventMap _events
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void DoAction(int32 actionId) override
void JustAppeared() override
InstanceScript * _instance
void JustEngagedWith(Unit *) override
void UpdateAI(uint32 diff) override
npc_parasitic_shadowfiend(Creature *creature)
void UpdateAI(uint32 diff) override
void DoAction(int32 action) override
void SetGUID(ObjectGuid const &guid, int32) override
npc_shadow_demon(Creature *creature)
void UpdateAI(uint32 diff) override
void Reset() override
InstanceScript * _instance
TaskScheduler _scheduler