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_i(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();
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();
632 break;
634 for (uint32 summonSpell : SummonCageTrapSpells)
635 DoCastSelf(summonSpell, true);
637 break;
639 me->AttackStop();
640 events.Reset();
642 DoCastSelf(SPELL_DEATH, true);
645 break;
646 default:
647 break;
648 }
649 }
650
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;
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;
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
1043 }
1044
1045private:
1051 bool _dead;
1054};
1055
1056// 23089 - Akama
1058{
1059 npc_akama_illidan(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()),
1060 _orientation(0.0f), _isTeleportToMinions(false) { }
1061
1062 void Reset() override
1063 {
1064 _events.Reset();
1067 _isTeleportToMinions = false;
1068 }
1069
1070 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
1071 {
1072 if (gossipListId == GOSSIP_START_INTRO)
1073 {
1078 illidan->AI()->DoAction(ACTION_INTRO_DONE);
1079 CloseGossipMenuFor(player);
1080
1081 }
1082 else if (gossipListId == GOSSIP_START_FIGHT)
1083 {
1087 CloseGossipMenuFor(player);
1088 }
1089 return false;
1090 }
1091
1092 bool CanAIAttack(Unit const* who) const override
1093 {
1095 return false;
1096 return ScriptedAI::CanAIAttack(who);
1097 }
1098
1099 uint32 GetData(uint32 /*data*/) const override
1100 {
1101 return _isTeleportToMinions ? 1 : 0;
1102 }
1103
1104 void EnterEvadeMode(EvadeReason /*why*/) override { }
1105
1106 void JustSummoned(Creature* summon) override
1107 {
1108 if (summon->GetEntry() == NPC_SPIRIT_OF_UDALO)
1109 {
1110 _spiritOfUdaloGUID = summon->GetGUID();
1112 }
1113 else if (summon->GetEntry() == NPC_SPIRIT_OF_OLUM)
1114 {
1115 _spiritOfOlumGUID = summon->GetGUID();
1117 }
1118 }
1119
1120 void DoAction(int32 actionId) override
1121 {
1122 switch (actionId)
1123 {
1130 break;
1131 case ACTION_OPEN_DOOR:
1134 break;
1135 case ACTION_FREE:
1137 break;
1141 break;
1144 break;
1145 case ACTION_START_OUTRO:
1147 me->AttackStop();
1148 _events.Reset();
1150 break;
1151 default:
1152 break;
1153 }
1154 }
1155
1156 void ChangeOrientation(float orientation)
1157 {
1158 _orientation = orientation;
1160 }
1161
1162 void MovementInform(uint32 type, uint32 pointId) override
1163 {
1164 if (type != POINT_MOTION_TYPE && type != SPLINE_CHAIN_MOTION_TYPE)
1165 return;
1166
1167 switch (pointId)
1168 {
1172 break;
1173 case POINT_STAIRS:
1174 ChangeOrientation(6.265732f);
1176 break;
1177 case POINT_ILLIDAN_ROOM:
1178 ChangeOrientation(2.129302f);
1181 break;
1182 case POINT_FACE_ILLIDAN:
1183 ChangeOrientation(3.140537f);
1185 break;
1186 case POINT_TELEPORT:
1189 break;
1190 case POINT_MINIONS:
1192 me->SetImmuneToNPC(false);
1195 illidan->AI()->DoAction(ACTION_START_MINIONS_WEAVE);
1197 break;
1198 case POINT_MOVE_BACK:
1200 break;
1201 case POINT_ILLIDAN:
1203 break;
1204 default:
1205 break;
1206 }
1207 }
1208
1209 void DamageTaken(Unit* /*who*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1210 {
1211 if (damage >= me->GetHealth())
1212 damage = me->GetHealth() - 1;
1213 }
1214
1215 void UpdateAI(uint32 diff) override
1216 {
1218 return;
1219
1220 _events.Update(diff);
1221
1223 return;
1224
1225 while (uint32 eventId = _events.ExecuteEvent())
1226 {
1227 switch (eventId)
1228 {
1229 case EVENT_TELEPORT:
1231 break;
1234 break;
1238 break;
1242 break;
1246 break;
1250 break;
1251 case EVENT_SPIRIT_SAY_1:
1253 undalo->AI()->Talk(SAY_SPIRIT_ALONE);
1255 break;
1256 case EVENT_SPIRIT_SAY_2:
1258 olum->AI()->Talk(SAY_SPIRIT_ALONE);
1260 break;
1264 undalo->CastSpell((Unit*) nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL);
1266 olum->CastSpell((Unit*) nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL);
1268 break;
1271 musicController->PlayDirectMusic(EVENT_BT_SUMMIT_WALK_SOUND_ID);
1272 break;
1273 case EVENT_AKAMA_THANKS:
1277 break;
1280 {
1281 undalo->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
1282 undalo->DespawnOrUnsummon(7s);
1283 }
1285 {
1286 olum->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
1287 olum->DespawnOrUnsummon(7s);
1288 }
1289 break;
1292 break;
1295 illidan->AI()->DoAction(ACTION_START_ENCOUNTER);
1296 break;
1297 case EVENT_FREE:
1300 break;
1304 break;
1305 case EVENT_ROAR:
1308 break;
1311 break;
1313 if (me->HealthBelowPct(20))
1315 _events.Repeat(1s);
1316 break;
1320 break;
1323 me->AttackStop();
1325 me->SetImmuneToNPC(true);
1327 break;
1329 _isTeleportToMinions = true;
1331 break;
1334 break;
1337 _events.Repeat(8s + 500ms);
1338 break;
1341 break;
1345 break;
1349 break;
1350 case EVENT_FINAL_SALUTE:
1353 break;
1356 break;
1357 default:
1358 break;
1359 }
1360
1362 return;
1363 }
1364
1366 }
1367
1368private:
1375};
1376
1377// 23498 - Parasitic Shadowfiend
1379{
1380 npc_parasitic_shadowfiend(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
1381
1382 void Reset() override
1383 {
1385 {
1387 return;
1388 }
1389
1391 illidan->AI()->JustSummoned(me);
1393 _scheduler.Schedule(2s, [this](TaskContext /*context*/)
1394 {
1397 });
1398 }
1399
1400 void DoAction(int32 action) override
1401 {
1402 if (action == ACTION_START_PHASE_4)
1403 {
1405 me->AttackStop();
1406 }
1407 else if (action == ACTION_RESUME_COMBAT)
1408 _scheduler.Schedule(2s, [this](TaskContext /*context*/)
1409 {
1412 });
1413 }
1414
1415 void UpdateAI(uint32 diff) override
1416 {
1417 _scheduler.Update(diff);
1418
1419 if (!UpdateVictim())
1420 return;
1421
1423 }
1424
1425private:
1428};
1429
1430// 22996 - Blade of Azzinoth
1432{
1433 npc_blade_of_azzinoth(Creature* creature) : NullCreatureAI(creature), _instance(creature->GetInstanceScript()) { }
1434
1435 void Reset() override
1436 {
1438 {
1440 return;
1441 }
1442
1444 illidan->AI()->JustSummoned(me);
1445 _flameGuid.Clear();
1447 DoCastSelf(SPELL_BIRTH, true);
1448 _scheduler.Schedule(3s, [this](TaskContext /*context*/)
1449 {
1451 _scheduler.Schedule(500ms, [this](TaskContext /*context*/)
1452 {
1455 });
1456 });
1457 }
1458
1459 void JustSummoned(Creature* summon) override
1460 {
1461 if (summon->GetEntry() == NPC_FLAME_OF_AZZINOTH)
1462 _flameGuid = summon->GetGUID();
1463 }
1464
1465 void UpdateAI(uint32 diff) override
1466 {
1467 _scheduler.Update(diff);
1468 }
1469
1470private:
1474};
1475
1476// 22997 - Flame of Azzinoth
1478{
1479 npc_flame_of_azzinoth(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
1480 {
1482 }
1483
1484 void Reset() override
1485 {
1487 {
1489 return;
1490 }
1491
1493 illidan->AI()->JustSummoned(me);
1494 DoCastSelf(SPELL_FLAME_TEAR_OF_AZZINOTH, true); // Idk what this spell should do
1498 }
1499
1500 void UpdateAI(uint32 diff) override
1501 {
1502 if (!UpdateVictim())
1503 return;
1504
1506 return;
1507
1508 _events.Update(diff);
1509
1510 while (uint32 eventId = _events.ExecuteEvent())
1511 {
1512 switch (eventId)
1513 {
1514 case EVENT_ENGAGE:
1518 break;
1519 case EVENT_FLAME_CHARGE:
1521 {
1522 DoCast(target, SPELL_CHARGE);
1523 _events.Repeat(5s);
1524 }
1525 else
1526 _events.Repeat(1s);
1527 break;
1528 case EVENT_FLAME_BLAST:
1530 _events.Repeat(12s);
1531 break;
1532 default:
1533 break;
1534 }
1535
1537 return;
1538 }
1539
1541 }
1542
1543 void JustDied(Unit* /*killer*/) override
1544 {
1546 illidan->AI()->DoAction(ACTION_FLAME_DEAD);
1547 }
1548
1549private:
1552};
1553
1554// 23070 - Illidan DB Target
1556{
1558
1559 void Reset() override
1560 {
1562 }
1563
1564 void JustSummoned(Creature* summon) override
1565 {
1566 if (summon->GetEntry() == NPC_DEMON_FIRE)
1568 }
1569
1570 void MovementInform(uint32 type, uint32 pointId) override
1571 {
1572 if (type == POINT_MOTION_TYPE && pointId == POINT_DB_TARGET)
1573 {
1576 }
1577 }
1578};
1579
1580// 23375 - Shadow Demon
1582{
1583 npc_shadow_demon(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
1584
1585 void Reset() override
1586 {
1588 {
1590 return;
1591 }
1592
1595 _scheduler.Schedule(1s, [this](TaskContext checkTarget)
1596 {
1597 if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID))
1598 {
1599 if (!target->IsAlive())
1601 else if (me->IsWithinMeleeRange(target))
1602 {
1603 me->InterruptNonMeleeSpells(false);
1604 DoCast(target, SPELL_CONSUME_SOUL, true);
1605 }
1606 }
1607 checkTarget.Repeat();
1608 });
1609 }
1610
1611 void SetGUID(ObjectGuid const& guid, int32 /*id*/) override
1612 {
1613 _targetGUID = guid;
1614 if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID))
1615 me->GetMotionMaster()->MoveChase(target);
1616 }
1617
1618 void UpdateAI(uint32 diff) override
1619 {
1620 _scheduler.Update(diff);
1621 }
1622
1623private:
1627};
1628
1629// 23197 - Maiev Shadowsong
1630struct npc_maiev : public ScriptedAI
1631{
1632 npc_maiev(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _canDown(true) { }
1633
1646
1654
1655 void DoAction(int32 actionId) override
1656 {
1657 if (actionId == ACTION_START_OUTRO)
1658 {
1659 _events.Reset();
1662 me->AttackStop();
1664 me->SetFacingToObject(illidan);
1667 }
1668 else if (actionId == ACTION_MAIEV_DOWN_FADE)
1669 _canDown = true;
1670 }
1671
1672 void DamageTaken(Unit* /*who*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1673 {
1674 if (damage >= me->GetHealth() && _canDown)
1675 {
1676 damage = me->GetHealth() - 1;
1677 _canDown = false;
1680 }
1681 }
1682
1683 void UpdateAI(uint32 diff) override
1684 {
1686 return;
1687
1689 return;
1690
1691 _events.Update(diff);
1692
1693 while (uint32 eventId = _events.ExecuteEvent())
1694 {
1695 switch (eventId)
1696 {
1697 case EVENT_MAIEV_APPEAR:
1699 break;
1702 break;
1706 break;
1707 case EVENT_MAIEV_YES:
1710 break;
1711 case EVENT_MAIEV_ROAR:
1714 break;
1715 case EVENT_MAIEV_COMBAT:
1718 AttackStart(illidan);
1719 break;
1720 case EVENT_CAGE_TRAP:
1722 illidan->CastSpell(illidan, SPELL_CAGED_TRAP_TELEPORT, true);
1725 _events.Repeat(30s);
1726 break;
1729 _events.Repeat(50s);
1730 break;
1731 case EVENT_THROW_DAGGER:
1732 if (Unit* target = me->GetVictim())
1733 if (!me->IsWithinMeleeRange(target))
1734 {
1736 _events.Repeat(5s);
1737 break;
1738 }
1739 _events.Repeat(1s);
1740 break;
1741 case EVENT_TAUNT:
1743 _events.Repeat(30s, 60s);
1744 break;
1748 break;
1752 break;
1755 me->DespawnOrUnsummon(1s);
1756 break;
1757 default:
1758 break;
1759 }
1760
1762 return;
1763 }
1764
1766 }
1767
1768private:
1772};
1773
1774// 23304 - Cage Trap Disturb Trigger
1776{
1777 npc_cage_trap_trigger(Creature* creature) : PassiveAI(creature) { }
1778
1779 void Reset() override
1780 {
1781 _scheduler.Schedule(1s, [this](TaskContext checkTarget)
1782 {
1784 checkTarget.Repeat();
1785 });
1786 }
1787
1788 void UpdateAI(uint32 diff) override
1789 {
1790 _scheduler.Update(diff);
1791 }
1792
1793private:
1795};
1796
1797// 23226 - Illidari Elite
1799{
1800 npc_illidari_elite(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
1801
1802 void Reset() override
1803 {
1805 {
1806 AttackStart(akama);
1807 AddThreat(akama, 1000.0f);
1808 }
1809 }
1810
1811 bool CanAIAttack(Unit const* who) const override
1812 {
1813 if (who->GetEntry() == NPC_AKAMA)
1814 return true;
1815 return false;
1816 }
1817
1818private:
1820};
1821
1822// 23069 - Demon Fire
1823// 23259 - Blaze
1824// 23336 - Flame Crash
1826{
1827 npc_illidan_generic_fire(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
1828 {
1829 SetCombatMovement(false);
1830 }
1831
1832 void Reset() override
1833 {
1835 illidan->AI()->JustSummoned(me);
1836
1838 switch (me->GetEntry())
1839 {
1840 case NPC_DEMON_FIRE:
1842 break;
1843 case NPC_BLAZE:
1844 DoCastSelf(SPELL_BLAZE, true);
1845 DoCastSelf(SPELL_BIRTH, true);
1846 break;
1847 case NPC_FLAME_CRASH:
1849 break;
1850 default:
1851 break;
1852 }
1853 }
1854
1855 void UpdateAI(uint32 /*diff*/) override { }
1856
1857private:
1859};
1860
1861// 41077 - Akama Teleport
1863{
1865
1867 {
1868 if (Creature* caster = GetCaster()->ToCreature())
1869 {
1870 uint32 destination = caster->AI()->GetData(DATA_AKAMA_TELEPORT_POSITION);
1871 dest.Relocate(AkamaTeleportPositions[destination]);
1872 }
1873 }
1874
1879};
1880
1881// 41268 - Quest - Black Temple - Akama - Door Open
1883{
1885
1886 bool Validate(SpellInfo const* /*spell*/) override
1887 {
1889 }
1890
1891 void OnRemoveDummy(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1892 {
1893 Unit* target = GetTarget();
1894 target->CastSpell(target, SPELL_ARCANE_EXPLOSION, true);
1895
1896 if (InstanceScript* instance = target->GetInstanceScript())
1897 if (Creature* akama = instance->GetCreature(DATA_AKAMA))
1898 akama->AI()->DoAction(ACTION_OPEN_DOOR);
1899 }
1900
1905};
1906
1907// 40904 - Draw Soul
1928
1929/* 41917 - Parasitic Shadowfiend
1930 41914 - Parasitic Shadowfiend */
1932{
1934
1935 bool Validate(SpellInfo const* /*spellInfo*/) override
1936 {
1938 }
1939
1940 void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1941 {
1943 if (removeMode != AURA_REMOVE_BY_EXPIRE && removeMode != AURA_REMOVE_BY_DEATH)
1944 return;
1945
1946 Unit* target = GetTarget();
1947 target->CastSpell(target, SPELL_SUMMON_PARASITIC_SHADOWFIENDS, true);
1948 }
1949
1954};
1955
1956// 41913 - Parasitic Shadowfiend Passive
1977
1978// 41923 - Remove Parasitic Shadowfiends (SERVERSIDE)
1999
2000/* 39635 - Throw Glaive
2001 39849 - Throw Glaive */
2017
2018// 39857 - Tear of Azzinoth Summon Channel
2020{
2022
2023 bool Validate(SpellInfo const* /*spellInfo*/) override
2024 {
2026 }
2027
2028 void OnPeriodic(AuraEffect const* /*aurEff*/)
2029 {
2031 if (Unit* caster = GetCaster())
2032 {
2033 Unit* target = GetTarget();
2034 if (caster->GetDistance2d(target) > 25.0f)
2035 {
2036 target->CastSpell(target, SPELL_UNCAGED_WRATH, true);
2037 Remove();
2038 }
2039 }
2040 }
2041
2046};
2047
2048// 40631 - Flame Blast
2050{
2052
2053 bool Validate(SpellInfo const* /*spellInfo*/) override
2054 {
2056 }
2057
2058 void HandleBlaze(SpellEffIndex /*effIndex*/)
2059 {
2060 Unit* target = GetHitUnit();
2061 if (target->GetTypeId() == TYPEID_PLAYER)
2062 target->CastSpell(target, SPELL_BLAZE_SUMMON, true);
2063 }
2064
2069};
2070
2071// 39873 - Glaive Returns
2088
2089// 40834 - Agonizing Flames
2091{
2093
2094 bool Validate(SpellInfo const* /*spellInfo*/) override
2095 {
2097 }
2098
2099 void FilterTargets(std::list<WorldObject*>& targets)
2100 {
2101 if (targets.empty())
2102 return;
2103
2105 targets.clear();
2106 targets.push_back(target);
2107 }
2108
2109 void HandleScript(SpellEffIndex /*effIndex*/)
2110 {
2112 }
2113
2119};
2120
2121// 40511 - Demon Transform 1
2143
2144// 40398 - Demon Transform 2
2146{
2148
2149 bool Validate(SpellInfo const* /*spellInfo*/) override
2150 {
2152 }
2153
2154 void OnPeriodic(AuraEffect const* aurEff)
2155 {
2157 Unit* target = GetTarget();
2158
2159 if (aurEff->GetTickNumber() == 1)
2160 {
2161 if (target->GetDisplayId() == target->GetNativeDisplayId())
2162 target->CastSpell(target, SPELL_DEMON_FORM, true);
2163 else
2165 }
2166 else if (aurEff->GetTickNumber() == 2)
2167 {
2168 target->CastSpell(target, SPELL_DEMON_TRANSFORM_3, true);
2170 aura->SetDuration(4300);
2171 Remove();
2172 }
2173 }
2174
2179};
2180
2181// 41126 - Flame Burst
2201
2202// 41081 - Find Target
2204{
2206
2207 bool Validate(SpellInfo const* /*spellInfo*/) override
2208 {
2210 }
2211
2212 void FilterTargets(std::list<WorldObject*>& targets)
2213 {
2214 targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_PARALYZE));
2215
2216 if (targets.empty())
2217 return;
2218
2220 targets.clear();
2221 targets.push_back(target);
2222 }
2223
2224 void HandleScript(SpellEffIndex /*effIndex*/)
2225 {
2226 Unit* target = GetHitUnit();
2227 if (Creature* caster = GetCaster()->ToCreature())
2228 {
2229 caster->CastSpell(target, SPELL_PARALYZE, true);
2230 caster->AI()->SetGUID(target->GetGUID(), 0);
2231 }
2232 }
2233
2239};
2240
2241// 39908 - Eye Blast
2243{
2245
2246 void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2247 {
2248 if (Creature* target = GetTarget()->ToCreature())
2249 target->DespawnOrUnsummon();
2250 }
2251
2256};
2257
2258// 40761 - Cage Trap
2260{
2262
2264 {
2265 Creature* target = GetHitCreature();
2266 Creature* caster = GetCaster()->ToCreature();
2267
2268 if (!target || !caster)
2269 return;
2270
2271 if (caster->GetDistance2d(target) < 4.0f)
2272 {
2273 target->AI()->DoAction(ACTION_ILLIDAN_CAGED);
2274 caster->DespawnOrUnsummon();
2275 if (GameObject* trap = target->FindNearestGameObject(GO_ILLIDAN_CAGE_TRAP, 10.0f))
2276 trap->UseDoorOrButton();
2277 }
2278 }
2279
2284};
2285
2286// 40760 - Cage Trap
2288{
2290
2291 bool Validate(SpellInfo const* /*spellInfo*/) override
2292 {
2294 }
2295
2296 void OnPeriodic(AuraEffect const* /*aurEff*/)
2297 {
2299 Unit* target = GetTarget();
2300 target->CastSpell(target, SPELL_CAGED_DEBUFF, true);
2301 Remove();
2302 }
2303
2308};
2309
2310// 40409 - Maiev Down
2337
2338// 40693 - Cage Trap
2354
2355// 41242 - Akama Despawn
2357{
2359
2360 void HandleDummy(SpellEffIndex /*effIndex*/)
2361 {
2362 if (Creature* target = GetHitCreature())
2363 target->DespawnOrUnsummon(1s);
2364 }
2365
2370};
2371
2373{
2406}
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint64_t uint64
Definition Define.h:132
uint32_t uint32
Definition Define.h:133
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:38
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
bool roll_chance_i(int chance)
Definition Random.h:59
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
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
AuraRemoveMode
@ AURA_REMOVE_BY_DEATH
@ AURA_REMOVE_BY_EXPIRE
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ 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)
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_NPC_FLAG_GOSSIP
@ SHEATH_STATE_UNARMED
Definition UnitDefines.h:98
@ SHEATH_STATE_MELEE
Definition UnitDefines.h:99
@ UNIT_FLAG_UNINTERACTIBLE
@ UNIT_STATE_ROOT
Definition Unit.h:230
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
@ 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:80
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
void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Unit * GetUnitOwner() const
HookList< EffectApplyHandler > OnEffectApply
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
@ EVADE_REASON_NO_HOSTILES
Definition CreatureAI.h:94
void DoZoneInCombat(Creature *creature=nullptr)
bool IsInBoundary(Position const *who=nullptr) const
bool UpdateVictim()
void SetBoundary(CreatureBoundary const *boundary, bool negativeBoundaries=false)
Creature *const me
Definition CreatureAI.h:82
void LoadEquipment(int8 id=1, bool force=false)
void SetReactState(ReactStates st)
Definition Creature.h:119
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void SetImmuneToNPC(bool apply) override
Definition Creature.h:132
void SetImmuneToAll(bool apply) override
Definition Creature.h:126
void SetCanDualWield(bool value) override
CreatureAI * AI() const
Definition Creature.h:154
void Update(uint32 time)
Definition EventMap.h:67
void Repeat(Milliseconds time)
Definition EventMap.cpp:63
Milliseconds GetTimeUntilEvent(EventId eventId) const
Definition EventMap.cpp:179
EventId ExecuteEvent()
Definition EventMap.cpp:73
bool IsInPhase(PhaseIndex phase) const
Definition EventMap.h:236
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 SetPhase(PhaseIndex phase)
Definition EventMap.cpp:28
void CancelEventGroup(GroupIndex group)
Definition EventMap.cpp:165
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
void Reset()
Definition EventMap.cpp:21
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)
iterator end()
iterator begin()
PlayerList const & GetPlayers() const
Definition Map.h:448
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={})
void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk)
void MoveCloserAndStop(uint32 id, Unit *target, float distance)
void Clear()
Definition ObjectGuid.h:150
static Creature * ToCreature(Object *o)
Definition Object.h:186
TypeID GetTypeId() const
Definition Object.h:93
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
Unit * GetActionTarget() const
Definition Unit.h:509
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(std::chrono::duration< _Rep, _Period > const &duration)
TaskScheduler & Schedule(std::chrono::duration< _Rep, _Period > const &time, task_handler_t const &task)
TaskScheduler & Update(success_t const &callback=EmptyCallback)
virtual void DoAction(int32)
Definition UnitAI.h:154
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:241
virtual bool CanAIAttack(Unit const *) const
Definition UnitAI.h:139
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 DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:243
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
bool IsWithinMeleeRange(Unit const *obj) const
Definition Unit.h:844
void SetControlled(bool apply, UnitState state)
Definition Unit.cpp:11256
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3093
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
void RemoveNpcFlag(NPCFlags flags)
Definition Unit.h:1098
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
UnitAI * GetAI() const
Definition Unit.h:800
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition Unit.cpp:13286
virtual void SetSheath(SheathState sheathed)
Definition Unit.h:970
void SetFacingToObject(WorldObject const *object, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13259
void SetEmoteState(Emote emote)
Definition Unit.h:967
uint32 GetDisplayId() const
Definition Unit.h:1582
uint32 GetNativeDisplayId() const
Definition Unit.h:1584
bool HealthBelowPct(int32 pct) const
Definition Unit.h:917
uint32 GetHealth() const
Definition Unit.h:913
void SendPlaySpellVisualKit(uint32 id, uint32 type) const
Definition Unit.cpp:12019
void SetNpcFlag(NPCFlags flags)
Definition Unit.h:1097
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
Unit * GetVictim() const
Definition Unit.h:859
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
void HandleEmoteCommand(Emote emoteId)
Definition Unit.cpp:1568
void SetFacingTo(float ori, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13250
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
bool AttackStop()
Definition Unit.cpp:5645
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:955
GameObject * FindNearestGameObject(uint32 entry, float range, bool spawnedOnly=true) const
Definition Object.cpp:2121
Map * GetMap() const
Definition Object.h:449
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
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:1992
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1141
EventProcessor m_Events
Definition Object.h:591
void PlayDirectSound(uint32 soundId, Player *target=nullptr)
Definition Object.cpp:3433
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=nullptr)
Definition Object.cpp:2082
virtual uint32 GetData(uint32) const
Definition ZoneScript.h:55
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:56
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
void FilterTargets(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_illidan_agonizing_flames)
void OnRemoveDummy(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_illidan_akama_door_channel)
PrepareSpellScript(spell_illidan_akama_teleport)
void SetDest(SpellDestination &dest)
void SetDest(SpellDestination &dest)
PrepareSpellScript(spell_illidan_cage_teleport)
PrepareSpellScript(spell_illidan_cage_trap)
void HandleScriptEffect(SpellEffIndex)
PrepareAuraScript(spell_illidan_caged)
void Register() override
void OnPeriodic(AuraEffect const *)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_illidan_demon_transform1)
void OnPeriodic(AuraEffect const *)
void OnPeriodic(AuraEffect const *aurEff)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_illidan_demon_transform2)
PrepareSpellScript(spell_illidan_despawn_akama)
void HandleDummy(SpellEffIndex)
PrepareSpellScript(spell_illidan_draw_soul)
void HandleScriptEffect(SpellEffIndex effIndex)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_illidan_eye_blast)
void HandleEffectRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareSpellScript(spell_illidan_find_target)
void FilterTargets(std::list< WorldObject * > &targets)
void HandleScript(SpellEffIndex)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_illidan_flame_blast)
bool Validate(SpellInfo const *) override
void HandleBlaze(SpellEffIndex)
PrepareSpellScript(spell_illidan_flame_burst)
bool Validate(SpellInfo const *) override
void HandleScriptEffect(SpellEffIndex)
PrepareAuraScript(spell_illidan_parasitic_shadowfiend_proc)
bool CheckProc(ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
void HandleEffectRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_illidan_parasitic_shadowfiend)
bool Validate(SpellInfo const *) override
void HandleApply(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_illidan_remove_parasitic_shadowfiend)
bool Validate(SpellInfo const *) override
void HandleScriptEffect(SpellEffIndex)
PrepareSpellScript(spell_illidan_return_glaives)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_illidan_tear_of_azzinoth_channel)
PrepareSpellScript(spell_illidan_throw_warglaive)
void HandleDummy(SpellEffIndex)
bool Load() override
void HandleEffectRemove(AuraEffect const *, AuraEffectHandleModes)
void HandleEffectApply(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_maiev_down)
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) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition Containers.h:108
float GetPositionZ() const
Definition Position.h:81
float GetOrientation() const
Definition Position.h:82
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:128
void SetOrientation(float orientation)
Definition Position.h:74
void Relocate(float x, float y)
Definition Position.h:66
void AttackStart(Unit *) override
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:110
void Relocate(Position const &pos)
Definition Spell.cpp:99
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