TrinityCore
Loading...
Searching...
No Matches
boss_faction_champions.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 "GridNotifiers.h"
20#include "InstanceScript.h"
21#include "MotionMaster.h"
22#include "ObjectAccessor.h"
23#include "Player.h"
24#include "ScriptedCreature.h"
25#include "SpellAuraEffects.h"
26#include "SpellScript.h"
27#include "TemporarySummon.h"
29
30enum AIs
31{
35 AI_PET = 3
36};
37
39{
40 // generic
41 SPELL_LEAP = 67382, // intro
44
45 // druid healer
52 SPELL_THORNS = 66068,
54
55 // shaman healer
58 SPELL_SPIRIT_CLEANSE = 66056, //friendly only
61 SPELL_HEX = 66054,
65 AURA_SATED = 57724,
66
67 // paladin healer
77
78 // priest healer
79 SPELL_RENEW = 66177,
80 SPELL_SHIELD = 66099,
82 SPELL_DISPEL = 65546,
86
87 // priest dps
93 SPELL_HORROR = 65545,
96
97 // warlock
102 SPELL_FEAR = 65809,
108
109 // mage
113 SPELL_BLINK = 65793,
119
120 // hunter
126 SPELL_SHOOT = 65868,
131
132 // druid dps
140 SPELL_WRATH = 65862,
141
142 // warrior
152
153 // death knight
161 SPELL_DEATH_GRIP_PULL = 64431, // used at spellscript
162
163 // rogue
165 SPELL_BLIND = 65960,
166 SPELL_CLOAK = 65961,
172
173 // shaman dps (some spells taken from shaman healer)
177
178 // paladin dps
186
187 // warlock pet
190
191 // hunter pet
192 SPELL_CLAW = 67793
194
196{
197 // generic
200
201 // druid healer
210
211 // shaman healer
219
220 // paladin healer
229
230 // priest healer
238
239 // priest dps
248
249 // warlock
257
258 // mage
267
268 // hunter
277
278 // druid dps
287
288 // warrior
298
299 // death knight
307
308 // rogue
317
318 // shaman dps
325
326 // paladin dps
335
336 // warlock pet
340
342{
343 { 514.231f, 105.569f, 418.234f, 0 }, // 0 - Horde Initial Pos 0
344 { 508.334f, 115.377f, 418.234f, 0 }, // 1 - Horde Initial Pos 1
345 { 506.454f, 126.291f, 418.234f, 0 }, // 2 - Horde Initial Pos 2
346 { 506.243f, 106.596f, 421.592f, 0 }, // 3 - Horde Initial Pos 3
347 { 499.885f, 117.717f, 421.557f, 0 }, // 4 - Horde Initial Pos 4
348
349 { 613.127f, 100.443f, 419.74f, 0 }, // 5 - Ally Initial Pos 0
350 { 621.126f, 128.042f, 418.231f, 0 }, // 6 - Ally Initial Pos 1
351 { 618.829f, 113.606f, 418.232f, 0 }, // 7 - Ally Initial Pos 2
352 { 625.845f, 112.914f, 421.575f, 0 }, // 8 - Ally Initial Pos 3
353 { 615.566f, 109.653f, 418.234f, 0 }, // 9 - Ally Initial Pos 4
354
355 { 535.469f, 113.012f, 394.66f, 0 }, // 10 - Horde Final Pos 0
356 { 526.417f, 137.465f, 394.749f, 0 }, // 11 - Horde Final Pos 1
357 { 528.108f, 111.057f, 395.289f, 0 }, // 12 - Horde Final Pos 2
358 { 519.92f, 134.285f, 395.289f, 0 }, // 13 - Horde Final Pos 3
359 { 533.648f, 119.148f, 394.646f, 0 }, // 14 - Horde Final Pos 4
360 { 531.399f, 125.63f, 394.708f, 0 }, // 15 - Horde Final Pos 5
361 { 528.958f, 131.47f, 394.73f, 0 }, // 16 - Horde Final Pos 6
362 { 526.309f, 116.667f, 394.833f, 0 }, // 17 - Horde Final Pos 7
363 { 524.238f, 122.411f, 394.819f, 0 }, // 18 - Horde Final Pos 8
364 { 521.901f, 128.488f, 394.832f, 0 } // 19 - Horde Final Pos 9
365};
366
368{
373
375 {
379 _inProgress = false;
380 }
381
382 void Reset() override
383 {
384 Initialize();
385 }
386
387 void JustSummoned(Creature* /*summon*/) override { }
388
389 std::vector<uint32> SelectChampions(Team playerTeam)
390 {
391 std::vector<uint32> vHealersEntries;
392 vHealersEntries.clear();
393 vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_DRUID_RESTORATION : NPC_ALLIANCE_DRUID_RESTORATION);
394 vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_PALADIN_HOLY : NPC_ALLIANCE_PALADIN_HOLY);
395 vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_PRIEST_DISCIPLINE : NPC_ALLIANCE_PRIEST_DISCIPLINE);
396 vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_SHAMAN_RESTORATION : NPC_ALLIANCE_SHAMAN_RESTORATION);
397
398 std::vector<uint32> vOtherEntries;
399 vOtherEntries.clear();
400 vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_DEATH_KNIGHT : NPC_ALLIANCE_DEATH_KNIGHT);
401 vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_HUNTER : NPC_ALLIANCE_HUNTER);
402 vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_MAGE : NPC_ALLIANCE_MAGE);
403 vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_ROGUE : NPC_ALLIANCE_ROGUE);
404 vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_WARLOCK : NPC_ALLIANCE_WARLOCK);
405 vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_WARRIOR : NPC_ALLIANCE_WARRIOR);
406
407 uint8 healersSubtracted = 2;
408 if (Is25ManRaid())
409 healersSubtracted = 1;
410 for (uint8 i = 0; i < healersSubtracted; ++i)
411 {
412 uint8 pos = urand(0, vHealersEntries.size() - 1);
413 switch (vHealersEntries[pos])
414 {
416 vOtherEntries.push_back(NPC_ALLIANCE_DRUID_BALANCE);
417 break;
419 vOtherEntries.push_back(NPC_HORDE_DRUID_BALANCE);
420 break;
422 vOtherEntries.push_back(NPC_ALLIANCE_PALADIN_RETRIBUTION);
423 break;
425 vOtherEntries.push_back(NPC_HORDE_PALADIN_RETRIBUTION);
426 break;
428 vOtherEntries.push_back(NPC_ALLIANCE_PRIEST_SHADOW);
429 break;
431 vOtherEntries.push_back(NPC_HORDE_PRIEST_SHADOW);
432 break;
434 vOtherEntries.push_back(NPC_ALLIANCE_SHAMAN_ENHANCEMENT);
435 break;
437 vOtherEntries.push_back(NPC_HORDE_SHAMAN_ENHANCEMENT);
438 break;
439 default:
440 break;
441 }
442 vHealersEntries.erase(vHealersEntries.begin() + pos);
443 }
444
445 if (!Is25ManRaid())
446 for (uint8 i = 0; i < 4; ++i)
447 vOtherEntries.erase(vOtherEntries.begin() + urand(0, vOtherEntries.size() - 1));
448
449 std::vector<uint32> vChampionEntries;
450 vChampionEntries.clear();
451 for (uint8 i = 0; i < vHealersEntries.size(); ++i)
452 vChampionEntries.push_back(vHealersEntries[i]);
453 for (uint8 i = 0; i < vOtherEntries.size(); ++i)
454 vChampionEntries.push_back(vOtherEntries[i]);
455
456 return vChampionEntries;
457 }
458
459 void SummonChampions(Team playerTeam)
460 {
461 std::vector<Position> vChampionJumpOrigin;
462 if (playerTeam == ALLIANCE)
463 for (uint8 i = 0; i < 5; i++)
464 vChampionJumpOrigin.push_back(FactionChampionLoc[i]);
465 else
466 for (uint8 i = 5; i < 10; i++)
467 vChampionJumpOrigin.push_back(FactionChampionLoc[i]);
468
469 std::vector<Position> vChampionJumpTarget;
470 for (uint8 i = 10; i < 20; i++)
471 vChampionJumpTarget.push_back(FactionChampionLoc[i]);
472 std::vector<uint32> vChampionEntries = SelectChampions(playerTeam);
473
474 for (uint8 i = 0; i < vChampionEntries.size(); ++i)
475 {
476 uint8 pos = urand(0, vChampionJumpTarget.size()-1);
477 if (Creature* champion = me->SummonCreature(vChampionEntries[i], vChampionJumpOrigin[urand(0, vChampionJumpOrigin.size()-1)], TEMPSUMMON_MANUAL_DESPAWN))
478 {
479 summons.Summon(champion);
480 champion->SetReactState(REACT_PASSIVE);
481 champion->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
482 champion->SetImmuneToPC(false);
483 if (playerTeam == ALLIANCE)
484 {
485 champion->SetHomePosition(vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 0);
486 champion->CastSpell(vChampionJumpTarget[pos], SPELL_LEAP);
487 }
488 else
489 {
490 Position jumpTarget = { (ToCCommonLoc[1].GetPositionX() * 2) - vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 3 };
491 champion->SetHomePosition(jumpTarget);
492 champion->CastSpell(jumpTarget, SPELL_LEAP);
493 champion->SetOrientation(3);
494 }
495 }
496 vChampionJumpTarget.erase(vChampionJumpTarget.begin()+pos);
497 }
498 }
499
500 void SetData(uint32 uiType, uint32 uiData) override
501 {
502 switch (uiType)
503 {
504 case 0:
505 SummonChampions((Team)uiData);
506 break;
507 case 1:
508 for (SummonList::iterator i = summons.begin(); i != summons.end(); ++i)
509 {
510 if (Creature* summon = ObjectAccessor::GetCreature(*me, *i))
511 {
512 summon->SetReactState(REACT_AGGRESSIVE);
513 summon->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
514 summon->SetImmuneToPC(false);
515 }
516 }
517 break;
518 case 2:
519 switch (uiData)
520 {
521 case FAIL:
524 {
528 }
529 break;
530 case IN_PROGRESS:
531 if (!_inProgress)
532 {
536 _inProgress = true;
539 }
540 break;
541 case DONE:
542 {
544 if (_championsKilled == 1)
545 instance->SetData(DATA_FACTION_CRUSADERS, 0); // Used in Resilience will Fix Achievement
546 else if (_championsKilled >= summons.size())
547 {
551 }
552 break;
553 }
554 default:
555 break;
556 }
557 break;
558 default:
559 break;
560 }
561 }
562 private:
567};
568
570{
576
577 void Reset() override
578 {
581 if (IsHeroic() && (_aiType != AI_PET))
583 }
584
585 void JustReachedHome() override
586 {
587 if (Creature* pChampionController = instance->GetCreature(DATA_FACTION_CRUSADERS))
588 pChampionController->AI()->SetData(2, FAIL);
590 }
591
592 float CalculateThreat(float distance, float armor, uint32 health)
593 {
594 float dist_mod = (_aiType == AI_MELEE || _aiType == AI_PET) ? 15.0f / (15.0f + distance) : 1.0f;
595 float armor_mod = (_aiType == AI_MELEE || _aiType == AI_PET) ? armor / 16635.0f : 0.0f;
596 float eh = (health + 1) * (1.0f + armor_mod);
597 return dist_mod * 30000.0f / eh;
598 }
599
601 {
603 if (Player* victim = ref->GetVictim()->ToPlayer())
604 {
605 ref->ScaleThreat(0.0f);
606 ref->AddThreat(1000000.0f * CalculateThreat(me->GetDistance2d(victim), victim->GetArmor(), victim->GetHealth()));
607 }
608 }
609
611 {
612 if (me->GetPowerType() == POWER_MANA)
614 }
615
625
626 void JustDied(Unit* /*killer*/) override
627 {
628 if (_aiType != AI_PET)
629 if (Creature* pChampionController = instance->GetCreature(DATA_FACTION_CRUSADERS))
630 pChampionController->AI()->SetData(2, DONE);
631 }
632
633 void JustEngagedWith(Unit* /*who*/) override
634 {
635 DoCast(me, SPELL_ANTI_AOE, true);
636 me->setActive(true);
638 if (Creature* pChampionController = instance->GetCreature(DATA_FACTION_CRUSADERS))
639 pChampionController->AI()->SetData(2, IN_PROGRESS);
640 }
641
642 void KilledUnit(Unit* who) override
643 {
644 if (who->GetTypeId() == TYPEID_PLAYER)
645 {
646 if (_teamInstance == ALLIANCE)
647 {
649 varian->AI()->DoAction(ACTION_SAY_KILLED_PLAYER);
650 }
651 else if (Creature* garrosh = instance->GetCreature(DATA_GARROSH))
652 garrosh->AI()->DoAction(ACTION_SAY_KILLED_PLAYER);
653 }
654 }
655
657 {
658 std::list<Creature*> lst = DoFindFriendlyMissingBuff(40.0f, spell);
659 std::list<Creature*>::const_iterator itr = lst.begin();
660 if (lst.empty())
661 return nullptr;
662 advance(itr, rand32() % lst.size());
663 return (*itr);
664 }
665
666 Unit* SelectEnemyCaster(bool /*casting*/)
667 {
668 for (auto const& pair : me->GetCombatManager().GetPvECombatRefs())
669 if (Player* player = pair.second->GetOther(me)->ToPlayer())
670 if (player->GetPowerType() == POWER_MANA)
671 return player;
672 return nullptr;
673 }
674
675 uint32 EnemiesInRange(float distance)
676 {
677 uint32 count = 0;
679 if (me->GetDistance2d(ref->GetVictim()) < distance)
680 ++count;
681 return count;
682 }
683
684 void AttackStart(Unit* who) override
685 {
686 if (!who)
687 return;
688
689 if (me->Attack(who, true))
690 {
691 AddThreat(who, 10.0f);
692
693 if (_aiType == AI_MELEE || _aiType == AI_PET)
694 DoStartMovement(who);
695 else
696 DoStartMovement(who, 20.0f);
697 SetCombatMovement(true);
698 }
699 }
700
701 void UpdateAI(uint32 diff) override
702 {
703 _events.Update(diff);
704
705 while (uint32 eventId = _events.ExecuteEvent())
706 {
707 switch (eventId)
708 {
709 case EVENT_THREAT:
710 UpdatePower();
711 UpdateThreat();
713 return;
714 case EVENT_REMOVE_CC:
716 {
717 RemoveCC();
719 }
720 else
722 return;
723 default:
724 return;
725 }
726 }
727 }
728
729 private:
732 // make sure that every bosses separate events dont mix with these _events
734};
735
736/********************************************************************
737 HEALERS
738********************************************************************/
740{
742
756
757 void UpdateAI(uint32 diff) override
758 {
759 if (!UpdateVictim())
760 return;
761
762 events.Update(diff);
764
766 return;
767
768 while (uint32 eventId = events.ExecuteEvent())
769 {
770 switch (eventId)
771 {
772 case EVENT_LIFEBLOOM:
773 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
774 DoCast(target, SPELL_LIFEBLOOM);
776 return;
777 case EVENT_NOURISH:
778 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
779 DoCast(target, SPELL_NOURISH);
781 return;
782 case EVENT_REGROWTH:
783 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
784 DoCast(target, SPELL_REGROWTH);
786 return;
788 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
789 DoCast(target, SPELL_REJUVENATION);
791 return;
795 return;
797 if (HealthBelowPct(30))
798 {
801 }
802 else
804 return;
805 case EVENT_THORNS:
807 DoCast(target, SPELL_THORNS);
809 return;
813 return;
814 default:
815 return;
816 }
817 }
818 }
819};
820
822{
824
837
838 void UpdateAI(uint32 diff) override
839 {
840 if (!UpdateVictim())
841 return;
842
843 events.Update(diff);
845
847 return;
848
849 while (uint32 eventId = events.ExecuteEvent())
850 {
851 switch (eventId)
852 {
854 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
855 DoCast(target, SPELL_HEALING_WAVE);
857 return;
858 case EVENT_RIPTIDE:
859 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
860 DoCast(target, SPELL_RIPTIDE);
862 return;
864 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
867 return;
869 if (me->GetFaction()) // alliance = 1
870 {
873 }
874 else
875 {
876 if (!me->HasAura(AURA_SATED))
878 }
880 return;
881 case EVENT_HEX:
883 DoCast(target, SPELL_HEX);
884 events.ScheduleEvent(EVENT_HEX, 15s, 30s);
885 return;
888 DoCast(target, SPELL_EARTH_SHIELD);
890 return;
892 if (Unit* target = SelectEnemyCaster(true))
893 DoCast(target, SPELL_EARTH_SHOCK);
895 return;
896 default:
897 return;
898 }
899 }
900 }
901};
902
904{
906
920
921 void UpdateAI(uint32 diff) override
922 {
923 if (!UpdateVictim())
924 return;
925
926 events.Update(diff);
928
930 return;
931
932 while (uint32 eventId = events.ExecuteEvent())
933 {
934 switch (eventId)
935 {
940 return;
943 {
946 }
947 else
949 return;
950 case EVENT_CLEANSE:
951 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
952 DoCast(target, SPELL_CLEANSE);
954 return;
956 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
959 return;
960 case EVENT_HOLY_LIGHT:
961 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
962 DoCast(target, SPELL_HOLY_LIGHT);
964 return;
965 case EVENT_HOLY_SHOCK:
966 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
967 DoCast(target, SPELL_HOLY_SHOCK);
969 return;
971 if (Unit* target = DoSelectLowestHpFriendly(30.0f))
972 {
973 if (!target->HasAura(SPELL_FORBEARANCE))
974 {
977 }
978 else
980 }
981 else
983 return;
985 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 15.0f, true))
988 return;
989 default:
990 return;
991 }
992 }
993 }
994};
995
997{
999
1012
1013 void UpdateAI(uint32 diff) override
1014 {
1015 if (!UpdateVictim())
1016 return;
1017
1018 events.Update(diff);
1020
1022 return;
1023
1024 while (uint32 eventId = events.ExecuteEvent())
1025 {
1026 switch (eventId)
1027 {
1028 case EVENT_RENEW:
1029 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
1030 DoCast(target, SPELL_RENEW);
1032 return;
1033 case EVENT_SHIELD:
1034 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
1035 DoCast(target, SPELL_SHIELD);
1037 return;
1038 case EVENT_FLASH_HEAL:
1039 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
1040 DoCast(target, SPELL_FLASH_HEAL);
1042 return;
1043 case EVENT_HEAL_DISPEL:
1044 if (Unit* target = urand(0, 1) ? SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true) : DoSelectLowestHpFriendly(40.0f))
1045 DoCast(target, SPELL_DISPEL);
1047 return;
1049 if (EnemiesInRange(10.0f) >= 2)
1052 return;
1053 case EVENT_MANA_BURN:
1054 if (Unit* target = SelectEnemyCaster(false))
1055 DoCast(target, SPELL_MANA_BURN);
1057 return;
1058 case EVENT_PENANCE:
1059 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
1060 DoCast(target, SPELL_PENANCE);
1062 return;
1063 default:
1064 return;
1065 }
1066 }
1067 }
1068};
1069
1070/********************************************************************
1071 RANGED
1072********************************************************************/
1074{
1076
1091
1092 void UpdateAI(uint32 diff) override
1093 {
1094 if (!UpdateVictim())
1095 return;
1096
1097 events.Update(diff);
1099
1101 return;
1102
1103 while (uint32 eventId = events.ExecuteEvent())
1104 {
1105 switch (eventId)
1106 {
1107 case EVENT_SILENCE:
1108 if (Unit* target = SelectEnemyCaster(true))
1109 DoCast(target, SPELL_SILENCE);
1111 return;
1113 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true))
1116 return;
1117 case EVENT_SW_PAIN:
1118 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true))
1119 DoCast(target, SPELL_SW_PAIN);
1121 return;
1122 case EVENT_MIND_BLAST:
1125 return;
1126 case EVENT_HORROR:
1129 return;
1130 case EVENT_DISPERSION:
1131 if (HealthBelowPct(40))
1132 {
1135 }
1136 else
1138 return;
1139 case EVENT_DPS_DISPEL:
1140 if (Unit* target = urand(0, 1) ? SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true) : DoSelectLowestHpFriendly(40.0f))
1141 DoCast(target, SPELL_DISPEL);
1143 return;
1145 if (EnemiesInRange(10.0f) >= 2)
1148 return;
1149 default:
1150 return;
1151 }
1152 }
1154 }
1155};
1156
1158{
1160
1173
1179
1180 void UpdateAI(uint32 diff) override
1181 {
1182 if (!UpdateVictim())
1183 return;
1184
1185 events.Update(diff);
1187
1189 return;
1190
1191 while (uint32 eventId = events.ExecuteEvent())
1192 {
1193 switch (eventId)
1194 {
1195 case EVENT_HELLFIRE:
1196 if (EnemiesInRange(10.0f) >= 2)
1199 return;
1200 case EVENT_CORRUPTION:
1201 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f))
1202 DoCast(target, SPELL_CORRUPTION);
1204 return;
1206 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f))
1209 return;
1211 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f))
1214 return;
1215 case EVENT_FEAR:
1216 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 20.0f, true))
1217 DoCast(target, SPELL_FEAR);
1219 return;
1220 case EVENT_SEARING_PAIN:
1223 return;
1225 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true))
1228 return;
1229 default:
1230 return;
1231 }
1232 }
1234 }
1235};
1236
1238{
1240
1254
1255 void UpdateAI(uint32 diff) override
1256 {
1257 if (!UpdateVictim())
1258 return;
1259
1260 events.Update(diff);
1262
1264 return;
1265
1266 while (uint32 eventId = events.ExecuteEvent())
1267 {
1268 switch (eventId)
1269 {
1273 return;
1274 case EVENT_ARCANE_BLAST:
1277 return;
1279 if (EnemiesInRange(10.0f) >= 2)
1282 return;
1283 case EVENT_BLINK:
1284 if (EnemiesInRange(10.0f) >= 2)
1286 events.ScheduleEvent(EVENT_BLINK, 10s, 30s);
1287 return;
1288 case EVENT_COUNTERSPELL:
1289 if (Unit* target = SelectEnemyCaster(true))
1290 DoCast(target, SPELL_COUNTERSPELL);
1292 return;
1293 case EVENT_FROST_NOVA:
1294 if (EnemiesInRange(10.0f) >= 2)
1297 return;
1298 case EVENT_ICE_BLOCK:
1299 if (HealthBelowPct(30))
1300 {
1303 }
1304 else
1306 return;
1307 case EVENT_POLYMORPH:
1309 DoCast(target, SPELL_POLYMORPH);
1311 return;
1312 default:
1313 return;
1314 }
1315 }
1317 }
1318};
1319
1321{
1323 {
1324 me->SetCanMelee(false); // DoSpellAttackIfReady
1325 }
1326
1340
1341 void JustEngagedWith(Unit* who) override
1342 {
1345 }
1346
1347 void UpdateAI(uint32 diff) override
1348 {
1349 if (!UpdateVictim())
1350 return;
1351
1352 events.Update(diff);
1354
1356 return;
1357
1358 while (uint32 eventId = events.ExecuteEvent())
1359 {
1360 switch (eventId)
1361 {
1362 case EVENT_AIMED_SHOT:
1365 return;
1366 case EVENT_DETERRENCE:
1367 if (HealthBelowPct(30))
1368 {
1371 }
1372 else
1374 return;
1375 case EVENT_DISENGAGE:
1376 if (EnemiesInRange(10.0f) >= 2)
1379 return;
1383 return;
1384 case EVENT_FROST_TRAP:
1385 if (EnemiesInRange(10.0f) >= 2)
1388 return;
1389 case EVENT_STEADY_SHOT:
1392 return;
1393 case EVENT_WING_CLIP:
1394 if (Unit* target = me->GetVictim())
1395 {
1396 if (me->GetDistance2d(target) < 6.0f)
1397 DoCast(target, SPELL_WING_CLIP);
1398 }
1400 return;
1401 case EVENT_WYVERN_STING:
1403 DoCast(target, SPELL_WYVERN_STING);
1405 return;
1406 default:
1407 return;
1408 }
1409 }
1411 }
1412};
1413
1415{
1417
1432
1433 void UpdateAI(uint32 diff) override
1434 {
1435 if (!UpdateVictim())
1436 return;
1437
1438 events.Update(diff);
1440
1442 return;
1443
1444 while (uint32 eventId = events.ExecuteEvent())
1445 {
1446 switch (eventId)
1447 {
1448 case EVENT_CYCLONE:
1450 DoCast(target, SPELL_CYCLONE);
1452 return;
1454 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true))
1457 return;
1458 case EVENT_FAERIE_FIRE:
1461 return;
1465 return;
1466 case EVENT_INSECT_SWARM:
1469 return;
1470 case EVENT_MOONFIRE:
1473 return;
1474 case EVENT_STARFIRE:
1477 return;
1478 case EVENT_DPS_BARKSKIN:
1479 if (HealthBelowPct(30))
1480 {
1483 }
1484 else
1486 return;
1487 default:
1488 return;
1489 }
1490 }
1492 }
1493};
1494
1495/********************************************************************
1496 MELEE
1497********************************************************************/
1499{
1501
1516
1517 void UpdateAI(uint32 diff) override
1518 {
1519 if (!UpdateVictim())
1520 return;
1521
1522 events.Update(diff);
1524
1526 return;
1527
1528 while (uint32 eventId = events.ExecuteEvent())
1529 {
1530 switch (eventId)
1531 {
1532 case EVENT_BLADESTORM:
1535 return;
1539 return;
1543 return;
1544 case EVENT_WARR_CHARGE:
1547 return;
1548 case EVENT_DISARM:
1551 return;
1552 case EVENT_OVERPOWER:
1555 return;
1556 case EVENT_SUNDER_ARMOR:
1559 return;
1561 if (Unit* target = me->GetVictim())
1562 {
1563 if (target->HasAuraWithMechanic(1 << MECHANIC_IMMUNE_SHIELD))
1564 {
1567 return;
1568 }
1569 }
1571 return;
1572 case EVENT_RETALIATION:
1573 if (HealthBelowPct(50))
1574 {
1577 }
1578 else
1580 return;
1581 default:
1582 return;
1583 }
1584 }
1585 }
1586};
1587
1589{
1591
1604
1605 void UpdateAI(uint32 diff) override
1606 {
1607 if (!UpdateVictim())
1608 return;
1609
1610 events.Update(diff);
1612
1614 return;
1615
1616 while (uint32 eventId = events.ExecuteEvent())
1617 {
1618 switch (eventId)
1619 {
1623 return;
1624 case EVENT_DEATH_COIL:
1627 return;
1628 case EVENT_DEATH_GRIP:
1629 if (Unit* target = me->GetVictim())
1630 {
1631 if (me->IsInRange(target, 5.0f, 30.0f, false))
1632 {
1633 DoCast(target, SPELL_DEATH_GRIP);
1635 return;
1636 }
1637 }
1639 return;
1640 case EVENT_FROST_STRIKE:
1643 return;
1645 if (HealthBelowPct(50))
1646 {
1649 }
1650 else
1652 return;
1653 case EVENT_ICY_TOUCH:
1656 return;
1657 case EVENT_STRANGULATE:
1658 if (Unit* target = SelectEnemyCaster(false))
1659 {
1660 DoCast(target, SPELL_STRANGULATE);
1662 }
1663 else
1665 return;
1666 default:
1667 return;
1668 }
1669 }
1670 }
1671};
1672
1674{
1676
1692
1693 void UpdateAI(uint32 diff) override
1694 {
1695 if (!UpdateVictim())
1696 return;
1697
1698 events.Update(diff);
1700
1702 return;
1703
1704 while (uint32 eventId = events.ExecuteEvent())
1705 {
1706 switch (eventId)
1707 {
1709 if (EnemiesInRange(10.0f) >= 2)
1712 return;
1713 case EVENT_BLIND:
1715 DoCast(target, SPELL_BLIND);
1716 events.ScheduleEvent(EVENT_BLIND, 10s, 30s);
1717 return;
1718 case EVENT_CLOAK:
1719 if (HealthBelowPct(50))
1720 {
1723 }
1724 else
1726 return;
1727 case EVENT_BLADE_FLURRY:
1728 if (EnemiesInRange(10.0f) >= 2)
1729 {
1732 }
1733 else
1735 return;
1736 case EVENT_SHADOWSTEP:
1737 if (Unit* target = me->GetVictim())
1738 {
1739 if (me->IsInRange(target, 10.0f, 40.0f, false))
1740 {
1741 DoCast(target, SPELL_SHADOWSTEP);
1743 return;
1744 }
1745 }
1747 return;
1748 case EVENT_HEMORRHAGE:
1751 return;
1752 case EVENT_EVISCERATE:
1755 return;
1756 case EVENT_WOUND_POISON:
1759 return;
1760 default:
1761 return;
1762 }
1763 }
1764 }
1765};
1766
1768{
1770 {
1771 Initialize();
1772 }
1773
1775 {
1776 _totemCount = 0;
1779 }
1780
1795
1796 void JustSummoned(Creature* summoned) override
1797 {
1798 summons.Summon(summoned);
1799 }
1800
1801 void SummonedCreatureDespawn(Creature* /*pSummoned*/) override
1802 {
1803 --_totemCount;
1804 }
1805
1807 {
1808 _totemCount = 4;
1811 /*
1812 -Windfury (16% melee haste)
1813 -Grounding (redirects one harmful magic spell to the totem)
1814
1815 -Healing Stream (unable to find amount of healing in our logs)
1816
1817 -Tremor (prevents fear effects)
1818 -Strength of Earth (155 strength and agil for the opposing team)
1819
1820 -Searing (average ~3500 damage on a random target every ~3.5 seconds)
1821 */
1822 }
1823
1824 void JustDied(Unit* killer) override
1825 {
1828 }
1829
1830 void UpdateAI(uint32 diff) override
1831 {
1832 if (!UpdateVictim())
1833 return;
1834
1835 events.Update(diff);
1837
1839 return;
1840
1841 while (uint32 eventId = events.ExecuteEvent())
1842 {
1843 switch (eventId)
1844 {
1846 if (Unit* target = SelectEnemyCaster(true))
1847 DoCast(target, SPELL_EARTH_SHOCK);
1849 return;
1850 case EVENT_LAVA_LASH:
1853 return;
1854 case EVENT_STORMSTRIKE:
1857 return;
1859 if (me->GetFaction()) //Am i alliance?
1860 {
1861 if (!me->HasAura(AURA_EXHAUSTION))
1863 }
1864 else
1865 {
1866 if (!me->HasAura(AURA_SATED))
1868 }
1870 return;
1871 case EVENT_DEPLOY_TOTEM:
1872 if (_totemCount < 4 || me->GetDistance2d(_totemOldCenterX, _totemOldCenterY) > 20.0f)
1873 DeployTotem();
1875 return;
1876 case EVENT_WINDFURY:
1879 return;
1880 default:
1881 return;
1882 }
1883 }
1884 }
1885 private:
1888};
1889
1891{
1893
1907
1913
1914 void UpdateAI(uint32 diff) override
1915 {
1916 if (!UpdateVictim())
1917 return;
1918
1919 events.Update(diff);
1921
1923 return;
1924
1925 while (uint32 eventId = events.ExecuteEvent())
1926 {
1927 switch (eventId)
1928 {
1932 return;
1936 return;
1937 case EVENT_DIVINE_STORM:
1938 if (EnemiesInRange(10.0f) >= 2)
1941 return;
1945 return;
1949 return;
1950 case EVENT_REPENTANCE:
1952 DoCast(target, SPELL_REPENTANCE);
1954 return;
1956 if (Unit* target = DoSelectLowestHpFriendly(30.0f))
1957 {
1958 if (!target->HasAura(SPELL_FORBEARANCE))
1959 {
1962 }
1963 else
1965 }
1966 else
1968 return;
1971 {
1974 }
1975 else
1977 return;
1978 default:
1979 return;
1980 }
1981 }
1982 }
1983};
1984
1986{
1988
1989 void Reset() override
1990 {
1994 }
1995
1996 void UpdateAI(uint32 diff) override
1997 {
1998 if (!UpdateVictim())
1999 return;
2000
2001 events.Update(diff);
2003
2005 return;
2006
2007 while (uint32 eventId = events.ExecuteEvent())
2008 {
2009 switch (eventId)
2010 {
2011 case EVENT_DEVOUR_MAGIC:
2014 return;
2015 case EVENT_SPELL_LOCK:
2018 return;
2019 default:
2020 return;
2021 }
2022 }
2023 }
2024};
2025
2027{
2029 {
2030 Initialize();
2031 }
2032
2034 {
2036 }
2037
2038 void Reset() override
2039 {
2041 Initialize();
2042 }
2043
2044 void UpdateAI(uint32 diff) override
2045 {
2046 if (!UpdateVictim())
2047 return;
2048
2050
2051 if (_clawTimer <= diff)
2052 {
2055 }
2056 else
2057 _clawTimer -= diff;
2058 }
2059 private:
2061};
2062
2063// 65812, 68154, 68155, 68156 - Unstable Affliction
2065{
2066 bool Validate(SpellInfo const* /*spell*/) override
2067 {
2069 }
2070
2071 void HandleDispel(DispelInfo* dispelInfo)
2072 {
2073 if (Unit* caster = GetCaster())
2074 caster->CastSpell(dispelInfo->GetDispeller(), SPELL_UNSTABLE_AFFLICTION_DISPEL, GetEffect(EFFECT_0));
2075 }
2076
2081};
2082
2083// 66017, 68753, 68754, 68755 - Death Grip
2085{
2086 bool Validate(SpellInfo const* /*spell*/) override
2087 {
2089 }
2090
2091 void HandleDummy(SpellEffIndex /*effIndex*/)
2092 {
2093 if (Unit* target = GetHitUnit())
2094 {
2095 if (Unit* caster = GetCaster())
2096 target->CastSpell(caster, SPELL_DEATH_GRIP_PULL);
2097 }
2098 }
2099
2104};
2105
2106// 65980 - Bloodlust
2108{
2109 bool Validate(SpellInfo const* /*spellInfo*/) override
2110 {
2111 return ValidateSpellInfo({ AURA_SATED });
2112 }
2113
2114 void RemoveInvalidTargets(std::list<WorldObject*>& targets)
2115 {
2116 targets.remove_if(Trinity::UnitAuraCheck(true, AURA_SATED));
2117 }
2118
2120 {
2121 if (Unit* target = GetHitUnit())
2122 target->CastSpell(target, AURA_SATED, true);
2123 }
2124
2131};
2132
2133// 65983 - Heroism
2135{
2136 bool Validate(SpellInfo const* /*spellInfo*/) override
2137 {
2139 }
2140
2141 void RemoveInvalidTargets(std::list<WorldObject*>& targets)
2142 {
2143 targets.remove_if(Trinity::UnitAuraCheck(true, AURA_EXHAUSTION));
2144 }
2145
2147 {
2148 if (Unit* target = GetHitUnit())
2149 target->CastSpell(target, AURA_EXHAUSTION, true);
2150 }
2151
2158};
2159
@ IN_MILLISECONDS
Definition Common.h:38
@ EQUIP_NO_CHANGE
Definition CreatureAI.h:56
uint8_t uint8
Definition Define.h:156
uint32_t uint32
Definition Define.h:154
@ IN_PROGRESS
@ FAIL
@ DONE
@ TEMPSUMMON_MANUAL_DESPAWN
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
Spells
Definition PlayerAI.cpp:32
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
uint32 rand32()
Definition Random.cpp:70
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ TARGET_UNIT_SRC_AREA_ALLY
@ SPELL_EFFECT_DUMMY
@ MECHANIC_IMMUNE_SHIELD
@ ALLIANCE
@ POWER_ENERGY
@ POWER_MANA
@ SPELL_AURA_MOD_FEAR
@ SPELL_AURA_MOD_PACIFY
@ SPELL_AURA_MOD_ROOT
@ SPELL_AURA_MOD_CONFUSE
@ SPELL_AURA_MOD_STUN
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define SpellHitFn(F)
#define AuraDispelFn(F)
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_FLAG_NON_ATTACKABLE
@ UNIT_STATE_CASTING
Definition Unit.h:276
void AddSC_boss_faction_champions()
Position const FactionChampionLoc[]
@ SPELL_HAMMER_OF_JUSTICE
@ SPELL_ICEBOUND_FORTITUDE
@ SPELL_JUDGEMENT_OF_COMMAND
@ SPELL_VAMPIRIC_TOUCH
@ SPELL_ENTANGLING_ROOTS
@ SPELL_SHATTERING_THROW
@ SPELL_UNSTABLE_AFFLICTION
@ SPELL_SUMMON_FELHUNTER
@ SPELL_FLASH_OF_LIGHT
@ SPELL_ARCANE_EXPLOSION
@ SPELL_CRUSADER_STRIKE
@ SPELL_SPIRIT_CLEANSE
@ SPELL_HAMMER_OF_JUSTICE_RET
@ SPELL_DIVINE_SHIELD
@ SPELL_FORCE_OF_NATURE
@ SPELL_DEATH_GRIP_PULL
@ SPELL_CURSE_OF_EXHAUSTION
@ SPELL_HAND_OF_FREEDOM
@ SPELL_UNSTABLE_AFFLICTION_DISPEL
@ SPELL_INTIMIDATING_SHOUT
@ SPELL_HAND_OF_PROTECTION
@ SPELL_SEAL_OF_COMMAND
@ SPELL_PSYCHIC_SCREAM
@ EVENT_DPS_DIVINE_SHIELD
@ EVENT_CURSE_OF_EXHAUSTION
@ EVENT_HEAL_HAND_OF_PROTECTION
@ EVENT_HEAL_EARTH_SHOCK
@ EVENT_DPS_PSYCHIC_SCREAM
@ EVENT_HAMMER_OF_JUSTICE
@ EVENT_DPS_HAND_OF_PROTECTION
@ EVENT_HAND_OF_FREEDOM
@ EVENT_FORCE_OF_NATURE
@ EVENT_HAMMER_OF_JUSTICE_RET
@ EVENT_ARCANE_EXPLOSION
@ EVENT_INTIMIDATING_SHOUT
@ EVENT_HEAL_BLOODLUST_HEROISM
@ EVENT_CRUSADER_STRIKE
@ EVENT_HEAL_PSYCHIC_SCREAM
@ EVENT_ICEBOUND_FORTITUDE
@ EVENT_SHATTERING_THROW
@ EVENT_JUDGEMENT_OF_COMMAND
@ EVENT_HEAL_DIVINE_SHIELD
@ EVENT_DPS_EARTH_SHOCK
@ EVENT_UNSTABLE_AFFLICTION
@ EVENT_ENTANGLING_ROOTS
@ EVENT_DPS_BLOODLUST_HEROISM
Unit * GetCaster() const
AuraEffect * GetEffect(uint8 effIndex) const
HookList< AuraDispelHandler > AfterDispel
TypeID GetTypeId() const
Definition BaseEntity.h:166
InstanceScript *const instance
SummonList summons
EventMap events
std::unordered_map< ObjectGuid, CombatReference * > const & GetPvECombatRefs() const
void DoZoneInCombat()
Definition CreatureAI.h:169
bool UpdateVictim()
void SetBoundary(CreatureBoundary const *boundary, bool negativeBoundaries=false)
Creature *const me
Definition CreatureAI.h:63
void SetCanMelee(bool canMelee, bool fleeFromMelee=false)
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
WorldObject * GetDispeller() const
Definition Unit.h:396
uint32 ExecuteEvent()
Definition EventMap.cpp:77
void Update(uint32 time)
Definition EventMap.h:61
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:40
void RescheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:56
virtual bool SetBossState(uint32 id, EncounterState state)
Creature * GetCreature(uint32 type)
CreatureBoundary const * GetBossBoundary(uint32 id) const
Player * ToPlayer()
Definition Object.h:126
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Unit * GetCaster() const
HookList< HitHandler > AfterHit
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
iterator begin()
void Summon(Creature const *summon)
iterator end()
size_type size() const
void DoZoneInCombat(uint32 entry=0)
StorageType::iterator iterator
Trinity::IteratorPair< ThreatListIterator, std::nullptr_t > GetUnsortedThreatList() const
std::vector< ThreatReference * > GetModifiableThreatList()
bool DoSpellAttackIfReady(uint32 spellId)
Definition UnitAI.cpp:61
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:180
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:79
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:162
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:89
Definition Unit.h:635
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:8697
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3955
ThreatManager & GetThreatManager()
Definition Unit.h:1078
Powers GetPowerType() const
Definition Unit.h:811
int32 GetMaxPower(Powers power) const
Definition Unit.cpp:10037
bool Attack(Unit *victim, bool meleeAttack)
Definition Unit.cpp:5853
uint32 GetFaction() const override
Definition Unit.h:871
void SetFullPower(Powers power)
Definition Unit.h:825
Unit * GetVictim() const
Definition Unit.h:726
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4804
bool HasBreakableByDamageCrowdControlAura(Unit const *excludeCasterChannel=nullptr) const
Definition Unit.cpp:778
CombatManager & GetCombatManager()
Definition Unit.h:1038
void SetPowerType(Powers power, bool sendUpdate=true, bool onInit=false)
Definition Unit.cpp:5697
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition Object.cpp:1398
void setActive(bool isActiveObject)
Definition Object.cpp:276
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:450
bool IsInRange(WorldObject const *obj, float minRange, float maxRange, bool is3D=true) const
Definition Object.cpp:592
virtual uint32 GetData(uint32) const
Definition ZoneScript.h:99
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:100
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void RemoveInvalidTargets(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *) override
void RemoveInvalidTargets(std::list< WorldObject * > &targets)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
bool IsHeroic() const
void SetEquipmentSlots(bool loadDefault, int32 mainHand=EQUIP_NO_CHANGE, int32 offHand=EQUIP_NO_CHANGE, int32 ranged=EQUIP_NO_CHANGE)
void SetCombatMovement(bool allowMovement)
Unit * DoSelectLowestHpFriendly(float range, uint32 minHPDiff=1)
bool HealthBelowPct(uint32 pct) const
std::list< Creature * > DoFindFriendlyMissingBuff(float range, uint32 spellId)
bool Is25ManRaid() const
void AddThreat(Unit *victim, float amount, Unit *who=nullptr)
void DoStartMovement(Unit *target, float distance=0.0f, float angle=0.0f)
Creature * SelectRandomFriendlyMissingBuff(uint32 spell)
void JustEngagedWith(Unit *) override
void AttackStart(Unit *who) override
void UpdateAI(uint32 diff) override
void KilledUnit(Unit *who) override
float CalculateThreat(float distance, float armor, uint32 health)
uint32 EnemiesInRange(float distance)
boss_faction_championsAI(Creature *creature, uint32 aitype)
std::vector< uint32 > SelectChampions(Team playerTeam)
void JustSummoned(Creature *) override
boss_toc_champion_controller(Creature *creature)
void SetData(uint32 uiType, uint32 uiData) override
npc_toc_boomkin(Creature *creature)
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
void Reset() override
npc_toc_dk(Creature *creature)
void UpdateAI(uint32 diff) override
npc_toc_druid(Creature *creature)
void JustSummoned(Creature *summoned) override
void SummonedCreatureDespawn(Creature *) override
npc_toc_enh_shaman(Creature *creature)
void JustDied(Unit *killer) override
void UpdateAI(uint32 diff) override
npc_toc_hunter(Creature *creature)
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *who) override
npc_toc_mage(Creature *creature)
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
npc_toc_paladin(Creature *creature)
void UpdateAI(uint32 diff) override
npc_toc_pet_hunter(Creature *creature)
npc_toc_pet_warlock(Creature *creature)
void UpdateAI(uint32 diff) override
npc_toc_priest(Creature *creature)
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
npc_toc_retro_paladin(Creature *creature)
void JustEngagedWith(Unit *who) override
npc_toc_rogue(Creature *creature)
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
npc_toc_shadow_priest(Creature *creature)
npc_toc_shaman(Creature *creature)
void UpdateAI(uint32 diff) override
npc_toc_warlock(Creature *creature)
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
npc_toc_warrior(Creature *creature)
void UpdateAI(uint32 diff) override
constexpr Position ToCCommonLoc[]
@ NPC_ALLIANCE_SHAMAN_RESTORATION
@ NPC_ALLIANCE_MAGE
@ NPC_ALLIANCE_PALADIN_HOLY
@ NPC_HORDE_SHAMAN_RESTORATION
@ NPC_ALLIANCE_DRUID_RESTORATION
@ NPC_ALLIANCE_DRUID_BALANCE
@ NPC_ALLIANCE_HUNTER
@ NPC_HORDE_ROGUE
@ NPC_HORDE_HUNTER
@ NPC_HORDE_PRIEST_SHADOW
@ NPC_HORDE_WARLOCK
@ NPC_ALLIANCE_ROGUE
@ NPC_HORDE_PALADIN_RETRIBUTION
@ NPC_ALLIANCE_WARRIOR
@ NPC_HORDE_DRUID_RESTORATION
@ NPC_HORDE_DEATH_KNIGHT
@ NPC_ALLIANCE_PALADIN_RETRIBUTION
@ NPC_HORDE_DRUID_BALANCE
@ NPC_HORDE_SHAMAN_ENHANCEMENT
@ NPC_ALLIANCE_PRIEST_DISCIPLINE
@ NPC_HORDE_PRIEST_DISCIPLINE
@ NPC_ALLIANCE_DEATH_KNIGHT
@ NPC_ALLIANCE_SHAMAN_ENHANCEMENT
@ NPC_ALLIANCE_WARLOCK
@ NPC_HORDE_PALADIN_HOLY
@ NPC_ALLIANCE_PRIEST_SHADOW
@ ACTION_SAY_KILLED_PLAYER
@ DATA_FACTION_CHAMPIONS
@ DATA_FACTION_CRUSADERS
#define RegisterTrialOfTheCrusaderCreatureAI(ai_name)
@ NPC_HORDE_WARRIOR