Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_yogg_saron.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "ScriptMgr.h"
7#include "ScriptedCreature.h"
8#include "PassiveAI.h"
9#include "SpellScript.h"
10#include "SpellAuraEffects.h"
11#include "MoveSplineInit.h"
12#include "CreatureTextMgr.h"
13#include "ulduar.h"
14
16{
17 // Sara
18 SAY_SARA_ULDUAR_SCREAM_1 = 0, // screams randomly in a whole instance, unused on retail
19 SAY_SARA_ULDUAR_SCREAM_2 = 1, // screams randomly in a whole instance, unused on retail
30
31 // Yogg-Saron
41
42 // Voice of Yogg-Saron
45
46 // Brain of Yogg-Saron
48
49 // Ominous Cloud
51
52 // Keepers
55
56 // Yogg-Saron illusions
62
63 // Neltharion
66
67 // Ysera
69
70 // Malygos
72
73 // Immolated Champion
76
77 // The Lich King
80
81 // Garona
86
87 // King Llane
89};
90
92{
93 // Voice of Yogg-Saron
96 SPELL_SANITY = 63050,
98 SPELL_INSANE = 63120,
99 //SPELL_CLEAR_INSANE = 63122, // when it should be casted?
104
105 // Sara
119 SPELL_BRAIN_LINK_DAMAGE = 63803, // red beam
120 SPELL_BRAIN_LINK_NO_DAMAGE = 63804, // yellow beam
122
123 // Ominous Cloud
126
127 // Guardian of Yogg-Saron
131
132 // Yogg-Saron
141
142 // Brain of Yogg-Saron
149
150 // Tentacles
151 SPELL_ERUPT = 64144,
152 SPELL_TENTACLE_VOID_ZONE = 64017, // used by Corruptor Tentacle and Crusher Tentacle only
153
154 // Crusher Tentacle
158 SPELL_CRUSH = 64146,
159 //SPELL_CRUSH_2 = 65201, // triggered by SPELL_CRUSH, basepoints of SPELL_MALADY_OF_THE_MIND
160
161 // Constrictor Tentacle
163 SPELL_LUNGE = 64131,
164
165 // Corruptor Tentacle
170
171 // Immortal Guardian
179
180 // Keepers at Observation Ring
182
183 // Keepers
186
187 // Mimiron
190
191 // Freya
194
195 // Sanity Well
198
199 // Thorim
202
203 // Hodir
207
208 // Death Orb
210
211 // Death Ray
215
216 // Laughing Skull
218
219 // Descend Into Madness
221
222 // Illusions
225
226 // Suit of Armor
228
229 // Dragon Consorts & Deathsworn Zealot
231
232 // Garona
234
235 // King Llane
237
238 // The Lich King
240
241 // Turned Champion
243
244 // Player self cast spells
254
256};
257
265
267{
268 // Voice of Yogg-Saron
276 EVENT_EXTINGUISH_ALL_LIFE = 8, // handled by Voice, timer starts at the beginning of the fight (Yogg-Saron is not spawned at this moment)
277
278 // Sara
290
291 // Tentacles
294
295 // Yogg-Saron
299 EVENT_DEAFENING_ROAR = 25, // only on 25-man with 0-3 keepers active (Hard Mode)
300
301 // Guardian of Yogg-Saron
303
304 // Immortal Guardian
306
307 // Keepers
310
311 // Chamber Illusion
317
318 // Icecrown Illusion
325
326 // Stormwind Illusion
334};
335
340
353
360
361Position const YoggSaronSpawnPos = {1980.43f, -25.7708f, 324.9724f, 3.141593f};
363{
364 {1945.682f, 33.34201f, 411.4408f, 5.270895f}, // Freya
365 {1945.761f, -81.52171f, 411.4407f, 1.029744f}, // Hodir
366 {2028.822f, -65.73573f, 411.4426f, 2.460914f}, // Thorim
367 {2028.766f, 17.42014f, 411.4446f, 3.857178f}, // Mimiron
368};
370{
371 {2036.873f, 25.42513f, 338.4984f, 3.909538f}, // Freya
372 {1939.045f, -90.87457f, 338.5426f, 0.994837f}, // Hodir
373 {1939.148f, 42.49035f, 338.5427f, 5.235988f}, // Thorim
374 {2036.658f, -73.58822f, 338.4985f, 2.460914f}, // Mimiron
375};
377{
378 {1928.793f, 65.03109f, 242.3763f, 0.0f}, // Garona end position
379 {1912.324f, -155.7967f, 239.9896f, 0.0f}, // Saurfang end position
380};
381
387
389{
390 public:
392 : _summoner(summoner), _owner(owner)
393 {
394 }
395
396 bool Execute(uint64 /*time*/, uint32 /*diff*/)
397 {
398 _owner->SetReactState(REACT_AGGRESSIVE);
399 if (Unit* target = _summoner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 300.0f))
400 _owner->AI()->AttackStart(target);
401 return true;
402 }
403
404 private:
407};
408
410{
411 public:
412 boss_voice_of_yogg_saron() : CreatureScript("boss_voice_of_yogg_saron") { }
413
415 {
417 {
418 SetCombatMovement(false);
419 }
420
422
423 {
424 // TODO: MoveInLineOfSight doesn't work for such a big distance
425 if (who->GetTypeId() == TypeID::TYPEID_PLAYER && me->GetDistance2d(who) < 99.0f && !me->IsInCombat())
426 me->SetInCombatWithZone();
427 }
428
430 {
432
433 for (uint8 i = DATA_SARA; i <= DATA_MIMIRON_YS; ++i)
434 if (Creature* creature = ObjectAccessor::GetCreature(*me, instance->GetData64(i)))
435 creature->AI()->EnterEvadeMode();
436
437 // not sure, spoken by Sara (sound), regarding to wowwiki Voice whispers it
438 Map::PlayerList const& players = me->GetMap()->GetPlayers();
439 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
440 if (Player* player = itr->GetSource())
441 {
442 if (events.IsInPhase(PHASE_ONE))
444
445 player->RemoveAurasDueToSpell(SPELL_SANITY);
446 player->RemoveAurasDueToSpell(SPELL_INSANE);
447 }
448 }
449
451 {
452 _Reset();
453 events.SetPhase(PHASE_ONE);
454
455 instance->SetData(DATA_DRIVE_ME_CRAZY, uint32(true));
457
458 _guardiansCount = 0;
459 _guardianTimer = 20000;
460 _illusionShattered = false;
461
462 bool clockwise = false;
463 std::list<TempSummon*> clouds;
464 me->SummonCreatureGroup(CREATURE_GROUP_CLOUDS, &clouds);
465 clouds.sort(Skyfire::ObjectDistanceOrderPred(me, true));
466 for (std::list<TempSummon*>::const_iterator itr = clouds.begin(); itr != clouds.end(); ++itr)
467 {
468 (*itr)->AI()->DoAction(int32(clockwise));
469 clockwise = !clockwise;
470 }
471 }
472
473 void EnterCombat(Unit* /*who*/) OVERRIDE
474 {
475 if (Creature* sara = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SARA)))
476 sara->SetInCombatWith(me);
477
478 for (uint8 i = DATA_FREYA_YS; i <= DATA_MIMIRON_YS; ++i)
479 if (Creature* keeper = ObjectAccessor::GetCreature(*me, instance->GetData64(i)))
480 keeper->SetInCombatWith(me);
481
483
486
487 events.ScheduleEvent(EVENT_LOCK_DOOR, 15000);
489 events.ScheduleEvent(EVENT_EXTINGUISH_ALL_LIFE, 900000); // 15 minutes
490 }
491
492 void JustDied(Unit* killer) OVERRIDE
493 {
494 // don't despawn Yogg-Saron's corpse, remove him from SummonList!
496 summons.Despawn(yogg);
497
498 BossAI::JustDied(killer);
499 }
500
502 {
503 if (!UpdateVictim())
504 return;
505
506 events.Update(diff);
507 // don't summon tentacles when illusion is shattered, delay them
509 events.DelayEvents(diff, EVENT_GROUP_SUMMON_TENTACLES);
510
511 while (uint32 eventId = events.ExecuteEvent())
512 {
513 switch (eventId)
514 {
515 case EVENT_LOCK_DOOR:
517 instance->SetBossState(BOSS_YOGG_SARON, IN_PROGRESS);
518 break;
521 {
522 yogg->AI()->Talk(EMOTE_YOGG_SARON_EXTINGUISH_ALL_LIFE, me);
523 yogg->CastSpell((Unit*)NULL, SPELL_EXTINGUISH_ALL_LIFE, true);
524 }
525 events.ScheduleEvent(EVENT_EXTINGUISH_ALL_LIFE, 10000); // cast it again after a short while, players can survive
526 break;
530 if (_guardiansCount <= 6 && _guardiansCount % 3 == 0)
531 _guardianTimer -= 5000;
533 break;
537 break;
541 break;
545 break;
546 case EVENT_ILLUSION:
547 {
549 {
550 yogg->AI()->Talk(EMOTE_YOGG_SARON_MADNESS);
551 yogg->AI()->Talk(SAY_YOGG_SARON_MADNESS);
552 }
553
554 me->SummonCreatureGroup(CREATURE_GROUP_PORTALS_10);
555 if (me->GetMap()->Is25ManRaid())
556 me->SummonCreatureGroup(CREATURE_GROUP_PORTALS_25);
557
558 uint8 illusion = std::rand() % STORMWIND_ILLUSION + CHAMBER_ILLUSION;
559 instance->SetData(DATA_ILLUSION, illusion);
560
562 brain->AI()->DoAction(ACTION_INDUCE_MADNESS);
563 events.ScheduleEvent(EVENT_ILLUSION, 80000, 0, PHASE_TWO); // wowwiki says 80 secs, wowhead says something about 90 secs
564 break;
565 }
568 events.ScheduleEvent(EVENT_SUMMON_IMMORTAL_GUARDIAN, 15000, 0, PHASE_THREE);
569 break;
570 default:
571 break;
572 }
573 }
574 }
575
577 {
578 switch (action)
579 {
581 events.SetPhase(PHASE_TRANSFORM);
582 summons.DespawnEntry(NPC_OMINOUS_CLOUD);
583 break;
584 case ACTION_PHASE_TWO:
585 events.SetPhase(PHASE_TWO);
586 me->SummonCreature(NPC_YOGG_SARON, YoggSaronSpawnPos);
588 brain->SetInCombatWithZone();
592 events.ScheduleEvent(EVENT_ILLUSION, 60000, 0, PHASE_TWO);
593 break;
596 break;
598 events.SetPhase(PHASE_THREE);
599 events.ScheduleEvent(EVENT_SUMMON_IMMORTAL_GUARDIAN, 1000, 0, PHASE_THREE);
600 break;
601 default:
602 break;
603 }
604 }
605
607 {
608 switch (summon->GetEntry())
609 {
611 summon->m_Events.AddEvent(new StartAttackEvent(me, summon), summon->m_Events.CalculateTime(1000));
612 break;
613 case NPC_YOGG_SARON:
614 summon->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
615 break;
617 summon->CastSpell(summon, SPELL_LUNGE, true);
618 break;
621 summon->SetReactState(REACT_PASSIVE);
622 summon->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
623 summon->m_Events.AddEvent(new StartAttackEvent(me, summon), summon->m_Events.CalculateTime(5000));
624 break;
626 summon->CastSpell(summon, SPELL_TELEPORT_PORTAL_VISUAL, true);
627 break;
629 summon->CastSpell(summon, SPELL_SIMPLE_TELEPORT, true);
630 break;
631 }
632
633 BossAI::JustSummoned(summon);
634 }
635
636 private:
640 };
641
643 {
645 }
646};
647
649{
650 public:
651 boss_sara() : CreatureScript("boss_sara") { }
652
653 struct boss_saraAI : public ScriptedAI
654 {
655 boss_saraAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
656
658 {
659 std::map<uint64, uint64>::const_iterator itr = _linkData.find(guid);
660 if (itr != _linkData.end())
661 return itr->second;
662
663 return 0;
664 }
665
666 void SetLinkBetween(uint64 player1, uint64 player2)
667 {
668 _linkData[player1] = player2;
669 _linkData[player2] = player1;
670 }
671
672 // called once for each target on aura remove
673 void RemoveLinkFrom(uint64 player1)
674 {
675 _linkData.erase(player1);
676 }
677
678 void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
679 {
680 if (_events.IsInPhase(PHASE_ONE) && damage >= me->GetHealth())
681 {
682 damage = 0;
683
685 voice->AI()->DoAction(ACTION_PHASE_TRANSFORM);
686
688 _events.SetPhase(PHASE_TRANSFORM);
689 _events.ScheduleEvent(EVENT_TRANSFORM_1, 4700, 0, PHASE_TRANSFORM);
690 _events.ScheduleEvent(EVENT_TRANSFORM_2, 9500, 0, PHASE_TRANSFORM);
691 _events.ScheduleEvent(EVENT_TRANSFORM_3, 14300, 0, PHASE_TRANSFORM);
692 _events.ScheduleEvent(EVENT_TRANSFORM_4, 14500, 0, PHASE_TRANSFORM);
693 }
694 }
695
696 void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) OVERRIDE
697 {
698 if (!roll_chance_i(30) || _events.IsInPhase(PHASE_TRANSFORM))
699 return;
700
701 switch (spell->Id)
702 {
705 break;
708 break;
709 case SPELL_PSYCHOSIS:
711 break;
712 default:
713 break;
714 }
715 }
716
718 {
719 if (victim->GetTypeId() == TypeID::TYPEID_PLAYER && !me->IsInEvadeMode())
721 }
722
723 void EnterCombat(Unit* /*who*/) OVERRIDE
724 {
726 _events.ScheduleEvent(EVENT_SARAS_FERVOR, 5000, 0, PHASE_ONE);
727 _events.ScheduleEvent(EVENT_SARAS_BLESSING, std::rand() % 30000 + 10000, 0, PHASE_ONE);
728 _events.ScheduleEvent(EVENT_SARAS_ANGER, std::rand() % 25000 + 15000, 0, PHASE_ONE);
729 }
730
732 {
733 me->RemoveAllAuras();
734 me->SetReactState(REACT_PASSIVE);
735 me->setFaction(35);
736 _events.Reset();
737 _events.SetPhase(PHASE_ONE);
738 }
739
741 {
742 if (!me->IsInCombat())
743 return;
744
745 if (me->HasAura(SPELL_SHATTERED_ILLUSION))
746 return;
747
748 _events.Update(diff);
749
750 if (me->HasUnitState(UNIT_STATE_CASTING))
751 return;
752
753 while (uint32 eventId = _events.ExecuteEvent())
754 {
755 switch (eventId)
756 {
759 _events.ScheduleEvent(EVENT_SARAS_FERVOR, 6000, 0, PHASE_ONE);
760 break;
763 _events.ScheduleEvent(EVENT_SARAS_ANGER, std::rand() % 8000 + 6000, 0, PHASE_ONE);
764 break;
767 _events.ScheduleEvent(EVENT_SARAS_BLESSING, std::rand() % 30000 + 6000, 0, PHASE_ONE);
768 break;
771 break;
774 break;
778 me->setFaction(16);
780 voice->AI()->DoAction(ACTION_PHASE_TWO);
782 mimiron->AI()->DoAction(ACTION_PHASE_TWO);
783 break;
789 _events.SetPhase(PHASE_TWO);
790 _events.ScheduleEvent(EVENT_DEATH_RAY, 20000, 0, PHASE_TWO); // almost never casted at scheduled time, why?
791 _events.ScheduleEvent(EVENT_MALADY_OF_THE_MIND, 18000, 0, PHASE_TWO);
792 _events.ScheduleEvent(EVENT_PSYCHOSIS, 1, 0, PHASE_TWO);
793 _events.ScheduleEvent(EVENT_BRAIN_LINK, 23000, 0, PHASE_TWO);
794 break;
795 case EVENT_DEATH_RAY:
797 _events.ScheduleEvent(EVENT_DEATH_RAY, 21000, 0, PHASE_TWO);
798 break;
801 _events.ScheduleEvent(EVENT_MALADY_OF_THE_MIND, std::rand() % 25000 + 18000, 0, PHASE_TWO);
802 break;
803 case EVENT_PSYCHOSIS:
804 me->CastCustomSpell(SPELL_PSYCHOSIS, SPELLVALUE_MAX_TARGETS, 1);
805 _events.ScheduleEvent(EVENT_PSYCHOSIS, 4000, 0, PHASE_TWO);
806 break;
807 case EVENT_BRAIN_LINK:
808 me->CastCustomSpell(SPELL_BRAIN_LINK, SPELLVALUE_MAX_TARGETS, 2);
809 _events.ScheduleEvent(EVENT_BRAIN_LINK, std::rand() % 26000 + 23000, 0, PHASE_TWO);
810 break;
811 default:
812 break;
813 }
814 }
815 }
816
818 {
819 summon->SetReactState(REACT_PASSIVE);
820
821 switch (summon->GetEntry())
822 {
823 case NPC_DEATH_ORB:
825 summon->CastSpell(summon, SPELL_DEATH_RAY_ORIGIN_VISUAL);
826 for (uint8 i = 0; i < 4; ++i)
827 {
828 Position pos;
829 float radius = frand(25.0f, 50.0f);
830 float angle = frand(0.0f, 2.0f * M_PI);
831 pos.m_positionX = YoggSaronSpawnPos.GetPositionX() + radius * cosf(angle);
832 pos.m_positionY = YoggSaronSpawnPos.GetPositionY() + radius * sinf(angle);
833 pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhaseMask(), pos.GetPositionX(), pos.GetPositionY(), YoggSaronSpawnPos.GetPositionZ() + 5.0f);
834 me->SummonCreature(NPC_DEATH_RAY, pos, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 20000);
835 }
836 break;
837 case NPC_DEATH_RAY:
838 summon->CastSpell(summon, SPELL_DEATH_RAY_WARNING_VISUAL);
839 break;
840 }
841
843 voice->AI()->JustSummoned(summon);
844 }
845
847 {
848 switch (action)
849 {
850 case ACTION_PHASE_THREE: // Sara does nothing in phase 3
851 _events.SetPhase(PHASE_THREE);
852 break;
853 default:
854 break;
855 }
856 }
857
858 private:
861 std::map<uint64, uint64> _linkData;
862 };
863
865 {
866 return GetUlduarAI<boss_saraAI>(creature);
867 }
868};
869
871{
872 public:
873 boss_yogg_saron() : CreatureScript("boss_yogg_saron") { }
874
876 {
877 boss_yogg_saronAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
878
880 {
881 _events.Reset();
882 _events.SetPhase(PHASE_TWO);
883 _events.ScheduleEvent(EVENT_YELL_BOW_DOWN, 3000, 0, PHASE_TWO);
886
887 me->ResetLootMode();
888 switch (_instance->GetData(DATA_KEEPERS_COUNT))
889 {
890 case 0:
891 me->AddLootMode(LOOT_MODE_HARD_MODE_4);
892 case 1:
893 me->AddLootMode(LOOT_MODE_HARD_MODE_3);
894 case 2:
895 me->AddLootMode(LOOT_MODE_HARD_MODE_2);
896 case 3:
897 me->AddLootMode(LOOT_MODE_HARD_MODE_1);
898 }
899 }
900
901 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
902 {
903 if (spell->Id == SPELL_IN_THE_MAWS_OF_THE_OLD_GOD)
904 me->AddLootMode(32);
905 }
906
907 void JustDied(Unit* /*killer*/) OVERRIDE
908 {
910
912 me->Kill(creature);
913
914 for (uint8 i = DATA_SARA; i <= DATA_BRAIN_OF_YOGG_SARON; ++i)
915 if (Creature* creature = ObjectAccessor::GetCreature(*me, _instance->GetData64(i)))
916 creature->DisappearAndDie();
917
918 for (uint8 i = DATA_FREYA_YS; i <= DATA_MIMIRON_YS; ++i)
919 if (Creature* creature = ObjectAccessor::GetCreature(*me, _instance->GetData64(i)))
920 creature->AI()->EnterEvadeMode();
921
922 Map::PlayerList const& players = me->GetMap()->GetPlayers();
923 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
924 if (Player* player = itr->GetSource())
925 {
926 player->RemoveAurasDueToSpell(SPELL_SANITY);
927 player->RemoveAurasDueToSpell(SPELL_INSANE);
928 }
929 }
930
932 {
933 _events.Update(diff);
934
935 if (me->HasUnitState(UNIT_STATE_CASTING))
936 return;
937
938 while (uint32 eventId = _events.ExecuteEvent())
939 {
940 switch (eventId)
941 {
944 break;
948 _events.ScheduleEvent(EVENT_SHADOW_BEACON, 45000, 0, PHASE_THREE);
949 break;
953 _events.ScheduleEvent(EVENT_LUNATIC_GAZE, 12000, 0, PHASE_THREE);
954 break;
959 _events.ScheduleEvent(EVENT_DEAFENING_ROAR, std::rand() % 25000 + 20000, 0, PHASE_THREE); // timer guessed
960 break;
961 default:
962 break;
963 }
964 }
965 }
966
968 {
969 switch (action)
970 {
972 _events.SetPhase(PHASE_THREE);
973 _events.ScheduleEvent(EVENT_SHADOW_BEACON, 45000, 0, PHASE_THREE);
974 _events.ScheduleEvent(EVENT_LUNATIC_GAZE, 12000, 0, PHASE_THREE);
975 if (me->GetMap()->Is25ManRaid() && _instance->GetData(DATA_KEEPERS_COUNT) < 4)
976 _events.ScheduleEvent(EVENT_DEAFENING_ROAR, std::rand() % 25000 + 20000, 0, PHASE_THREE); // timer guessed
979 me->RemoveAurasDueToSpell(SPELL_SHADOWY_BARRIER_YOGG);
980 me->ResetPlayerDamageReq();
981 break;
982 default:
983 break;
984 }
985 }
986
987 private:
990 };
991
993 {
994 return GetUlduarAI<boss_yogg_saronAI>(creature);
995 }
996};
997
999{
1000 public:
1001 boss_brain_of_yogg_saron() : CreatureScript("boss_brain_of_yogg_saron") { }
1002
1004 {
1005 boss_brain_of_yogg_saronAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()), _summons(creature) { }
1006
1008 {
1011 _summons.DespawnAll();
1012 }
1013
1014 void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
1015 {
1016 if (me->HealthBelowPctDamaged(30, damage) && !me->HasAura(SPELL_BRAIN_HURT_VISUAL))
1017 {
1018 me->RemoveAllAuras();
1019 me->InterruptNonMeleeSpells(true);
1021 DoCast(me, SPELL_MATCH_HEALTH_2, true); // it doesn't seem to hit Yogg-Saron here
1024
1026 voice->AI()->DoAction(ACTION_PHASE_THREE);
1027 if (Creature* sara = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_SARA)))
1028 sara->AI()->DoAction(ACTION_PHASE_THREE);
1030 yogg->AI()->DoAction(ACTION_PHASE_THREE);
1031
1032 for (uint8 i = DATA_THORIM_YS; i <= DATA_MIMIRON_YS; ++i)
1033 if (Creature* keeper = ObjectAccessor::GetCreature(*me, _instance->GetData64(i)))
1034 keeper->AI()->DoAction(ACTION_PHASE_THREE);
1035 }
1036 }
1037
1038 void UpdateAI(uint32 /*diff*/) OVERRIDE { }
1039
1041 {
1042 switch (action)
1043 {
1045 {
1046 _tentaclesKilled = 0;
1047
1048 me->SummonCreatureGroup(_instance->GetData(DATA_ILLUSION));
1049
1050 // make sure doors won't be opened
1052 _instance->HandleGameObject(_instance->GetData64(i), false);
1053
1055 break;
1056 }
1058 {
1059 uint8 illusion = _instance->GetData(DATA_ILLUSION);
1060 if (++_tentaclesKilled >= (illusion == ICECROWN_ILLUSION ? 9 : 8))
1061 {
1063 _summons.DespawnAll();
1065 _instance->HandleGameObject(_instance->GetData64(GO_BRAIN_ROOM_DOOR_1 + illusion), true);
1066
1068 voice->AI()->DoAction(ACTION_TOGGLE_SHATTERED_ILLUSION);
1069 }
1070 break;
1071 }
1072 default:
1073 break;
1074 }
1075 }
1076
1078 {
1079 _summons.Summon(summon);
1080 }
1081
1082 private:
1086 };
1087
1089 {
1091 }
1092};
1093
1095{
1096 public:
1097 npc_ominous_cloud() : CreatureScript("npc_ominous_cloud") { }
1098
1100 {
1101 npc_ominous_cloudAI(Creature* creature) : PassiveAI(creature) { }
1102
1104 {
1106 }
1107
1108 void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise)
1109 {
1110 float step = clockwise ? -M_PI / 8.0f : M_PI / 8.0f;
1111 float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY());
1112
1113 for (uint8 i = 0; i < 16; angle += step, ++i)
1114 {
1115 G3D::Vector3 point;
1116 point.x = centerPos.GetPositionX() + radius * cosf(angle);
1117 point.y = centerPos.GetPositionY() + radius * sinf(angle);
1118 point.z = me->GetMap()->GetHeight(me->GetPhaseMask(), point.x, point.y, z + 5.0f);
1119 path.push_back(point);
1120 }
1121 }
1122
1123 void UpdateAI(uint32 /*diff*/) OVERRIDE { }
1124
1126 {
1128 FillCirclePath(YoggSaronSpawnPos, me->GetDistance2d(YoggSaronSpawnPos.GetPositionX(), YoggSaronSpawnPos.GetPositionY()), me->GetPositionZ(), init.Path(), action);
1129 init.SetWalk(true);
1130 init.SetCyclic();
1131 init.Launch();
1132 }
1133 };
1134
1136 {
1137 return GetUlduarAI<npc_ominous_cloudAI>(creature);
1138 }
1139};
1140
1142{
1143 public:
1144 npc_guardian_of_yogg_saron() : CreatureScript("npc_guardian_of_yogg_saron") { }
1145
1147 {
1148 npc_guardian_of_yogg_saronAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
1149
1150 void JustDied(Unit* /*killer*/) OVERRIDE
1151 {
1154 }
1155
1157 {
1158 _events.ScheduleEvent(EVENT_DARK_VOLLEY, std::rand() % 15000 + 10000);
1159 }
1160
1162 {
1163 if (!UpdateVictim())
1164 return;
1165
1166 _events.Update(diff);
1167
1168 if (me->HasUnitState(UNIT_STATE_CASTING))
1169 return;
1170
1171 while (uint32 eventId = _events.ExecuteEvent())
1172 {
1173 switch (eventId)
1174 {
1175 case EVENT_DARK_VOLLEY:
1177 _events.ScheduleEvent(EVENT_DARK_VOLLEY, std::rand() % 15000 + 10000);
1178 break;
1179 default:
1180 break;
1181 }
1182 }
1183
1185 }
1186
1188 {
1189 if (summoner->GetEntry() != NPC_OMINOUS_CLOUD)
1190 return;
1191
1192 // Guardian can be summoned both by Voice of Yogg-Saron and by Ominous Cloud
1194 voice->AI()->JustSummoned(me);
1195 }
1196
1197 private:
1200 };
1201
1203 {
1205 }
1206};
1207
1209{
1210 public:
1211 npc_corruptor_tentacle() : CreatureScript("npc_corruptor_tentacle") { }
1212
1214 {
1216 {
1217 SetCombatMovement(false);
1218 }
1219
1221 {
1224 _events.ScheduleEvent(EVENT_CAST_RANDOM_SPELL, 1);
1225 }
1226
1228 {
1229 if (!UpdateVictim())
1230 return;
1231
1232 if (me->HasAura(SPELL_SHATTERED_ILLUSION))
1233 return;
1234
1235 _events.Update(diff);
1236
1237 if (me->HasUnitState(UNIT_STATE_CASTING))
1238 return;
1239
1240 while (uint32 eventId = _events.ExecuteEvent())
1241 {
1242 switch (eventId)
1243 {
1245 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
1247 _events.ScheduleEvent(EVENT_CAST_RANDOM_SPELL, 3000);
1248 break;
1249 default:
1250 break;
1251 }
1252 }
1253 }
1254
1255 private:
1257 };
1258
1260 {
1262 }
1263};
1264
1266{
1267 public:
1268 npc_constrictor_tentacle() : CreatureScript("npc_constrictor_tentacle") { }
1269
1271 {
1272 npc_constrictor_tentacleAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
1273 {
1274 SetCombatMovement(false);
1275 }
1276
1282
1283 void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) OVERRIDE
1284 {
1285 if (!apply)
1286 passenger->RemoveAurasDueToSpell(SPELL_SQUEEZE);
1287 }
1288
1289 void UpdateAI(uint32 /*diff*/) OVERRIDE
1290 {
1291 UpdateVictim();
1292 }
1293
1294 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
1295 {
1297 voice->AI()->JustSummoned(me);
1298 }
1299
1300 private:
1302 };
1303
1305 {
1307 }
1308};
1309
1311{
1312 public:
1313 npc_crusher_tentacle() : CreatureScript("npc_crusher_tentacle") { }
1314
1316 {
1318 {
1319 SetCombatMovement(false);
1320 }
1321
1323 {
1329
1330 _events.ScheduleEvent(EVENT_DIMINISH_POWER, std::rand() % 8000 + 6000);
1331 }
1332
1334 {
1335 if (!UpdateVictim())
1336 return;
1337
1338 if (me->HasAura(SPELL_SHATTERED_ILLUSION) || me->HasUnitState(UNIT_STATE_CASTING))
1339 return;
1340
1341 // update timers when the Diminish Power is not being channeled so the next one
1342 // is not cast immediately after interrupt
1343 _events.Update(diff);
1344
1345 while (uint32 eventId = _events.ExecuteEvent())
1346 {
1347 switch (eventId)
1348 {
1351 _events.ScheduleEvent(EVENT_DIMINISH_POWER, std::rand() % 30000 + 20000);
1352 break;
1353 default:
1354 break;
1355 }
1356 }
1357
1359 }
1360
1361 private:
1363 };
1364
1366 {
1367 return GetUlduarAI<npc_crusher_tentacleAI>(creature);
1368 }
1369};
1370
1372{
1373 public:
1374 npc_influence_tentacle() : CreatureScript("npc_influence_tentacle") { }
1375
1377 {
1378 npc_influence_tentacleAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
1379
1381 {
1383 }
1384
1385 void JustDied(Unit* /*killer*/) OVERRIDE
1386 {
1388 brain->AI()->DoAction(ACTION_TENTACLE_KILLED);
1389 }
1390
1391 void UpdateAI(uint32 /*diff*/) OVERRIDE { }
1392
1393 private:
1395 };
1396
1398 {
1400 }
1401};
1402
1404
1406{
1407 public:
1408 npc_descend_into_madness() : CreatureScript("npc_descend_into_madness") { }
1409
1411 {
1412 npc_descend_into_madnessAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
1413
1414 void OnSpellClick(Unit* clicker, bool& result) OVERRIDE
1415 {
1416 if (!result)
1417 return;
1418 clicker->RemoveAurasDueToSpell(SPELL_BRAIN_LINK);
1419 me->DespawnOrUnsummon();
1420 }
1421
1422 void UpdateAI(uint32 /*diff*/) OVERRIDE { }
1423
1424 private:
1426 };
1427
1429 {
1431 }
1432};
1433
1435{
1436 public:
1437 npc_immortal_guardian() : CreatureScript("npc_immortal_guardian") { }
1438
1440 {
1442
1444 {
1447 _events.ScheduleEvent(EVENT_DRAIN_LIFE, std::rand() % 13000 + 3000);
1448 }
1449
1450 void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
1451 {
1452 if (me->HealthBelowPctDamaged(1, damage))
1453 damage = me->GetHealth() - me->CountPctFromMaxHealth(1); // or set immune to damage? should be done here or in SPELL_WEAKENED spell script?
1454 }
1455
1457 {
1458 if (!UpdateVictim())
1459 return;
1460
1461 _events.Update(diff);
1462
1463 if (me->HasUnitState(UNIT_STATE_CASTING))
1464 return;
1465
1466 while (uint32 eventId = _events.ExecuteEvent())
1467 {
1468 switch (eventId)
1469 {
1470 case EVENT_DRAIN_LIFE:
1472 _events.ScheduleEvent(EVENT_DRAIN_LIFE, std::rand() % 30000 + 20000);
1473 break;
1474 default:
1475 break;
1476 }
1477 }
1478
1480 }
1481
1482 private:
1484 };
1485
1487 {
1488 return GetUlduarAI<npc_immortal_guardianAI>(creature);
1489 }
1490};
1491
1493{
1494 public:
1495 npc_observation_ring_keeper() : CreatureScript("npc_observation_ring_keeper") { }
1496
1498 {
1500
1502 {
1503 DoCast(SPELL_SIMPLE_TELEPORT_KEEPERS); // not visible here
1505 }
1506
1507 void sGossipSelect(Player* player, uint32 sender, uint32 /*action*/) OVERRIDE
1508 {
1509 if (sender != 10333)
1510 return;
1511
1513 me->DespawnOrUnsummon(2000);
1515 Talk(SAY_KEEPER_CHOSEN_1, player);
1516 Talk(SAY_KEEPER_CHOSEN_2, player);
1517
1518 switch (me->GetEntry())
1519 {
1521 me->SummonCreature(NPC_FREYA_YS, YSKeepersPos[0]);
1522 break;
1524 me->SummonCreature(NPC_HODIR_YS, YSKeepersPos[1]);
1525 break;
1527 me->SummonCreature(NPC_THORIM_YS, YSKeepersPos[2]);
1528 break;
1530 me->SummonCreature(NPC_MIMIRON_YS, YSKeepersPos[3]);
1531 break;
1532 }
1533 }
1534
1535 void UpdateAI(uint32 /*diff*/) OVERRIDE { }
1536 };
1537
1539 {
1541 }
1542};
1543
1545{
1546 public:
1547 npc_yogg_saron_keeper() : CreatureScript("npc_yogg_saron_keeper") { }
1548
1550 {
1552
1553 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
1554 {
1556 }
1557
1559 {
1560 _events.Reset();
1561 _events.SetPhase(PHASE_ONE);
1562 me->SetReactState(REACT_PASSIVE);
1563 me->RemoveAllAuras();
1564
1565 DoCast(SPELL_KEEPER_ACTIVE); // can we skip removing this aura somehow?
1566
1567 if (me->GetEntry() == NPC_FREYA_YS)
1568 {
1569 std::list<Creature*> wells;
1571 for (std::list<Creature*>::const_iterator itr = wells.begin(); itr != wells.end(); ++itr)
1572 {
1573 (*itr)->RemoveAurasDueToSpell(SPELL_SANITY_WELL);
1574 (*itr)->RemoveAurasDueToSpell(SPELL_SANITY_WELL_VISUAL);
1575 }
1576 }
1577 }
1578
1580 {
1581 switch (me->GetEntry())
1582 {
1583 case NPC_FREYA_YS:
1586 break;
1587 case NPC_HODIR_YS:
1590 break;
1591 case NPC_THORIM_YS:
1593 break;
1594 case NPC_MIMIRON_YS:
1596 break;
1597 }
1598 }
1599
1601 {
1602 if (!me->IsInCombat())
1603 return;
1604
1605 _events.Update(diff);
1606
1607 if (me->HasUnitState(UNIT_STATE_CASTING))
1608 return;
1609
1610 while (uint32 eventId = _events.ExecuteEvent())
1611 {
1612 switch (eventId)
1613 {
1616 _events.ScheduleEvent(EVENT_DESTABILIZATION_MATRIX, std::rand()% 25000 + 15000, 0, PHASE_TWO);
1617 break;
1620 break;
1621 }
1622 }
1623 }
1624
1626 {
1627 switch (action)
1628 {
1629 // setting the phases is only for Thorim and Mimiron
1630 case ACTION_PHASE_TWO:
1631 _events.SetPhase(PHASE_TWO);
1632 _events.ScheduleEvent(EVENT_DESTABILIZATION_MATRIX, std::rand() % 15000 + 5000, 0, PHASE_TWO);
1633 break;
1634 case ACTION_PHASE_THREE:
1635 _events.SetPhase(PHASE_THREE);
1636 if (me->GetEntry() == NPC_THORIM_YS)
1638 break;
1640 {
1641 std::list<Creature*> wells;
1643 for (std::list<Creature*>::const_iterator itr = wells.begin(); itr != wells.end(); ++itr)
1644 {
1645 (*itr)->CastSpell(*itr, SPELL_SANITY_WELL);
1646 (*itr)->CastSpell(*itr, SPELL_SANITY_WELL_VISUAL);
1647 }
1648 break;
1649 }
1652 _events.ScheduleEvent(EVENT_HODIRS_PROTECTIVE_GAZE, std::rand() % 30000 + 25000);
1653 break;
1654 }
1655 }
1656
1657 private:
1659 };
1660
1662 {
1663 return GetUlduarAI<npc_yogg_saron_keeperAI>(creature);
1664 }
1665};
1666
1668{
1669 public:
1670 npc_yogg_saron_illusions() : CreatureScript("npc_yogg_saron_illusions") { }
1671
1673 {
1674 npc_yogg_saron_illusionsAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
1675
1676 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
1677 {
1678 switch (_instance->GetData(DATA_ILLUSION))
1679 {
1680 case CHAMBER_ILLUSION:
1681 // i think the first Talk should be delayed as in this moment
1682 // players are too far away to be able to see it
1683 if (Creature* neltharion = me->FindNearestCreature(NPC_NELTHARION, 50.0f))
1684 neltharion->AI()->Talk(SAY_CHAMBER_ROLEPLAY_1);
1685
1686 _events.ScheduleEvent(EVENT_CHAMBER_ROLEPLAY_1, 16000);
1687 _events.ScheduleEvent(EVENT_CHAMBER_ROLEPLAY_2, 22000);
1688 _events.ScheduleEvent(EVENT_CHAMBER_ROLEPLAY_3, 28000);
1689 _events.ScheduleEvent(EVENT_CHAMBER_ROLEPLAY_4, 36000);
1690 break;
1691 case ICECROWN_ILLUSION:
1692 // same here
1693 _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_1, 1000);
1694 _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_2, 7500);
1695 _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_3, 19500);
1696 _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_4, 25500);
1697 _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_5, 33000);
1698 _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_6, 41300);
1699 break;
1700 case STORMWIND_ILLUSION:
1701 _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_4, 33800); // "A thousand deaths..."
1702 _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_5, 38850);
1703 _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_7, 58750);
1704 // TODO: use "or one murder." sound and split the text in DB
1705 break;
1706 }
1707 }
1708
1710 {
1711 _events.Update(diff);
1712
1713 while (uint32 eventId = _events.ExecuteEvent())
1714 {
1715 switch (eventId)
1716 {
1718 if (Creature* ysera = me->FindNearestCreature(NPC_YSERA, 50.0f))
1719 ysera->AI()->Talk(SAY_CHAMBER_ROLEPLAY_2);
1720 break;
1722 if (Creature* neltharion = me->FindNearestCreature(NPC_NELTHARION, 50.0f))
1723 neltharion->AI()->Talk(SAY_CHAMBER_ROLEPLAY_3);
1724 break;
1726 if (Creature* malygos = me->FindNearestCreature(NPC_MALYGOS, 50.0f))
1727 malygos->AI()->Talk(SAY_CHAMBER_ROLEPLAY_4);
1728 break;
1731 break;
1733 if (Creature* bolvar = me->FindNearestCreature(NPC_IMMOLATED_CHAMPION, 50.0f))
1734 {
1735 bolvar->AI()->Talk(SAY_ICECROWN_ROLEPLAY_1);
1736
1737 if (Creature* lichKing = me->FindNearestCreature(NPC_THE_LICH_KING, 50.0f))
1738 lichKing->CastSpell(bolvar, SPELL_DEATHGRASP);
1739 }
1740 break;
1742 if (Creature* lichKing = me->FindNearestCreature(NPC_THE_LICH_KING, 50.0f))
1743 lichKing->AI()->Talk(SAY_ICECROWN_ROLEPLAY_2);
1744 break;
1746 if (Creature* bolvar = me->FindNearestCreature(NPC_IMMOLATED_CHAMPION, 50.0f))
1747 bolvar->AI()->Talk(SAY_ICECROWN_ROLEPLAY_3);
1748 if (Creature* saurfang = me->FindNearestCreature(NPC_TURNED_CHAMPION, 50.0f))
1749 saurfang->AI()->DoAction(ACTION_START_ROLEPLAY);
1750 break;
1752 if (Creature* lichKing = me->FindNearestCreature(NPC_THE_LICH_KING, 50.0f))
1753 lichKing->AI()->Talk(SAY_ICECROWN_ROLEPLAY_4);
1754 break;
1757 break;
1760 break;
1763 break;
1765 if (Creature* llane = me->FindNearestCreature(NPC_KING_LLANE, 50.0f))
1766 llane->AI()->Talk(SAY_STORMWIND_ROLEPLAY_5);
1767 break;
1770 break;
1771 default:
1772 break;
1773 }
1774 }
1775 }
1776
1777 private:
1780 };
1781
1783 {
1785 }
1786};
1787
1789{
1790 public:
1791 npc_garona() : CreatureScript("npc_garona") { }
1792
1793 struct npc_garonaAI : public ScriptedAI
1794 {
1795 npc_garonaAI(Creature* creature) : ScriptedAI(creature) { }
1796
1798 {
1799 _events.Reset();
1800
1801 me->SetWalk(true);
1802 me->GetMotionMaster()->MovePoint(0, IllusionsMiscPos[0]);
1803
1804 _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_1, 9250);
1805 _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_2, 16700);
1806 _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_3, 24150);
1807 _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_6, 52700);
1808 }
1809
1811 {
1812 _events.Update(diff);
1813
1814 while (uint32 eventId = _events.ExecuteEvent())
1815 {
1816 switch (eventId)
1817 {
1820 break;
1823 break;
1826 break;
1829 if (Creature* llane = me->FindNearestCreature(NPC_KING_LLANE, 50.0f))
1830 {
1832 llane->CastSpell(llane, SPELL_PERMANENT_FEIGN_DEATH);
1833 }
1834 break;
1835 default:
1836 break;
1837 }
1838 }
1839 }
1840
1841 private:
1843 };
1844
1846 {
1847 return GetUlduarAI<npc_garonaAI>(creature);
1848 }
1849};
1850
1852{
1853 public:
1854 npc_turned_champion() : CreatureScript("npc_turned_champion") { }
1855
1857 {
1858 npc_turned_championAI(Creature* creature) : ScriptedAI(creature) { }
1859
1861 {
1863 }
1864
1866 {
1867 if (type != POINT_MOTION_TYPE || pointId != 0)
1868 return;
1869
1870 me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
1871 }
1872
1874 {
1875 if (action != ACTION_START_ROLEPLAY)
1876 return;
1877
1878 me->SetWalk(true);
1879 me->GetMotionMaster()->MovePoint(0, IllusionsMiscPos[1]);
1880 }
1881 };
1882
1884 {
1885 return GetUlduarAI<npc_turned_championAI>(creature);
1886 }
1887};
1888
1890{
1891 public:
1892 npc_laughing_skull() : CreatureScript("npc_laughing_skull") { }
1893
1895 {
1896 npc_laughing_skullAI(Creature* creature) : ScriptedAI(creature) { }
1897
1899 {
1900 me->SetReactState(REACT_PASSIVE);
1902 }
1903
1904 // don't evade, otherwise the Lunatic Gaze aura is removed
1905 void UpdateAI(uint32 /*diff*/) OVERRIDE { }
1906 };
1907
1909 {
1910 return GetUlduarAI<npc_laughing_skullAI>(creature);
1911 }
1912};
1913
1940
1942{
1943 public:
1945 SanityReduction(uint8 stacks) : SpellScript(), _stacks(stacks) { }
1946
1947 void RemoveSanity(SpellEffIndex /*effIndex*/)
1948 {
1949 if (Unit* target = GetHitUnit())
1950 if (Aura* sanity = target->GetAura(SPELL_SANITY))
1951 sanity->ModStackAmount(-int32(_stacks), AURA_REMOVE_BY_ENEMY_SPELL);
1952 }
1953
1954 protected:
1956};
1957
1959{
1960 public:
1962
1964 {
1965 if (Unit* unit = object->ToUnit())
1966 if (Aura* sanity = unit->GetAura(SPELL_SANITY))
1967 return sanity->GetStackAmount() <= 40;
1968 return true;
1969 }
1970};
1971
2006
2008{
2009 public:
2010 spell_yogg_saron_malady_of_the_mind() : SpellScriptLoader("spell_yogg_saron_malady_of_the_mind") { }
2011
2037
2039 {
2041
2042 bool Validate(SpellInfo const* /*spell*/) OVERRIDE
2043 {
2044 if (!sSpellMgr->GetSpellInfo(SPELL_MALADY_OF_THE_MIND_JUMP))
2045 return false;
2046 return true;
2047 }
2048
2049 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2050 {
2051 switch (GetTargetApplication()->GetRemoveMode())
2052 {
2056 break;
2057 default:
2058 return;
2059 }
2060
2062 }
2063
2068 };
2069
2074
2079};
2080
2082{
2083 public:
2084 spell_yogg_saron_brain_link() : SpellScriptLoader("spell_yogg_saron_brain_link") { }
2085
2087 {
2089
2090 void FilterTargets(std::list<WorldObject*>& targets)
2091 {
2092 targets.remove_if(Skyfire::UnitAuraCheck(true, SPELL_ILLUSION_ROOM));
2093
2094 if (targets.size() != 2)
2095 {
2096 targets.clear();
2097 return;
2098 }
2099
2100 if (SaraAI* ai = CAST_AI(SaraAI, GetCaster()->GetAI()))
2101 ai->SetLinkBetween(targets.front()->GetGUID(), targets.back()->GetGUID());
2102 }
2103
2108 };
2109
2111 {
2113
2114 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2115 {
2116 if (!sSpellMgr->GetSpellInfo(SPELL_BRAIN_LINK_DAMAGE))
2117 return false;
2118 if (!sSpellMgr->GetSpellInfo(SPELL_BRAIN_LINK_NO_DAMAGE))
2119 return false;
2120 return true;
2121 }
2122
2123 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2124 {
2125 Unit* caster = GetCaster();
2126 if (!caster)
2127 return;
2128
2129 if (SaraAI* ai = CAST_AI(SaraAI, caster->GetAI()))
2130 {
2131 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
2132 ai->RemoveLinkFrom(GetTarget()->GetGUID());
2133 else
2134 {
2135 if (Player* player = ObjectAccessor::GetPlayer(*GetTarget(), ai->GetLinkedPlayerGUID(GetTarget()->GetGUID())))
2136 {
2137 ai->RemoveLinkFrom(GetTarget()->GetGUID());
2138 player->RemoveAurasDueToSpell(SPELL_BRAIN_LINK);
2139 }
2140 }
2141 }
2142 }
2143
2144 void DummyTick(AuraEffect const* aurEff)
2145 {
2146 Unit* caster = GetCaster();
2147 if (!caster)
2148 return;
2149
2150 SaraAI* ai = CAST_AI(SaraAI, caster->GetAI());
2151 if (!ai)
2152 return;
2153
2155 if (!linked)
2156 return;
2157
2158 GetTarget()->CastSpell(linked, (GetTarget()->GetDistance(linked) > (float)aurEff->GetAmount()) ? SPELL_BRAIN_LINK_DAMAGE : SPELL_BRAIN_LINK_NO_DAMAGE, true);
2159 }
2160
2166 };
2167
2172
2177};
2178
2202
2204{
2205 public:
2206 spell_yogg_saron_boil_ominously() : SpellScriptLoader("spell_yogg_saron_boil_ominously") { }
2207
2209 {
2211
2212 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2213 {
2214 if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_GUARDIAN_1))
2215 return false;
2216 return true;
2217 }
2218
2219 void HandleDummy(SpellEffIndex /*effIndex*/)
2220 {
2221 if (Unit* target = GetHitUnit())
2222 if (!target->HasAura(SPELL_FLASH_FREEZE) && !GetCaster()->HasAura(SPELL_SUMMON_GUARDIAN_1) && !GetCaster()->HasAura(SPELL_SUMMON_GUARDIAN_2))
2223 {
2224 if (Creature* caster = GetCaster()->ToCreature())
2225 caster->AI()->Talk(EMOTE_OMINOUS_CLOUD_PLAYER_TOUCH, target);
2226
2228 }
2229 }
2230
2235 };
2236
2241};
2242
2276
2303
2305{
2306 public:
2307 spell_yogg_saron_empowering_shadows_missile() : SpellScriptLoader("spell_yogg_saron_empowering_shadows_missile") { }
2308
2310 {
2312
2313 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2314 {
2315 if (!sSpellMgr->GetSpellInfo(SPELL_EMPOWERING_SHADOWS))
2316 return false;
2317 return true;
2318 }
2319
2320 void HandleScript(SpellEffIndex /*effIndex*/)
2321 {
2322 if (Unit* target = GetHitUnit())
2323 target->CastSpell((Unit*)NULL, SPELL_EMPOWERING_SHADOWS, true);
2324 }
2325
2330 };
2331
2336};
2337
2338// it works, but is it scripted correctly? why is it aura with 2500ms duration?
2371
2373{
2374 public:
2375 spell_yogg_saron_lunge() : SpellScriptLoader("spell_yogg_saron_lunge") { }
2376
2378 {
2380
2381 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2382 {
2383 if (!sSpellMgr->GetSpellInfo(SPELL_SQUEEZE))
2384 return false;
2385 return true;
2386 }
2387
2388 void HandleScript(SpellEffIndex /*effIndex*/)
2389 {
2390 if (Unit* target = GetHitUnit())
2391 {
2392 target->CastSpell(target, SPELL_SQUEEZE, true);
2393 target->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
2394 }
2395 }
2396
2401 };
2402
2407};
2408
2410{
2411 public:
2412 spell_yogg_saron_squeeze() : SpellScriptLoader("spell_yogg_saron_squeeze") { }
2413
2415 {
2417
2418 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2419 {
2420 if (Unit* vehicle = GetTarget()->GetVehicleBase())
2421 if (vehicle->IsAlive())
2422 vehicle->Kill(vehicle); // should tentacle die or just release its target?
2423 }
2424
2429 };
2430
2435};
2436
2465
2466// not sure about SPELL_WEAKENED part, where should it be handled?
2468{
2469 public:
2470 spell_yogg_saron_empowered() : SpellScriptLoader("spell_yogg_saron_empowered") { }
2471
2473 {
2475
2476 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2477 {
2478 if (!sSpellMgr->GetSpellInfo(SPELL_EMPOWERED_BUFF))
2479 return false;
2480 if (!sSpellMgr->GetSpellInfo(SPELL_WEAKENED))
2481 return false;
2482 return true;
2483 }
2484
2489
2490 void OnPeriodic(AuraEffect const* /*aurEff*/)
2491 {
2492 Unit* target = GetTarget();
2493 float stack = ceil((target->GetHealthPct() / 10) - 1);
2495
2496 if (stack)
2497 {
2500 }
2501 else if (!target->HealthAbovePct(1) && !target->HasAura(SPELL_WEAKENED))
2502 target->CastSpell(target, SPELL_WEAKENED, true);
2503 }
2504
2510 };
2511
2516};
2517
2519{
2520 public:
2521 spell_yogg_saron_match_health() : SpellScriptLoader("spell_yogg_saron_match_health") { }
2522
2524 {
2526
2527 void HandleScript(SpellEffIndex /*effIndex*/)
2528 {
2529 if (Unit* target = GetHitUnit())
2530 target->SetHealth(target->CountPctFromMaxHealth((int32)GetCaster()->GetHealthPct()));
2531 }
2532
2537 };
2538
2543};
2544
2571
2573{
2574 public:
2575 spell_yogg_saron_death_ray_warning_visual() : SpellScriptLoader("spell_yogg_saron_death_ray_warning_visual") { }
2576
2578 {
2580
2581 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2582 {
2583 if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_RAY_PERIODIC))
2584 return false;
2585 if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_RAY_DAMAGE_VISUAL))
2586 return false;
2587 return true;
2588 }
2589
2590 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2591 {
2592 if (Unit* caster = GetCaster())
2593 {
2594 caster->CastSpell(caster, SPELL_DEATH_RAY_PERIODIC, true);
2595 caster->CastSpell((Unit*)NULL, SPELL_DEATH_RAY_DAMAGE_VISUAL, true);
2596 // TODO: set better movement
2597 caster->GetMotionMaster()->MoveConfused();
2598 }
2599 }
2600
2605 };
2606
2611};
2612
2614{
2615 public:
2616 spell_yogg_saron_cancel_illusion_room_aura() : SpellScriptLoader("spell_yogg_saron_cancel_illusion_room_aura") { }
2617
2619 {
2621
2622 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2623 {
2624 if (!sSpellMgr->GetSpellInfo(SPELL_TELEPORT_BACK_TO_MAIN_ROOM))
2625 return false;
2626 return true;
2627 }
2628
2629 void HandleScript(SpellEffIndex /*effIndex*/)
2630 {
2631 if (Unit* target = GetHitUnit())
2632 {
2633 target->CastSpell(target, SPELL_TELEPORT_BACK_TO_MAIN_ROOM);
2634 target->RemoveAurasDueToSpell(uint32(GetEffectValue()));
2635 }
2636 }
2637
2642 };
2643
2648};
2649
2675
2677{
2678 public:
2679 spell_yogg_saron_revealed_tentacle() : SpellScriptLoader("spell_yogg_saron_revealed_tentacle") { }
2680
2682 {
2684
2685 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2686 {
2687 if (!sSpellMgr->GetSpellInfo(SPELL_TENTACLE_VOID_ZONE))
2688 return false;
2689 if (!sSpellMgr->GetSpellInfo(SPELL_GRIM_REPRISAL))
2690 return false;
2691 return true;
2692 }
2693
2694 void HandleScript(SpellEffIndex /*effIndex*/)
2695 {
2696 if (Creature* caster = GetCaster()->ToCreature())
2697 {
2698 caster->CastSpell(caster, SPELL_TENTACLE_VOID_ZONE, true);
2699 caster->CastSpell(caster, SPELL_GRIM_REPRISAL, true);
2700 caster->UpdateEntry(NPC_INFLUENCE_TENTACLE, 0, caster->GetCreatureData());
2701 }
2702 }
2703
2708 };
2709
2714};
2715
2717{
2718 public:
2719 spell_yogg_saron_grim_reprisal() : SpellScriptLoader("spell_yogg_saron_grim_reprisal") { }
2720
2722 {
2724
2725 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2726 {
2727 if (!sSpellMgr->GetSpellInfo(SPELL_GRIM_REPRISAL_DAMAGE))
2728 return false;
2729 return true;
2730 }
2731
2732 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
2733 {
2734 int32 damage = CalculatePct(int32(eventInfo.GetDamageInfo()->GetDamage()), 60);
2736 }
2737
2742 };
2743
2748};
2749
2751{
2752 public:
2753 spell_yogg_saron_induce_madness() : SpellScriptLoader("spell_yogg_saron_induce_madness") { }
2754
2756 {
2758
2759 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2760 {
2761 if (!sSpellMgr->GetSpellInfo(SPELL_TELEPORT_BACK_TO_MAIN_ROOM))
2762 return false;
2763 if (!sSpellMgr->GetSpellInfo(SPELL_SHATTERED_ILLUSION_REMOVE))
2764 return false;
2765 return true;
2766 }
2767
2768 void HandleScript(SpellEffIndex /*effIndex*/)
2769 {
2770 if (Unit* target = GetHitUnit())
2771 {
2772 target->CastSpell(target, SPELL_TELEPORT_BACK_TO_MAIN_ROOM);
2773 target->RemoveAurasDueToSpell(SPELL_SANITY, 0, 0, AURA_REMOVE_BY_ENEMY_SPELL);
2774 target->RemoveAurasDueToSpell(uint32(GetEffectValue()));
2775 }
2776 }
2777
2779 {
2781
2782 if (InstanceScript* instance = GetCaster()->GetInstanceScript())
2783 if (Creature* voice = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_VOICE_OF_YOGG_SARON)))
2784 voice->AI()->DoAction(ACTION_TOGGLE_SHATTERED_ILLUSION);
2785 }
2786
2792 };
2793
2798};
2799
2801{
2802 public:
2803 spell_yogg_saron_sanity() : SpellScriptLoader("spell_yogg_saron_sanity") { }
2804
2806 {
2808
2809 // don't target players outside of room or handle it in SPELL_INSANE_PERIODIC?
2810
2815
2820 };
2821
2823 {
2825
2826 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2827 {
2828 if (!sSpellMgr->GetSpellInfo(SPELL_LOW_SANITY_SCREEN_EFFECT))
2829 return false;
2830 if (!sSpellMgr->GetSpellInfo(SPELL_INSANE))
2831 return false;
2832 return true;
2833 }
2834
2835 void DummyTick(AuraEffect const* /*aurEff*/)
2836 {
2837 if (GetTarget()->HasAura(SPELL_SANITY_WELL))
2838 ModStackAmount(20);
2839
2840 if (GetStackAmount() <= 40 && !GetTarget()->HasAura(SPELL_LOW_SANITY_SCREEN_EFFECT))
2842 }
2843
2844 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2845 {
2846 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
2847 return;
2848
2849 if (InstanceScript* instance = GetTarget()->GetInstanceScript())
2850 instance->SetData(DATA_DRIVE_ME_CRAZY, uint32(false));
2851
2853
2854 if (Unit* caster = GetCaster())
2855 caster->CastSpell(GetTarget(), SPELL_INSANE, true);
2856 }
2857
2863 };
2864
2869
2871 {
2873 }
2874};
2875
2877{
2878 public:
2879 spell_yogg_saron_insane() : SpellScriptLoader("spell_yogg_saron_insane") { }
2880
2882 {
2884
2885 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2886 {
2887 if (!sSpellMgr->GetSpellInfo(SPELL_INSANE_VISUAL))
2888 return false;
2889 return true;
2890 }
2891
2892 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2893 {
2894 if (Unit* caster = GetCaster())
2895 if (Creature* yogg = caster->ToCreature())
2896 yogg->AI()->Talk(WHISPER_VOICE_INSANE, GetTarget());
2897
2899 }
2900
2901 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2902 {
2903 if (GetTarget()->IsAlive())
2904 GetTarget()->Kill(GetTarget());
2905 }
2906
2912 };
2913
2915 {
2917 }
2918};
2919
2946
2948{
2949 public:
2951
2953 {
2954 return !object->HasInArc(static_cast<float>(M_PI), _caster);
2955 }
2956
2957 private:
2959};
2960
2994
2995class spell_yogg_saron_keeper_aura : public SpellScriptLoader // 62650, 62670, 62671, 62702
2996{
2997 public:
2998 spell_yogg_saron_keeper_aura() : SpellScriptLoader("spell_yogg_saron_keeper_aura") { }
2999
3001 {
3003
3004 bool CanApply(Unit* target)
3005 {
3006 if (target->GetTypeId() != TypeID::TYPEID_PLAYER && target != GetCaster())
3007 return false;
3008 return true;
3009 }
3010
3015 };
3016
3021};
3022
3024{
3025 public:
3026 spell_yogg_saron_hate_to_zero() : SpellScriptLoader("spell_yogg_saron_hate_to_zero") { }
3027
3029 {
3031
3032 void HandleScript(SpellEffIndex /*effIndex*/)
3033 {
3034 if (Unit* target = GetHitUnit())
3035 if (target->CanHaveThreatList())
3036 target->getThreatManager().modifyThreatPercent(GetCaster(), -100);
3037 }
3038
3043 };
3044
3049};
3050
3052{
3053 public:
3054 spell_yogg_saron_in_the_maws_of_the_old_god() : SpellScriptLoader("spell_yogg_saron_in_the_maws_of_the_old_god") { }
3055
3080
3085};
3086
3113
3115{
3116 public:
3117 spell_yogg_saron_hodirs_protective_gaze() : SpellScriptLoader("spell_yogg_saron_hodirs_protective_gaze") { }
3118
3120 {
3122
3123 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
3124 {
3125 if (!sSpellMgr->GetSpellInfo(SPELL_FLASH_FREEZE))
3126 return false;
3127 return true;
3128 }
3129
3130 bool CanApply(Unit* target)
3131 {
3132 if (target->GetTypeId() != TypeID::TYPEID_PLAYER && target != GetCaster())
3133 return false;
3134 return true;
3135 }
3136
3137 void OnAbsorb(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& absorbAmount)
3138 {
3139 if (dmgInfo.GetDamage() >= GetTarget()->GetHealth())
3140 {
3141 absorbAmount = dmgInfo.GetDamage();
3142 // or absorbAmount = dmgInfo.GetDamage() - GetTarget()->GetHealth() + 1
3144 }
3145 else
3147 }
3148
3154 };
3155
3160};
3161
3163{
3165 new boss_sara();
3166 new boss_yogg_saron();
3168 new npc_ominous_cloud();
3179 new npc_garona();
3180 new npc_turned_champion();
3181 new npc_laughing_skull();
3213}
Actions
#define M_PI
Definition Common.h:192
const T & RAND(const T &v1, const T &v2)
#define sCreatureTextMgr
@ TEXT_RANGE_AREA
@ TEXT_RANGE_NORMAL
@ ACHIEVEMENT_TIMED_TYPE_EVENT
Definition DBCEnums.h:158
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::int8_t int8
Definition Define.h:75
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
@ IN_PROGRESS
@ POINT_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:70
void GetCreatureListWithEntryInGrid(std::list< Creature * > &list, WorldObject *source, uint32 entry, float maxSearchRange)
#define CAST_AI(a, b)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ EFFECT_2
@ EMOTE_ONESHOT_EMERGE
@ EMOTE_ONESHOT_SALUTE
@ CHAT_MSG_MONSTER_YELL
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ TARGET_UNIT_SRC_AREA_ENEMY
@ TEAM_OTHER
@ LOOT_MODE_HARD_MODE_3
@ LOOT_MODE_HARD_MODE_1
@ LOOT_MODE_HARD_MODE_2
@ LOOT_MODE_HARD_MODE_4
SpellCastResult
@ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW
@ SPELL_STATE_CASTING
Definition Spell.h:266
@ 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
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
#define sSpellMgr
Definition SpellMgr.h:744
#define SpellCheckCastFn(F)
#define AuraEffectProcFn(F, I, N)
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define SpellCastFn(F)
#define AuraEffectAbsorbFn(F, I)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraCheckAreaTargetFn(F)
#define AuraEffectRemoveFn(F, I, N, M)
@ UNIT_NPC_FLAG_GOSSIP
Definition Unit.h:687
@ SPELLVALUE_AURA_STACK
Definition Unit.h:119
@ SPELLVALUE_MAX_TARGETS
Definition Unit.h:118
@ SPELLVALUE_BASE_POINT0
Definition Unit.h:114
@ AURA_REMOVE_BY_DEATH
Definition Unit.h:411
@ AURA_REMOVE_BY_EXPIRE
Definition Unit.h:410
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition Unit.h:409
@ TRIGGERED_FULL_MASK
Will ignore most target checks (mostly DBC target checks).
Definition Unit.h:435
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:1110
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ REACT_PASSIVE
Definition Unit.h:1156
@ REACT_AGGRESSIVE
Definition Unit.h:1158
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_NPC_FLAGS
@ UNIT_FIELD_FLAGS
float frand(float min, float max)
Definition Util.cpp:39
bool roll_chance_i(int chance)
Definition Util.h:89
T CalculatePct(T base, U pct)
Definition Util.h:103
@ ACTION_PHASE_TWO
Position const centerPos
@ PHASE_TRANSFORM
Definition boss_buru.cpp:41
@ SPELL_SHADOW_NOVA
@ SPELL_KNOCK_AWAY
Definition boss_gyth.cpp:16
@ PHASE_ONE
@ PHASE_THREE
@ PHASE_TWO
@ SPELL_FLASH_FREEZE
@ SPELL_FLASH_FREEZE_VISUAL
@ SPELL_DRAIN_LIFE
@ SPELL_CRUSH
@ EVENT_GROUP_SUMMON_TENTACLES
@ SOUND_LUNATIC_GAZE
@ ACHIEV_TIMED_START_EVENT
@ 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_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_SQUEEZE
@ 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_KNOCK_AWAY
@ SPELL_PHASE_3_TRANSFORM
@ SPELL_BLACK_PLAGUE
@ SPELL_FURY_OF_THE_STORM
@ SPELL_INSANE_VISUAL
@ SPELL_DRAINING_POISON
@ SPELL_ILLUSION_ROOM
@ SPELL_DESTABILIZATION_MATRIX
@ SPELL_FULL_HEAL
@ SPELL_INSANE_PERIODIC
@ SPELL_LUNATIC_GAZE
@ SPELL_SUMMON_GUARDIAN_2
@ 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_DIMINISH_POWER
@ SPELL_SHADOW_BEACON
@ SPELL_TENTACLE_VOID_ZONE_2
@ SPELL_CRUSH
@ PHASE_ONE
@ PHASE_THREE
@ PHASE_TRANSFORM
@ PHASE_TWO
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:143
uint32 m_scriptSpellId
Definition SpellScript.h:95
int32 GetAmount() const
void PreventDefaultAction()
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
HookList< EffectApplyHandler > AfterEffectApply
Unit * GetCaster() const
HookList< EffectAbsorbHandler > OnEffectAbsorb
HookList< CheckAreaTargetHandler > DoCheckAreaTarget
Unit * GetTarget() const
HookList< EffectApplyHandler > OnEffectRemove
HookList< EffectProcHandler > OnEffectProc
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
BossAI(Creature *creature, uint32 bossId)
void JustDied(Unit *) OVERRIDE
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:56
virtual void EnterEvadeMode()
CreatureScript(const char *name)
Unit * GetAttacker() const
Definition Unit.h:899
uint32 GetDamage() const
Definition Unit.h:923
bool operator()(WorldObject *object)
bool operator()(WorldObject *object)
MapRefManager PlayerList
Definition Map.h:406
iterator end()
iterator begin()
LinkedListHead::Iterator< MapReference const > const_iterator
void SetWalk(bool enable)
static Creature * GetCreature(WorldObject const &u, uint64 guid)
static Player * GetPlayer(WorldObject const &, uint64 guid)
TypeID GetTypeId() const
Definition Object.h:131
Creature * ToCreature()
Definition Object.h:207
Unit * ToUnit()
Definition Object.h:210
PassiveAI(Creature *c)
Definition PassiveAI.cpp:10
DamageInfo * GetDamageInfo() const
Definition Unit.h:985
SanityReduction(uint8 stacks)
void RemoveSanity(SpellEffIndex)
Definition Spell.h:289
void SetSpellValue(SpellValueMod mod, int32 value)
Definition Spell.cpp:7659
uint32 Id
Definition SpellInfo.h:160
HookList< CastHandler > AfterCast
HookList< CheckCastHandler > OnCheckCast
SpellInfo const * GetSpellInfo()
HookList< EffectHandler > OnEffectHitTarget
Unit * GetHitUnit()
int32 GetEffectValue()
HookList< CastHandler > BeforeCast
Spell * GetSpell()
Unit * GetCaster()
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
SpellScriptLoader(const char *name)
StartAttackEvent(Creature *summoner, Creature *owner)
bool Execute(uint64, uint32)
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
Unit * SelectTarget(SelectAggroTarget targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, int32 aura=0)
Definition UnitAI.cpp:66
void DoCastAOE(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:176
Definition Unit.h:1367
bool HealthAbovePct(int32 pct) const
Definition Unit.h:1621
float GetHealthPct() const
Definition Unit.h:1629
void Kill(Unit *victim, bool durabilityLoss=true)
Definition Unit.cpp:6342
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
void RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID=0, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
void CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
UnitAI * GetAI()
Definition Unit.h:1393
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true)
Definition Unit.cpp:1365
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
void OnApply(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_yogg_saron_empowered_AuraScript)
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
void OnApply(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_yogg_saron_insane_AuraScript)
SpellScript * GetSpellScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
PrepareSpellScript(spell_yogg_saron_lunge_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
void OnRemove(AuraEffect const *aurEff, AuraEffectHandleModes)
AuraScript * GetAuraScript() const OVERRIDE
PrepareSpellScript(spell_yogg_saron_psychosis_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_yogg_saron_sanity_AuraScript)
PrepareSpellScript(spell_yogg_saron_sanity_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_yogg_saron_squeeze_AuraScript)
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
@ NPC_MALYGOS
std::vector< Vector3 > PointsArray
@ ACHIEV_TIMED_START_EVENT
float m_positionZ
Definition Object.h:289
float m_positionX
Definition Object.h:287
float m_positionY
Definition Object.h:288
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
void SetCombatMovement(bool allowMovement)
Creature * me
ScriptedAI(Creature *creature)
void DamageTaken(Unit *, uint32 &damage) OVERRIDE
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void SpellHitTarget(Unit *, SpellInfo const *spell) OVERRIDE
void SetLinkBetween(uint64 player1, uint64 player2)
void JustSummoned(Creature *summon) OVERRIDE
boss_saraAI(Creature *creature)
void EnterCombat(Unit *) OVERRIDE
void DamageTaken(Unit *, uint32 &damage) OVERRIDE
void RemoveLinkFrom(uint64 player1)
std::map< uint64, uint64 > _linkData
void DoAction(int32 action) OVERRIDE
void KilledUnit(Unit *victim) OVERRIDE
uint64 GetLinkedPlayerGUID(uint64 guid) const
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHit(Unit *, SpellInfo const *spell) OVERRIDE
void DoAction(int32 action) OVERRIDE
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void PassengerBoarded(Unit *passenger, int8, bool apply) OVERRIDE
== Fields =======================================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void OnSpellClick(Unit *clicker, bool &result) OVERRIDE
npc_garonaAI(Creature *creature)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void DamageTaken(Unit *, uint32 &damage) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void sGossipSelect(Player *player, uint32 sender, uint32) OVERRIDE
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void FillCirclePath(Position const &centerPos, float radius, float z, Movement::PointsArray &path, bool clockwise)
void MovementInform(uint32 type, uint32 pointId) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
@ ICECROWN_ILLUSION
Definition ulduar.h:331
@ STORMWIND_ILLUSION
Definition ulduar.h:332
@ CHAMBER_ILLUSION
Definition ulduar.h:330
@ BOSS_YOGG_SARON
Definition ulduar.h:35
@ DATA_SARA
Definition ulduar.h:285
@ DATA_DRIVE_ME_CRAZY
Definition ulduar.h:292
@ DATA_ILLUSION
Definition ulduar.h:291
@ DATA_MIMIRON_YS
Definition ulduar.h:290
@ DATA_KEEPERS_COUNT
Definition ulduar.h:293
@ DATA_FREYA_YS
Definition ulduar.h:287
@ DATA_BRAIN_OF_YOGG_SARON
Definition ulduar.h:286
@ DATA_VOICE_OF_YOGG_SARON
Definition ulduar.h:284
@ DATA_THORIM_YS
Definition ulduar.h:289
@ GO_BRAIN_ROOM_DOOR_3
Definition ulduar.h:202
@ GO_BRAIN_ROOM_DOOR_1
Definition ulduar.h:200
AI * GetUlduarAI(T *obj)
Definition ulduar.h:336
@ NPC_INFLUENCE_TENTACLE
Definition ulduar.h:131
@ NPC_KING_LLANE
Definition ulduar.h:122
@ NPC_OMINOUS_CLOUD
Definition ulduar.h:116
@ NPC_HODIR_OBSERVATION_RING
Definition ulduar.h:111
@ NPC_MIMIRON_OBSERVATION_RING
Definition ulduar.h:114
@ NPC_DEATH_RAY
Definition ulduar.h:128
@ NPC_IMMORTAL_GUARDIAN
Definition ulduar.h:136
@ NPC_DESCEND_INTO_MADNESS
Definition ulduar.h:138
@ NPC_YOGG_SARON
Definition ulduar.h:67
@ NPC_THORIM_YS
Definition ulduar.h:120
@ NPC_CONSTRICTOR_TENTACLE
Definition ulduar.h:134
@ NPC_CORRUPTOR_TENTACLE
Definition ulduar.h:135
@ NPC_SANITY_WELL
Definition ulduar.h:137
@ NPC_FREYA_OBSERVATION_RING
Definition ulduar.h:112
@ NPC_HODIR_YS
Definition ulduar.h:118
@ NPC_THORIM_OBSERVATION_RING
Definition ulduar.h:113
@ NPC_CRUSHER_TENTACLE
Definition ulduar.h:133
@ NPC_NELTHARION
Definition ulduar.h:126
@ NPC_IMMOLATED_CHAMPION
Definition ulduar.h:124
@ NPC_MARKED_IMMORTAL_GUARDIAN
Definition ulduar.h:139
@ NPC_TURNED_CHAMPION
Definition ulduar.h:132
@ NPC_MIMIRON_YS
Definition ulduar.h:119
@ NPC_SUIT_OF_ARMOR
Definition ulduar.h:121
@ NPC_DEATH_ORB
Definition ulduar.h:129
@ NPC_FREYA_YS
Definition ulduar.h:117
@ NPC_YSERA
Definition ulduar.h:125
@ NPC_GUARDIAN_OF_YOGG_SARON
Definition ulduar.h:110