TrinityCore
boss_yogg_saron.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 "CreatureTextMgr.h"
20#include "GridNotifiers.h"
21#include "InstanceScript.h"
22#include "Map.h"
23#include "MotionMaster.h"
24#include "ObjectAccessor.h"
25#include "PassiveAI.h"
26#include "Player.h"
27#include "ScriptedCreature.h"
28#include "Spell.h"
29#include "SpellAuraEffects.h"
30#include "SpellScript.h"
31#include "TemporarySummon.h"
32#include "ulduar.h"
33
35{
36 // Sara
37 SAY_SARA_ULDUAR_SCREAM_1 = 0, // screams randomly in a whole instance, unused on retail
38 SAY_SARA_ULDUAR_SCREAM_2 = 1, // screams randomly in a whole instance, unused on retail
49
50 // Yogg-Saron
60
61 // Voice of Yogg-Saron
64
65 // Brain of Yogg-Saron
67
68 // Ominous Cloud
70
71 // Keepers
74
75 // Yogg-Saron illusions
81
82 // Neltharion
85
86 // Ysera
88
89 // Malygos
91
92 // Immolated Champion
95
96 // The Lich King
99
100 // Garona
105
106 // King Llane
108};
109
111{
112 // Voice of Yogg-Saron
118 //SPELL_CLEAR_INSANE = 63122, // when should it be cast?
123
124 // Sara
138 SPELL_BRAIN_LINK_DAMAGE = 63803, // red beam
139 SPELL_BRAIN_LINK_NO_DAMAGE = 63804, // yellow beam
141
142 // Ominous Cloud
145
146 // Guardian of Yogg-Saron
150
151 // Yogg-Saron
160
161 // Brain of Yogg-Saron
168
169 // Tentacles
170 SPELL_ERUPT = 64144,
171 SPELL_TENTACLE_VOID_ZONE = 64017, // used by Corruptor Tentacle and Crusher Tentacle only
172
173 // Crusher Tentacle
177 SPELL_CRUSH = 64146,
178 //SPELL_CRUSH_2 = 65201, // triggered by SPELL_CRUSH, basepoints of SPELL_MALADY_OF_THE_MIND
179
180 // Constrictor Tentacle
182 SPELL_LUNGE = 64131,
183
184 // Corruptor Tentacle
189
190 // Immortal Guardian
198
199 // Keepers at Observation Ring
201
202 // Keepers
205
206 // Mimiron
209
210 // Freya
213
214 // Sanity Well
217
218 // Thorim
221
222 // Hodir
226
227 // Death Orb
229
230 // Death Ray
234
235 // Laughing Skull
237
238 // Descend Into Madness
243
244 // Illusions
247
248 // Suit of Armor
250
251 // Dragon Consorts & Deathsworn Zealot
253
254 // Garona
256
257 // King Llane
259
260 // The Lich King
262
263 // Turned Champion
265
266 // Player self cast spells
277
279};
280
282{
287};
288
290{
291 // Voice of Yogg-Saron
299 EVENT_EXTINGUISH_ALL_LIFE = 8, // handled by Voice, timer starts at the beginning of the fight (Yogg-Saron is not spawned at this moment)
300
301 // Sara
313
314 // Tentacles
317
318 // Yogg-Saron
322 EVENT_DEAFENING_ROAR = 25, // only on 25-man with 0-3 keepers active (Hard Mode)
323
324 // Guardian of Yogg-Saron
326
327 // Immortal Guardian
329
330 // Keepers
333
334 // Chamber Illusion
340
341 // Icecrown Illusion
348
349 // Stormwind Illusion
357};
358
360{
362};
363
365{
375};
376
378{
382};
383
384Position const YoggSaronSpawnPos = {1980.43f, -25.7708f, 324.9724f, 3.141593f};
386{
387 {1945.682f, 33.34201f, 411.4408f, 5.270895f}, // Freya
388 {1945.761f, -81.52171f, 411.4407f, 1.029744f}, // Hodir
389 {2028.822f, -65.73573f, 411.4426f, 2.460914f}, // Thorim
390 {2028.766f, 17.42014f, 411.4446f, 3.857178f}, // Mimiron
391};
393{
394 {2036.873f, 25.42513f, 338.4984f, 3.909538f}, // Freya
395 {1939.045f, -90.87457f, 338.5426f, 0.994837f}, // Hodir
396 {1939.148f, 42.49035f, 338.5427f, 5.235988f}, // Thorim
397 {2036.658f, -73.58822f, 338.4985f, 2.460914f}, // Mimiron
398};
400{
401 {1928.793f, 65.03109f, 242.3763f, 0.0f}, // Garona end position
402 {1912.324f, -155.7967f, 239.9896f, 0.0f}, // Saurfang end position
403};
404
406{
411
413{
417};
418
420{
421 public:
423 : _summonerGuid(summoner->GetGUID()), _owner(owner)
424 {
425 }
426
427 bool Execute(uint64 /*time*/, uint32 /*diff*/) override
428 {
431 if (Unit* target = _summoner->AI()->SelectTarget(SelectTargetMethod::Random, 0, 300.0f))
432 _owner->AI()->AttackStart(target);
433 return true;
434 }
435
436 private:
439};
440
442{
443 public:
444 boss_voice_of_yogg_saron() : CreatureScript("boss_voice_of_yogg_saron") { }
445
447 {
449 {
450 Initialize();
451 SetCombatMovement(false);
452 }
453
455 {
456 _guardiansCount = 0;
457 _guardianTimer = 20s;
458 _illusionShattered = false;
459 }
460
461 void MoveInLineOfSight(Unit* who) override
462 {
463 // TODO: MoveInLineOfSight doesn't work for such a big distance
464 if (who->GetTypeId() == TYPEID_PLAYER && !who->ToPlayer()->IsGameMaster() && me->GetDistance2d(who) < 99.0f && !me->IsInCombat())
466 }
467
468 void EnterEvadeMode(EvadeReason why) override
469 {
471
472 for (uint8 i = DATA_SARA; i <= DATA_MIMIRON_YS; ++i)
474 creature->AI()->EnterEvadeMode();
475
476 // not sure, spoken by Sara (sound), regarding to wowwiki Voice whispers it
477 Map::PlayerList const& players = me->GetMap()->GetPlayers();
478 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
479 if (Player* player = itr->GetSource())
480 {
483
484 player->RemoveAurasDueToSpell(SPELL_SANITY);
485 player->RemoveAurasDueToSpell(SPELL_INSANE);
486 }
487 }
488
489 void Reset() override
490 {
491 _Reset();
493
495
496 Initialize();
497
498 bool clockwise = false;
499 std::list<TempSummon*> clouds;
501 clouds.sort(Trinity::ObjectDistanceOrderPred(me, true));
502 for (std::list<TempSummon*>::const_iterator itr = clouds.begin(); itr != clouds.end(); ++itr)
503 {
504 (*itr)->AI()->DoAction(int32(clockwise));
505 clockwise = !clockwise;
506 }
507 }
508
509 void JustEngagedWith(Unit* /*who*/) override
510 {
512 sara->SetInCombatWith(me);
513
514 for (uint8 i = DATA_FREYA_YS; i <= DATA_MIMIRON_YS; ++i)
516 keeper->SetInCombatWith(me);
517
519
522
525 events.ScheduleEvent(EVENT_EXTINGUISH_ALL_LIFE, 15min); // 15 minutes
526 }
527
528 void JustDied(Unit* /*killer*/) override
529 {
530 // don't despawn Yogg-Saron's corpse, remove him from SummonList!
532 summons.Despawn(yogg);
533
534 _JustDied();
535 }
536
537 void UpdateAI(uint32 diff) override
538 {
539 if (!UpdateVictim())
540 return;
541
544
545 events.Update(diff);
546 // don't summon tentacles when illusion is shattered, delay them
549
550 while (uint32 eventId = events.ExecuteEvent())
551 {
552 switch (eventId)
553 {
554 case EVENT_LOCK_DOOR:
557 break;
560 {
561 yogg->AI()->Talk(EMOTE_YOGG_SARON_EXTINGUISH_ALL_LIFE, me);
562 yogg->CastSpell(nullptr, SPELL_EXTINGUISH_ALL_LIFE, true);
563 }
564 events.ScheduleEvent(EVENT_EXTINGUISH_ALL_LIFE, 10s); // cast it again after a short while, players can survive
565 break;
569 if (_guardiansCount <= 6 && _guardiansCount % 3 == 0)
570 _guardianTimer -= 5s;
572 break;
576 break;
580 break;
584 break;
585 case EVENT_ILLUSION:
586 {
588 {
589 yogg->AI()->Talk(EMOTE_YOGG_SARON_MADNESS);
590 yogg->AI()->Talk(SAY_YOGG_SARON_MADNESS);
591 }
592
594 if (me->GetMap()->Is25ManRaid())
596
598 instance->SetData(DATA_ILLUSION, illusion);
599
601 brain->AI()->DoAction(ACTION_INDUCE_MADNESS);
602 events.ScheduleEvent(EVENT_ILLUSION, 80s, 0, PHASE_TWO); // wowwiki says 80 secs, wowhead says something about 90 secs
603 break;
604 }
608 break;
609 default:
610 break;
611 }
612 }
613 }
614
615 void DoAction(int32 action) override
616 {
617 switch (action)
618 {
622 break;
623 case ACTION_PHASE_TWO:
627 DoZoneInCombat(brain);
632 break;
635 break;
639 break;
640 default:
641 break;
642 }
643 }
644
645 void JustSummoned(Creature* summon) override
646 {
647 switch (summon->GetEntry())
648 {
650 summon->m_Events.AddEvent(new StartAttackEvent(me, summon), summon->m_Events.CalculateTime(1s));
651 break;
652 case NPC_YOGG_SARON:
654 break;
656 summon->CastSpell(summon, SPELL_LUNGE, true);
657 break;
662 summon->m_Events.AddEvent(new StartAttackEvent(me, summon), summon->m_Events.CalculateTime(5s));
663 break;
665 summon->CastSpell(summon, SPELL_TELEPORT_PORTAL_VISUAL, true);
666 break;
668 summon->CastSpell(summon, SPELL_SIMPLE_TELEPORT, true);
669 break;
670 }
671
672 BossAI::JustSummoned(summon);
673 }
674
675 private:
679 };
680
681 CreatureAI* GetAI(Creature* creature) const override
682 {
683 return GetUlduarAI<boss_voice_of_yogg_saronAI>(creature);
684 }
685};
686
688{
689 public:
690 boss_sara() : CreatureScript("boss_sara") { }
691
692 struct boss_saraAI : public ScriptedAI
693 {
694 boss_saraAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
695
697 {
698 std::map<ObjectGuid, ObjectGuid>::const_iterator itr = _linkData.find(guid);
699 if (itr != _linkData.end())
700 return itr->second;
701
702 return ObjectGuid::Empty;
703 }
704
705 void SetLinkBetween(ObjectGuid player1, ObjectGuid player2)
706 {
707 _linkData[player1] = player2;
708 _linkData[player2] = player1;
709 }
710
711 // called once for each target on aura remove
713 {
714 _linkData.erase(player1);
715 }
716
717 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
718 {
719 if (damage >= me->GetHealth())
720 {
721 damage = me->GetHealth() - 1;
722
724 {
726 voice->AI()->DoAction(ACTION_PHASE_TRANSFORM);
727
734 }
735 }
736 }
737
738 void SpellHitTarget(WorldObject* /*target*/, SpellInfo const* spellInfo) override
739 {
741 return;
742
743 switch (spellInfo->Id)
744 {
747 break;
750 break;
751 case SPELL_PSYCHOSIS:
753 break;
754 default:
755 break;
756 }
757 }
758
759 void KilledUnit(Unit* victim) override
760 {
761 if (victim->GetTypeId() == TYPEID_PLAYER && !me->IsInEvadeMode())
763 }
764
765 void JustEngagedWith(Unit* /*who*/) override
766 {
771 }
772
773 void JustEnteredCombat(Unit* who) override
774 {
775 if (IsEngaged())
776 return;
777
778 EngagementStart(who);
779 }
780
781 void Reset() override
782 {
786 _events.Reset();
788 }
789
790 void UpdateAI(uint32 diff) override
791 {
792 if (!me->IsInCombat())
793 return;
794
796 return;
797
798 _events.Update(diff);
799
801 return;
802
803 while (uint32 eventId = _events.ExecuteEvent())
804 {
805 switch (eventId)
806 {
810 break;
814 break;
818 break;
821 break;
824 break;
830 voice->AI()->DoAction(ACTION_PHASE_TWO);
832 mimiron->AI()->DoAction(ACTION_PHASE_TWO);
833 break;
840 _events.ScheduleEvent(EVENT_DEATH_RAY, 20s, 0, PHASE_TWO); // almost never cast at scheduled time, why?
844 break;
845 case EVENT_DEATH_RAY:
848 break;
852 break;
853 case EVENT_PSYCHOSIS:
856 break;
857 case EVENT_BRAIN_LINK:
860 break;
861 default:
862 break;
863 }
864 }
865 }
866
867 void JustSummoned(Creature* summon) override
868 {
870
871 switch (summon->GetEntry())
872 {
873 case NPC_DEATH_ORB:
876 for (uint8 i = 0; i < 4; ++i)
877 {
878 Position pos;
879 float radius = frand(25.0f, 50.0f);
880 float angle = frand(0.0f, 2.0f * float(M_PI));
881 pos.m_positionX = YoggSaronSpawnPos.GetPositionX() + radius * cosf(angle);
882 pos.m_positionY = YoggSaronSpawnPos.GetPositionY() + radius * sinf(angle);
885 }
886 break;
887 case NPC_DEATH_RAY:
889 break;
890 }
891
893 voice->AI()->JustSummoned(summon);
894 }
895
896 void DoAction(int32 action) override
897 {
898 switch (action)
899 {
900 case ACTION_PHASE_THREE: // Sara does nothing in phase 3
902 break;
903 default:
904 break;
905 }
906 }
907
908 private:
911 std::map<ObjectGuid, ObjectGuid> _linkData;
912 };
913
914 CreatureAI* GetAI(Creature* creature) const override
915 {
916 return GetUlduarAI<boss_saraAI>(creature);
917 }
918};
919
921{
922 public:
923 boss_yogg_saron() : CreatureScript("boss_yogg_saron") { }
924
926 {
927 boss_yogg_saronAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
928
929 void Reset() override
930 {
931 _events.Reset();
936
937 me->ResetLootMode();
939 if (keepersCount == 0)
941 if (keepersCount <= 1)
943 if (keepersCount <= 2)
945 if (keepersCount <= 3)
947 }
948
949 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
950 {
951 // Val'anyr
952 if (spellInfo->Id == SPELL_IN_THE_MAWS_OF_THE_OLD_GOD)
953 me->AddLootMode(32);
954 }
955
956 void JustDied(Unit* /*killer*/) override
957 {
959
961 Unit::Kill(me, creature);
962
963 for (uint8 i = DATA_SARA; i <= DATA_BRAIN_OF_YOGG_SARON; ++i)
965 creature->DisappearAndDie();
966
967 for (uint8 i = DATA_FREYA_YS; i <= DATA_MIMIRON_YS; ++i)
969 creature->AI()->EnterEvadeMode();
970
971 Map::PlayerList const& players = me->GetMap()->GetPlayers();
972 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
973 if (Player* player = itr->GetSource())
974 {
975 player->RemoveAurasDueToSpell(SPELL_SANITY);
976 player->RemoveAurasDueToSpell(SPELL_INSANE);
977 }
978 }
979
980 void UpdateAI(uint32 diff) override
981 {
982 _events.Update(diff);
983
985 return;
986
987 while (uint32 eventId = _events.ExecuteEvent())
988 {
989 switch (eventId)
990 {
993 break;
998 break;
1003 break;
1008 _events.ScheduleEvent(EVENT_DEAFENING_ROAR, 20s, 25s, 0, PHASE_THREE); // timer guessed
1009 break;
1010 default:
1011 break;
1012 }
1013 }
1014 }
1015
1016 void DoAction(int32 action) override
1017 {
1018 switch (action)
1019 {
1020 case ACTION_PHASE_THREE:
1025 _events.ScheduleEvent(EVENT_DEAFENING_ROAR, 20s, 25s, 0, PHASE_THREE); // timer guessed
1030 break;
1031 default:
1032 break;
1033 }
1034 }
1035
1036 private:
1039 };
1040
1041 CreatureAI* GetAI(Creature* creature) const override
1042 {
1043 return GetUlduarAI<boss_yogg_saronAI>(creature);
1044 }
1045};
1046
1048{
1049 public:
1050 boss_brain_of_yogg_saron() : CreatureScript("boss_brain_of_yogg_saron") { }
1051
1053 {
1054 boss_brain_of_yogg_saronAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()), _summons(creature)
1055 {
1056 _tentaclesKilled = 0;
1057 }
1058
1059 void Reset() override
1060 {
1061 me->SetUninteractible(false);
1062 me->SetImmuneToPC(false);
1065 }
1066
1067 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1068 {
1070 {
1071 me->RemoveAllAuras();
1074 DoCast(me, SPELL_MATCH_HEALTH_2, true); // it doesn't seem to hit Yogg-Saron here
1076 me->SetUninteractible(true);
1077 me->SetImmuneToPC(true);
1078
1080 voice->AI()->DoAction(ACTION_PHASE_THREE);
1082 sara->AI()->DoAction(ACTION_PHASE_THREE);
1084 yogg->AI()->DoAction(ACTION_PHASE_THREE);
1085
1086 for (uint8 i = DATA_THORIM_YS; i <= DATA_MIMIRON_YS; ++i)
1088 keeper->AI()->DoAction(ACTION_PHASE_THREE);
1089 }
1090 }
1091
1092 void UpdateAI(uint32 /*diff*/) override { }
1093
1094 void DoAction(int32 action) override
1095 {
1096 switch (action)
1097 {
1099 {
1100 _tentaclesKilled = 0;
1101
1103
1104 // make sure doors won't be opened
1107
1109 break;
1110 }
1112 {
1113 uint8 illusion = _instance->GetData(DATA_ILLUSION);
1114 if (++_tentaclesKilled >= (illusion == ICECROWN_ILLUSION ? 9 : 8))
1115 {
1120
1122 voice->AI()->DoAction(ACTION_TOGGLE_SHATTERED_ILLUSION);
1123 }
1124 break;
1125 }
1126 default:
1127 break;
1128 }
1129 }
1130
1131 void JustSummoned(Creature* summon) override
1132 {
1133 _summons.Summon(summon);
1134 }
1135
1136 private:
1140 };
1141
1142 CreatureAI* GetAI(Creature* creature) const override
1143 {
1144 return GetUlduarAI<boss_brain_of_yogg_saronAI>(creature);
1145 }
1146};
1147
1149{
1150 public:
1151 npc_ominous_cloud() : CreatureScript("npc_ominous_cloud") { }
1152
1154 {
1155 npc_ominous_cloudAI(Creature* creature) : PassiveAI(creature) { }
1156
1157 void Reset() override
1158 {
1160 }
1161
1162 void UpdateAI(uint32 /*diff*/) override { }
1163
1164 void DoAction(int32 action) override
1165 {
1166 clockwise = bool(action);
1168 }
1169
1170 bool clockwise = false;
1171 };
1172
1173 CreatureAI* GetAI(Creature* creature) const override
1174 {
1175 return GetUlduarAI<npc_ominous_cloudAI>(creature);
1176 }
1177};
1178
1180{
1181 public:
1182 npc_guardian_of_yogg_saron() : CreatureScript("npc_guardian_of_yogg_saron") { }
1183
1185 {
1186 npc_guardian_of_yogg_saronAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
1187
1188 void JustDied(Unit* /*killer*/) override
1189 {
1192 }
1193
1194 void Reset() override
1195 {
1197 }
1198
1199 void UpdateAI(uint32 diff) override
1200 {
1201 if (!UpdateVictim())
1202 return;
1203
1204 _events.Update(diff);
1205
1207 return;
1208
1209 while (uint32 eventId = _events.ExecuteEvent())
1210 {
1211 switch (eventId)
1212 {
1213 case EVENT_DARK_VOLLEY:
1216 break;
1217 default:
1218 break;
1219 }
1220 }
1221 }
1222
1223 void IsSummonedBy(WorldObject* summoner) override
1224 {
1225 if (summoner->GetEntry() != NPC_OMINOUS_CLOUD)
1226 return;
1227
1228 // Guardian can be summoned both by Voice of Yogg-Saron and by Ominous Cloud
1230 voice->AI()->JustSummoned(me);
1231 }
1232
1233 private:
1236 };
1237
1238 CreatureAI* GetAI(Creature* creature) const override
1239 {
1240 return GetUlduarAI<npc_guardian_of_yogg_saronAI>(creature);
1241 }
1242};
1243
1245{
1246 public:
1247 npc_corruptor_tentacle() : CreatureScript("npc_corruptor_tentacle") { }
1248
1250 {
1252 {
1253 SetCombatMovement(false);
1254 }
1255
1256 void Reset() override
1257 {
1261 }
1262
1263 void UpdateAI(uint32 diff) override
1264 {
1265 if (!UpdateVictim())
1266 return;
1267
1269 return;
1270
1271 _events.Update(diff);
1272
1274 return;
1275
1276 while (uint32 eventId = _events.ExecuteEvent())
1277 {
1278 switch (eventId)
1279 {
1284 break;
1285 default:
1286 break;
1287 }
1288 }
1289 }
1290
1291 private:
1293 };
1294
1295 CreatureAI* GetAI(Creature* creature) const override
1296 {
1297 return GetUlduarAI<npc_corruptor_tentacleAI>(creature);
1298 }
1299};
1300
1302{
1303 public:
1304 npc_constrictor_tentacle() : CreatureScript("npc_constrictor_tentacle") { }
1305
1307 {
1308 npc_constrictor_tentacleAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
1309 {
1310 SetCombatMovement(false);
1311 }
1312
1313 void Reset() override
1314 {
1317 }
1318
1319 void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override
1320 {
1321 if (!apply)
1323 }
1324
1325 void UpdateAI(uint32 /*diff*/) override
1326 {
1327 UpdateVictim();
1328 }
1329
1330 void IsSummonedBy(WorldObject* /*summoner*/) override
1331 {
1333 voice->AI()->JustSummoned(me);
1334 }
1335
1336 private:
1338 };
1339
1340 CreatureAI* GetAI(Creature* creature) const override
1341 {
1342 return GetUlduarAI<npc_constrictor_tentacleAI>(creature);
1343 }
1344};
1345
1347{
1348 public:
1349 npc_crusher_tentacle() : CreatureScript("npc_crusher_tentacle") { }
1350
1352 {
1354 {
1355 SetCombatMovement(false);
1356 }
1357
1358 void Reset() override
1359 {
1365
1367 }
1368
1369 void UpdateAI(uint32 diff) override
1370 {
1371 if (!UpdateVictim())
1372 return;
1373
1375 return;
1376
1377 // update timers when the Diminish Power is not being channeled so the next one
1378 // is not cast immediately after interrupt
1379 _events.Update(diff);
1380
1381 while (uint32 eventId = _events.ExecuteEvent())
1382 {
1383 switch (eventId)
1384 {
1388 break;
1389 default:
1390 break;
1391 }
1392 }
1393 }
1394
1395 private:
1397 };
1398
1399 CreatureAI* GetAI(Creature* creature) const override
1400 {
1401 return GetUlduarAI<npc_crusher_tentacleAI>(creature);
1402 }
1403};
1404
1406{
1407 public:
1408 npc_influence_tentacle() : CreatureScript("npc_influence_tentacle") { }
1409
1411 {
1412 npc_influence_tentacleAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
1413
1414 void Reset() override
1415 {
1417 }
1418
1419 void JustDied(Unit* /*killer*/) override
1420 {
1422 brain->AI()->DoAction(ACTION_TENTACLE_KILLED);
1423 }
1424
1425 void UpdateAI(uint32 /*diff*/) override { }
1426
1427 private:
1429 };
1430
1431 CreatureAI* GetAI(Creature* creature) const override
1432 {
1433 return GetUlduarAI<npc_influence_tentacleAI>(creature);
1434 }
1435};
1436
1438
1440{
1441 public:
1442 npc_descend_into_madness() : CreatureScript("npc_descend_into_madness") { }
1443
1445 {
1446 npc_descend_into_madnessAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
1447
1448 void OnSpellClick(Unit* clicker, bool spellClickHandled) override
1449 {
1450 if (!spellClickHandled)
1451 return;
1452
1455 if (illusion < MAX_ILLUSION_ROOMS)
1456 DoCast(clicker, IllusionSpells[illusion], true);
1458 }
1459
1460 void UpdateAI(uint32 /*diff*/) override { }
1461
1462 private:
1464 };
1465
1466 CreatureAI* GetAI(Creature* creature) const override
1467 {
1468 return GetUlduarAI<npc_descend_into_madnessAI>(creature);
1469 }
1470};
1471
1473{
1474 public:
1475 npc_immortal_guardian() : CreatureScript("npc_immortal_guardian") { }
1476
1478 {
1480
1481 void Reset() override
1482 {
1486 }
1487
1488 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1489 {
1490 if (me->HealthBelowPctDamaged(1, damage))
1491 damage = me->GetHealth() - me->CountPctFromMaxHealth(1); // or set immune to damage? should be done here or in SPELL_WEAKENED spell script?
1492 }
1493
1494 void UpdateAI(uint32 diff) override
1495 {
1496 if (!UpdateVictim())
1497 return;
1498
1499 _events.Update(diff);
1500
1502 return;
1503
1504 while (uint32 eventId = _events.ExecuteEvent())
1505 {
1506 switch (eventId)
1507 {
1508 case EVENT_DRAIN_LIFE:
1511 break;
1512 default:
1513 break;
1514 }
1515 }
1516 }
1517
1518 private:
1520 };
1521
1522 CreatureAI* GetAI(Creature* creature) const override
1523 {
1524 return GetUlduarAI<npc_immortal_guardianAI>(creature);
1525 }
1526};
1527
1529{
1530 public:
1531 npc_observation_ring_keeper() : CreatureScript("npc_observation_ring_keeper") { }
1532
1534 {
1536
1537 void Reset() override
1538 {
1539 DoCast(SPELL_SIMPLE_TELEPORT_KEEPERS); // not visible here
1541 }
1542
1543 bool OnGossipSelect(Player* player, uint32 menuId, uint32 /*gossipListId*/) override
1544 {
1545 if (menuId != 10333)
1546 return false;
1547
1549 me->DespawnOrUnsummon(2s);
1551 Talk(SAY_KEEPER_CHOSEN_1, player);
1552 Talk(SAY_KEEPER_CHOSEN_2, player);
1553
1554 switch (me->GetEntry())
1555 {
1558 break;
1561 break;
1564 break;
1567 break;
1568 }
1569 return false;
1570 }
1571
1572 void UpdateAI(uint32 /*diff*/) override { }
1573 };
1574
1575 CreatureAI* GetAI(Creature* creature) const override
1576 {
1577 return GetUlduarAI<npc_observation_ring_keeperAI>(creature);
1578 }
1579};
1580
1582{
1583 public:
1584 npc_yogg_saron_keeper() : CreatureScript("npc_yogg_saron_keeper") { }
1585
1587 {
1589
1590 void IsSummonedBy(WorldObject* /*summoner*/) override
1591 {
1593 }
1594
1595 void Reset() override
1596 {
1597 _events.Reset();
1600 me->RemoveAllAuras();
1601
1602 DoCast(SPELL_KEEPER_ACTIVE); // can we skip removing this aura somehow?
1603
1604 if (me->GetEntry() == NPC_FREYA_YS)
1605 {
1606 std::list<Creature*> wells;
1608 for (std::list<Creature*>::const_iterator itr = wells.begin(); itr != wells.end(); ++itr)
1609 {
1610 (*itr)->RemoveAurasDueToSpell(SPELL_SANITY_WELL);
1611 (*itr)->RemoveAurasDueToSpell(SPELL_SANITY_WELL_VISUAL);
1612 }
1613 }
1614 }
1615
1616 void JustEnteredCombat(Unit* who) override
1617 {
1618 if (IsEngaged())
1619 return;
1620
1621 EngagementStart(who);
1622
1623 switch (me->GetEntry())
1624 {
1625 case NPC_FREYA_YS:
1628 break;
1629 case NPC_HODIR_YS:
1632 break;
1633 case NPC_THORIM_YS:
1635 break;
1636 case NPC_MIMIRON_YS:
1638 break;
1639 }
1640 }
1641
1642 void UpdateAI(uint32 diff) override
1643 {
1644 if (!me->IsInCombat())
1645 return;
1646
1647 _events.Update(diff);
1648
1650 return;
1651
1652 while (uint32 eventId = _events.ExecuteEvent())
1653 {
1654 switch (eventId)
1655 {
1659 break;
1662 break;
1663 }
1664 }
1665 }
1666
1667 void DoAction(int32 action) override
1668 {
1669 switch (action)
1670 {
1671 // setting the phases is only for Thorim and Mimiron
1672 case ACTION_PHASE_TWO:
1675 break;
1676 case ACTION_PHASE_THREE:
1678 if (me->GetEntry() == NPC_THORIM_YS)
1680 break;
1682 {
1683 std::list<Creature*> wells;
1685 for (std::list<Creature*>::const_iterator itr = wells.begin(); itr != wells.end(); ++itr)
1686 {
1687 (*itr)->CastSpell(*itr, SPELL_SANITY_WELL);
1688 (*itr)->CastSpell(*itr, SPELL_SANITY_WELL_VISUAL);
1689 }
1690 break;
1691 }
1695 break;
1696 }
1697 }
1698
1699 private:
1701 };
1702
1703 CreatureAI* GetAI(Creature* creature) const override
1704 {
1705 return GetUlduarAI<npc_yogg_saron_keeperAI>(creature);
1706 }
1707};
1708
1710{
1711 public:
1712 npc_yogg_saron_illusions() : CreatureScript("npc_yogg_saron_illusions") { }
1713
1715 {
1716 npc_yogg_saron_illusionsAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
1717
1718 void IsSummonedBy(WorldObject* /*summoner*/) override
1719 {
1721 {
1722 case CHAMBER_ILLUSION:
1723 // i think the first Talk should be delayed as in this moment
1724 // players are too far away to be able to see it
1725 if (Creature* neltharion = me->FindNearestCreature(NPC_NELTHARION, 50.0f))
1726 neltharion->AI()->Talk(SAY_CHAMBER_ROLEPLAY_1);
1727
1732 break;
1733 case ICECROWN_ILLUSION:
1734 // same here
1741 break;
1742 case STORMWIND_ILLUSION:
1743 _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_4, 33800ms); // "A thousand deaths..."
1746 // TODO: use "or one murder." sound and split the text in DB
1747 break;
1748 }
1749 }
1750
1751 void UpdateAI(uint32 diff) override
1752 {
1753 _events.Update(diff);
1754
1755 while (uint32 eventId = _events.ExecuteEvent())
1756 {
1757 switch (eventId)
1758 {
1760 if (Creature* ysera = me->FindNearestCreature(NPC_YSERA, 50.0f))
1761 ysera->AI()->Talk(SAY_CHAMBER_ROLEPLAY_2);
1762 break;
1764 if (Creature* neltharion = me->FindNearestCreature(NPC_NELTHARION, 50.0f))
1765 neltharion->AI()->Talk(SAY_CHAMBER_ROLEPLAY_3);
1766 break;
1768 if (Creature* malygos = me->FindNearestCreature(NPC_MALYGOS, 50.0f))
1769 malygos->AI()->Talk(SAY_CHAMBER_ROLEPLAY_4);
1770 break;
1773 break;
1776 {
1777 bolvar->AI()->Talk(SAY_ICECROWN_ROLEPLAY_1);
1778
1779 if (Creature* lichKing = me->FindNearestCreature(NPC_THE_LICH_KING, 50.0f))
1780 lichKing->CastSpell(bolvar, SPELL_DEATHGRASP);
1781 }
1782 break;
1784 if (Creature* lichKing = me->FindNearestCreature(NPC_THE_LICH_KING, 50.0f))
1785 lichKing->AI()->Talk(SAY_ICECROWN_ROLEPLAY_2);
1786 break;
1789 bolvar->AI()->Talk(SAY_ICECROWN_ROLEPLAY_3);
1790 if (Creature* saurfang = me->FindNearestCreature(NPC_TURNED_CHAMPION, 50.0f))
1791 saurfang->AI()->DoAction(ACTION_START_ROLEPLAY);
1792 break;
1794 if (Creature* lichKing = me->FindNearestCreature(NPC_THE_LICH_KING, 50.0f))
1795 lichKing->AI()->Talk(SAY_ICECROWN_ROLEPLAY_4);
1796 break;
1799 break;
1802 break;
1805 break;
1807 if (Creature* llane = me->FindNearestCreature(NPC_KING_LLANE, 50.0f))
1808 llane->AI()->Talk(SAY_STORMWIND_ROLEPLAY_5);
1809 break;
1812 break;
1813 default:
1814 break;
1815 }
1816 }
1817 }
1818
1819 private:
1822 };
1823
1824 CreatureAI* GetAI(Creature* creature) const override
1825 {
1826 return GetUlduarAI<npc_yogg_saron_illusionsAI>(creature);
1827 }
1828};
1829
1831{
1832 public:
1833 npc_garona() : CreatureScript("npc_garona") { }
1834
1835 struct npc_garonaAI : public ScriptedAI
1836 {
1837 npc_garonaAI(Creature* creature) : ScriptedAI(creature) { }
1838
1839 void Reset() override
1840 {
1841 _events.Reset();
1842
1843 me->SetWalk(true);
1845
1850 }
1851
1852 void UpdateAI(uint32 diff) override
1853 {
1854 _events.Update(diff);
1855
1856 while (uint32 eventId = _events.ExecuteEvent())
1857 {
1858 switch (eventId)
1859 {
1862 break;
1865 break;
1868 break;
1871 if (Creature* llane = me->FindNearestCreature(NPC_KING_LLANE, 50.0f))
1872 {
1874 llane->CastSpell(llane, SPELL_PERMANENT_FEIGN_DEATH);
1875 }
1876 break;
1877 default:
1878 break;
1879 }
1880 }
1881 }
1882
1883 private:
1885 };
1886
1887 CreatureAI* GetAI(Creature* creature) const override
1888 {
1889 return GetUlduarAI<npc_garonaAI>(creature);
1890 }
1891};
1892
1894{
1895 public:
1896 npc_turned_champion() : CreatureScript("npc_turned_champion") { }
1897
1899 {
1900 npc_turned_championAI(Creature* creature) : ScriptedAI(creature) { }
1901
1902 void Reset() override
1903 {
1905 }
1906
1907 void MovementInform(uint32 type, uint32 pointId) override
1908 {
1909 if (type != POINT_MOTION_TYPE || pointId != 0)
1910 return;
1911
1913 }
1914
1915 void DoAction(int32 action) override
1916 {
1917 if (action != ACTION_START_ROLEPLAY)
1918 return;
1919
1920 me->SetWalk(true);
1922 }
1923 };
1924
1925 CreatureAI* GetAI(Creature* creature) const override
1926 {
1927 return GetUlduarAI<npc_turned_championAI>(creature);
1928 }
1929};
1930
1932{
1933 public:
1934 npc_laughing_skull() : CreatureScript("npc_laughing_skull") { }
1935
1937 {
1938 npc_laughing_skullAI(Creature* creature) : ScriptedAI(creature) { }
1939
1940 void Reset() override
1941 {
1944 }
1945
1946 // don't evade, otherwise the Lunatic Gaze aura is removed
1947 void UpdateAI(uint32 /*diff*/) override { }
1948 };
1949
1950 CreatureAI* GetAI(Creature* creature) const override
1951 {
1952 return GetUlduarAI<npc_laughing_skullAI>(creature);
1953 }
1954};
1955
1956/* 63744 - Sara's Anger
1957 63745 - Sara's Blessing
1958 63747 - Sara's Fervor
1959 65206 - Destabilization Matrix */
1960class spell_yogg_saron_target_selectors : public SpellScriptLoader // 63744, 63745, 63747, 65206
1961{
1962 public:
1963 spell_yogg_saron_target_selectors() : SpellScriptLoader("spell_yogg_saron_target_selectors") { }
1964
1966 {
1967 void HandleScript(SpellEffIndex /*effIndex*/)
1968 {
1969 if (Unit* target = GetHitUnit())
1971 }
1972
1973 void Register() override
1974 {
1976 }
1977 };
1978
1979 SpellScript* GetSpellScript() const override
1980 {
1982 }
1983};
1984
1986{
1987 public:
1989 SanityReduction(uint8 stacks) : SpellScript(), _stacks(stacks) { }
1990
1991 void RemoveSanity(SpellEffIndex /*effIndex*/)
1992 {
1993 if (Unit* target = GetHitUnit())
1994 if (Aura* sanity = target->GetAura(SPELL_SANITY))
1995 sanity->ModStackAmount(-int32(_stacks), AURA_REMOVE_BY_ENEMY_SPELL);
1996 }
1997
1998 protected:
2000};
2001
2003{
2004 public:
2006
2008 {
2009 if (Unit* unit = object->ToUnit())
2010 if (Aura* sanity = unit->GetAura(SPELL_SANITY))
2011 return sanity->GetStackAmount() <= 40;
2012 return true;
2013 }
2014};
2015
2016// 63795, 65301 - Psychosis
2017class spell_yogg_saron_psychosis : public SpellScriptLoader // 63795, 65301
2018{
2019 public:
2020 spell_yogg_saron_psychosis() : SpellScriptLoader("spell_yogg_saron_psychosis") { }
2021
2023 {
2024 bool Load() override
2025 {
2026 _stacks = GetSpellInfo()->Id == SPELL_PSYCHOSIS ? 9 : 12;
2027 return true;
2028 }
2029
2030 void FilterTargets(std::list<WorldObject*>& targets)
2031 {
2032 targets.remove_if(HighSanityTargetSelector());
2033 targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_ILLUSION_ROOM));
2034 }
2035
2036 void Register() override
2037 {
2041 }
2042 };
2043
2044 SpellScript* GetSpellScript() const override
2045 {
2047 }
2048};
2049
2050// 63830, 63881 - Malady of the Mind
2052{
2053 public:
2054 spell_yogg_saron_malady_of_the_mind() : SpellScriptLoader("spell_yogg_saron_malady_of_the_mind") { }
2055
2057 {
2058 public:
2060
2061 void FilterTargets(std::list<WorldObject*>& targets)
2062 {
2063 targets.remove_if(HighSanityTargetSelector());
2064 targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_ILLUSION_ROOM));
2065 }
2066
2067 void Register() override
2068 {
2070 {
2074 }
2075
2077 }
2078 };
2079
2081 {
2082 bool Validate(SpellInfo const* /*spell*/) override
2083 {
2085 }
2086
2087 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2088 {
2089 switch (GetTargetApplication()->GetRemoveMode())
2090 {
2094 break;
2095 default:
2096 return;
2097 }
2098
2100 }
2101
2102 void Register() override
2103 {
2105 }
2106 };
2107
2108 SpellScript* GetSpellScript() const override
2109 {
2111 }
2112
2113 AuraScript* GetAuraScript() const override
2114 {
2116 }
2117};
2118
2119// 63802 - Brain Link
2121{
2122 public:
2123 spell_yogg_saron_brain_link() : SpellScriptLoader("spell_yogg_saron_brain_link") { }
2124
2126 {
2127 void FilterTargets(std::list<WorldObject*>& targets)
2128 {
2129 targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_ILLUSION_ROOM));
2130
2131 if (targets.size() != 2)
2132 {
2133 targets.clear();
2134 return;
2135 }
2136
2137 if (SaraAI* ai = CAST_AI(SaraAI, GetCaster()->GetAI()))
2138 ai->SetLinkBetween(targets.front()->GetGUID(), targets.back()->GetGUID());
2139 }
2140
2141 void Register() override
2142 {
2144 }
2145 };
2146
2148 {
2149 bool Validate(SpellInfo const* /*spellInfo*/) override
2150 {
2152 }
2153
2154 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2155 {
2156 Unit* caster = GetCaster();
2157 if (!caster)
2158 return;
2159
2160 if (SaraAI* ai = CAST_AI(SaraAI, caster->GetAI()))
2161 {
2162 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
2163 ai->RemoveLinkFrom(GetTarget()->GetGUID());
2164 else
2165 {
2166 if (Player* player = ObjectAccessor::GetPlayer(*GetTarget(), ai->GetLinkedPlayerGUID(GetTarget()->GetGUID())))
2167 {
2168 ai->RemoveLinkFrom(GetTarget()->GetGUID());
2169 player->RemoveAurasDueToSpell(SPELL_BRAIN_LINK);
2170 }
2171 }
2172 }
2173 }
2174
2175 void DummyTick(AuraEffect const* aurEff)
2176 {
2177 Unit* caster = GetCaster();
2178 if (!caster)
2179 return;
2180
2181 SaraAI* ai = CAST_AI(SaraAI, caster->GetAI());
2182 if (!ai)
2183 return;
2184
2186 if (!linked)
2187 return;
2188
2189 GetTarget()->CastSpell(linked, (GetTarget()->GetDistance(linked) > (float)aurEff->GetAmount()) ? SPELL_BRAIN_LINK_DAMAGE : SPELL_BRAIN_LINK_NO_DAMAGE, true);
2190 }
2191
2192 void Register() override
2193 {
2196 }
2197 };
2198
2199 SpellScript* GetSpellScript() const override
2200 {
2202 }
2203
2204 AuraScript* GetAuraScript() const override
2205 {
2207 }
2208};
2209
2210// 63803 - Brain Link (Damage)
2212{
2213 public:
2214 spell_yogg_saron_brain_link_damage() : SpellScriptLoader("spell_yogg_saron_brain_link_damage") { }
2215
2217 {
2218 public:
2220
2221 void Register() override
2222 {
2224 }
2225 };
2226
2227 SpellScript* GetSpellScript() const override
2228 {
2230 }
2231};
2232
2233// 63030 - Boil Ominously
2235{
2236 public:
2237 spell_yogg_saron_boil_ominously() : SpellScriptLoader("spell_yogg_saron_boil_ominously") { }
2238
2240 {
2241 bool Validate(SpellInfo const* /*spellInfo*/) override
2242 {
2244 }
2245
2246 void HandleDummy(SpellEffIndex /*effIndex*/)
2247 {
2248 if (Unit* target = GetHitUnit())
2250 {
2251 if (Creature* caster = GetCaster()->ToCreature())
2252 caster->AI()->Talk(EMOTE_OMINOUS_CLOUD_PLAYER_TOUCH, target);
2253
2255 }
2256 }
2257
2258 void Register() override
2259 {
2261 }
2262 };
2263
2264 SpellScript* GetSpellScript() const override
2265 {
2267 }
2268};
2269
2270// 64465 - Shadow Beacon
2272{
2273 public:
2274 spell_yogg_saron_shadow_beacon() : SpellScriptLoader("spell_yogg_saron_shadow_beacon") { }
2275
2277 {
2278 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2279 {
2280 if (Creature* target = GetTarget()->ToCreature())
2281 target->SetEntry(NPC_MARKED_IMMORTAL_GUARDIAN);
2282 }
2283
2284 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2285 {
2286 if (Creature* target = GetTarget()->ToCreature())
2287 target->SetEntry(NPC_IMMORTAL_GUARDIAN);
2288 }
2289
2290 void Register() override
2291 {
2294 }
2295 };
2296
2297 AuraScript* GetAuraScript() const override
2298 {
2300 }
2301};
2302
2303// 64466 - Empowering Shadows
2305{
2306 public:
2307 spell_yogg_saron_empowering_shadows_range_check() : SpellScriptLoader("spell_yogg_saron_empowering_shadows_range_check") { }
2308
2310 {
2311 void HandleScript(SpellEffIndex /*effIndex*/)
2312 {
2313 if (Unit* target = GetHitUnit())
2314 target->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
2315 }
2316
2317 void Register() override
2318 {
2320 }
2321 };
2322
2323 SpellScript* GetSpellScript() const override
2324 {
2326 }
2327};
2328
2329// 64467 - Empowering Shadows
2331{
2332 public:
2333 spell_yogg_saron_empowering_shadows_missile() : SpellScriptLoader("spell_yogg_saron_empowering_shadows_missile") { }
2334
2336 {
2337 bool Validate(SpellInfo const* /*spellInfo*/) override
2338 {
2340 }
2341
2342 void HandleScript(SpellEffIndex /*effIndex*/)
2343 {
2344 if (Unit* target = GetHitUnit())
2345 target->CastSpell(nullptr, SPELL_EMPOWERING_SHADOWS, true);
2346 }
2347
2348 void Register() override
2349 {
2351 }
2352 };
2353
2354 SpellScript* GetSpellScript() const override
2355 {
2357 }
2358};
2359
2360// it works, but is it scripted correctly? why is it aura with 2500ms duration?
2361// 64132 - Constrictor Tentacle
2363{
2364 public:
2365 spell_yogg_saron_constrictor_tentacle() : SpellScriptLoader("spell_yogg_saron_constrictor_tentacle") { }
2366
2368 {
2369 bool Validate(SpellInfo const* /*spellInfo*/) override
2370 {
2372 }
2373
2374 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2375 {
2377 }
2378
2379 void Register() override
2380 {
2382 }
2383 };
2384
2385 AuraScript* GetAuraScript() const override
2386 {
2388 }
2389};
2390
2391// 64131 - Lunge
2393{
2394 public:
2395 spell_yogg_saron_lunge() : SpellScriptLoader("spell_yogg_saron_lunge") { }
2396
2398 {
2399 bool Validate(SpellInfo const* /*spellInfo*/) override
2400 {
2402 }
2403
2404 void HandleScript(SpellEffIndex /*effIndex*/)
2405 {
2406 if (Unit* target = GetHitUnit())
2407 {
2408 if (target->GetMap()->Is25ManRaid())
2409 target->CastSpell(target, SPELL_SQUEEZE_25, true);
2410 else
2411 target->CastSpell(target, SPELL_SQUEEZE_10, true);
2412
2413 target->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
2414 }
2415 }
2416
2417 void Register() override
2418 {
2420 }
2421 };
2422
2423 SpellScript* GetSpellScript() const override
2424 {
2426 }
2427};
2428
2429// 64125, 64126 - Squeeze
2430class spell_yogg_saron_squeeze : public SpellScriptLoader // 64125, 64126
2431{
2432 public:
2433 spell_yogg_saron_squeeze() : SpellScriptLoader("spell_yogg_saron_squeeze") { }
2434
2436 {
2437 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2438 {
2439 if (Unit* vehicle = GetTarget()->GetVehicleBase())
2440 if (vehicle->IsAlive())
2441 vehicle->KillSelf(); // should tentacle die or just release its target?
2442 }
2443
2444 void Register() override
2445 {
2447 }
2448 };
2449
2450 AuraScript* GetAuraScript() const override
2451 {
2453 }
2454};
2455
2456// 64148 - Diminsh Power
2458{
2459 public:
2460 spell_yogg_saron_diminsh_power() : SpellScriptLoader("spell_yogg_saron_diminsh_power") { }
2461
2463 {
2464 void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
2465 {
2467 if (Spell* spell = GetTarget()->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
2468 if (spell->getState() == SPELL_STATE_CASTING)
2470 }
2471
2472 void Register() override
2473 {
2475 }
2476 };
2477
2478 AuraScript* GetAuraScript() const override
2479 {
2481 }
2482};
2483
2484// not sure about SPELL_WEAKENED part, where should it be handled?
2485// 64161 - Empowered
2487{
2488 public:
2489 spell_yogg_saron_empowered() : SpellScriptLoader("spell_yogg_saron_empowered") { }
2490
2492 {
2493 bool Validate(SpellInfo const* /*spellInfo*/) override
2494 {
2496 }
2497
2498 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2499 {
2503 }
2504
2505 void OnPeriodic(AuraEffect const* /*aurEff*/)
2506 {
2507 Unit* target = GetTarget();
2508 float stack = std::ceil((target->GetHealthPct() / 10) - 1);
2510
2511 if (stack)
2512 {
2516 target->CastSpell(target, SPELL_EMPOWERED_BUFF, args);
2517 }
2518 else if (!target->HealthAbovePct(1) && !target->HasAura(SPELL_WEAKENED))
2519 target->CastSpell(target, SPELL_WEAKENED, true);
2520 }
2521
2522 void Register() override
2523 {
2526 }
2527 };
2528
2529 AuraScript* GetAuraScript() const override
2530 {
2532 }
2533};
2534
2535// 64069 - Match Health
2537{
2538 public:
2539 spell_yogg_saron_match_health() : SpellScriptLoader("spell_yogg_saron_match_health") { }
2540
2542 {
2543 void HandleScript(SpellEffIndex /*effIndex*/)
2544 {
2545 if (Unit* target = GetHitUnit())
2546 target->SetHealth(target->CountPctFromMaxHealth((int32)GetCaster()->GetHealthPct()));
2547 }
2548
2549 void Register() override
2550 {
2552 }
2553 };
2554
2555 SpellScript* GetSpellScript() const override
2556 {
2558 }
2559};
2560
2561// 65238 - Shattered Illusion
2563{
2564 public:
2565 spell_yogg_saron_shattered_illusion() : SpellScriptLoader("spell_yogg_saron_shattered_illusion") { }
2566
2568 {
2569 void HandleScript(SpellEffIndex /*effIndex*/)
2570 {
2571 if (Unit* target = GetHitUnit())
2572 target->RemoveAurasDueToSpell(uint32(GetEffectValue()));
2573 }
2574
2575 void Register() override
2576 {
2578 }
2579 };
2580
2581 SpellScript* GetSpellScript() const override
2582 {
2584 }
2585};
2586
2587// 63882 - Death Ray Warning Visual
2589{
2590 public:
2591 spell_yogg_saron_death_ray_warning_visual() : SpellScriptLoader("spell_yogg_saron_death_ray_warning_visual") { }
2592
2594 {
2595 bool Validate(SpellInfo const* /*spellInfo*/) override
2596 {
2598 }
2599
2600 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2601 {
2602 if (Unit* caster = GetCaster())
2603 {
2604 caster->CastSpell(caster, SPELL_DEATH_RAY_PERIODIC, true);
2605 caster->CastSpell(nullptr, SPELL_DEATH_RAY_DAMAGE_VISUAL, true);
2606 // TODO: set better movement
2607 caster->GetMotionMaster()->MoveConfused();
2608 }
2609 }
2610
2611 void Register() override
2612 {
2614 }
2615 };
2616
2617 AuraScript* GetAuraScript() const override
2618 {
2620 }
2621};
2622
2623// 63993 - Cancel Illusion Room Aura
2625{
2626 public:
2627 spell_yogg_saron_cancel_illusion_room_aura() : SpellScriptLoader("spell_yogg_saron_cancel_illusion_room_aura") { }
2628
2630 {
2631 bool Validate(SpellInfo const* /*spellInfo*/) override
2632 {
2634 }
2635
2636 void HandleScript(SpellEffIndex /*effIndex*/)
2637 {
2638 if (Unit* target = GetHitUnit())
2639 {
2640 target->CastSpell(target, SPELL_TELEPORT_BACK_TO_MAIN_ROOM);
2641 target->RemoveAurasDueToSpell(uint32(GetEffectValue()));
2642 }
2643 }
2644
2645 void Register() override
2646 {
2648 }
2649 };
2650
2651 SpellScript* GetSpellScript() const override
2652 {
2654 }
2655};
2656
2657// 64010, 64013 - Nondescript
2659{
2660 public:
2661 spell_yogg_saron_nondescript() : SpellScriptLoader("spell_yogg_saron_nondescript") { }
2662
2664 {
2665 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
2666 {
2667 GetTarget()->CastSpell(GetTarget(), uint32(aurEff->GetAmount()), true);
2668 }
2669
2670 void Register() override
2671 {
2673 }
2674 };
2675
2676 AuraScript* GetAuraScript() const override
2677 {
2679 }
2680};
2681
2682// 64012 - Revealed Tentacle
2684{
2685 public:
2686 spell_yogg_saron_revealed_tentacle() : SpellScriptLoader("spell_yogg_saron_revealed_tentacle") { }
2687
2689 {
2690 bool Validate(SpellInfo const* /*spellInfo*/) override
2691 {
2693 }
2694
2695 void HandleScript(SpellEffIndex /*effIndex*/)
2696 {
2697 if (Creature* caster = GetCaster()->ToCreature())
2698 {
2699 caster->CastSpell(caster, SPELL_TENTACLE_VOID_ZONE, true);
2700 caster->CastSpell(caster, SPELL_GRIM_REPRISAL, true);
2701 caster->UpdateEntry(NPC_INFLUENCE_TENTACLE, caster->GetCreatureData());
2702 }
2703 }
2704
2705 void Register() override
2706 {
2708 }
2709 };
2710
2711 SpellScript* GetSpellScript() const override
2712 {
2714 }
2715};
2716
2717// 63305 - Grim Reprisal
2719{
2720 public:
2721 spell_yogg_saron_grim_reprisal() : SpellScriptLoader("spell_yogg_saron_grim_reprisal") { }
2722
2724 {
2725 bool Validate(SpellInfo const* /*spellInfo*/) override
2726 {
2728 }
2729
2730 void HandleProc(AuraEffect* aurEff, ProcEventInfo& eventInfo)
2731 {
2733 DamageInfo* damageInfo = eventInfo.GetDamageInfo();
2734 if (!damageInfo || !damageInfo->GetDamage())
2735 return;
2736
2737 CastSpellExtraArgs args(aurEff);
2738 args.AddSpellBP0(CalculatePct(damageInfo->GetDamage(), 60));
2740 }
2741
2742 void Register() override
2743 {
2745 }
2746 };
2747
2748 AuraScript* GetAuraScript() const override
2749 {
2751 }
2752};
2753
2754// 64059 - Induce Madness
2756{
2757 public:
2758 spell_yogg_saron_induce_madness() : SpellScriptLoader("spell_yogg_saron_induce_madness") { }
2759
2761 {
2762 bool Validate(SpellInfo const* /*spellInfo*/) override
2763 {
2765 }
2766
2767 void HandleScript(SpellEffIndex /*effIndex*/)
2768 {
2769 if (Unit* target = GetHitUnit())
2770 {
2771 target->CastSpell(target, SPELL_TELEPORT_BACK_TO_MAIN_ROOM);
2772 target->RemoveAurasDueToSpell(SPELL_SANITY, ObjectGuid::Empty, 0, AURA_REMOVE_BY_ENEMY_SPELL);
2773 target->RemoveAurasDueToSpell(uint32(GetEffectValue()));
2774 }
2775 }
2776
2778 {
2780
2781 if (InstanceScript* instance = GetCaster()->GetInstanceScript())
2782 if (Creature* voice = instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
2783 voice->AI()->DoAction(ACTION_TOGGLE_SHATTERED_ILLUSION);
2784 }
2785
2786 void Register() override
2787 {
2790 }
2791 };
2792
2793 SpellScript* GetSpellScript() const override
2794 {
2796 }
2797};
2798
2799// 63050 - Sanity
2801{
2802 public:
2803 spell_yogg_saron_sanity() : SpellScriptLoader("spell_yogg_saron_sanity") { }
2804
2806 {
2807 // don't target players outside of room or handle it in SPELL_INSANE_PERIODIC?
2808
2810 {
2812 }
2813
2814 void Register() override
2815 {
2817 }
2818 };
2819
2821 {
2822 bool Validate(SpellInfo const* /*spellInfo*/) override
2823 {
2825 }
2826
2827 void DummyTick(AuraEffect const* /*aurEff*/)
2828 {
2830 ModStackAmount(20);
2831
2834 }
2835
2836 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2837 {
2838 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
2839 return;
2840
2841 if (InstanceScript* instance = GetTarget()->GetInstanceScript())
2842 instance->SetData(DATA_DRIVE_ME_CRAZY, uint32(false));
2843
2845
2846 if (Unit* caster = GetCaster())
2847 caster->CastSpell(GetTarget(), SPELL_INSANE, true);
2848 }
2849
2850 void Register() override
2851 {
2854 }
2855 };
2856
2857 SpellScript* GetSpellScript() const override
2858 {
2860 }
2861
2862 AuraScript* GetAuraScript() const override
2863 {
2865 }
2866};
2867
2868// 63120 - Insane
2870{
2871 public:
2872 spell_yogg_saron_insane() : SpellScriptLoader("spell_yogg_saron_insane") { }
2873
2875 {
2876 bool Validate(SpellInfo const* /*spellInfo*/) override
2877 {
2879 }
2880
2881 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2882 {
2883 if (Unit* caster = GetCaster())
2884 if (Creature* yogg = caster->ToCreature())
2885 yogg->AI()->Talk(WHISPER_VOICE_INSANE, GetTarget());
2886
2888 }
2889
2890 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2891 {
2892 if (GetTarget()->IsAlive())
2893 GetTarget()->KillSelf();
2894 }
2895
2896 void Register() override
2897 {
2900 }
2901 };
2902
2903 AuraScript* GetAuraScript() const override
2904 {
2906 }
2907};
2908
2909// 64555 - Insane Periodic
2911{
2912 public:
2913 spell_yogg_saron_insane_periodic() : SpellScriptLoader("spell_yogg_saron_insane_periodic") { }
2914
2916 {
2917 void HandleScript(SpellEffIndex /*effIndex*/)
2918 {
2919 if (Unit* target = GetHitUnit())
2920 GetCaster()->CastSpell(target, uint32(GetEffectValue()), true);
2921 }
2922
2923 void Register() override
2924 {
2926 }
2927 };
2928
2929 SpellScript* GetSpellScript() const override
2930 {
2932 }
2933};
2934
2936{
2937 public:
2939
2941 {
2942 return !object->HasInArc(static_cast<float>(M_PI), _caster);
2943 }
2944
2945 private:
2947};
2948
2949// 64164, 64168 - Lunatic Gaze
2951{
2952 public:
2953 spell_yogg_saron_lunatic_gaze() : SpellScriptLoader("spell_yogg_saron_lunatic_gaze") { }
2954
2956 {
2957 bool Load() override
2958 {
2960 return true;
2961 }
2962
2963 void FilterTargets(std::list<WorldObject*>& targets)
2964 {
2965 targets.remove_if(LunaticGazeTargetSelector(GetCaster()));
2966 }
2967
2968 void Register() override
2969 {
2973 }
2974 };
2975
2976 SpellScript* GetSpellScript() const override
2977 {
2979 }
2980};
2981
2982/* 62650 - Fortitude of Frost
2983 62670 - Resilience of Nature
2984 62671 - Speed of Invention
2985 62702 - Fury of the Storm */
2986class spell_yogg_saron_keeper_aura : public SpellScriptLoader // 62650, 62670, 62671, 62702
2987{
2988 public:
2989 spell_yogg_saron_keeper_aura() : SpellScriptLoader("spell_yogg_saron_keeper_aura") { }
2990
2992 {
2993 bool CanApply(Unit* target)
2994 {
2995 if (target->GetTypeId() != TYPEID_PLAYER && target != GetCaster())
2996 return false;
2997 return true;
2998 }
2999
3000 void Register() override
3001 {
3003 }
3004 };
3005
3006 AuraScript* GetAuraScript() const override
3007 {
3009 }
3010};
3011
3012// 64184 - In the Maws of the Old God
3014{
3015 public:
3016 spell_yogg_saron_in_the_maws_of_the_old_god() : SpellScriptLoader("spell_yogg_saron_in_the_maws_of_the_old_god") { }
3017
3019 {
3021 {
3022 if (InstanceScript* instance = GetCaster()->GetInstanceScript())
3023 {
3024 if (Creature* yogg = instance->GetCreature(DATA_YOGG_SARON))
3025 {
3026 if (yogg->FindCurrentSpellBySpellId(SPELL_DEAFENING_ROAR))
3027 {
3028 if (GetCaster()->GetDistance(yogg) > 20.0f)
3030 else
3031 return SPELL_CAST_OK;
3032 }
3033 }
3034 }
3035
3037 }
3038
3039 void Register() override
3040 {
3042 }
3043 };
3044
3045 SpellScript* GetSpellScript() const override
3046 {
3048 }
3049};
3050
3051// 64172 - Titanic Storm
3053{
3054 public:
3055 spell_yogg_saron_titanic_storm() : SpellScriptLoader("spell_yogg_saron_titanic_storm") { }
3056
3058 {
3059 void HandleScript(SpellEffIndex /*effIndex*/)
3060 {
3061 if (Unit* target = GetHitUnit())
3062 Unit::Kill(GetCaster(), target);
3063 }
3064
3065 void Register() override
3066 {
3068 }
3069 };
3070
3071 SpellScript* GetSpellScript() const override
3072 {
3074 }
3075};
3076
3077// 64174 - Hodir's Protective Gaze
3079{
3080 public:
3081 spell_yogg_saron_hodirs_protective_gaze() : SpellScriptLoader("spell_yogg_saron_hodirs_protective_gaze") { }
3082
3084 {
3085 bool Validate(SpellInfo const* /*spellInfo*/) override
3086 {
3088 }
3089
3090 bool CanApply(Unit* target)
3091 {
3092 if (target->GetTypeId() != TYPEID_PLAYER && target != GetCaster())
3093 return false;
3094 return true;
3095 }
3096
3097 void OnAbsorb(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& absorbAmount)
3098 {
3099 if (dmgInfo.GetDamage() >= GetTarget()->GetHealth())
3100 {
3101 absorbAmount = dmgInfo.GetDamage();
3102 // or absorbAmount = dmgInfo.GetDamage() - GetTarget()->GetHealth() + 1
3104 }
3105 else
3107 }
3108
3109 void Register() override
3110 {
3113 }
3114 };
3115
3116 AuraScript* GetAuraScript() const override
3117 {
3119 }
3120};
3121
3123{
3125 new boss_sara();
3126 new boss_yogg_saron();
3128 new npc_ominous_cloud();
3139 new npc_garona();
3140 new npc_turned_champion();
3141 new npc_laughing_skull();
3172}
Actions
#define M_PI
Definition: Common.h:115
First const & RAND(First const &first, Second const &second, Rest const &... rest)
#define sCreatureTextMgr
@ TEXT_RANGE_AREA
uint8_t uint8
Definition: Define.h:145
int8_t int8
Definition: Define.h:141
int32_t int32
Definition: Define.h:139
uint64_t uint64
Definition: Define.h:142
uint32_t uint32
Definition: Define.h:143
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
@ IN_PROGRESS
@ POINT_MOTION_TYPE
@ TEMPSUMMON_TIMED_DESPAWN
Definition: ObjectDefines.h:65
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
Spells
Definition: PlayerAI.cpp:32
float frand(float min, float max)
Definition: Random.cpp:55
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
bool roll_chance_i(int chance)
Definition: Random.h:59
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_1
Definition: SharedDefines.h:31
@ EFFECT_0
Definition: SharedDefines.h:30
@ EFFECT_2
Definition: SharedDefines.h:32
@ LANG_ADDON
@ TARGET_UNIT_SRC_AREA_ENEMY
@ EMOTE_ONESHOT_EMERGE
@ EMOTE_ONESHOT_SALUTE
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ LOOT_MODE_HARD_MODE_3
Definition: SharedDefines.h:80
@ LOOT_MODE_HARD_MODE_1
Definition: SharedDefines.h:78
@ LOOT_MODE_HARD_MODE_2
Definition: SharedDefines.h:79
@ LOOT_MODE_HARD_MODE_4
Definition: SharedDefines.h:81
SpellCastResult
@ SPELL_FAILED_OUT_OF_RANGE
@ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW
@ SPELL_CAST_OK
@ FACTION_MONSTER_2
@ FACTION_FRIENDLY
@ CHAT_MSG_ADDON
@ CHAT_MSG_MONSTER_YELL
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ AURA_REMOVE_BY_DEATH
@ AURA_REMOVE_BY_EXPIRE
@ AURA_REMOVE_BY_ENEMY_SPELL
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ SPELL_AURA_MOD_FEAR
@ SPELL_AURA_DUMMY
@ SPELL_AURA_AOE_CHARM
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ SPELL_AURA_MOD_STUN
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:231
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:230
#define SpellCheckCastFn(F)
Definition: SpellScript.h:830
#define AuraEffectProcFn(F, I, N)
Definition: SpellScript.h:2160
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define SpellObjectAreaTargetSelectFn(F, I, N)
Definition: SpellScript.h:864
#define AuraEffectPeriodicFn(F, I, N)
Definition: SpellScript.h:2046
#define SpellCastFn(F)
Definition: SpellScript.h:825
#define AuraEffectAbsorbFn(F, I)
Definition: SpellScript.h:2090
#define AuraEffectApplyFn(F, I, N, M)
Definition: SpellScript.h:2029
#define AuraCheckAreaTargetFn(F)
Definition: SpellScript.h:2008
#define AuraEffectRemoveFn(F, I, N, M)
Definition: SpellScript.h:2040
@ SPELL_STATE_CASTING
Definition: Spell.h:235
EvadeReason
Definition: UnitAICommon.h:30
#define CAST_AI(a, b)
Definition: UnitAI.h:28
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
@ UNIT_NPC_FLAG_GOSSIP
Definition: UnitDefines.h:297
DamageEffectType
Definition: UnitDefines.h:131
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:586
@ UNIT_STATE_CASTING
Definition: Unit.h:265
T CalculatePct(T base, U pct)
Definition: Util.h:72
MiscData
Yells
@ EVENT_GROUP_SUMMON_TENTACLES
@ SOUND_LUNATIC_GAZE
@ ACHIEV_TIMED_START_EVENT
@ MAX_ILLUSION_ROOMS
@ ACTION_TOGGLE_SHATTERED_ILLUSION
@ ACTION_PHASE_TRANSFORM
@ ACTION_TENTACLE_KILLED
@ ACTION_PHASE_THREE
@ ACTION_FLASH_FREEZE
@ ACTION_START_ROLEPLAY
@ ACTION_SANITY_WELLS
@ ACTION_PHASE_TWO
@ ACTION_INDUCE_MADNESS
Position const ObservationRingKeepersPos[4]
@ EMOTE_BRAIN_ILLUSION_SHATTERED
@ SAY_STORMWIND_ROLEPLAY_6
@ SAY_SARA_DEATH_RAY
@ WHISPER_VOICE_INSANE
@ SAY_ICECROWN_ROLEPLAY_6
@ EMOTE_YOGG_SARON_EXTINGUISH_ALL_LIFE
@ SAY_YOGG_SARON_MADNESS
@ SAY_CHAMBER_ROLEPLAY_3
@ SAY_CHAMBER_ROLEPLAY_2
@ SAY_SARA_FERVOR_HIT
@ SAY_YOGG_SARON_DEATH
@ SAY_SARA_ULDUAR_SCREAM_1
@ SAY_ICECROWN_ROLEPLAY_3
@ SAY_SARA_ULDUAR_SCREAM_2
@ SAY_CHAMBER_ROLEPLAY_4
@ SAY_STORMWIND_ROLEPLAY_3
@ SAY_CHAMBER_ROLEPLAY_5
@ SAY_STORMWIND_ROLEPLAY_1
@ SAY_SARA_PSYCHOSIS_HIT
@ SAY_YOGG_SARON_SPAWN
@ SAY_SARA_TRANSFORM_2
@ SAY_STORMWIND_ROLEPLAY_5
@ SAY_SARA_BLESSING_HIT
@ EMOTE_OMINOUS_CLOUD_PLAYER_TOUCH
@ EMOTE_YOGG_SARON_MADNESS
@ SAY_STORMWIND_ROLEPLAY_4
@ SAY_SARA_TRANSFORM_1
@ SAY_ICECROWN_ROLEPLAY_5
@ SAY_SARA_TRANSFORM_3
@ SAY_STORMWIND_ROLEPLAY_7
@ EMOTE_YOGG_SARON_EMPOWERING_SHADOWS
@ SAY_ICECROWN_ROLEPLAY_2
@ SAY_YOGG_SARON_DEAFENING_ROAR
@ SAY_CHAMBER_ROLEPLAY_1
@ SAY_ICECROWN_ROLEPLAY_4
@ SAY_KEEPER_CHOSEN_1
@ SAY_YOGG_SARON_PHASE_3
@ SAY_ICECROWN_ROLEPLAY_1
@ SAY_STORMWIND_ROLEPLAY_2
@ EMOTE_YOGG_SARON_DEAFENING_ROAR
@ SAY_SARA_AGGRO
@ SAY_SARA_KILL
@ WHISPER_VOICE_PHASE_1_WIPE
@ SAY_KEEPER_CHOSEN_2
@ SAY_SARA_TRANSFORM_4
Position const IllusionsMiscPos[2]
Position const YoggSaronSpawnPos
@ SPELL_TELEPORT_BACK_TO_MAIN_ROOM
@ SPELL_TELEPORT_PORTAL_VISUAL
@ SPELL_BRAIN_LINK_DAMAGE
@ SPELL_NONDESCRIPT_1
@ SPELL_PSYCHOSIS
@ SPELL_SPEED_OF_INVENTION
@ SPELL_SANITY
@ SPELL_DIMINSH_POWER
@ SPELL_LOW_SANITY_SCREEN_EFFECT
@ SPELL_DEATH_RAY_ORIGIN_VISUAL
@ SPELL_SANITY_WELL_VISUAL
@ SPELL_MATCH_HEALTH_2
@ SPELL_WEAKENED
@ SPELL_TITANIC_STORM
@ SPELL_NONDESCRIPT_2
@ SPELL_SANITY_WELL
@ SPELL_TENTACLE_VOID_ZONE
@ SPELL_DEATH_RAY_DAMAGE_VISUAL
@ SPELL_BRAIN_LINK_NO_DAMAGE
@ SPELL_KEEPER_ACTIVE
@ SPELL_DARK_VOLLEY
@ SPELL_ERUPT
@ SPELL_SHADOWY_BARRIER_YOGG
@ SPELL_SARAS_BLESSING
@ SPELL_EMPOWERED
@ SPELL_DEATH_RAY_PERIODIC
@ SPELL_LUNGE
@ SPELL_EMPOWERED_BUFF
@ SPELL_MALADY_OF_THE_MIND_JUMP
@ SPELL_SHATTERED_ILLUSION_REMOVE
@ SPELL_SQUEEZE_10
@ SPELL_PHASE_2_TRANSFORM
@ SPELL_EMPOWERING_SHADOWS
@ SPELL_INSANE
@ SPELL_RESILIENCE_OF_NATURE
@ SPELL_SHADOW_NOVA_2
@ SPELL_SARAS_FERVOR_TARGET_SELECTOR
@ SPELL_DEATH_RAY
@ SPELL_SIMPLE_TELEPORT
@ SPELL_SUMMON_GUARDIAN_1
@ SPELL_FLASH_FREEZE
@ SPELL_LUNATIC_GAZE_DAMAGE
@ SPELL_TELEPORT
@ SPELL_FOCUSED_ANGER
@ SPELL_GRIM_REPRISAL
@ SPELL_VERTEX_COLOR_BLACK
@ SPELL_HODIRS_PROTECTIVE_GAZE
@ SPELL_SHADOWY_BARRIER_SARA
@ SPELL_DEATH_RAY_WARNING_VISUAL
@ SPELL_IMMORTAL_GUARDIAN
@ SPELL_CRUSHER_TENTACLE_SUMMON
@ SPELL_CURSE_OF_DOOM
@ SPELL_SIMPLE_TELEPORT_KEEPERS
@ SPELL_EXTINGUISH_ALL_LIFE
@ SPELL_RECENTLY_SPAWNED
@ SPELL_SARAS_ANGER
@ SPELL_SANITY_PERIODIC
@ SPELL_LUNATIC_GAZE_SKULL
@ SPELL_APATHY
@ SPELL_MALADY_OF_THE_MIND
@ SPELL_FLASH_FREEZE_VISUAL
@ SPELL_HATE_TO_ZERO
@ SPELL_SHATTERED_ILLUSION
@ SPELL_MATCH_HEALTH
@ SPELL_GRIM_REPRISAL_DAMAGE
@ SPELL_BRAIN_LINK
@ SPELL_CONSTRICTOR_TENTACLE_SUMMON
@ SPELL_TELEPORT_TO_ICECROWN_ILLUSION
@ SPELL_KNOCK_AWAY
@ SPELL_PHASE_3_TRANSFORM
@ SPELL_BLACK_PLAGUE
@ SPELL_FURY_OF_THE_STORM
@ SPELL_INSANE_VISUAL
@ SPELL_DRAINING_POISON
@ SPELL_TELEPORT_TO_CHAMBER_ILLUSION
@ SPELL_ILLUSION_ROOM
@ SPELL_DESTABILIZATION_MATRIX
@ SPELL_FULL_HEAL
@ SPELL_INSANE_PERIODIC
@ SPELL_LUNATIC_GAZE
@ SPELL_SUMMON_GUARDIAN_2
@ SPELL_TELEPORT_TO_STORMWIND_ILLUSION
@ SPELL_SARAS_ANGER_TARGET_SELECTOR
@ SPELL_SARAS_FERVOR
@ SPELL_BRAIN_HURT_VISUAL
@ SPELL_CORRUPTOR_TENTACLE_SUMMON
@ SPELL_SHADOW_NOVA
@ SPELL_PERMANENT_FEIGN_DEATH
@ SPELL_SANITY_WELL_SUMMON
@ SPELL_OMINOUS_CLOUD_VISUAL
@ SPELL_FORTITUDE_OF_FROST
@ SPELL_DEATHGRASP
@ SPELL_ASSASSINATE
@ SPELL_DEAFENING_ROAR
@ SPELL_CONSTRICTOR_TENTACLE
@ SPELL_RIDE_YOGG_SARON_VEHICLE
@ SPELL_IN_THE_MAWS_OF_THE_OLD_GOD
@ SPELL_INDUCE_MADNESS
@ SPELL_SARAS_BLESSING_TARGET_SELECTOR
@ SPELL_DRAIN_LIFE
@ SPELL_SQUEEZE_25
@ SPELL_DIMINISH_POWER
@ SPELL_SHADOW_BEACON
@ SPELL_TENTACLE_VOID_ZONE_2
@ SPELL_CRUSH
@ PHASE_ONE
@ PHASE_THREE
@ PHASE_TRANSFORM
@ PHASE_TWO
uint32 const IllusionSpells[MAX_ILLUSION_ROOMS]
Position const YSKeepersPos[4]
boss_sara::boss_saraAI SaraAI
CreatureGroups
@ CREATURE_GROUP_PORTALS_25
@ CREATURE_GROUP_CLOUDS
@ CREATURE_GROUP_PORTALS_10
void AddSC_boss_yogg_saron()
@ EVENT_CHAMBER_ROLEPLAY_2
@ EVENT_DEATH_RAY
@ EVENT_CHAMBER_ROLEPLAY_3
@ EVENT_SHADOW_BEACON
@ EVENT_DRAIN_LIFE
@ EVENT_MALADY_OF_THE_MIND
@ EVENT_ICECROWN_ROLEPLAY_4
@ EVENT_PSYCHOSIS
@ EVENT_SUMMON_IMMORTAL_GUARDIAN
@ EVENT_TRANSFORM_2
@ EVENT_YELL_BOW_DOWN
@ EVENT_ICECROWN_ROLEPLAY_6
@ EVENT_LOCK_DOOR
@ EVENT_TRANSFORM_4
@ EVENT_SARAS_ANGER
@ EVENT_ICECROWN_ROLEPLAY_1
@ EVENT_SUMMON_CRUSHER_TENTACLE
@ EVENT_DESTABILIZATION_MATRIX
@ EVENT_CAST_RANDOM_SPELL
@ EVENT_ICECROWN_ROLEPLAY_2
@ EVENT_STORMWIND_ROLEPLAY_4
@ EVENT_STORMWIND_ROLEPLAY_7
@ EVENT_HODIRS_PROTECTIVE_GAZE
@ EVENT_SARAS_BLESSING
@ EVENT_ICECROWN_ROLEPLAY_3
@ EVENT_SUMMON_CORRUPTOR_TENTACLE
@ EVENT_CHAMBER_ROLEPLAY_4
@ EVENT_DARK_VOLLEY
@ EVENT_EXTINGUISH_ALL_LIFE
@ EVENT_STORMWIND_ROLEPLAY_6
@ EVENT_BRAIN_LINK
@ EVENT_CHAMBER_ROLEPLAY_1
@ EVENT_SARAS_FERVOR
@ EVENT_CHAMBER_ROLEPLAY_5
@ EVENT_ICECROWN_ROLEPLAY_5
@ EVENT_DIMINISH_POWER
@ EVENT_STORMWIND_ROLEPLAY_5
@ EVENT_STORMWIND_ROLEPLAY_2
@ EVENT_ILLUSION
@ EVENT_TRANSFORM_1
@ EVENT_TRANSFORM_3
@ EVENT_LUNATIC_GAZE
@ EVENT_SUMMON_CONSTRICTOR_TENTACLE
@ EVENT_SUMMON_GUARDIAN_OF_YOGG_SARON
@ EVENT_STORMWIND_ROLEPLAY_3
@ EVENT_DEAFENING_ROAR
@ EVENT_STORMWIND_ROLEPLAY_1
@ NPC_THE_LICH_KING
Definition: chapter5.cpp:162
int32 GetAmount() const
void PreventDefaultAction()
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
Definition: SpellScript.h:2039
HookList< EffectPeriodicHandler > OnEffectPeriodic
Definition: SpellScript.h:2045
HookList< EffectApplyHandler > AfterEffectApply
Definition: SpellScript.h:2028
Unit * GetCaster() const
HookList< EffectAbsorbHandler > OnEffectAbsorb
Definition: SpellScript.h:2089
HookList< CheckAreaTargetHandler > DoCheckAreaTarget
Definition: SpellScript.h:2007
Unit * GetTarget() const
HookList< EffectApplyHandler > OnEffectRemove
Definition: SpellScript.h:2035
HookList< EffectProcHandler > OnEffectProc
Definition: SpellScript.h:2155
uint8 GetStackAmount() const
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
InstanceScript *const instance
void JustSummoned(Creature *summon) override
SummonList summons
EventMap events
void _JustDied()
bool HasPvECombatWithPlayers() const
void DoZoneInCombat()
Definition: CreatureAI.h:161
bool IsEngaged() const
Definition: CreatureAI.h:77
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:219
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
void EngagementStart(Unit *who)
Definition: CreatureAI.cpp:275
Creature *const me
Definition: CreatureAI.h:61
static void SendSound(Creature *source, uint32 sound, ChatMsg msgType, WorldObject const *whisperTarget=nullptr, CreatureTextRange range=TEXT_RANGE_NORMAL, Team team=TEAM_OTHER, bool gmOnly=false, uint32 keyBroadcastTextId=0, SoundKitPlayType playType=SoundKitPlayType::Normal)
void ResetLootMode()
Definition: Creature.h:270
void SetImmuneToPC(bool apply) override
Definition: Creature.h:150
void SetReactState(ReactStates st)
Definition: Creature.h:140
void ResetPlayerDamageReq()
Definition: Creature.h:362
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2422
void AddLootMode(uint16 lootMode)
Definition: Creature.h:268
bool IsInEvadeMode() const
Definition: Creature.h:179
CreatureAI * AI() const
Definition: Creature.h:187
Unit * GetAttacker() const
Definition: Unit.h:435
uint32 GetDamage() const
Definition: Unit.h:441
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void DelayEvents(Milliseconds delay)
Definition: EventMap.cpp:96
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
bool IsInPhase(uint8 phase) const
Definition: EventMap.h:217
void SetPhase(uint8 phase)
Definition: EventMap.cpp:28
void Reset()
Definition: EventMap.cpp:21
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
Milliseconds CalculateTime(Milliseconds t_offset) const
bool operator()(WorldObject *object)
virtual bool SetBossState(uint32 id, EncounterState state)
Creature * GetCreature(uint32 type)
void HandleGameObject(ObjectGuid guid, bool open, GameObject *go=nullptr)
virtual ObjectGuid GetGuidData(uint32 type) const override
void TriggerGameEvent(uint32 gameEventId, WorldObject *source=nullptr, WorldObject *target=nullptr) override
bool operator()(WorldObject *object)
LunaticGazeTargetSelector(Unit *caster)
iterator end()
Definition: MapRefManager.h:35
iterator begin()
Definition: MapRefManager.h:34
bool Is25ManRaid() const
Definition: Map.cpp:3287
float GetHeight(PhaseShift const &phaseShift, float x, float y, float z, bool vmap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH)
Definition: Map.h:289
PlayerList const & GetPlayers() const
Definition: Map.h:363
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount, Optional< Milliseconds > duration={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default)
static ObjectGuid const Empty
Definition: ObjectGuid.h:272
static Creature * ToCreature(Object *o)
Definition: Object.h:206
static Unit * ToUnit(Object *o)
Definition: Object.h:212
TypeID GetTypeId() const
Definition: Object.h:172
uint32 GetEntry() const
Definition: Object.h:160
static Player * ToPlayer(Object *o)
Definition: Object.h:200
bool IsGameMaster() const
Definition: Player.h:1178
DamageInfo * GetDamageInfo() const
Definition: Unit.h:500
SanityReduction(uint8 stacks)
void RemoveSanity(SpellEffIndex)
uint32 const Id
Definition: SpellInfo.h:325
uint32 m_scriptSpellId
Definition: SpellScript.h:134
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
HookList< CastHandler > AfterCast
Definition: SpellScript.h:824
HookList< CheckCastHandler > OnCheckCast
Definition: SpellScript.h:829
Unit * GetCaster() const
Unit * GetHitUnit() const
int32 GetEffectValue() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
HookList< CastHandler > BeforeCast
Definition: SpellScript.h:820
Spell * GetSpell() const
Definition: SpellScript.h:987
SpellInfo const * GetSpellInfo() const
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:863
Definition: Spell.h:254
void SetSpellValue(SpellValueMod mod, int32 value)
Definition: Spell.cpp:8564
StartAttackEvent(Creature *summoner, Creature *owner)
ObjectGuid _summonerGuid
bool Execute(uint64, uint32) override
void Despawn(Creature const *summon)
void DespawnEntry(uint32 entry)
void Summon(Creature const *summon)
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:79
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:29
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:622
bool HealthAbovePct(int32 pct) const
Definition: Unit.h:777
float GetHealthPct() const
Definition: Unit.h:779
void SetFaction(uint32 faction) override
Definition: Unit.h:854
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:3086
MotionMaster * GetMotionMaster()
Definition: Unit.h:1637
void RemoveNpcFlag(NPCFlags flags)
Definition: Unit.h:978
UnitAI * GetAI() const
Definition: Unit.h:655
void SetUninteractible(bool apply)
Definition: Unit.cpp:8120
uint64 GetHealth() const
Definition: Unit.h:771
bool SetWalk(bool enable)
Definition: Unit.cpp:12620
uint64 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:780
bool HasUnitState(const uint32 f) const
Definition: Unit.h:727
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4645
void RemoveAllAuras()
Definition: Unit.cpp:4223
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition: Unit.cpp:1596
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition: Unit.h:776
CombatManager & GetCombatManager()
Definition: Unit.h:1018
void KillSelf(bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition: Unit.h:916
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3812
static void Kill(Unit *attacker, Unit *victim, bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition: Unit.cpp:10525
bool IsInCombat() const
Definition: Unit.h:1038
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true)
Definition: Unit.cpp:3014
Map * GetMap() const
Definition: Object.h:604
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2884
TempSummon * SummonCreature(