Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_the_lich_king.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 "ObjectMgr.h"
7#include "ScriptMgr.h"
8#include "ScriptedCreature.h"
9#include "SpellScript.h"
10#include "SpellAuraEffects.h"
11#include "Spell.h"
12#include "Vehicle.h"
13#include "Cell.h"
14#include "CellImpl.h"
15#include "GridNotifiers.h"
16#include "GridNotifiersImpl.h"
17#include "CreatureTextMgr.h"
18#include "icecrown_citadel.h"
19
60
62{
63 // The Lich King
64 SPELL_PLAGUE_AVOIDANCE = 72846, // raging spirits also get it
69
70 // Phase 1
74 SPELL_INFEST = 70541,
81
82 // Phase Transition
95 SPELL_QUAKE = 72262,
96
97 // Phase 2
98 SPELL_DEFILE = 72762,
103 SPELL_HARVEST_SOUL_VALKYR = 68985, // Val'kyr Shadowguard vehicle aura
108 SPELL_CHARGE = 74399, // cast on selected target
109 SPELL_VALKYR_CARRY = 74445, // removes unselectable flag
113
114 // Phase 3
120 SPELL_HARVEST_SOULS = 73654, // Heroic version, weird because it has all 4 difficulties just like above spell
130
131 // Frostmourne
134 SPELL_RESTORE_SOULS = 73650, // Heroic
135 SPELL_DARK_HUNGER = 69383, // Passive proc healing
137 SPELL_DESTROY_SOUL = 74086, // Used when Terenas Menethil dies
138 SPELL_SOUL_RIP = 69397, // Deals increasing damage
141 SPELL_SUMMON_SPIRIT_BOMB_1 = 73581, // (Heroic)
142 SPELL_SUMMON_SPIRIT_BOMB_2 = 74299, // (Heroic)
143 SPELL_EXPLOSION = 73576, // Spirit Bomb (Heroic)
145
146 // Outro
152 SPELL_JUMP = 71809,
157 SPELL_SUMMON_BROKEN_FROSTMOURNE_3 = 73017, // real summon
165
166 // Shambling Horror
170};
171
172#define NECROTIC_PLAGUE_LK RAID_MODE<uint32>(70337, 73912, 73913, 73914)
173#define NECROTIC_PLAGUE_PLR RAID_MODE<uint32>(70338, 73785, 73786, 73787)
174#define REMORSELESS_WINTER_1 RAID_MODE<uint32>(68981, 74270, 74271, 74272)
175#define REMORSELESS_WINTER_2 RAID_MODE<uint32>(72259, 74273, 74274, 74275)
176#define SUMMON_VALKYR RAID_MODE<uint32>(69037, 74361, 69037, 74361)
177#define HARVEST_SOUL RAID_MODE<uint32>(68980, 74325, 74296, 74297)
178
180{
181 // The Lich King
182 // intro events
192
193 // combat events
198 EVENT_SHADOW_TRAP = 14, // heroic only
201 EVENT_HARVEST_SOUL = 17, // normal mode only
209 EVENT_LIFE_SIPHON = 25, // heroic only
213 EVENT_HARVEST_SOULS = 29, // heroic only
242
243 // Shambling Horror
246
247 // Raging Spirit
249
250 // Strangulate Vehicle (Harvest Soul)
254};
255
261
263{
269 PHASE_FROSTMOURNE = 6, // only set on heroic mode when all players are sent into frostmourne
271};
272
273#define PHASE_TWO_THREE (events.IsInPhase(PHASE_TWO) ? PHASE_TWO : PHASE_THREE)
274
275Position const CenterPosition = {503.6282f, -2124.655f, 840.8569f, 0.0f};
276Position const TirionIntro = {489.2970f, -2124.840f, 840.8569f, 0.0f};
277Position const TirionCharge = {482.9019f, -2124.479f, 840.8570f, 0.0f};
279{
280 {432.0851f, -2123.673f, 864.6582f, 0.0f},
281 {457.8351f, -2123.423f, 841.1582f, 0.0f},
282 {465.0730f, -2123.470f, 840.8569f, 0.0f},
283};
284Position const OutroPosition1 = {493.6286f, -2124.569f, 840.8569f, 0.0f};
285Position const OutroFlying = {508.9897f, -2124.561f, 845.3565f, 0.0f};
286Position const TerenasSpawn = {495.5542f, -2517.012f, 1050.000f, 4.6993f};
287Position const TerenasSpawnHeroic = {495.7080f, -2523.760f, 1050.000f, 0.0f};
288Position const SpiritWardenSpawn = {495.3406f, -2529.983f, 1050.000f, 1.5592f};
289
307
320
322{
325
327 MUSIC_SPECIAL = 17458, // Summon Shambling Horror, Remorseless Winter, Quake, Summon Val'kyr Periodic, Harvest Soul, Vile Spirits
329 MUSIC_FINAL = 17460, // Raise Dead, Light's Blessing
330
331 SOUND_PAIN = 17360, // separate sound, not attached to any text
332
335};
336
338{
340 DATA_VILE = 45814622
341};
342
344{
345 public:
346 NecroticPlagueTargetCheck(Unit const* obj, uint32 notAura1 = 0, uint32 notAura2 = 0)
347 : _sourceObj(obj), _notAura1(notAura1), _notAura2(notAura2)
348 {
349 }
350
351 bool operator()(Unit* unit) const
352 {
353 if (!unit || unit == _sourceObj || !unit->isTargetableForAttack() || unit->IsTotem() || unit->HasAura(SPELL_PLAGUE_AVOIDANCE))
354 return false;
355 if ((_notAura1 && unit->HasAura(_notAura1)) || (_notAura2 && unit->HasAura(_notAura2)))
356 return false;
357 return true;
358 }
359
360 private:
364};
365
367{
368 public:
370
372 {
373 switch (go->GetEntry())
374 {
377 break;
380 break;
383 break;
388 go->ResetDoorOrButton();
389 break;
390 default:
391 break;
392 }
393
394 return false;
395 }
396};
397
399{
400 public:
402 : _summoner(summoner), _owner(owner)
403 {
404 }
405
406 bool Execute(uint64 /*time*/, uint32 /*diff*/)
407 {
408 _owner->SetReactState(REACT_AGGRESSIVE);
409 if (Unit* target = _summoner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(_summoner)))
410 _owner->AI()->AttackStart(target);
411 return true;
412 }
413
414 private:
417};
418
420{
421 public:
423 : _owner(owner)
424 {
425 }
426
427 bool Execute(uint64 /*time*/, uint32 /*diff*/)
428 {
429 _owner->SetReactState(REACT_AGGRESSIVE);
431 _owner->CastSpell((Unit*)NULL, SPELL_VILE_SPIRIT_DAMAGE_SEARCH, true);
432 return true;
433 }
434
435 private:
437};
438
440{
441 public:
443 : _owner(owner), _counter(13)
444 {
445 }
446
447 bool Execute(uint64 /*time*/, uint32 /*diff*/)
448 {
449 _owner->CastCustomSpell(SPELL_TRIGGER_VILE_SPIRIT_HEROIC, SPELLVALUE_MAX_TARGETS, 1, NULL, true);
450
451 if (--_counter)
452 {
453 _owner->m_Events.AddEvent(this, _owner->m_Events.CalculateTime(3000));
454 return false;
455 }
456
457 return true;
458 }
459
460 private:
463};
464
466{
467 public:
468 boss_the_lich_king() : CreatureScript("boss_the_lich_king") { }
469
471 {
473 {
474 }
475
477 {
478 _Reset();
479 me->SetReactState(REACT_PASSIVE);
480 events.SetPhase(PHASE_INTRO);
483 SetEquipmentSlots(true);
484 }
485
486 void JustDied(Unit* /*killer*/) OVERRIDE
487 {
488 _JustDied();
490 me->SetDisableGravity(false);
492 me->GetMotionMaster()->MoveFall();
493 if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f))
494 frostmourne->DespawnOrUnsummon();
495 }
496
498 {
499 if (!instance->CheckRequiredBosses(DATA_THE_LICH_KING, target->ToPlayer()))
500 {
502 instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
503 return;
504 }
505
506 me->setActive(true);
508
509 events.SetPhase(PHASE_ONE);
510 events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 20000, 0, PHASE_ONE);
511 events.ScheduleEvent(EVENT_SUMMON_DRUDGE_GHOUL, 10000, 0, PHASE_ONE);
512 events.ScheduleEvent(EVENT_INFEST, 5000, 0, PHASE_ONE);
513 events.ScheduleEvent(EVENT_NECROTIC_PLAGUE, std::rand() % 33000 + 30000, 0, PHASE_ONE);
514 events.ScheduleEvent(EVENT_BERSERK, 900000, EVENT_GROUP_BERSERK);
515 if (IsHeroic())
516 events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500, 0, PHASE_ONE);
517 }
518
520 {
523
524 // Reset The Frozen Throne gameobjects
527 me->VisitNearbyGridObject(333.0f, worker);
528
529 // Reset any light override
530 SendLightOverride(0, 5000);
531 }
532
533 bool CanAIAttack(Unit const* target) const OVERRIDE
534 {
535 // The Lich King must not select targets in frostmourne room if he killed everyone outside
536 return !target->HasAura(SPELL_IN_FROSTMOURNE_ROOM);
537 }
538
549
551 {
552 if (victim->GetTypeId() == TypeID::TYPEID_PLAYER && !me->IsInEvadeMode() && !events.IsInPhase(PHASE_OUTRO))
554 }
555
557 {
558 switch (action)
559 {
564 // schedule talks
565 me->SetStandState(UNIT_STAND_STATE_STAND);
566 events.ScheduleEvent(EVENT_INTRO_MOVE_1, 4000);
567 break;
569 events.ScheduleEvent(EVENT_START_ATTACK, 5000);
570 break;
573 break;
575 SendLightOverride(0, 5000);
576 break;
581 events.ScheduleEvent(EVENT_OUTRO_TALK_6, 2500, 0, PHASE_OUTRO);
582 break;
584 events.ScheduleEvent(EVENT_OUTRO_TALK_7, 7000, 0, PHASE_OUTRO);
585 events.ScheduleEvent(EVENT_OUTRO_TALK_8, 17000, 0, PHASE_OUTRO);
586 break;
588 {
590 summons.DoAction(ACTION_TELEPORT_BACK, pred);
591 if (!IsHeroic())
593 break;
594 }
595 default:
596 break;
597 }
598 }
599
601 {
602 switch (type)
603 {
606 case DATA_VILE:
608 default:
609 break;
610 }
611
612 return 0;
613 }
614
615 void SetData(uint32 type, uint32 value) OVERRIDE
616 {
617 switch (type)
618 {
621 break;
622 case DATA_VILE:
623 _vileSpiritExplosions += value;
624 break;
625 default:
626 break;
627 }
628 }
629
630 void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) OVERRIDE
631 {
632 if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(70))
633 {
634 events.SetPhase(PHASE_TRANSITION);
635 me->SetReactState(REACT_PASSIVE);
636 me->AttackStop();
637 me->GetMotionMaster()->MovePoint(POINT_CENTER_1, CenterPosition);
638 return;
639 }
640
641 if (events.IsInPhase(PHASE_TWO) && !HealthAbovePct(40))
642 {
643 events.SetPhase(PHASE_TRANSITION);
644 me->SetReactState(REACT_PASSIVE);
645 me->AttackStop();
646 me->GetMotionMaster()->MovePoint(POINT_CENTER_2, CenterPosition);
647 return;
648 }
649
650 if (events.IsInPhase(PHASE_THREE) && !HealthAbovePct(10))
651 {
652 me->SetReactState(REACT_PASSIVE);
653 me->AttackStop();
654 events.Reset();
655 events.SetPhase(PHASE_OUTRO);
656 summons.DespawnAll();
658 me->InterruptNonMeleeSpells(true);
659 me->CastSpell((Unit*)NULL, SPELL_FURY_OF_FROSTMOURNE, TRIGGERED_NONE);
660 me->SetWalk(true);
661 events.ScheduleEvent(EVENT_OUTRO_TALK_1, 2600, 0, PHASE_OUTRO);
662 events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 6600, 0, PHASE_OUTRO);
663 events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 17600, 0, PHASE_OUTRO);
664 events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 27600, 0, PHASE_OUTRO);
665 events.ScheduleEvent(EVENT_OUTRO_TALK_2, 34600, 0, PHASE_OUTRO);
666 events.ScheduleEvent(EVENT_OUTRO_TALK_3, 43600, 0, PHASE_OUTRO);
667 events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 54600, 0, PHASE_OUTRO);
668 events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 58600, 0, PHASE_OUTRO);
669 events.ScheduleEvent(EVENT_OUTRO_MOVE_CENTER, 69600, 0, PHASE_OUTRO);
670 // stop here. rest will get scheduled from MovementInform
671 return;
672 }
673 }
674
676 {
677 switch (summon->GetEntry())
678 {
680 case NPC_DRUDGE_GHOUL:
681 summon->CastSpell(summon, SPELL_RISEN_WITCH_DOCTOR_SPAWN, true);
682 summon->SetReactState(REACT_PASSIVE);
683 summon->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
684 summon->m_Events.AddEvent(new StartMovementEvent(me, summon), summon->m_Events.CalculateTime(5000));
685 break;
686 case NPC_ICE_SPHERE:
687 {
688 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
689 {
690 summon->SetReactState(REACT_PASSIVE);
691 summon->CastSpell(summon, SPELL_ICE_SPHERE, false);
692 summon->CastSpell(summon, SPELL_ICE_BURST_TARGET_SEARCH, false);
693 summon->CastSpell(target, SPELL_ICE_PULSE, false);
694 summon->ClearUnitState(UNIT_STATE_CASTING);
695 summon->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f);
696 }
697 else
698 summon->DespawnOrUnsummon();
699 break;
700 }
701 case NPC_DEFILE:
702 summon->SetReactState(REACT_PASSIVE);
703 summon->CastSpell(summon, SPELL_DEFILE_AURA, false);
704 break;
706 {
707 summon->CastSpell((Unit*)NULL, SPELL_BROKEN_FROSTMOURNE, true);
708
711
712 events.ScheduleEvent(EVENT_OUTRO_SOUL_BARRAGE, 5000, 0, PHASE_OUTRO);
713 return;
714 }
715 case NPC_VILE_SPIRIT:
716 {
717 summons.Summon(summon);
718 summon->SetReactState(REACT_PASSIVE);
719 summon->SetSpeed(MOVE_FLIGHT, 0.5f);
720 summon->GetMotionMaster()->MoveRandom(10.0f);
721 if (!events.IsInPhase(PHASE_FROSTMOURNE))
722 summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000));
723 return;
724 }
726 summons.Summon(summon);
727 return;
728 default:
729 break;
730 }
731
732 BossAI::JustSummoned(summon);
733 }
734
735 void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) OVERRIDE
736 {
737 switch (summon->GetEntry())
738 {
740 case NPC_DRUDGE_GHOUL:
741 case NPC_ICE_SPHERE:
744 case NPC_VILE_SPIRIT:
745 summon->ToTempSummon()->SetTempSummonType(TempSummonType::TEMPSUMMON_CORPSE_DESPAWN);
746 break;
747 default:
748 break;
749 }
750 }
751
752 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
753 {
754 if (spell->Id == SPELL_HARVESTED_SOUL && me->IsInCombat() && !IsHeroic())
756 }
757
758 void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) OVERRIDE
759 {
760 if (spell->Id == REMORSELESS_WINTER_1 || spell->Id == REMORSELESS_WINTER_2)
761 {
764 }
765 }
766
768 {
769 if (type != POINT_MOTION_TYPE)
770 return;
771
772 switch (pointId)
773 {
774 case POINT_LK_INTRO_1:
775 // schedule for next update cycle, current update must finalize movement
776 events.ScheduleEvent(EVENT_INTRO_MOVE_2, 1, 0, PHASE_INTRO);
777 break;
778 case POINT_LK_INTRO_2:
779 events.ScheduleEvent(EVENT_INTRO_MOVE_3, 1, 0, PHASE_INTRO);
780 break;
781 case POINT_LK_INTRO_3:
783 tirion->AI()->DoAction(ACTION_CONTINUE_INTRO);
784 events.ScheduleEvent(EVENT_INTRO_TALK_1, 9000, 0, PHASE_INTRO);
785 break;
786 case POINT_CENTER_1:
787 me->SetFacingTo(0.0f);
791 events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions
792 events.ScheduleEvent(EVENT_QUAKE, 62500, 0, PHASE_TRANSITION);
793 events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 4000, 0, PHASE_TRANSITION);
794 events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8000, 0, PHASE_TRANSITION);
795 events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 3000, 0, PHASE_TRANSITION);
796 events.ScheduleEvent(EVENT_SUMMON_VALKYR, 78000, 0, PHASE_TWO);
797 events.ScheduleEvent(EVENT_INFEST, 70000, 0, PHASE_TWO);
798 events.ScheduleEvent(EVENT_DEFILE, 97000, 0, PHASE_TWO);
799 events.ScheduleEvent(EVENT_SOUL_REAPER, 94000, 0, PHASE_TWO);
800 break;
801 case POINT_CENTER_2:
802 me->SetFacingTo(0.0f);
806 summons.DespawnEntry(NPC_VALKYR_SHADOWGUARD);
807 events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions
808 events.ScheduleEvent(EVENT_QUAKE_2, 62500, 0, PHASE_TRANSITION);
809 events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 6000, 0, PHASE_TRANSITION);
810 events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8000, 0, PHASE_TRANSITION);
811 events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 5000, 0, PHASE_TRANSITION);
812 events.ScheduleEvent(EVENT_DEFILE, 95500, 0, PHASE_THREE);
813 events.ScheduleEvent(EVENT_SOUL_REAPER, 99500, 0, PHASE_THREE);
815 events.ScheduleEvent(IsHeroic() ? EVENT_HARVEST_SOULS : EVENT_HARVEST_SOUL, 73500, 0, PHASE_THREE);
816 break;
817 case POINT_LK_OUTRO_1:
818 events.ScheduleEvent(EVENT_OUTRO_TALK_4, 1, 0, PHASE_OUTRO);
819 events.ScheduleEvent(EVENT_OUTRO_RAISE_DEAD, 1000, 0, PHASE_OUTRO);
820 events.ScheduleEvent(EVENT_OUTRO_TALK_5, 29000, 0, PHASE_OUTRO);
821 break;
822 case POINT_LK_OUTRO_2:
824 tirion->AI()->Talk(SAY_TIRION_OUTRO_2);
825 if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f))
826 frostmourne->AI()->DoAction(ACTION_SUMMON_TERENAS);
827 break;
828 default:
829 break;
830 }
831 }
832
834 {
835 // check phase first to prevent updating victim and entering evade mode when not wanted
836 if (!(events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_INTRO) || events.IsInPhase(PHASE_FROSTMOURNE)))
837 if (!UpdateVictim())
838 return;
839
840 events.Update(diff);
841
842 // during Remorseless Winter phases The Lich King is channeling a spell, but we must continue casting other spells
843 if (me->HasUnitState(UNIT_STATE_CASTING) && !(events.IsInPhase(PHASE_TRANSITION) || events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_FROSTMOURNE)))
844 return;
845
846 while (uint32 eventId = events.ExecuteEvent())
847 {
848 switch (eventId)
849 {
851 me->SetSheath(SHEATH_STATE_MELEE);
852 me->RemoveAurasDueToSpell(SPELL_EMOTE_SIT_NO_SHEATH);
853 me->SetWalk(true);
854 me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_1, LichKingIntro[0]);
855 break;
857 me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_2, LichKingIntro[1]);
858 break;
860 me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_3, LichKingIntro[2]);
861 break;
864 // for some reason blizz sends 2 emotes in row here so (we handle one in Talk)
865 me->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NO_SHEATHE);
866 events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 7000, 0, PHASE_INTRO);
867 events.ScheduleEvent(EVENT_INTRO_EMOTE_1, 13000, 0, PHASE_INTRO);
868 events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 18000, 0, PHASE_INTRO);
869 events.ScheduleEvent(EVENT_INTRO_CAST_FREEZE, 31000, 0, PHASE_INTRO);
870 break;
873 break;
875 me->HandleEmoteCommand(EMOTE_ONESHOT_POINT_NO_SHEATHE);
876 break;
880 events.ScheduleEvent(EVENT_FINISH_INTRO, 1000, 0, PHASE_INTRO);
881 break;
883 me->SetWalk(false);
885 me->SetReactState(REACT_AGGRESSIVE);
886 events.SetPhase(PHASE_ONE);
887 break;
891 events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 60000, 0, PHASE_ONE);
892 break;
895 events.ScheduleEvent(EVENT_SUMMON_DRUDGE_GHOUL, 30000, 0, PHASE_ONE);
896 break;
897 case EVENT_INFEST:
899 events.ScheduleEvent(EVENT_INFEST, std::rand() % 24000 + 21000, 0, events.IsInPhase(PHASE_ONE) ? PHASE_ONE : PHASE_TWO);
900 break;
903 {
906 }
907 events.ScheduleEvent(EVENT_NECROTIC_PLAGUE, std::rand() % 33000 + 30000, 0, PHASE_ONE);
908 break;
911 DoCast(target, SPELL_SHADOW_TRAP);
912 events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500, 0, PHASE_ONE);
913 break;
916 events.ScheduleEvent(EVENT_SOUL_REAPER, std::rand() % 35000 + 33000, 0, PHASE_TWO_THREE);
917 break;
918 case EVENT_DEFILE:
919 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_HARVEST_SOUL_VALKYR))
920 {
922 DoCast(target, SPELL_DEFILE);
923 }
924 events.ScheduleEvent(EVENT_DEFILE, std::rand() % 35000 + 32000, 0, PHASE_TWO_THREE);
925 break;
929 DoCast(target, SPELL_HARVEST_SOUL);
930 events.ScheduleEvent(EVENT_HARVEST_SOUL, 75000, 0, PHASE_THREE);
931 break;
933 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
934 me->CastSpell(target, SPELL_PAIN_AND_SUFFERING, TRIGGERED_NONE);
935 events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, std::rand() % 4000 + 1000, 0, PHASE_TRANSITION);
936 break;
939 events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, std::rand() % 8500 + 7500, 0, PHASE_TRANSITION);
940 break;
942 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
943 me->CastSpell(target, SPELL_RAGING_SPIRIT, TRIGGERED_NONE);
944 events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, std::rand() % 23000 + 22000, 0, PHASE_TRANSITION);
945 break;
946 case EVENT_QUAKE:
947 events.SetPhase(PHASE_TWO);
948 me->ClearUnitState(UNIT_STATE_CASTING); // clear state to ensure check in DoCastAOE passes
952 break;
953 case EVENT_QUAKE_2:
954 events.SetPhase(PHASE_THREE);
955 me->ClearUnitState(UNIT_STATE_CASTING); // clear state to ensure check in DoCastAOE passes
959 break;
964 events.ScheduleEvent(EVENT_SUMMON_VALKYR, std::rand() % 50000 + 45000, 0, PHASE_TWO);
965 break;
967 me->SetReactState(REACT_AGGRESSIVE);
968 if (events.IsInPhase(PHASE_FROSTMOURNE))
969 events.SetPhase(PHASE_THREE);
970 break;
974 events.ScheduleEvent(EVENT_VILE_SPIRITS, std::rand() % 40000 + 35000, EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);
975 break;
979 events.ScheduleEvent(EVENT_HARVEST_SOULS, std::rand() % 110000 + 100000, 0, PHASE_THREE);
980 events.SetPhase(PHASE_FROSTMOURNE); // will stop running UpdateVictim (no evading)
981 me->SetReactState(REACT_PASSIVE);
982 me->AttackStop();
983 events.DelayEvents(50000, EVENT_GROUP_VILE_SPIRITS);
984 events.RescheduleEvent(EVENT_DEFILE, 50000, 0, PHASE_THREE);
985 events.RescheduleEvent(EVENT_SOUL_REAPER, std::rand() % 62000 + 57000, 0, PHASE_THREE);
986 events.ScheduleEvent(EVENT_START_ATTACK, 49000);
987 events.ScheduleEvent(EVENT_FROSTMOURNE_HEROIC, 6500);
988 break;
990 if (TempSummon* terenas = me->GetMap()->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE_H, TerenasSpawnHeroic, NULL, 50000))
991 {
992 terenas->AI()->DoAction(ACTION_FROSTMOURNE_INTRO);
993 std::list<Creature*> triggers;
995 if (!triggers.empty())
996 {
997 triggers.sort(Skyfire::ObjectDistanceOrderPred(terenas, true));
998 Creature* spawner = triggers.front();
999 spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_1, true); // summons bombs randomly
1000 spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_2, true); // summons bombs on players
1001 spawner->m_Events.AddEvent(new TriggerWickedSpirit(spawner), spawner->m_Events.CalculateTime(3000));
1002 }
1003
1004 for (SummonList::iterator i = summons.begin(); i != summons.end(); ++i)
1005 {
1006 Creature* summon = ObjectAccessor::GetCreature(*me, *i);
1007 if (summon && summon->GetEntry() == NPC_VILE_SPIRIT)
1008 {
1009 summon->m_Events.KillAllEvents(true);
1010 summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(50000));
1011 summon->GetMotionMaster()->MoveRandom(10.0f);
1013 }
1014 }
1015 }
1016 break;
1017 case EVENT_OUTRO_TALK_1:
1020 break;
1021 case EVENT_OUTRO_TALK_2:
1024 break;
1026 me->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NO_SHEATHE);
1027 break;
1028 case EVENT_OUTRO_TALK_3:
1030 me->SetFacingToObject(tirion);
1032 break;
1034 me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_1, CenterPosition);
1035 break;
1036 case EVENT_OUTRO_TALK_4:
1037 me->SetFacingTo(0.01745329f);
1039 break;
1042 me->ClearUnitState(UNIT_STATE_CASTING);
1044 break;
1045 case EVENT_OUTRO_TALK_5:
1048 tirion->AI()->DoAction(ACTION_OUTRO);
1049 break;
1050 case EVENT_OUTRO_TALK_6:
1053 tirion->SetFacingToObject(me);
1056 break;
1060 // set flight
1061 me->SetDisableGravity(true);
1063 me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_2, OutroFlying);
1064 break;
1065 case EVENT_OUTRO_TALK_7:
1067 break;
1068 case EVENT_OUTRO_TALK_8:
1070 break;
1071 case EVENT_BERSERK:
1074 break;
1075 default:
1076 break;
1077 }
1078 }
1079
1081 }
1082
1083 private:
1084 void SendMusicToPlayers(uint32 /*musicId*/) const
1085 {
1087 //WorldPacket data(SMSG_PLAY_MUSIC, 4);
1088 //data << uint32(musicId);
1089 //data << uint64(me->GetGUID());
1090 //SendPacketToPlayers(&data);
1091 }
1092
1093 void SendLightOverride(uint32 overrideId, uint32 fadeInTime) const
1094 {
1096 data << uint32(2488); // Light.dbc entry (map default)
1097 data << uint32(overrideId); // Light.dbc entry (override)
1098 data << uint32(fadeInTime);
1099 SendPacketToPlayers(&data);
1100 }
1101
1102 void SendWeather(WeatherState weather) const
1103 {
1104 WorldPacket data(SMSG_WEATHER, 4 + 4 + 1);
1105 data << uint32(weather); // WeatherID
1106 data << float(0.5f); // Intensity
1107 data.WriteBit(false); // Abrupt
1108 data.FlushBits();
1109 SendPacketToPlayers(&data);
1110 }
1111
1112 // Send packet to all players in The Frozen Throne
1113 void SendPacketToPlayers(WorldPacket const* data) const
1114 {
1115 Map::PlayerList const& players = me->GetMap()->GetPlayers();
1116 if (!players.isEmpty())
1117 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
1118 if (Player* player = itr->GetSource())
1119 if (player->GetAreaId() == AREA_THE_FROZEN_THRONE)
1120 player->GetSession()->SendPacket(data);
1121 }
1122
1125 };
1126
1128 {
1130 }
1131};
1132
1134{
1135 public:
1136 npc_tirion_fordring_tft() : CreatureScript("npc_tirion_fordring_tft") { }
1137
1139 {
1141 _instance(creature->GetInstanceScript())
1142 {
1143 }
1144
1146 {
1147 _events.Reset();
1148 if (_instance->GetBossState(DATA_THE_LICH_KING) == DONE)
1150 }
1151
1153 {
1154 if (type != POINT_MOTION_TYPE)
1155 return;
1156
1157 switch (id)
1158 {
1159 case POINT_TIRION_INTRO:
1161 if (Creature* theLichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
1162 theLichKing->AI()->DoAction(ACTION_START_ENCOUNTER);
1163 break;
1165 _events.ScheduleEvent(EVENT_OUTRO_JUMP, 1, 0, PHASE_OUTRO);
1166 break;
1167 }
1168 }
1169
1171 {
1172 switch (action)
1173 {
1176 _events.ScheduleEvent(EVENT_INTRO_TALK_1, 34000, 0, PHASE_INTRO);
1177 break;
1178 case ACTION_OUTRO:
1179 _events.SetPhase(PHASE_OUTRO);
1180 _events.ScheduleEvent(EVENT_OUTRO_TALK_1, 7000, 0, PHASE_OUTRO);
1181 _events.ScheduleEvent(EVENT_OUTRO_BLESS, 18000, 0, PHASE_OUTRO);
1182 _events.ScheduleEvent(EVENT_OUTRO_REMOVE_ICE, 23000, 0, PHASE_OUTRO);
1183 _events.ScheduleEvent(EVENT_OUTRO_MOVE_1, 25000, 0, PHASE_OUTRO);
1184 break;
1185 }
1186 }
1187
1188 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
1189 {
1190 if (spell->Id == SPELL_ICE_LOCK)
1191 me->SetFacingTo(3.085098f);
1192 else if (spell->Id == SPELL_BROKEN_FROSTMOURNE_KNOCK)
1193 SetEquipmentSlots(true); // remove glow on ashbringer
1194 }
1195
1196 void sGossipSelect(Player* /*player*/, uint32 sender, uint32 action) OVERRIDE
1197 {
1198 if (me->GetCreatureTemplate()->GossipMenuId == sender && !action)
1199 {
1200 _events.SetPhase(PHASE_INTRO);
1202 me->SetWalk(true);
1203 me->GetMotionMaster()->MovePoint(POINT_TIRION_INTRO, TirionIntro);
1204 }
1205 }
1206
1208 {
1210
1211 if (_instance->GetBossState(DATA_THE_LICH_KING) == DONE)
1212 return;
1213
1215 }
1216
1218 {
1219 if (!UpdateVictim() && !(_events.IsInPhase(PHASE_OUTRO) || _events.IsInPhase(PHASE_INTRO)))
1220 return;
1221
1222 _events.Update(diff);
1223
1224 if (me->HasUnitState(UNIT_STATE_CASTING))
1225 return;
1226
1227 while (uint32 eventId = _events.ExecuteEvent())
1228 {
1229 switch (eventId)
1230 {
1231 case EVENT_INTRO_TALK_1:
1233 _events.ScheduleEvent(EVENT_INTRO_EMOTE_1, 2000, 0, PHASE_INTRO);
1234 _events.ScheduleEvent(EVENT_INTRO_CHARGE, 5000, 0, PHASE_INTRO);
1235 break;
1237 me->HandleEmoteCommand(EMOTE_ONESHOT_POINT_NO_SHEATHE);
1238 break;
1239 case EVENT_INTRO_CHARGE:
1240 me->SetWalk(false);
1241 me->GetMotionMaster()->MovePoint(POINT_TIRION_CHARGE, TirionCharge);
1242 break;
1243 case EVENT_OUTRO_TALK_1:
1245 break;
1246 case EVENT_OUTRO_BLESS:
1248 break;
1250 me->RemoveAurasDueToSpell(SPELL_ICE_LOCK);
1253 {
1254 me->SetFacingToObject(lichKing);
1255 lichKing->AI()->DoAction(ACTION_PLAY_MUSIC);
1256 }
1257 break;
1258 case EVENT_OUTRO_MOVE_1:
1259 me->GetMotionMaster()->MovePoint(POINT_TIRION_OUTRO_1, OutroPosition1);
1260 break;
1261 case EVENT_OUTRO_JUMP:
1263 break;
1264 default:
1265 break;
1266 }
1267 }
1268
1270 }
1271
1272 private:
1275 };
1276
1278 {
1280 }
1281};
1282
1284{
1285 public:
1286 npc_shambling_horror_icc() : CreatureScript("npc_shambling_horror_icc") { }
1287
1289 {
1291 {
1292 _frenzied = false;
1293 }
1294
1296 {
1297 _events.Reset();
1298 _events.ScheduleEvent(EVENT_SHOCKWAVE, std::rand() % 25000 + 20000);
1299 _events.ScheduleEvent(EVENT_ENRAGE, std::rand() % 14000 + 11000);
1300 }
1301
1302 void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
1303 {
1304 if (!_frenzied && IsHeroic() && me->HealthBelowPctDamaged(20, damage))
1305 {
1306 _frenzied = true;
1307 DoCast(me, SPELL_FRENZY, true);
1308 }
1309 }
1310
1312 {
1313 if (!UpdateVictim())
1314 return;
1315
1316 _events.Update(diff);
1317
1318 if (me->HasUnitState(UNIT_STATE_CASTING))
1319 return;
1320
1321 while (uint32 eventId = _events.ExecuteEvent())
1322 {
1323 switch (eventId)
1324 {
1325 case EVENT_SHOCKWAVE:
1327 _events.ScheduleEvent(EVENT_SHOCKWAVE, std::rand() % 25000 + 20000);
1328 break;
1329 case EVENT_ENRAGE:
1331 _events.ScheduleEvent(EVENT_ENRAGE, std::rand() % 25000 + 20000);
1332 break;
1333 default:
1334 break;
1335 }
1336 }
1337
1339 }
1340
1341 private:
1344 };
1345
1347 {
1349 }
1350};
1351
1353{
1354 public:
1355 npc_raging_spirit() : CreatureScript("npc_raging_spirit") { }
1356
1358 {
1360 _instance(creature->GetInstanceScript())
1361 {
1362 }
1363
1365 {
1366 _events.Reset();
1367 _events.ScheduleEvent(EVENT_SOUL_SHRIEK, std::rand() % 15000 + 12000);
1370 if (TempSummon* summon = me->ToTempSummon())
1371 if (Unit* summoner = summon->GetSummoner())
1372 summoner->CastSpell(me, SPELL_RAGING_SPIRIT_VISUAL_CLONE, true);
1374 }
1375
1376 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
1377 {
1378 // player is the spellcaster so register summon manually
1380 lichKing->AI()->JustSummoned(me);
1381 }
1382
1383 void JustDied(Unit* /*killer*/) OVERRIDE
1384 {
1386 lichKing->AI()->SummonedCreatureDespawn(me);
1387 if (TempSummon* summon = me->ToTempSummon())
1388 summon->SetTempSummonType(TempSummonType::TEMPSUMMON_CORPSE_DESPAWN);
1389 }
1390
1392 {
1393 if (!UpdateVictim())
1394 return;
1395
1396 _events.Update(diff);
1397
1398 if (me->HasUnitState(UNIT_STATE_CASTING))
1399 return;
1400
1401 while (uint32 eventId = _events.ExecuteEvent())
1402 {
1403 switch (eventId)
1404 {
1405 case EVENT_SOUL_SHRIEK:
1407 _events.ScheduleEvent(EVENT_SOUL_SHRIEK, std::rand() % 15000 + 12000);
1408 break;
1409 default:
1410 break;
1411 }
1412 }
1413
1415 }
1416
1417 private:
1420 };
1421
1423 {
1425 }
1426};
1427
1429{
1430 public:
1431 npc_valkyr_shadowguard() : CreatureScript("npc_valkyr_shadowguard") { }
1432
1434 {
1436 _grabbedPlayer(0), _instance(creature->GetInstanceScript())
1437 {
1438 }
1439
1441 {
1442 _events.Reset();
1443 me->SetReactState(REACT_PASSIVE);
1445 me->SetSpeed(MOVE_FLIGHT, 0.642857f, true);
1446 }
1447
1448 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
1449 {
1450 _events.Reset();
1451 _events.ScheduleEvent(EVENT_GRAB_PLAYER, 2500);
1452 }
1453
1454 void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
1455 {
1456 if (!IsHeroic())
1457 return;
1458
1459 if (!me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
1460 return;
1461
1462 if (me->HealthBelowPctDamaged(50, damage))
1463 {
1464 _events.Reset();
1466 me->GetMotionMaster()->MoveTargetedHome();
1467 me->ClearUnitState(UNIT_STATE_EVADE);
1468 }
1469 }
1470
1472 {
1473 // schedule siphon life event (heroic only)
1475 _events.Reset();
1476 _events.ScheduleEvent(EVENT_LIFE_SIPHON, 2000);
1477 }
1478
1479 void AttackStart(Unit* /*target*/) OVERRIDE
1480 {
1481 }
1482
1484 {
1485 if (type != POINT_MOTION_TYPE)
1486 return;
1487
1488 switch (id)
1489 {
1490 case POINT_DROP_PLAYER:
1492 me->DespawnOrUnsummon(1000);
1493 break;
1494 case POINT_CHARGE:
1496 {
1499 {
1500 std::list<Creature*> triggers;
1502 triggers.remove_if(Skyfire::HeightDifferenceCheck(platform, 5.0f, true));
1503 if (triggers.empty())
1504 return;
1505
1506 triggers.sort(Skyfire::ObjectDistanceOrderPred(me));
1507 DoCast(target, SPELL_VALKYR_CARRY);
1508 _dropPoint.Relocate(triggers.front());
1509 _events.ScheduleEvent(EVENT_MOVE_TO_DROP_POS, 1500);
1510 }
1511 }
1512 else
1513 me->DespawnOrUnsummon();
1514 break;
1515 default:
1516 break;
1517 }
1518 }
1519
1520 void SetGUID(uint64 guid, int32 /* = 0*/) OVERRIDE
1521 {
1522 _grabbedPlayer = guid;
1523 }
1524
1526 {
1527 if (!UpdateVictim())
1528 return;
1529
1530 _events.Update(diff);
1531
1532 if (me->HasUnitState(UNIT_STATE_CASTING))
1533 return;
1534
1535 while (uint32 eventId = _events.ExecuteEvent())
1536 {
1537 switch (eventId)
1538 {
1539 case EVENT_GRAB_PLAYER:
1540 if (!_grabbedPlayer)
1541 {
1543 _events.ScheduleEvent(EVENT_GRAB_PLAYER, 2000);
1544 }
1545 break;
1547 me->GetMotionMaster()->MovePoint(POINT_DROP_PLAYER, _dropPoint);
1548 break;
1549 case EVENT_LIFE_SIPHON:
1550 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
1551 DoCast(target, SPELL_LIFE_SIPHON);
1552 _events.ScheduleEvent(EVENT_LIFE_SIPHON, 2500);
1553 break;
1554 default:
1555 break;
1556 }
1557 }
1558
1559 // no melee attacks
1560 }
1561
1562 private:
1567 };
1568
1570 {
1572 }
1573};
1574
1576{
1577 public:
1578 npc_strangulate_vehicle() : CreatureScript("npc_strangulate_vehicle") { }
1579
1581 {
1583 _instance(creature->GetInstanceScript())
1584 {
1585 }
1586
1588 {
1589 me->SetFacingToObject(summoner);
1591 _events.Reset();
1592 _events.ScheduleEvent(EVENT_MOVE_TO_LICH_KING, 2000);
1593 _events.ScheduleEvent(EVENT_TELEPORT, 6000);
1594
1595 // this will let us easily access all creatures of this entry on heroic mode when its time to teleport back
1597 lichKing->AI()->JustSummoned(me);
1598 }
1599
1601 {
1602 if (action != ACTION_TELEPORT_BACK)
1603 return;
1604
1605 if (TempSummon* summ = me->ToTempSummon())
1606 {
1607 if (Unit* summoner = summ->GetSummoner())
1608 {
1610 summoner->RemoveAurasDueToSpell(SPELL_HARVEST_SOUL_DAMAGE_AURA);
1611 }
1612 }
1613
1615 lichKing->AI()->SummonedCreatureDespawn(me);
1616 }
1617
1619 {
1620 UpdateVictim();
1621
1622 _events.Update(diff);
1623
1624 while (uint32 eventId = _events.ExecuteEvent())
1625 {
1626 switch (eventId)
1627 {
1628 case EVENT_TELEPORT:
1629 me->GetMotionMaster()->Clear(false);
1630 me->GetMotionMaster()->MoveIdle();
1631 if (TempSummon* summ = me->ToTempSummon())
1632 {
1633 if (Unit* summoner = summ->GetSummoner())
1634 {
1635 summoner->CastSpell((Unit*)NULL, SPELL_HARVEST_SOUL_VISUAL, true);
1636 summoner->ExitVehicle(summoner);
1637 if (!IsHeroic())
1638 summoner->CastSpell(summoner, SPELL_HARVEST_SOUL_TELEPORT, true);
1639 else
1640 {
1641 summoner->CastSpell(summoner, SPELL_HARVEST_SOULS_TELEPORT, true);
1642 summoner->RemoveAurasDueToSpell(HARVEST_SOUL, 0, 0, AURA_REMOVE_BY_EXPIRE);
1643 }
1644 }
1645 }
1646
1647 _events.ScheduleEvent(EVENT_DESPAWN_SELF, 65000);
1648 break;
1651 {
1652 if (me->GetExactDist(lichKing) > 10.0f)
1653 {
1654 Position pos;
1655 lichKing->GetNearPosition(pos, float(rand_norm()) * 5.0f + 7.5f, lichKing->GetAngle(me));
1656 me->GetMotionMaster()->MovePoint(0, pos);
1657 }
1658 }
1659 break;
1660 case EVENT_DESPAWN_SELF:
1662 lichKing->AI()->SummonedCreatureDespawn(me);
1663 me->DespawnOrUnsummon(1);
1664 break;
1665 default:
1666 break;
1667 }
1668 }
1669 }
1670
1671 private:
1674 };
1675
1677 {
1679 }
1680};
1681
1683{
1684 public:
1685 npc_terenas_menethil() : CreatureScript("npc_terenas_menethil") { }
1686
1688 {
1690 _instance(creature->GetInstanceScript())
1691 {
1692 }
1693
1694 bool CanAIAttack(Unit const* target) const OVERRIDE
1695 {
1696 return target->GetEntry() != NPC_THE_LICH_KING;
1697 }
1698
1700 {
1701 switch (action)
1702 {
1704 me->setActive(true);
1705 if (!IsHeroic())
1706 me->SetHealth(me->GetMaxHealth() / 2);
1708 _events.Reset();
1710 _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_2, 11000, PHASE_FROSTMOURNE);
1711 if (!IsHeroic())
1712 {
1713 _events.ScheduleEvent(EVENT_DESTROY_SOUL, 60000, PHASE_FROSTMOURNE);
1714 _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_3, 25000);
1715 }
1716 break;
1718 me->CastSpell((Unit*)NULL, SPELL_RESTORE_SOUL, TRIGGERED_NONE);
1719 me->DespawnOrUnsummon(3000);
1720 break;
1721 default:
1722 break;
1723 }
1724 }
1725
1727 {
1728 // no running back home
1729 if (!me->IsAlive())
1730 return;
1731
1732 me->DeleteThreatList();
1733 me->CombatStop(false);
1734 }
1735
1736 void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
1737 {
1738 if (damage >= me->GetHealth())
1739 {
1740 damage = me->GetHealth() - 1;
1741 if (!me->HasAura(SPELL_TERENAS_LOSES_INSIDE) && !IsHeroic())
1742 {
1745 _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1000);
1746 if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f))
1747 {
1748 warden->CastSpell((Unit*)NULL, SPELL_DESTROY_SOUL, TRIGGERED_NONE);
1749 warden->DespawnOrUnsummon(2000);
1750 }
1751
1752 me->DespawnOrUnsummon(2000);
1753 }
1754 }
1755 }
1756
1757 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
1758 {
1759 _events.Reset();
1760 _events.SetPhase(PHASE_OUTRO);
1762 me->SetFacingToObject(lichKing);
1763
1764 _events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_1, 2000, 0, PHASE_OUTRO);
1765 _events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_2, 14000, 0, PHASE_OUTRO);
1766 }
1767
1769 {
1770 UpdateVictim();
1771
1772 _events.Update(diff);
1773
1774 while (uint32 eventId = _events.ExecuteEvent())
1775 {
1776 switch (eventId)
1777 {
1780 if (IsHeroic())
1782 break;
1785 break;
1788 break;
1791 break;
1796 {
1797 lichKing->AI()->DoAction(ACTION_FINISH_OUTRO);
1798 lichKing->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC);
1800 tirion->AI()->AttackStart(lichKing);
1801 }
1802 break;
1803 case EVENT_DESTROY_SOUL:
1805 if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f))
1806 warden->CastSpell((Unit*)NULL, SPELL_DESTROY_SOUL, TRIGGERED_NONE);
1808 _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1000);
1809 break;
1812 lichKing->AI()->DoAction(ACTION_TELEPORT_BACK);
1813 break;
1814 default:
1815 break;
1816 }
1817 }
1818
1819 // fighting Spirit Warden
1820 if (me->IsInCombat())
1822 }
1823
1824 private:
1827 };
1828
1830 {
1832 }
1833};
1834
1836{
1837 public:
1838 npc_spirit_warden() : CreatureScript("npc_spirit_warden") { }
1839
1841 {
1843 _instance(creature->GetInstanceScript())
1844 {
1845 }
1846
1848 {
1849 _events.Reset();
1850 _events.ScheduleEvent(EVENT_SOUL_RIP, std::rand() % 15000 + 12000);
1852 }
1853
1854 void JustDied(Unit* /*killer*/) OVERRIDE
1855 {
1857 terenas->AI()->DoAction(ACTION_TELEPORT_BACK);
1858 }
1859
1861 {
1862 if (!UpdateVictim())
1863 return;
1864
1865 _events.Update(diff);
1866
1867 while (uint32 eventId = _events.ExecuteEvent())
1868 {
1869 switch (eventId)
1870 {
1871 case EVENT_SOUL_RIP:
1873 _events.ScheduleEvent(EVENT_SOUL_RIP, std::rand() % 27000 + 23000);
1874 break;
1875 default:
1876 break;
1877 }
1878 }
1879
1881 }
1882
1883 private:
1886 };
1887
1889 {
1891 }
1892};
1893
1895{
1896 public:
1897 npc_spirit_bomb() : CreatureScript("npc_spirit_bomb") { }
1898
1900 {
1902 {
1903 }
1904
1905 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
1906 {
1907 float destX, destY, destZ;
1908 me->GetPosition(destX, destY);
1909 destZ = 1055.0f; // approximation, gets more precise later
1910 me->UpdateGroundPositionZ(destX, destY, destZ);
1911 me->GetMotionMaster()->MovePoint(POINT_GROUND, destX, destY, destZ);
1912 }
1913
1915 {
1916 if (type != POINT_MOTION_TYPE || point != POINT_GROUND)
1917 return;
1918
1919 me->RemoveAllAuras();
1921 me->DespawnOrUnsummon(1000);
1922 }
1923
1924 void AttackStart(Unit* /*victim*/) OVERRIDE
1925 {
1926 }
1927
1928 void UpdateAI(uint32 /*diff*/) OVERRIDE
1929 {
1930 UpdateVictim();
1931 // no melee attacks
1932 }
1933 };
1934
1936 {
1938 }
1939};
1940
1942{
1943 public:
1944 npc_broken_frostmourne() : CreatureScript("npc_broken_frostmourne") { }
1945
1947 {
1949 {
1950 }
1951
1953 {
1954 _events.Reset();
1955 }
1956
1957 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
1958 {
1959 _events.SetPhase(PHASE_OUTRO);
1960 _events.ScheduleEvent(EVENT_OUTRO_KNOCK_BACK, 3000, 0, PHASE_OUTRO);
1961 }
1962
1964 {
1965 if (action == ACTION_SUMMON_TERENAS)
1966 _events.ScheduleEvent(EVENT_OUTRO_SUMMON_TERENAS, 6000, 0, PHASE_OUTRO);
1967 }
1968
1970 {
1971 }
1972
1974 {
1975 UpdateVictim();
1976
1977 _events.Update(diff);
1978
1979 while (uint32 eventId = _events.ExecuteEvent())
1980 {
1981 switch (eventId)
1982 {
1985 break;
1988 break;
1989 default:
1990 break;
1991 }
1992 }
1993
1994 // no melee attacks
1995 }
1996
1997 private:
1999 };
2000
2002 {
2004 }
2005};
2006
2008{
2009 public:
2010 spell_the_lich_king_infest() : SpellScriptLoader("spell_the_lich_king_infest") { }
2011
2013 {
2015
2016 void OnPeriodic(AuraEffect const* /*aurEff*/)
2017 {
2018 if (GetUnitOwner()->HealthAbovePct(90))
2019 {
2022 }
2023 }
2024
2025 void OnUpdate(AuraEffect* aurEff)
2026 {
2027 // multiply, starting from 2nd tick
2028 if (aurEff->GetTickNumber() == 1)
2029 return;
2030
2031 aurEff->SetAmount(int32(aurEff->GetAmount() * 1.15f));
2032 }
2033
2039 };
2040
2045};
2046
2048{
2049 public:
2050 spell_the_lich_king_necrotic_plague() : SpellScriptLoader("spell_the_lich_king_necrotic_plague") { }
2051
2053 {
2055
2056 bool Validate(SpellInfo const* /*spell*/) OVERRIDE
2057 {
2058 if (!sSpellMgr->GetSpellInfo(SPELL_NECROTIC_PLAGUE_JUMP))
2059 return false;
2060 return true;
2061 }
2062
2063 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2064 {
2065 switch (GetTargetApplication()->GetRemoveMode())
2066 {
2070 break;
2071 default:
2072 return;
2073 }
2074
2075 CustomSpellValues values;
2076 //values.AddSpellMod(SPELLVALUE_AURA_STACK, 2);
2079 if (Unit* caster = GetCaster())
2080 caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
2081 }
2082
2087 };
2088
2093};
2094
2096{
2097 public:
2098 spell_the_lich_king_necrotic_plague_jump() : SpellScriptLoader("spell_the_lich_king_necrotic_plague_jump") { }
2099
2101 {
2103
2105 {
2106 _hadAura = false;
2107 return true;
2108 }
2109
2110 void SelectTarget(std::list<Unit*>& targets)
2111 {
2113 if (targets.size() < 2)
2114 return;
2115
2116 targets.resize(1);
2117 }
2118
2120 {
2121 if (GetHitUnit()->HasAura(GetSpellInfo()->Id))
2122 _hadAura = true;
2123 }
2124
2126 {
2127 if (GetHitAura() && !_hadAura && GetSpellValue()->EffectBasePoints[EFFECT_1] != AURA_REMOVE_BY_ENEMY_SPELL)
2129 }
2130
2136
2138 };
2139
2141 {
2143
2145 {
2146 _lastAmount = 0;
2147 return true;
2148 }
2149
2150 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2151 {
2152 if (Unit* caster = GetCaster())
2153 if (caster->GetAI())
2154 caster->GetAI()->SetData(DATA_PLAGUE_STACK, GetStackAmount());
2155 }
2156
2157 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
2158 {
2159 _lastAmount = aurEff->GetAmount();
2160 switch (GetTargetApplication()->GetRemoveMode())
2161 {
2164 break;
2165 default:
2166 return;
2167 }
2168
2169 CustomSpellValues values;
2172 if (Unit* caster = GetCaster())
2173 caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
2174 }
2175
2176 void OnDispel(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
2177 {
2178 _lastAmount = aurEff->GetAmount();
2179 }
2180
2181 void AfterDispel(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
2182 {
2183 // this means the stack increased so don't process as if dispelled
2184 if (aurEff->GetAmount() > _lastAmount)
2185 return;
2186
2187 CustomSpellValues values;
2189 values.AddSpellMod(SPELLVALUE_BASE_POINT1, AURA_REMOVE_BY_ENEMY_SPELL); // add as marker (spell has no effect 1)
2191 if (Unit* caster = GetCaster())
2192 caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
2193
2195 }
2196
2204
2206 };
2207
2212
2217};
2218
2245
2274
2276{
2277 public:
2278 spell_the_lich_king_quake() : SpellScriptLoader("spell_the_lich_king_quake") { }
2279
2307
2312};
2313
2315{
2316 public:
2317 spell_the_lich_king_ice_burst_target_search() : SpellScriptLoader("spell_the_lich_king_ice_burst_target_search") { }
2318
2320 {
2322
2323 bool Validate(SpellInfo const* /*spell*/) OVERRIDE
2324 {
2325 if (!sSpellMgr->GetSpellInfo(SPELL_ICE_BURST))
2326 return false;
2327 return true;
2328 }
2329
2330 void CheckTargetCount(std::list<WorldObject*>& unitList)
2331 {
2332 if (unitList.empty())
2333 return;
2334
2335 // if there is at least one affected target cast the explosion
2337 if (GetCaster()->GetTypeId() == TypeID::TYPEID_UNIT)
2338 {
2340 GetCaster()->AttackStop();
2342 }
2343 }
2344
2349 };
2350
2355};
2356
2390
2392{
2393 public:
2394 ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) { }
2395
2397 {
2398 return _source->GetExactDist2d(unit) > _dist;
2399 }
2400
2401 private:
2402 Unit* _source;
2403 float _dist;
2404};
2405
2407{
2408 public:
2409 spell_the_lich_king_defile() : SpellScriptLoader("spell_the_lich_king_defile") { }
2410
2412 {
2414
2415 void CorrectRange(std::list<WorldObject*>& targets)
2416 {
2417 targets.remove_if(ExactDistanceCheck(GetCaster(), 10.0f * GetCaster()->GetObjectScale()));
2418 }
2419
2421 {
2422 SetHitDamage(int32(GetHitDamage() * GetCaster()->GetObjectScale()));
2423 // HACK: target player should cast this spell on defile
2424 // however with current aura handling auras cast by different units
2425 // cannot stack on the same aura object increasing the stack count
2427 }
2428
2435 };
2436
2441};
2442
2444{
2445 public:
2446 spell_the_lich_king_summon_into_air() : SpellScriptLoader("spell_the_lich_king_summon_into_air") { }
2447
2449 {
2451
2453 {
2454 static Position const offset = {0.0f, 0.0f, 15.0f, 0.0f};
2455 WorldLocation* dest = const_cast<WorldLocation*>(GetExplTargetDest());
2456 dest->RelocateOffset(offset);
2457 GetHitDest()->RelocateOffset(offset);
2458 // spirit bombs get higher
2459 if (GetSpellInfo()->Effects[effIndex].MiscValue == NPC_SPIRIT_BOMB)
2460 {
2461 dest->RelocateOffset(offset);
2462 GetHitDest()->RelocateOffset(offset);
2463 }
2464 }
2465
2470 };
2471
2476};
2477
2479{
2480 public:
2481 spell_the_lich_king_soul_reaper() : SpellScriptLoader("spell_the_lich_king_soul_reaper") { }
2482
2484 {
2486
2487 bool Validate(SpellInfo const* /*spell*/) OVERRIDE
2488 {
2489 if (!sSpellMgr->GetSpellInfo(SPELL_SOUL_REAPER_BUFF))
2490 return false;
2491 return true;
2492 }
2493
2494 void OnPeriodic(AuraEffect const* /*aurEff*/)
2495 {
2496 if (Unit* caster = GetCaster())
2497 GetTarget()->CastSpell(caster, SPELL_SOUL_REAPER_BUFF, true);
2498 }
2499
2504 };
2505
2510};
2511
2513{
2514 public:
2515 spell_the_lich_king_valkyr_target_search() : SpellScriptLoader("spell_the_lich_king_valkyr_target_search") { }
2516
2518 {
2520
2521 bool Validate(SpellInfo const* /*spell*/) OVERRIDE
2522 {
2523 if (!sSpellMgr->GetSpellInfo(SPELL_ICE_BURST))
2524 return false;
2525 return true;
2526 }
2527
2529 {
2530 _target = NULL;
2531 return true;
2532 }
2533
2534 void SelectTarget(std::list<WorldObject*>& targets)
2535 {
2536 if (targets.empty())
2537 return;
2538
2539 targets.remove_if(Skyfire::UnitAuraCheck(true, GetSpellInfo()->Id));
2540 if (targets.empty())
2541 return;
2542
2544 targets.clear();
2545 targets.push_back(_target);
2546 GetCaster()->GetAI()->SetGUID(_target->GetGUID());
2547 }
2548
2549 void ReplaceTarget(std::list<WorldObject*>& targets)
2550 {
2551 targets.clear();
2552 if (_target)
2553 targets.push_back(_target);
2554 }
2555
2557 {
2558 PreventHitDefaultEffect(effIndex);
2560 }
2561
2568
2570 };
2571
2576};
2577
2609
2635
2637{
2638 public:
2639 spell_the_lich_king_life_siphon() : SpellScriptLoader("spell_the_lich_king_life_siphon") { }
2640
2662
2667};
2668
2670{
2671 public:
2672 spell_the_lich_king_vile_spirits() : SpellScriptLoader("spell_the_lich_king_vile_spirits") { }
2673
2675 {
2677
2679 {
2681 return true;
2682 }
2683
2684 void OnPeriodic(AuraEffect const* aurEff)
2685 {
2686 if (_is25Man || ((aurEff->GetTickNumber() - 1) % 5))
2687 GetTarget()->CastSpell((Unit*)NULL, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, NULL, aurEff, GetCasterGUID());
2688 }
2689
2694
2696 };
2697
2702};
2703
2730
2732{
2733 public:
2734 spell_the_lich_king_vile_spirit_move_target_search() : SpellScriptLoader("spell_the_lich_king_vile_spirit_move_target_search") { }
2735
2737 {
2739
2741 {
2742 _target = NULL;
2744 }
2745
2746 void SelectTarget(std::list<WorldObject*>& targets)
2747 {
2748 if (targets.empty())
2749 return;
2750
2752 }
2753
2755 {
2756 PreventHitDefaultEffect(effIndex);
2757 // for this spell, all units are in target map, however it should select one to attack
2758 if (GetHitUnit() != _target)
2759 return;
2760
2762 GetCaster()->AddThreat(GetHitUnit(), 100000.0f);
2763 }
2764
2770
2772 };
2773
2778};
2779
2781{
2782 public:
2783 spell_the_lich_king_vile_spirit_damage_target_search() : SpellScriptLoader("spell_the_lich_king_vile_spirit_damage_target_search") { }
2784
2786 {
2788
2790 {
2792 }
2793
2794 void CheckTargetCount(std::list<WorldObject*>& targets)
2795 {
2796 if (targets.empty())
2797 return;
2798
2799 // this spell has SPELL_AURA_BLOCK_SPELL_FAMILY so every next cast of this
2800 // searcher spell will be blocked
2801 if (TempSummon* summon = GetCaster()->ToTempSummon())
2802 if (Unit* summoner = summon->GetSummoner())
2803 summoner->GetAI()->SetData(DATA_VILE, 1);
2804 GetCaster()->CastSpell((Unit*)NULL, SPELL_SPIRIT_BURST, true);
2807 }
2808
2813 };
2814
2819};
2820
2822{
2823 public:
2824 spell_the_lich_king_harvest_soul() : SpellScriptLoader("spell_the_lich_king_harvest_soul") { }
2825
2827 {
2829
2831 {
2832 return GetOwner()->GetInstanceScript() != NULL;
2833 }
2834
2835 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
2836 {
2837 // m_originalCaster to allow stacking from different casters, meh
2838 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
2839 GetTarget()->CastSpell((Unit*)NULL, SPELL_HARVESTED_SOUL, true, NULL, NULL, GetTarget()->GetInstanceScript()->GetData64(DATA_THE_LICH_KING));
2840 }
2841
2846 };
2847
2852};
2853
2855{
2856 public:
2857 spell_the_lich_king_lights_favor() : SpellScriptLoader("spell_the_lich_king_lights_favor") { }
2858
2860 {
2862
2863 void OnPeriodic(AuraEffect const* /*aurEff*/)
2864 {
2865 if (Unit* caster = GetCaster())
2866 if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1))
2867 effect->RecalculateAmount(caster);
2868 }
2869
2870 void CalculateBonus(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated)
2871 {
2872 canBeRecalculated = true;
2873 amount = 0;
2874 if (Unit* caster = GetCaster())
2875 amount = int32(caster->GetHealthPct());
2876 }
2877
2883 };
2884
2889};
2890
2892{
2893 public:
2894 spell_the_lich_king_soul_rip() : SpellScriptLoader("spell_the_lich_king_soul_rip") { }
2895
2897 {
2899
2900 void OnPeriodic(AuraEffect const* aurEff)
2901 {
2903 // shouldn't be needed, this is channeled
2904 if (Unit* caster = GetCaster())
2905 caster->CastCustomSpell(SPELL_SOUL_RIP_DAMAGE, SPELLVALUE_BASE_POINT0, 5000 * aurEff->GetTickNumber(), GetTarget(), true, NULL, aurEff, GetCasterGUID());
2906 }
2907
2912 };
2913
2918};
2919
2921{
2922 public:
2923 spell_the_lich_king_restore_soul() : SpellScriptLoader("spell_the_lich_king_restore_soul") { }
2924
2926 {
2928
2930 {
2932 return _instance != NULL;
2933 }
2934
2935 void HandleScript(SpellEffIndex /*effIndex*/)
2936 {
2938 lichKing->AI()->DoAction(ACTION_TELEPORT_BACK);
2939 if (Creature* spawner = GetCaster()->FindNearestCreature(NPC_WORLD_TRIGGER_INFINITE_AOI, 50.0f))
2940 spawner->RemoveAllAuras();
2941
2942 std::list<Creature*> spirits;
2944 for (std::list<Creature*>::iterator itr = spirits.begin(); itr != spirits.end(); ++itr)
2945 {
2946 (*itr)->m_Events.KillAllEvents(true);
2947 (*itr)->SetReactState(REACT_PASSIVE);
2948 (*itr)->AI()->EnterEvadeMode();
2949 }
2950 }
2951
2953 {
2954 if (Unit* target = GetHitUnit())
2955 target->RemoveAurasDueToSpell(target->GetMap()->IsHeroic() ? SPELL_HARVEST_SOULS_TELEPORT : SPELL_HARVEST_SOUL_TELEPORT);
2956 }
2957
2963
2965 };
2966
2971};
2972
2974{
2975 public:
2976 spell_the_lich_king_dark_hunger() : SpellScriptLoader("spell_the_lich_king_dark_hunger") { }
2977
2979 {
2981
2982 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
2983 {
2984 if (!sSpellMgr->GetSpellInfo(SPELL_DARK_HUNGER_HEAL))
2985 return false;
2986 return true;
2987 }
2988
2989 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
2990 {
2992 int32 heal = int32(eventInfo.GetDamageInfo()->GetDamage() / 2);
2994 }
2995
3000 };
3001
3006};
3007
3009{
3010 public:
3011 spell_the_lich_king_in_frostmourne_room() : SpellScriptLoader("spell_the_lich_king_in_frostmourne_room") { }
3012
3014 {
3016
3018 {
3019 return GetOwner()->GetInstanceScript() != NULL;
3020 }
3021
3022 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
3023 {
3024 // m_originalCaster to allow stacking from different casters, meh
3025 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
3026 GetTarget()->CastSpell((Unit*)NULL, SPELL_HARVESTED_SOUL, true, NULL, NULL, GetTarget()->GetInstanceScript()->GetData64(DATA_THE_LICH_KING));
3027 }
3028
3033 };
3034
3039};
3040
3067
3097
3127
3154
3156{
3157 public:
3158 achievement_been_waiting_long_time() : AchievementCriteriaScript("achievement_been_waiting_long_time") { }
3159
3160 bool OnCheck(Player* /*source*/, Unit* target) OVERRIDE
3161 {
3162 if (!target)
3163 return false;
3164
3165 return target->GetAI()->GetData(DATA_PLAGUE_STACK) >= 30;
3166 }
3167};
3168
3170{
3171 public:
3172 achievement_neck_deep_in_vile() : AchievementCriteriaScript("achievement_neck_deep_in_vile") { }
3173
3174 bool OnCheck(Player* /*source*/, Unit* target) OVERRIDE
3175 {
3176 if (!target)
3177 return false;
3178
3179 return !target->GetAI()->GetData(DATA_VILE);
3180 }
3181};
3182
3184{
3185 new boss_the_lich_king();
3188 new npc_raging_spirit();
3192 new npc_spirit_warden();
3193 new npc_spirit_bomb();
3224 new spell_trigger_spell_from_caster("spell_the_lich_king_mass_resurrection", SPELL_MASS_RESURRECTION_REAL);
3227}
@ EQUIP_UNEQUIP
Definition CreatureAI.h:50
#define sCreatureTextMgr
@ TEXT_RANGE_NORMAL
std::int32_t int32
Definition Define.h:73
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
@ GO_STATE_ACTIVE
Definition GameObject.h:576
@ GO_STATE_READY
Definition GameObject.h:577
@ IN_PROGRESS
@ FAIL
@ DONE
@ NOT_STARTED
@ POINT_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_UNIT
Definition Object.h:54
@ TEMPSUMMON_CORPSE_DESPAWN
Definition Object.h:72
void GetCreatureListWithEntryInGrid(std::list< Creature * > &list, WorldObject *source, uint32 entry, float maxSearchRange)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ EMOTE_ONESHOT_POINT_NO_SHEATHE
@ EMOTE_ONESHOT_EMERGE
@ EMOTE_STATE_READY2H
@ EMOTE_ONESHOT_NONE
@ EMOTE_ONESHOT_TALK_NO_SHEATHE
@ CHAT_MSG_MONSTER_YELL
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SEND_EVENT
@ SPELL_EFFECT_SUMMON
@ SPELL_EFFECT_APPLY_AURA
@ TARGET_UNIT_SRC_AREA_ENTRY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ GO_DESTRUCTIBLE_REBUILDING
@ TEAM_OTHER
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_CONTROL_VEHICLE
@ SPELL_AURA_PERIODIC_HEAL
@ SPELL_AURA_DUMMY
@ SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
@ SPELL_AURA_PERIODIC_DUMMY
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK
@ AURA_EFFECT_HANDLE_REAPPLY
@ AURA_EFFECT_HANDLE_REAL
#define sSpellMgr
Definition SpellMgr.h:744
#define AuraEffectProcFn(F, I, N)
#define SpellEffectFn(F, I, N)
#define AuraEffectCalcAmountFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define AuraEffectUpdatePeriodicFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
#define SpellHitFn(F)
#define AuraEffectRemoveFn(F, I, N, M)
#define SF_UNARY_FUNCTION
@ UNIT_NPC_FLAG_GOSSIP
Definition Unit.h:687
@ SPELLVALUE_AURA_STACK
Definition Unit.h:119
@ SPELLVALUE_BASE_POINT1
Definition Unit.h:115
@ SPELLVALUE_MAX_TARGETS
Definition Unit.h:118
@ SPELLVALUE_BASE_POINT0
Definition Unit.h:114
@ UNIT_BYTE1_FLAG_HOVER
Definition Unit.h:189
@ UNIT_BYTE1_FLAG_ALWAYS_STAND
Definition Unit.h:188
@ UNIT_STAND_STATE_STAND
Definition Unit.h:162
@ 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
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition Unit.h:422
@ TRIGGERED_NONE
Definition Unit.h:416
@ SHEATH_STATE_MELEE
Definition Unit.h:246
@ UNIT_STATE_EVADE
Definition Unit.h:533
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ MOVE_FLIGHT
Definition Unit.h:561
@ REACT_PASSIVE
Definition Unit.h:1156
@ REACT_AGGRESSIVE
Definition Unit.h:1158
@ UNIT_FLAG_IMMUNE_TO_NPC
Definition Unit.h:634
@ 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_ANIM_TIER
@ UNIT_FIELD_FLAGS
@ UNIT_FIELD_NPC_EMOTESTATE
double rand_norm(void)
Definition Util.cpp:50
@ SPELL_ENRAGE
@ SPELL_CHARGE
@ EVENT_ENRAGE
@ PHASE_INTRO
@ POINT_GROUND
@ SPELL_FRENZY
@ PHASE_ONE
@ PHASE_THREE
@ PHASE_TWO
@ ACTION_OUTRO
@ PHASE_OUTRO
@ SPELL_QUAKE
@ EVENT_BERSERK
@ SPELL_EJECT_ALL_PASSENGERS
Position const TirionCharge
#define REMORSELESS_WINTER_1
@ EVENT_GROUP_VILE_SPIRITS
@ EVENT_GROUP_BERSERK
@ LIGHT_SOULSTORM
@ MUSIC_FURY_OF_FROSTMOURNE
@ MUSIC_FROZEN_THRONE
@ LIGHT_SNOWSTORM
@ EQUIP_BROKEN_FROSTMOURNE
@ MUSIC_SPECIAL
@ EQUIP_ASHBRINGER_GLOWING
#define REMORSELESS_WINTER_2
@ DATA_PLAGUE_STACK
@ ACTION_TELEPORT_BACK
@ ACTION_PLAY_MUSIC
@ ACTION_CONTINUE_INTRO
@ ACTION_BREAK_FROSTMOURNE
@ ACTION_START_ATTACK
@ ACTION_START_ENCOUNTER
@ ACTION_SUMMON_TERENAS
@ ACTION_FINISH_OUTRO
Position const TirionIntro
@ SPELL_RAGING_SPIRIT_VISUAL
@ SPELL_HARVEST_SOULS
@ SPELL_ICE_PULSE
@ SPELL_PAIN_AND_SUFFERING
@ SPELL_EXPLOSION
@ SPELL_DARK_HUNGER
@ SPELL_SPIRIT_BURST
@ SPELL_HARVEST_SOUL_VISUAL
@ SPELL_NECROTIC_PLAGUE
@ SPELL_SHADOW_TRAP
@ SPELL_SOUL_RIP
@ SPELL_WINGS_OF_THE_DAMNED
@ SPELL_SOUL_SHRIEK
@ SPELL_VALKYR_TARGET_SEARCH
@ SPELL_TRIGGER_VILE_SPIRIT_HEROIC
@ SPELL_SUMMON_VALKYR
@ SPELL_TERENAS_LOSES_INSIDE
@ SPELL_SUMMON_BROKEN_FROSTMOURNE_2
@ SPELL_SHADOW_TRAP_AURA
@ SPELL_QUAKE
@ SPELL_REMORSELESS_WINTER_2
@ SPELL_SOUL_REAPER_BUFF
@ SPELL_SUMMON_BROKEN_FROSTMOURNE
@ SPELL_EMOTE_QUESTION_NO_SHEATH
@ SPELL_LIGHTS_FAVOR
@ SPELL_MASS_RESURRECTION
@ SPELL_HARVEST_SOUL_TELEPORT
@ SPELL_SUMMON_ICE_SPHERE
@ SPELL_SUMMON_DRUDGE_GHOULS
@ SPELL_PLAY_MOVIE
@ SPELL_SUMMON_SHAMBLING_HORROR
@ SPELL_VILE_SPIRIT_MOVE_SEARCH
@ SPELL_DEFILE_AURA
@ SPELL_HARVESTED_SOUL
@ SPELL_DARK_HUNGER_HEAL
@ SPELL_SUMMON_VALKYR_PERIODIC
@ SPELL_ICE_LOCK
@ SPELL_SUMMON_SPIRIT_BOMB_2
@ SPELL_VILE_SPIRIT_DAMAGE_SEARCH
@ SPELL_JUMP_TRIGGERED
@ SPELL_NECROTIC_PLAGUE_JUMP
@ SPELL_ICE_BURST
@ SPELL_MASS_RESURRECTION_REAL
@ SPELL_SOUL_BARRAGE
@ SPELL_HARVEST_SOUL_VEHICLE
@ SPELL_BROKEN_FROSTMOURNE_KNOCK
@ SPELL_SUMMON_BROKEN_FROSTMOURNE_3
@ SPELL_RESTORE_SOUL
@ SPELL_BOSS_HITTIN_YA
@ SPELL_SOUL_REAPER
@ SPELL_HARVEST_SOUL
@ SPELL_RISEN_WITCH_DOCTOR_SPAWN
@ SPELL_RAGING_SPIRIT_VISUAL_CLONE
@ SPELL_LIFE_SIPHON
@ SPELL_SUMMON_SPIRIT_BOMB_1
@ SPELL_KILL_FROSTMOURNE_PLAYERS
@ SPELL_DESTROY_SOUL
@ SPELL_LIGHTS_BLESSING
@ SPELL_BROKEN_FROSTMOURNE
@ SPELL_RAISE_DEAD
@ SPELL_SOUL_RIP_DAMAGE
@ SPELL_SHADOW_TRAP_KNOCKBACK
@ SPELL_RAGING_SPIRIT
@ SPELL_HARVEST_SOULS_TELEPORT
@ SPELL_HARVEST_SOUL_TELEPORT_BACK
@ SPELL_SHOCKWAVE
@ SPELL_REMORSELESS_WINTER_1
@ SPELL_FURY_OF_FROSTMOURNE
@ SPELL_HARVEST_SOUL_DAMAGE_AURA
@ SPELL_VALKYR_CARRY
@ SPELL_VILE_SPIRITS
@ SPELL_EJECT_ALL_PASSENGERS
@ SPELL_PLAGUE_AVOIDANCE
@ SPELL_SUMMON_TERENAS
@ SPELL_ICE_BURST_TARGET_SEARCH
@ SPELL_EMOTE_SHOUT_NO_SHEATH
@ SPELL_IN_FROSTMOURNE_ROOM
@ SPELL_LIFE_SIPHON_HEAL
@ SPELL_EMOTE_SIT_NO_SHEATH
@ SPELL_PLAGUE_SIPHON
@ SPELL_RESTORE_SOULS
@ SPELL_DEFILE_GROW
@ SPELL_DEFILE
@ SPELL_HARVEST_SOUL_VALKYR
@ SPELL_ICE_SPHERE
@ SPELL_FURY_OF_FROSTMOURNE_NO_REZ
@ SPELL_INFEST
@ PHASE_FROSTMOURNE
@ PHASE_TRANSITION
@ POINT_LK_INTRO_2
@ POINT_LK_OUTRO_1
@ POINT_TIRION_OUTRO_1
@ POINT_LK_OUTRO_2
@ POINT_CENTER_2
@ POINT_LK_INTRO_1
@ POINT_LK_INTRO_3
@ POINT_TIRION_INTRO
@ POINT_DROP_PLAYER
@ POINT_TIRION_CHARGE
@ POINT_CENTER_1
@ POINT_OUTRO_JUMP
Position const OutroPosition1
Position const TerenasSpawn
@ SAY_LK_QUAKE
@ SAY_LK_OUTRO_2
@ SAY_LK_INTRO_2
@ SAY_LK_FROSTMOURNE_ESCAPE
@ SAY_LK_REMORSELESS_WINTER
@ SAY_LK_OUTRO_4
@ SAY_TERENAS_INTRO_3
@ SAY_LK_SUMMON_VALKYR
@ EMOTE_NECROTIC_PLAGUE_WARNING
@ SAY_TERENAS_INTRO_2
@ SAY_TIRION_OUTRO_1
@ SAY_LK_HARVEST_SOUL
@ SAY_LK_KILL
@ SAY_LK_INTRO_1
@ SAY_LK_INTRO_3
@ SAY_TERENAS_OUTRO_2
@ SAY_LK_OUTRO_7
@ EMOTE_DEFILE_WARNING
@ SAY_LK_OUTRO_1
@ SAY_LK_BERSERK
@ SAY_LK_OUTRO_6
@ SAY_LK_FROSTMOURNE_KILL
@ SAY_TERENAS_INTRO_1
@ SAY_LK_OUTRO_5
@ SAY_TIRION_INTRO_2
@ SAY_LK_OUTRO_3
@ SAY_TIRION_INTRO_1
@ SAY_LK_OUTRO_8
@ SAY_TIRION_OUTRO_2
@ SAY_TERENAS_OUTRO_1
#define NECROTIC_PLAGUE_PLR
#define SUMMON_VALKYR
void AddSC_boss_the_lich_king()
#define PHASE_TWO_THREE
#define NECROTIC_PLAGUE_LK
Position const TerenasSpawnHeroic
Position const CenterPosition
Position const OutroFlying
Position const LichKingIntro[3]
#define HARVEST_SOUL
Position const SpiritWardenSpawn
@ EVENT_DESTROY_SOUL
@ EVENT_SUMMON_ICE_SPHERE
@ EVENT_OUTRO_EMOTE_TALK
@ EVENT_OUTRO_TALK_3
@ EVENT_OUTRO_TERENAS_TALK_1
@ EVENT_FROSTMOURNE_TALK_3
@ EVENT_SUMMON_SHAMBLING_HORROR
@ EVENT_MOVE_TO_LICH_KING
@ EVENT_INTRO_MOVE_3
@ EVENT_FROSTMOURNE_TALK_1
@ EVENT_FROSTMOURNE_HEROIC
@ EVENT_SHADOW_TRAP
@ EVENT_HARVEST_SOUL
@ EVENT_OUTRO_TERENAS_TALK_2
@ EVENT_GRAB_PLAYER
@ EVENT_OUTRO_TALK_4
@ EVENT_NECROTIC_PLAGUE
@ EVENT_OUTRO_MOVE_CENTER
@ EVENT_OUTRO_TALK_2
@ EVENT_OUTRO_TALK_7
@ EVENT_START_ATTACK
@ EVENT_OUTRO_KNOCK_BACK
@ EVENT_TELEPORT
@ EVENT_SUMMON_RAGING_SPIRIT
@ EVENT_INTRO_CAST_FREEZE
@ EVENT_TELEPORT_BACK
@ EVENT_OUTRO_TALK_8
@ EVENT_DESPAWN_SELF
@ EVENT_SUMMON_VALKYR
@ EVENT_QUAKE_2
@ EVENT_INTRO_MOVE_1
@ EVENT_HARVEST_SOULS
@ EVENT_OUTRO_JUMP
@ EVENT_LIFE_SIPHON
@ EVENT_OUTRO_SUMMON_TERENAS
@ EVENT_INTRO_MOVE_2
@ EVENT_BERSERK
@ EVENT_OUTRO_REMOVE_ICE
@ EVENT_MOVE_TO_DROP_POS
@ EVENT_INTRO_EMOTE_1
@ EVENT_INTRO_CHARGE
@ EVENT_OUTRO_RAISE_DEAD
@ EVENT_OUTRO_BLESS
@ EVENT_FROSTMOURNE_TALK_2
@ EVENT_SOUL_SHRIEK
@ EVENT_PAIN_AND_SUFFERING
@ EVENT_VILE_SPIRITS
@ EVENT_OUTRO_TALK_5
@ EVENT_SUMMON_DRUDGE_GHOUL
@ EVENT_SOUL_REAPER
@ EVENT_SHOCKWAVE
@ EVENT_OUTRO_TALK_6
@ EVENT_INTRO_TALK_1
@ EVENT_FINISH_INTRO
@ EVENT_OUTRO_TALK_1
@ EVENT_EMOTE_CAST_SHOUT
@ EVENT_OUTRO_MOVE_1
@ EVENT_SOUL_RIP
@ EVENT_OUTRO_SOUL_BARRAGE
MovePoints
@ NPC_THE_LICH_KING
Definition chapter5.cpp:143
AchievementCriteriaScript(const char *name)
uint32 GetTickNumber() const
void SetAmount(int32 amount)
uint32 GetEffIndex() const
int32 GetAmount() const
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
void PreventDefaultAction()
void Remove(uint32 removeMode=0)
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
SpellInfo const * GetSpellInfo() const
WorldObject * GetOwner() const
HookList< EffectApplyHandler > AfterEffectApply
HookList< EffectCalcAmountHandler > DoEffectCalcAmount
uint64 GetCasterGUID() const
Unit * GetCaster() const
HookList< EffectUpdatePeriodicHandler > OnEffectUpdatePeriodic
AuraEffect * GetEffect(uint8 effIndex) const
Aura * GetAura() const
Unit * GetTarget() const
HookList< EffectProcHandler > OnEffectProc
Unit * GetUnitOwner() const
uint8 GetStackAmount() const
HookList< EffectApplyHandler > OnEffectApply
InstanceScript *const instance
void _JustReachedHome()
void JustSummoned(Creature *summon) OVERRIDE
SummonList summons
EventMap events
BossAI(Creature *creature, uint32 bossId)
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void FlushBits()
Definition ByteBuffer.h:154
CreatureAI(Creature *creature)
Definition CreatureAI.h:69
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:56
virtual void EnterEvadeMode()
void DespawnOrUnsummon(uint32 msTimeToDespawn=0)
void SetReactState(ReactStates st)
Definition Creature.h:460
CreatureAI * AI() const
Definition Creature.h:483
CreatureScript(const char *name)
void AddSpellMod(SpellValueMod mod, int32 value)
Definition Unit.h:131
uint32 GetDamage() const
Definition Unit.h:923
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
void KillAllEvents(bool force)
uint64 CalculateTime(uint64 t_offset) const
ExactDistanceCheck(Unit *source, float dist)
bool operator()(WorldObject *unit)
bool operator()(GameObject *go)
void SetGoState(GOState state)
void ResetDoorOrButton()
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=NULL, bool setHealth=false)
bool isEmpty() const
Definition LinkedList.h:86
MapRefManager PlayerList
Definition Map.h:406
bool Is25ManRaid() const
Definition Map.cpp:3063
iterator end()
iterator begin()
LinkedListHead::Iterator< MapReference const > const_iterator
void MoveRandom(float spawndist=0.0f)
NecroticPlagueTargetCheck(Unit const *obj, uint32 notAura1=0, uint32 notAura2=0)
bool operator()(Unit *unit) const
static Creature * GetCreature(WorldObject const &u, uint64 guid)
static Player * GetPlayer(WorldObject const &, uint64 guid)
static GameObject * GetGameObject(WorldObject const &u, uint64 guid)
TypeID GetTypeId() const
Definition Object.h:131
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:1261
uint32 GetEntry() const
Definition Object.h:125
Creature * ToCreature()
Definition Object.h:207
DamageInfo * GetDamageInfo() const
Definition Unit.h:985
Creature * GetHitCreature()
Aura * GetHitAura()
WorldLocation const * GetExplTargetDest()
HookList< HitHandler > AfterHit
SpellInfo const * GetSpellInfo()
HookList< HitHandler > OnHit
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
HookList< EffectHandler > OnEffectHitTarget
Unit * GetHitUnit()
WorldLocation * GetHitDest()
int32 GetEffectValue()
void SetHitDamage(int32 damage)
HookList< EffectHandler > OnEffectLaunch
SpellValue const * GetSpellValue()
Unit * GetCaster()
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
HookList< HitHandler > BeforeHit
int32 GetHitDamage()
SpellScriptLoader(const char *name)
bool Execute(uint64, uint32)
StartMovementEvent(Creature *summoner, Creature *owner)
StorageType::iterator iterator
TriggerWickedSpirit(Creature *owner)
bool Execute(uint64, uint32)
virtual void DoAction(int32)
Definition UnitAI.h:126
virtual void SetGUID(uint64, int32=0)
Definition UnitAI.h:129
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 DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
void DoCastAOE(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:176
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:16
Definition Unit.h:1367
bool IsVehicle() const
Definition Unit.h:1523
bool isTargetableForAttack(bool checkFakeDeath=true) const
Definition Unit.cpp:3795
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)
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=NULL)
Definition Unit.cpp:4463
MotionMaster * GetMotionMaster()
Definition Unit.h:2605
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
EventProcessor m_Events
Definition Unit.h:2396
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
bool IsTotem() const
Definition Unit.h:1519
Vehicle * GetVehicleKit() const
Definition Unit.h:2739
bool AttackStop()
void RemoveAllPassengers()
Removes all current and pending passengers from the vehicle.
Definition Vehicle.cpp:241
bool Execute(uint64, uint32)
VileSpiritActivateEvent(Creature *owner)
Map * GetMap() const
Definition Object.h:740
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
void GetCreatureListWithEntryInGrid(std::list< Creature * > &lList, uint32 uiEntry, float fMaxSearchRange) const
Definition Object.cpp:2841
bool OnCheck(Player *, Unit *target) OVERRIDE
bool OnCheck(Player *, Unit *target) 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
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
AuraScript * GetAuraScript() const OVERRIDE
PrepareSpellScript(spell_the_lich_king_defile_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
PrepareAuraScript(spell_the_lich_king_infest_AuraScript)
AuraScript * GetAuraScript() const OVERRIDE
PrepareSpellScript(spell_the_lich_king_jump_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
void CalculateBonus(AuraEffect const *, int32 &amount, bool &canBeRecalculated)
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
PrepareSpellScript(spell_the_lich_king_quake_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
@ NPC_WORLD_TRIGGER
@ SMSG_WEATHER
Definition Opcodes.h:1065
@ SMSG_OVERRIDE_LIGHT
Definition Opcodes.h:840
WeatherState
Definition Weather.h:34
@ WEATHER_STATE_BLACKSNOW
Definition Weather.h:48
@ WEATHER_STATE_LIGHT_SNOW
Definition Weather.h:40
@ SPELL_SPIRIT_BURST
@ SPELL_SOUL_REAPER
@ SPELL_HARVEST_SOUL
@ SPELL_RAISE_DEAD
@ SPELL_FURY_OF_FROSTMOURNE
@ SAY_LK_INTRO_2
@ SAY_LK_INTRO_1
@ SAY_LK_INTRO_3
@ NPC_RAGING_SPIRIT
@ NPC_FROSTMOURNE_TRIGGER
@ NPC_VALKYR_SHADOWGUARD
@ NPC_SHAMBLING_HORROR
@ NPC_SPIRIT_WARDEN
@ NPC_SPIRIT_BOMB
@ NPC_WICKED_SPIRIT
@ NPC_STRANGULATE_VEHICLE
@ NPC_VILE_SPIRIT
@ NPC_DEFILE
@ NPC_WORLD_TRIGGER_INFINITE_AOI
@ NPC_ICE_SPHERE
@ NPC_TERENAS_MENETHIL_FROSTMOURNE_H
@ NPC_DRUDGE_GHOUL
CreatureAI * GetIcecrownCitadelAI(Creature *creature)
@ ACTION_FROSTMOURNE_INTRO
@ ACTION_RESTORE_LIGHT
@ LIGHT_S_HAMMER_TELEPORT
@ SPELL_BERSERK2
@ AREA_THE_FROZEN_THRONE
@ GO_DOODAD_ICESHARD_STANDING01
@ GO_DOODAD_ICESHARD_STANDING02
@ GO_DOODAD_ICESHARD_STANDING04
@ GO_ARTHAS_PLATFORM
@ GO_DOODAD_ICESHARD_STANDING03
@ GO_DOODAD_ICECROWN_THRONEFROSTYWIND01
@ GO_DOODAD_ICECROWN_THRONEFROSTYEDGE01
@ DATA_THE_LICH_KING
@ DATA_TERENAS_MENETHIL
@ DATA_HIGHLORD_TIRION_FORDRING
@ DATA_ARTHAS_PLATFORM
C::value_type const & SelectRandomContainerElement(C const &container)
Definition Containers.h:48
float GetAngle(Position const *pos) const
Definition Object.cpp:1860
void RelocateOffset(Position const &offset)
Definition Object.cpp:1841
bool IsHeroic() const
void SetEquipmentSlots(bool loadDefault, int32 mainHand=EQUIP_NO_CHANGE, int32 offHand=EQUIP_NO_CHANGE, int32 ranged=EQUIP_NO_CHANGE)
Creature * me
bool HealthAbovePct(uint32 pct) const
ScriptedAI(Creature *creature)
uint32 GetData(uint32 type) const OVERRIDE
void MovementInform(uint32 type, uint32 pointId) OVERRIDE
void DamageTaken(Unit *, uint32 &) OVERRIDE
void SetData(uint32 type, uint32 value) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHitTarget(Unit *, SpellInfo const *spell) OVERRIDE
bool CanAIAttack(Unit const *target) const OVERRIDE
void SummonedCreatureDies(Creature *summon, Unit *) OVERRIDE
void SpellHit(Unit *, SpellInfo const *spell) OVERRIDE
void SendPacketToPlayers(WorldPacket const *data) const
void SendLightOverride(uint32 overrideId, uint32 fadeInTime) const
void SendWeather(WeatherState weather) const
void JustSummoned(Creature *summon) OVERRIDE
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 MovementInform(uint32 type, uint32 point) OVERRIDE
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
bool CanAIAttack(Unit const *target) const OVERRIDE
void DamageTaken(Unit *, uint32 &damage) OVERRIDE
void SpellHit(Unit *, SpellInfo const *spell) OVERRIDE
void MovementInform(uint32 type, uint32 id) OVERRIDE
void sGossipSelect(Player *, uint32 sender, uint32 action) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void MovementInform(uint32 type, uint32 id) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void DamageTaken(Unit *, uint32 &damage) OVERRIDE