Guest User

ICC-FinalBattle-Bag

a guest
Jun 14th, 2012
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 130.73 KB | None | 0 0
  1. /*
  2.  * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify it
  5.  * under the terms of the GNU General Public License as published by the
  6.  * Free Software Foundation; either version 2 of the License, or (at your
  7.  * option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful, but WITHOUT
  10.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11.  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12.  * more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License along
  15.  * with this program. If not, see <http://www.gnu.org/licenses/>.
  16.  */
  17.  
  18. #include "ObjectMgr.h"
  19. #include "ScriptMgr.h"
  20. #include "ScriptedCreature.h"
  21. #include "SpellScript.h"
  22. #include "SpellAuraEffects.h"
  23. #include "Spell.h"
  24. #include "Vehicle.h"
  25. #include "Cell.h"
  26. #include "CellImpl.h"
  27. #include "GridNotifiers.h"
  28. #include "GridNotifiersImpl.h"
  29. #include "icecrown_citadel.h"
  30.  
  31. enum Texts
  32. {
  33.     // The Lich King
  34.     SAY_LK_INTRO_1                  = 0,
  35.     SAY_LK_INTRO_2                  = 1,
  36.     SAY_LK_INTRO_3                  = 2,
  37.     SAY_LK_REMORSELESS_WINTER       = 4,
  38.     SAY_LK_QUAKE                    = 5,
  39.     SAY_LK_SUMMON_VALKYR            = 6,
  40.     SAY_LK_HARVEST_SOUL             = 7,
  41.     SAY_LK_FROSTMOURNE_ESCAPE       = 8,    // not said on heroic
  42.     SAY_LK_FROSTMOURNE_KILL         = 9,    // not said on heroic
  43.     SAY_LK_KILL                     = 10,
  44.     SAY_LK_BERSERK                  = 11,
  45.     EMOTE_DEFILE_WARNING            = 12,
  46.     EMOTE_NECROTIC_PLAGUE_WARNING   = 13,
  47.     SAY_LK_OUTRO_1                  = 14,
  48.     SAY_LK_OUTRO_2                  = 15,
  49.     SAY_LK_OUTRO_3                  = 16,
  50.     SAY_LK_OUTRO_4                  = 17,
  51.     SAY_LK_OUTRO_5                  = 18,
  52.     SAY_LK_OUTRO_6                  = 19,
  53.     SAY_LK_OUTRO_7                  = 20,
  54.     SAY_LK_OUTRO_8                  = 21,
  55.  
  56.     // Highlord Tirion Fordring
  57.     SAY_TIRION_INTRO_1              = 0,
  58.     SAY_TIRION_INTRO_2              = 1,
  59.     SAY_TIRION_OUTRO_1              = 2,
  60.     SAY_TIRION_OUTRO_2              = 3,
  61.  
  62.     // Terenas Menethil (outro)
  63.     SAY_TERENAS_OUTRO_1             = 0,
  64.     SAY_TERENAS_OUTRO_2             = 1,
  65.  
  66.     // Terenas Menethil (Frostmourne)
  67.     SAY_TERENAS_INTRO_1             = 0,
  68.     SAY_TERENAS_INTRO_2             = 1,
  69.     SAY_TERENAS_INTRO_3             = 2,
  70. };
  71.  
  72. enum Spells
  73. {
  74.     // The Lich King
  75.     SPELL_PLAGUE_AVOIDANCE              = 72846,    // raging spirits also get it
  76.     SPELL_EMOTE_SIT_NO_SHEATH           = 73220,
  77.     SPELL_BOSS_HITTIN_YA                = 73878,
  78.     SPELL_EMOTE_SHOUT_NO_SHEATH         = 73213,
  79.     SPELL_ICE_LOCK                      = 71614,
  80.  
  81.     // Phase 1
  82.     SPELL_SUMMON_SHAMBLING_HORROR       = 70372,
  83.     SPELL_RISEN_WITCH_DOCTOR_SPAWN      = 69639,
  84.     SPELL_SUMMON_DRUDGE_GHOULS          = 70358,
  85.     SPELL_INFEST                        = 70541,
  86.     SPELL_NECROTIC_PLAGUE               = 70337,
  87.     SPELL_NECROTIC_PLAGUE_JUMP          = 70338,
  88.     SPELL_PLAGUE_SIPHON                 = 74074,
  89.     SPELL_SHADOW_TRAP                   = 73539,
  90.     SPELL_SHADOW_TRAP_AURA              = 73525,
  91.     SPELL_SHADOW_TRAP_KNOCKBACK         = 73529,
  92.  
  93.     // Phase Transition
  94.     SPELL_REMORSELESS_WINTER_1          = 68981,
  95.     SPELL_REMORSELESS_WINTER_2          = 72259,
  96.     SPELL_PAIN_AND_SUFFERING            = 72133,
  97.     SPELL_SUMMON_ICE_SPHERE             = 69104,
  98.     SPELL_ICE_SPHERE                    = 69090,
  99.     SPELL_ICE_BURST_TARGET_SEARCH       = 69109,
  100.     SPELL_ICE_PULSE                     = 69091,
  101.     SPELL_ICE_BURST                     = 69108,
  102.     SPELL_RAGING_SPIRIT                 = 69200,
  103.     SPELL_RAGING_SPIRIT_VISUAL          = 69197,
  104.     SPELL_RAGING_SPIRIT_VISUAL_CLONE    = 69198,
  105.     SPELL_SOUL_SHRIEK                   = 69242,
  106.     SPELL_QUAKE                         = 72262,
  107.  
  108.     // Phase 2
  109.     SPELL_DEFILE                        = 72762,
  110.     SPELL_DEFILE_AURA                   = 72743,
  111.     SPELL_DEFILE_GROW                   = 72756,
  112.     SPELL_SUMMON_VALKYR                 = 69037,
  113.     SPELL_SUMMON_VALKYR_PERIODIC        = 74361,
  114.     SPELL_HARVEST_SOUL_VALKYR           = 68985,    // Val'kyr Shadowguard vehicle aura
  115.     SPELL_SOUL_REAPER                   = 69409,
  116.     SPELL_SOUL_REAPER_BUFF              = 69410,
  117.     SPELL_WINGS_OF_THE_DAMNED           = 74352,
  118.     SPELL_VALKYR_TARGET_SEARCH          = 69030,
  119.     SPELL_CHARGE                        = 74399,    // cast on selected target
  120.     SPELL_VALKYR_CARRY                  = 74445,    // removes unselectable flag
  121.     SPELL_LIFE_SIPHON                   = 73488,
  122.     SPELL_LIFE_SIPHON_HEAL              = 73489,
  123.     SPELL_EJECT_ALL_PASSENGERS          = 68576,
  124.  
  125.     // Phase 3
  126.     SPELL_VILE_SPIRITS                  = 70498,
  127.     SPELL_VILE_SPIRIT_MOVE_SEARCH       = 70501,
  128.     SPELL_VILE_SPIRIT_DAMAGE_SEARCH     = 70502,
  129.     SPELL_SPIRIT_BURST                  = 70503,
  130.     SPELL_HARVEST_SOUL                  = 68980,
  131.     SPELL_HARVEST_SOULS                 = 73654,    // Heroic version, weird because it has all 4 difficulties just like above spell
  132.     SPELL_HARVEST_SOUL_VEHICLE          = 68984,
  133.     SPELL_HARVEST_SOUL_VISUAL           = 71372,
  134.     SPELL_HARVEST_SOUL_TELEPORT         = 72546,
  135.     SPELL_HARVEST_SOULS_TELEPORT        = 73655,
  136.     SPELL_HARVEST_SOUL_TELEPORT_BACK    = 72597,
  137.     SPELL_IN_FROSTMOURNE_ROOM           = 74276,
  138.     SPELL_KILL_FROSTMOURNE_PLAYERS      = 75127,
  139.     SPELL_HARVESTED_SOUL                = 72679,
  140.     SPELL_TRIGGER_VILE_SPIRIT_HEROIC    = 73582,
  141.  
  142.     // Frostmourne
  143.     SPELL_LIGHTS_FAVOR                  = 69382,
  144.     SPELL_RESTORE_SOUL                  = 72595,
  145.     SPELL_RESTORE_SOULS                 = 73650,    // Heroic
  146.     SPELL_DARK_HUNGER                   = 69383,    // Passive proc healing
  147.     SPELL_DESTROY_SOUL                  = 74086,    // Used when Terenas Menethil dies
  148.     SPELL_SOUL_RIP                      = 69397,    // Deals increasing damage
  149.     SPELL_SOUL_RIP_DAMAGE               = 69398,
  150.     SPELL_TERENAS_LOSES_INSIDE          = 72572,
  151.     SPELL_SUMMON_SPIRIT_BOMB_1          = 73581,    // (Heroic)
  152.     SPELL_SUMMON_SPIRIT_BOMB_2          = 74299,    // (Heroic)
  153.     SPELL_EXPLOSION                     = 73576,    // Spirit Bomb (Heroic)
  154.  
  155.     // Outro
  156.     SPELL_FURY_OF_FROSTMOURNE           = 72350,
  157.     SPELL_FURY_OF_FROSTMOURNE_NO_REZ    = 72351,
  158.     SPELL_EMOTE_QUESTION_NO_SHEATH      = 73330,
  159.     SPELL_RAISE_DEAD                    = 71769,
  160.     SPELL_LIGHTS_BLESSING               = 71797,
  161.     SPELL_JUMP                          = 71809,
  162.     SPELL_JUMP_TRIGGERED                = 71811,
  163.     SPELL_JUMP_2                        = 72431,
  164.     SPELL_SUMMON_BROKEN_FROSTMOURNE     = 74081,    // visual
  165.     SPELL_SUMMON_BROKEN_FROSTMOURNE_2   = 72406,    // animation
  166.     SPELL_SUMMON_BROKEN_FROSTMOURNE_3   = 73017,    // real summon
  167.     SPELL_BROKEN_FROSTMOURNE            = 72398,
  168.     SPELL_BROKEN_FROSTMOURNE_KNOCK      = 72405,
  169.     SPELL_SOUL_BARRAGE                  = 72305,
  170.     SPELL_SUMMON_TERENAS                = 72420,
  171.     SPELL_MASS_RESURRECTION             = 72429,
  172.     SPELL_MASS_RESURRECTION_REAL        = 72423,
  173.     SPELL_PLAY_MOVIE                    = 73159,
  174.  
  175.     // Shambling Horror
  176.     SPELL_SHOCKWAVE                     = 72149,
  177.     SPELL_ENRAGE                        = 72143,
  178.     SPELL_FRENZY                        = 28747,
  179. };
  180.  
  181. #define NECROTIC_PLAGUE_LK   RAID_MODE<uint32>(70337, 73912, 73913, 73914)
  182. #define NECROTIC_PLAGUE_PLR  RAID_MODE<uint32>(70338, 73785, 73786, 73787)
  183. #define REMORSELESS_WINTER_1 RAID_MODE<uint32>(68981, 74270, 74271, 74272)
  184. #define REMORSELESS_WINTER_2 RAID_MODE<uint32>(72259, 74273, 74274, 74275)
  185. #define SUMMON_VALKYR        RAID_MODE<uint32>(69037, 74361, 69037, 74361)
  186. #define HARVEST_SOUL         RAID_MODE<uint32>(68980, 74325, 74296, 74297)
  187.  
  188. enum Events
  189. {
  190.     // The Lich King
  191.     // intro events
  192.     EVENT_INTRO_MOVE_1              = 1,
  193.     EVENT_INTRO_MOVE_2              = 2,
  194.     EVENT_INTRO_MOVE_3              = 3,
  195.     EVENT_INTRO_TALK_1              = 4,
  196.     EVENT_EMOTE_CAST_SHOUT          = 5,
  197.     EVENT_INTRO_EMOTE_1             = 6,
  198.     EVENT_INTRO_CHARGE              = 7,
  199.     EVENT_INTRO_CAST_FREEZE         = 8,
  200.     EVENT_FINISH_INTRO              = 9,
  201.  
  202.     // combat events
  203.     EVENT_SUMMON_SHAMBLING_HORROR   = 10,
  204.     EVENT_SUMMON_DRUDGE_GHOUL       = 11,
  205.     EVENT_INFEST                    = 12,
  206.     EVENT_NECROTIC_PLAGUE           = 13,
  207.     EVENT_SHADOW_TRAP               = 14,   // heroic only
  208.     EVENT_SOUL_REAPER               = 15,
  209.     EVENT_DEFILE                    = 16,
  210.     EVENT_HARVEST_SOUL              = 17,   // normal mode only
  211.     EVENT_PAIN_AND_SUFFERING        = 18,
  212.     EVENT_SUMMON_ICE_SPHERE         = 19,
  213.     EVENT_SUMMON_RAGING_SPIRIT      = 20,
  214.     EVENT_QUAKE                     = 21,
  215.     EVENT_SUMMON_VALKYR             = 22,
  216.     EVENT_GRAB_PLAYER               = 23,
  217.     EVENT_MOVE_TO_DROP_POS          = 24,
  218.     EVENT_LIFE_SIPHON               = 25,   // heroic only
  219.     EVENT_START_ATTACK              = 26,
  220.     EVENT_QUAKE_2                   = 27,
  221.     EVENT_VILE_SPIRITS              = 28,
  222.     EVENT_HARVEST_SOULS             = 29,   // heroic only
  223.     EVENT_WICKED_SPIRITS            = 30,
  224.     EVENT_SOUL_RIP                  = 31,
  225.     EVENT_DESTROY_SOUL              = 32,
  226.     EVENT_FROSTMOURNE_TALK_1        = 33,
  227.     EVENT_FROSTMOURNE_TALK_2        = 34,
  228.     EVENT_FROSTMOURNE_TALK_3        = 35,
  229.     EVENT_TELEPORT_BACK             = 36,
  230.     EVENT_FROSTMOURNE_HEROIC        = 37,
  231.     EVENT_OUTRO_TALK_1              = 38,
  232.     EVENT_OUTRO_TALK_2              = 39,
  233.     EVENT_OUTRO_EMOTE_TALK          = 40,
  234.     EVENT_OUTRO_TALK_3              = 41,
  235.     EVENT_OUTRO_MOVE_CENTER         = 42,
  236.     EVENT_OUTRO_TALK_4              = 43,
  237.     EVENT_OUTRO_RAISE_DEAD          = 44,
  238.     EVENT_OUTRO_TALK_5              = 45,
  239.     EVENT_OUTRO_BLESS               = 46,
  240.     EVENT_OUTRO_REMOVE_ICE          = 47,
  241.     EVENT_OUTRO_MOVE_1              = 48,
  242.     EVENT_OUTRO_JUMP                = 49,
  243.     EVENT_OUTRO_TALK_6              = 50,
  244.     EVENT_OUTRO_KNOCK_BACK          = 51,
  245.     EVENT_OUTRO_SOUL_BARRAGE        = 52,
  246.     EVENT_OUTRO_SUMMON_TERENAS      = 53,
  247.     EVENT_OUTRO_TERENAS_TALK_1      = 54,
  248.     EVENT_OUTRO_TERENAS_TALK_2      = 55,
  249.     EVENT_OUTRO_TALK_7              = 56,
  250.     EVENT_OUTRO_TALK_8              = 57,
  251.     EVENT_BERSERK                   = 58,
  252.  
  253.     // Shambling Horror
  254.     EVENT_SHOCKWAVE                 = 59,
  255.     EVENT_ENRAGE                    = 60,
  256.  
  257.     // Raging Spirit
  258.     EVENT_SOUL_SHRIEK               = 61,
  259.  
  260.     // Strangulate Vehicle (Harvest Soul)
  261.     EVENT_TELEPORT                  = 62,
  262.     EVENT_MOVE_TO_LICH_KING         = 63,
  263.     EVENT_DESPAWN_SELF              = 64,
  264. };
  265.  
  266. enum EventGroups
  267. {
  268.     EVENT_GROUP_BERSERK         = 1,
  269.     EVENT_GROUP_VILE_SPIRITS    = 2,
  270. };
  271.  
  272. enum Phases
  273. {
  274.     PHASE_INTRO                 = 1,
  275.     PHASE_ONE                   = 2,
  276.     PHASE_TWO                   = 3,
  277.     PHASE_THREE                 = 4,
  278.     PHASE_TRANSITION            = 5,
  279.     PHASE_FROSTMOURNE           = 6,    // only set on heroic mode when all players are sent into frostmourne
  280.     PHASE_OUTRO                 = 7,
  281.  
  282.     PHASE_MASK_INTRO            = 1 << PHASE_INTRO,
  283.     PHASE_MASK_ONE              = 1 << PHASE_ONE,
  284.     PHASE_MASK_TWO              = 1 << PHASE_TWO,
  285.     PHASE_MASK_THREE            = 1 << PHASE_THREE,
  286.     PHASE_MASK_TRANSITION       = 1 << PHASE_TRANSITION,
  287.     PHASE_MASK_NO_CAST_CHECK    = (1 << PHASE_TRANSITION) | (1 << PHASE_FROSTMOURNE) | (1 << PHASE_OUTRO),
  288.     PHASE_MASK_FROSTMOURNE      = 1 << PHASE_FROSTMOURNE,
  289.     PHASE_MASK_OUTRO            = 1 << PHASE_OUTRO,
  290.     PHASE_MASK_NO_VICTIM        = (1 << PHASE_INTRO) | (1 << PHASE_OUTRO) | (1 << PHASE_FROSTMOURNE),
  291. };
  292.  
  293. #define PHASE_TWO_THREE  (events.GetPhaseMask() & PHASE_MASK_TWO ? PHASE_TWO : PHASE_THREE)
  294.  
  295. Position const CenterPosition     = {503.6282f, -2124.655f, 1040.8602f, 0.0f};
  296. Position const TirionIntro        = {489.2970f, -2124.840f, 1040.8602f, 0.0f};
  297. Position const TirionCharge       = {482.9019f, -2124.479f, 1040.8602f, 0.0f};
  298. Position const LichKingIntro[3]   =
  299. {
  300.     {432.0851f, -2123.673f, 1064.6615f, 0.0f},
  301.     {457.8351f, -2123.423f, 1041.1615f, 0.0f},
  302.     {465.0730f, -2123.470f, 1040.8602f, 0.0f},
  303. };
  304. Position const OutroPosition1     = {493.6286f, -2124.569f, 1040.8602f, 0.0f};
  305. Position const OutroFlying        = {508.9897f, -2124.561f, 1045.8598f, 0.0f};
  306. Position const TerenasSpawn       = {495.5542f, -2517.012f, 1050.000f, 4.6993f};
  307. Position const TerenasSpawnHeroic = {495.7080f, -2523.760f, 1050.000f, 0.0f};
  308. Position const SpiritWardenSpawn  = {495.3406f, -2529.983f, 1050.000f, 1.5592f};
  309.  
  310. enum MovePoints
  311. {
  312.     POINT_CENTER_1          = 1,
  313.     POINT_CENTER_2          = 2,
  314.     POINT_TIRION_INTRO      = 3,
  315.     POINT_LK_INTRO_1        = 4,
  316.     POINT_LK_INTRO_2        = 5,
  317.     POINT_LK_INTRO_3        = 6,
  318.     POINT_TIRION_CHARGE     = 7,
  319.     POINT_DROP_PLAYER       = 8,
  320.     POINT_LK_OUTRO_1        = 9,
  321.     POINT_TIRION_OUTRO_1    = 10,
  322.     POINT_OUTRO_JUMP        = 11,
  323.     POINT_LK_OUTRO_2        = 12,
  324.     POINT_GROUND            = 13,
  325.     POINT_CHARGE            = 1003, // globally used number for charge spell effects
  326. };
  327.  
  328. enum EncounterActions
  329. {
  330.     ACTION_START_ENCOUNTER      = 0,
  331.     ACTION_CONTINUE_INTRO       = 1,
  332.     ACTION_START_ATTACK         = 2,
  333.     ACTION_OUTRO                = 3,
  334.     ACTION_PLAY_MUSIC           = 4,
  335.     ACTION_BREAK_FROSTMOURNE    = 5,
  336.     ACTION_SUMMON_TERENAS       = 6,
  337.     ACTION_FINISH_OUTRO         = 7,
  338.     ACTION_TELEPORT_BACK        = 8,
  339. };
  340.  
  341. enum MiscData
  342. {
  343.     LIGHT_SNOWSTORM             = 2490,
  344.     LIGHT_SOULSTORM             = 2508,
  345.  
  346.     MUSIC_FROZEN_THRONE         = 17457,
  347.     MUSIC_SPECIAL               = 17458,    // Summon Shambling Horror, Remorseless Winter, Quake, Summon Val'kyr Periodic, Harvest Soul, Vile Spirits
  348.     MUSIC_FURY_OF_FROSTMOURNE   = 17459,
  349.     MUSIC_FINAL                 = 17460,    // Raise Dead, Light's Blessing
  350.  
  351.     SOUND_PAIN                  = 17360,    // separate sound, not attached to any text
  352.  
  353.     EQUIP_ASHBRINGER_GLOWING    = 50442,
  354.     EQUIP_BROKEN_FROSTMOURNE    = 50840,
  355.  
  356.     MOVIE_FALL_OF_THE_LICH_KING = 16,
  357. };
  358.  
  359. #define DATA_PLAGUE_STACK 70337
  360. #define DATA_VILE 45814622
  361.  
  362. class NecroticPlagueTargetCheck : public std::unary_function<Unit*, bool>
  363. {
  364.     public:
  365.         NecroticPlagueTargetCheck(Unit const* obj, uint32 notAura1 = 0, uint32 notAura2 = 0)
  366.             : _sourceObj(obj), _notAura1(notAura1), _notAura2(notAura2)
  367.         {
  368.         }
  369.  
  370.         bool operator()(Unit* unit) const
  371.         {
  372.             if (!unit || unit == _sourceObj || !unit->isTargetableForAttack() || unit->isTotem() || unit->HasAura(SPELL_PLAGUE_AVOIDANCE))
  373.                 return false;
  374.             if ((_notAura1 && unit->HasAura(_notAura1)) || (_notAura2 && unit->HasAura(_notAura2)))
  375.                 return false;
  376.             return true;
  377.         }
  378.  
  379.     private:
  380.         Unit const* _sourceObj;
  381.         uint32 _notAura1;
  382.         uint32 _notAura2;
  383. };
  384.  
  385. class HeightDifferenceCheck
  386. {
  387.     public:
  388.         HeightDifferenceCheck(GameObject* go, float diff, bool reverse)
  389.             : _baseObject(go), _difference(diff), _reverse(reverse)
  390.         {
  391.         }
  392.  
  393.         bool operator()(Unit* unit) const
  394.         {
  395.             return (unit->GetPositionZ() - _baseObject->GetPositionZ() > _difference) != _reverse;
  396.         }
  397.  
  398.     private:
  399.         GameObject* _baseObject;
  400.         float _difference;
  401.         bool _reverse;
  402. };
  403.  
  404. class FrozenThroneResetWorker
  405. {
  406.     public:
  407.         FrozenThroneResetWorker() { }
  408.  
  409.         bool operator()(GameObject* go)
  410.         {
  411.             switch (go->GetEntry())
  412.             {
  413.                 case GO_ARTHAS_PLATFORM:
  414.                     go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING);
  415.                     break;
  416.                 case GO_DOODAD_ICECROWN_THRONEFROSTYWIND01:
  417.                     go->SetGoState(GO_STATE_ACTIVE);
  418.                     break;
  419.                 case GO_DOODAD_ICECROWN_THRONEFROSTYEDGE01:
  420.                     go->SetGoState(GO_STATE_READY);
  421.                     break;
  422.                 case GO_DOODAD_ICESHARD_STANDING02:
  423.                 case GO_DOODAD_ICESHARD_STANDING01:
  424.                 case GO_DOODAD_ICESHARD_STANDING03:
  425.                 case GO_DOODAD_ICESHARD_STANDING04:
  426.                     go->ResetDoorOrButton();
  427.                     break;
  428.                 default:
  429.                     break;
  430.             }
  431.  
  432.             return false;
  433.         }
  434. };
  435.  
  436. class StartMovementEvent : public BasicEvent
  437. {
  438.     public:
  439.         StartMovementEvent(Creature* summoner, Creature* owner)
  440.             : _summoner(summoner), _owner(owner)
  441.         {
  442.         }
  443.  
  444.         bool Execute(uint64 /*time*/, uint32 /*diff*/)
  445.         {
  446.             _owner->SetReactState(REACT_AGGRESSIVE);
  447.             if (Unit* target = _summoner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(_summoner)))
  448.                 _owner->AI()->AttackStart(target);
  449.             return true;
  450.         }
  451.  
  452.     private:
  453.         Creature* _summoner;
  454.         Creature* _owner;
  455. };
  456.  
  457. class VileSpiritActivateEvent : public BasicEvent
  458. {
  459.     public:
  460.         explicit VileSpiritActivateEvent(Creature* owner)
  461.             : _owner(owner)
  462.         {
  463.         }
  464.  
  465.         bool Execute(uint64 /*time*/, uint32 /*diff*/)
  466.         {
  467.             _owner->SetReactState(REACT_AGGRESSIVE);
  468.             _owner->CastSpell(_owner, SPELL_VILE_SPIRIT_MOVE_SEARCH, true);
  469.             _owner->CastSpell((Unit*)NULL, SPELL_VILE_SPIRIT_DAMAGE_SEARCH, true);
  470.             return true;
  471.         }
  472.  
  473.     private:
  474.         Creature* _owner;
  475. };
  476.  
  477. class boss_the_lich_king : public CreatureScript
  478. {
  479.     public:
  480.         boss_the_lich_king() : CreatureScript("boss_the_lich_king") { }
  481.  
  482.         struct boss_the_lich_kingAI : public BossAI
  483.         {
  484.             boss_the_lich_kingAI(Creature* creature) : BossAI(creature, DATA_THE_LICH_KING)
  485.             {
  486.             }
  487.  
  488.             void Reset()
  489.             {
  490.                 _Reset();
  491.                 events.SetPhase(PHASE_INTRO);
  492.                 _necroticPlagueStack = 0;
  493.                 _vileSpiritExplosions = 0;
  494.                 SetEquipmentSlots(true);
  495.             }
  496.  
  497.             void JustDied(Unit* /*killer*/)
  498.             {
  499.                 _JustDied();
  500.                 DoCastAOE(SPELL_PLAY_MOVIE, false);
  501.                 me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
  502.                 me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x03);
  503.  
  504.                 //me->GetMotionMaster()->MoveFall();
  505.             }
  506.  
  507.             void EnterCombat(Unit* target)
  508.             {
  509.                 if (!instance->CheckRequiredBosses(DATA_THE_LICH_KING, target->ToPlayer()))
  510.                 {
  511.                     EnterEvadeMode();
  512.                     instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
  513.                     return;
  514.                 }
  515.  
  516.                 me->setActive(true);
  517.                 DoZoneInCombat();
  518.  
  519.                 events.SetPhase(PHASE_ONE);
  520.                 events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 20000, 0, PHASE_ONE);
  521.                 events.ScheduleEvent(EVENT_SUMMON_DRUDGE_GHOUL, 10000, 0, PHASE_ONE);
  522.                 events.ScheduleEvent(EVENT_INFEST, 5000, 0, PHASE_ONE);
  523.                 events.ScheduleEvent(EVENT_NECROTIC_PLAGUE, urand(30000, 33000), 0, PHASE_ONE);
  524.                 events.ScheduleEvent(EVENT_BERSERK, 900000, EVENT_GROUP_BERSERK);
  525.                 if (IsHeroic())
  526.                     events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500, 0, PHASE_ONE);
  527.             }
  528.  
  529.             void JustReachedHome()
  530.             {
  531.                 _JustReachedHome();
  532.                 instance->SetBossState(DATA_THE_LICH_KING, NOT_STARTED);
  533.  
  534.                 // Reset The Frozen Throne gameobjects
  535.                 FrozenThroneResetWorker reset;
  536.                 Trinity::GameObjectWorker<FrozenThroneResetWorker> worker(me, reset);
  537.                 me->VisitNearbyGridObject(333.0f, worker);
  538.  
  539.                 // Reset any light override
  540.                 SendLightOverride(0, 5000);
  541.             }
  542.  
  543.             bool CanAIAttack(Unit const* target) const
  544.             {
  545.                 // The Lich King must not select targets in frostmourne room if he killed everyone outside
  546.                 return !target->HasAura(SPELL_IN_FROSTMOURNE_ROOM);
  547.             }
  548.  
  549.             void EnterEvadeMode()
  550.             {
  551.                 instance->SetBossState(DATA_THE_LICH_KING, FAIL);
  552.                 BossAI::EnterEvadeMode();
  553.                 if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
  554.                     tirion->AI()->EnterEvadeMode();
  555.                 DoCastAOE(SPELL_KILL_FROSTMOURNE_PLAYERS);
  556.                 summons.DoAction(NPC_STRANGULATE_VEHICLE, ACTION_TELEPORT_BACK);
  557.             }
  558.  
  559.             void KilledUnit(Unit* victim)
  560.             {
  561.                 if (victim->GetTypeId() == TYPEID_PLAYER && !me->IsInEvadeMode() && !(events.GetPhaseMask() & PHASE_MASK_OUTRO))
  562.                     Talk(SAY_LK_KILL);
  563.             }
  564.  
  565.             void DoAction(int32 const action)
  566.             {
  567.                 switch (action)
  568.                 {
  569.                     case ACTION_START_ENCOUNTER:
  570.                         instance->SetBossState(DATA_THE_LICH_KING, IN_PROGRESS);
  571.                         Talk(SAY_LK_INTRO_1);
  572.                         SendMusicToPlayers(MUSIC_FROZEN_THRONE);
  573.                         // schedule talks
  574.                         me->SetStandState(UNIT_STAND_STATE_STAND);
  575.                         events.ScheduleEvent(EVENT_INTRO_MOVE_1, 4000);
  576.                         break;
  577.                     case ACTION_START_ATTACK:
  578.                         events.ScheduleEvent(EVENT_START_ATTACK, 5000);
  579.                         break;
  580.                     case ACTION_PLAY_MUSIC:
  581.                         SendMusicToPlayers(MUSIC_FINAL);
  582.                         break;
  583.                     case ACTION_RESTORE_LIGHT:
  584.                         SendLightOverride(0, 5000);
  585.                         break;
  586.                     case ACTION_BREAK_FROSTMOURNE:
  587.                         DoCastAOE(SPELL_SUMMON_BROKEN_FROSTMOURNE);
  588.                         DoCastAOE(SPELL_SUMMON_BROKEN_FROSTMOURNE_2);
  589.                         SetEquipmentSlots(false, EQUIP_BROKEN_FROSTMOURNE);
  590.                         events.ScheduleEvent(EVENT_OUTRO_TALK_6, 2500, 0, PHASE_OUTRO);
  591.                         break;
  592.                     case ACTION_FINISH_OUTRO:
  593.                         events.ScheduleEvent(EVENT_OUTRO_TALK_7, 7000, 0, PHASE_OUTRO);
  594.                         events.ScheduleEvent(EVENT_OUTRO_TALK_8, 17000, 0, PHASE_OUTRO);
  595.                         break;
  596.                     case ACTION_TELEPORT_BACK:
  597.                         summons.DoAction(NPC_STRANGULATE_VEHICLE, ACTION_TELEPORT_BACK);
  598.                         if (!IsHeroic())
  599.                             Talk(SAY_LK_FROSTMOURNE_ESCAPE);
  600.                         else
  601.                             DoCastAOE(SPELL_TRIGGER_VILE_SPIRIT_HEROIC);
  602.                         break;
  603.                     default:
  604.                         break;
  605.                 }
  606.             }
  607.  
  608.             uint32 GetData(uint32 type)
  609.             {
  610.                 switch (type)
  611.                 {
  612.                     case DATA_PLAGUE_STACK:
  613.                         return _necroticPlagueStack;
  614.                     case DATA_VILE:
  615.                         return _vileSpiritExplosions;
  616.                     default:
  617.                         break;
  618.                 }
  619.  
  620.                 return 0;
  621.             }
  622.  
  623.             void SetData(uint32 type, uint32 value)
  624.             {
  625.                 switch (type)
  626.                 {
  627.                     case DATA_PLAGUE_STACK:
  628.                         _necroticPlagueStack = std::max(value, _necroticPlagueStack);
  629.                         break;
  630.                     case DATA_VILE:
  631.                         _vileSpiritExplosions += value;
  632.                         break;
  633.                     default:
  634.                         break;
  635.                 }
  636.             }
  637.  
  638.             void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/)
  639.             {
  640.                 if (events.GetPhaseMask() & PHASE_MASK_ONE && !HealthAbovePct(70))
  641.                 {
  642.                     events.SetPhase(PHASE_TRANSITION);
  643.                     me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
  644.                     me->GetMotionMaster()->MovePoint(POINT_CENTER_1, CenterPosition);
  645.                     return;
  646.                 }
  647.  
  648.                 if (events.GetPhaseMask() & PHASE_MASK_TWO && !HealthAbovePct(40))
  649.                 {
  650.                     events.SetPhase(PHASE_TRANSITION);
  651.                     me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
  652.                     me->GetMotionMaster()->MovePoint(POINT_CENTER_2, CenterPosition);
  653.                     return;
  654.                 }
  655.  
  656.                 if (events.GetPhaseMask() & PHASE_MASK_THREE && !HealthAbovePct(10))
  657.                 {
  658.                     me->SetReactState(REACT_PASSIVE);
  659.                     me->AttackStop();
  660.                     events.Reset();
  661.                     events.SetPhase(PHASE_OUTRO);
  662.                     summons.DespawnAll();
  663.                     SendMusicToPlayers(MUSIC_FURY_OF_FROSTMOURNE);
  664.                     DoCastAOE(SPELL_FURY_OF_FROSTMOURNE);
  665.                     me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
  666.                     events.ScheduleEvent(EVENT_OUTRO_TALK_1, 2600, 0, PHASE_OUTRO);
  667.                     events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 6600, 0, PHASE_OUTRO);
  668.                     events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 17600, 0, PHASE_OUTRO);
  669.                     events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 27600, 0, PHASE_OUTRO);
  670.                     events.ScheduleEvent(EVENT_OUTRO_TALK_2, 34600, 0, PHASE_OUTRO);
  671.                     events.ScheduleEvent(EVENT_OUTRO_TALK_3, 43600, 0, PHASE_OUTRO);
  672.                     events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 54600, 0, PHASE_OUTRO);
  673.                     events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 58600, 0, PHASE_OUTRO);
  674.                     events.ScheduleEvent(EVENT_OUTRO_MOVE_CENTER, 69600, 0, PHASE_OUTRO);
  675.                     // stop here. rest will get scheduled from MovementInform
  676.                     return;
  677.                 }
  678.             }
  679.  
  680.             void JustSummoned(Creature* summon)
  681.             {
  682.                 switch (summon->GetEntry())
  683.                 {
  684.                     case NPC_SHAMBLING_HORROR:
  685.                     case NPC_DRUDGE_GHOUL:
  686.                         summon->CastSpell(summon, SPELL_RISEN_WITCH_DOCTOR_SPAWN, true);
  687.                         summon->SetReactState(REACT_PASSIVE);
  688.                         summon->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
  689.                         summon->m_Events.AddEvent(new StartMovementEvent(me, summon), summon->m_Events.CalculateTime(5000));
  690.                         break;
  691.                     case NPC_ICE_SPHERE:
  692.                     {
  693.                         if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
  694.                         {
  695.                             summon->SetReactState(REACT_PASSIVE);
  696.                             summon->CastSpell(summon, SPELL_ICE_SPHERE, false);
  697.                             summon->CastSpell(summon, SPELL_ICE_BURST_TARGET_SEARCH, false);
  698.                             summon->CastSpell(target, SPELL_ICE_PULSE, false);
  699.                             summon->ClearUnitState(UNIT_STAT_CASTING);
  700.                             summon->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f);
  701.                         }
  702.                         else
  703.                             summon->DespawnOrUnsummon();
  704.                         break;
  705.                     }
  706.                     case NPC_DEFILE:
  707.                         summon->SetReactState(REACT_PASSIVE);
  708.                         summon->CastSpell(summon, SPELL_DEFILE_AURA, false);
  709.                         break;
  710.                     case NPC_FROSTMOURNE_TRIGGER:
  711.                     {
  712.                         summons.Summon(summon);
  713.                         summon->CastSpell((Unit*)NULL, SPELL_BROKEN_FROSTMOURNE, true);
  714.  
  715.                         SendLightOverride(LIGHT_SOULSTORM, 10000);
  716.                         SendWeather(WEATHER_STATE_BLACKSNOW);
  717.  
  718.                         events.ScheduleEvent(EVENT_OUTRO_SOUL_BARRAGE, 5000, 0, PHASE_OUTRO);
  719.                         return;
  720.                     }
  721.                     case NPC_VILE_SPIRIT:
  722.                     {
  723.                         summons.Summon(summon);
  724.                         if (events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE)
  725.                         {
  726.                             TeleportSpirit(summon);
  727.                             return;
  728.                         }
  729.  
  730.                         summon->SetReactState(REACT_PASSIVE);
  731.                         summon->SetSpeed(MOVE_FLIGHT, 0.5f);
  732.                         summon->GetMotionMaster()->MoveRandom(10.0f);
  733.                         summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000));
  734.                         return;
  735.                     }
  736.                     case NPC_STRANGULATE_VEHICLE:
  737.                         summons.Summon(summon);
  738.                         return;
  739.                     default:
  740.                         break;
  741.                 }
  742.  
  743.                 BossAI::JustSummoned(summon);
  744.             }
  745.  
  746.             void SummonedCreatureDies(Creature* summon, Unit* /*killer*/)
  747.             {
  748.                 switch (summon->GetEntry())
  749.                 {
  750.                     case NPC_SHAMBLING_HORROR:
  751.                     case NPC_DRUDGE_GHOUL:
  752.                     case NPC_ICE_SPHERE:
  753.                     case NPC_VALKYR_SHADOWGUARD:
  754.                     case NPC_RAGING_SPIRIT:
  755.                     case NPC_VILE_SPIRIT:
  756.                     case NPC_WICKED_SPIRIT:
  757.                         summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN);
  758.                         break;
  759.                     default:
  760.                         break;
  761.                 }
  762.             }
  763.  
  764.             void SpellHit(Unit* /*caster*/, SpellInfo const* spell)
  765.             {
  766.                 if (spell->Id == SPELL_HARVESTED_SOUL && me->isInCombat() && !IsHeroic())
  767.                     Talk(SAY_LK_FROSTMOURNE_KILL);
  768.             }
  769.  
  770.             void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell)
  771.             {
  772.                 if (spell->Id == REMORSELESS_WINTER_1 || spell->Id == REMORSELESS_WINTER_2)
  773.                 {
  774.                     SendLightOverride(LIGHT_SNOWSTORM, 5000);
  775.                     SendWeather(WEATHER_STATE_LIGHT_SNOW);
  776.                 }
  777.             }
  778.  
  779.             void MovementInform(uint32 type, uint32 pointId)
  780.             {
  781.                 if (type != POINT_MOTION_TYPE)
  782.                     return;
  783.  
  784.                 switch (pointId)
  785.                 {
  786.                     case POINT_LK_INTRO_1:
  787.                         // schedule for next update cycle, current update must finalize movement
  788.                         events.ScheduleEvent(EVENT_INTRO_MOVE_2, 1, 0, PHASE_INTRO);
  789.                         break;
  790.                     case POINT_LK_INTRO_2:
  791.                         events.ScheduleEvent(EVENT_INTRO_MOVE_3, 1, 0, PHASE_INTRO);
  792.                         break;
  793.                     case POINT_LK_INTRO_3:
  794.                         if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
  795.                             tirion->AI()->DoAction(ACTION_CONTINUE_INTRO);
  796.                         events.ScheduleEvent(EVENT_INTRO_TALK_1, 9000, 0, PHASE_INTRO);
  797.                         break;
  798.                     case POINT_CENTER_1:
  799.                         me->SetFacing(0.0f);
  800.                         Talk(SAY_LK_REMORSELESS_WINTER);
  801.                         SendMusicToPlayers(MUSIC_SPECIAL);
  802.                         me->SetReactState(REACT_PASSIVE);
  803.                         me->AttackStop();
  804.                         DoCast(me, SPELL_REMORSELESS_WINTER_1);
  805.                         events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions
  806.                         events.ScheduleEvent(EVENT_QUAKE, 62500, 0, PHASE_TRANSITION);
  807.                         events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 4000, 0, PHASE_TRANSITION);
  808.                         events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8000, 0, PHASE_TRANSITION);
  809.                         events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 3000, 0, PHASE_TRANSITION);
  810.                         events.ScheduleEvent(EVENT_SUMMON_VALKYR, 78000, 0, PHASE_TWO);
  811.                         events.ScheduleEvent(EVENT_INFEST, 70000, 0, PHASE_TWO);
  812.                         events.ScheduleEvent(EVENT_DEFILE, 97000, 0, PHASE_TWO);
  813.                         events.ScheduleEvent(EVENT_SOUL_REAPER, 94000, 0, PHASE_TWO);
  814.                         me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
  815.                         break;
  816.                     case POINT_CENTER_2:
  817.                         me->SetFacing(0.0f);
  818.                         Talk(SAY_LK_REMORSELESS_WINTER);
  819.                         SendMusicToPlayers(MUSIC_SPECIAL);
  820.                         me->SetReactState(REACT_PASSIVE);
  821.                         me->AttackStop();
  822.                         DoCast(me, SPELL_REMORSELESS_WINTER_2);
  823.                         summons.DespawnEntry(NPC_VALKYR_SHADOWGUARD);
  824.                         events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions
  825.                         events.ScheduleEvent(EVENT_QUAKE_2, 62500, 0, PHASE_TRANSITION);
  826.                         events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 6000, 0, PHASE_TRANSITION);
  827.                         events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8000, 0, PHASE_TRANSITION);
  828.                         events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 5000, 0, PHASE_TRANSITION);
  829.                         events.ScheduleEvent(EVENT_DEFILE, 95500, 0, PHASE_THREE);
  830.                         events.ScheduleEvent(EVENT_SOUL_REAPER, 99500, 0, PHASE_THREE);
  831.                         events.ScheduleEvent(EVENT_VILE_SPIRITS, 79500, EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);
  832.                         events.ScheduleEvent(IsHeroic() ? EVENT_HARVEST_SOULS : EVENT_HARVEST_SOUL, 73500, 0, PHASE_THREE);
  833.                         me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
  834.                         break;
  835.                     case POINT_LK_OUTRO_1:
  836.                         events.ScheduleEvent(EVENT_OUTRO_TALK_4, 1, 0, PHASE_OUTRO);
  837.                         events.ScheduleEvent(EVENT_OUTRO_RAISE_DEAD, 1000, 0, PHASE_OUTRO);
  838.                         events.ScheduleEvent(EVENT_OUTRO_TALK_5, 29000, 0, PHASE_OUTRO);
  839.                         break;
  840.                     case POINT_LK_OUTRO_2:
  841.                         if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
  842.                             tirion->AI()->Talk(SAY_TIRION_OUTRO_2);
  843.                         if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f))
  844.                             frostmourne->AI()->DoAction(ACTION_SUMMON_TERENAS);
  845.                         break;
  846.                     default:
  847.                         break;
  848.                 }
  849.             }
  850.  
  851.             void UpdateAI(uint32 const diff)
  852.             {
  853.                 // check phase first to prevent updating victim and entering evade mode when not wanted
  854.                 if (!(events.GetPhaseMask() & PHASE_MASK_NO_VICTIM))
  855.                     if (!UpdateVictim())
  856.                         return;
  857.  
  858.                 events.Update(diff);
  859.  
  860.                 // during Remorseless Winter phases The Lich King is channeling a spell, but we must continue casting other spells
  861.                 if (me->HasUnitState(UNIT_STAT_CASTING) && !(events.GetPhaseMask() & PHASE_MASK_NO_CAST_CHECK))
  862.                     return;
  863.  
  864.                 while (uint32 eventId = events.ExecuteEvent())
  865.                 {
  866.                     switch (eventId)
  867.                     {
  868.                         case EVENT_INTRO_MOVE_1:
  869.                             me->SetSheath(SHEATH_STATE_MELEE);
  870.                             me->RemoveAurasDueToSpell(SPELL_EMOTE_SIT_NO_SHEATH);
  871.                             me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
  872.                             me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_1, LichKingIntro[0]);
  873.                             break;
  874.                         case EVENT_INTRO_MOVE_2:
  875.                             me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_2, LichKingIntro[1]);
  876.                             break;
  877.                         case EVENT_INTRO_MOVE_3:
  878.                             me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_3, LichKingIntro[2]);
  879.                             break;
  880.                         case EVENT_INTRO_TALK_1:
  881.                             Talk(SAY_LK_INTRO_2);
  882.                             // for some reason blizz sends 2 emotes in row here so (we handle one in Talk)
  883.                             me->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NOSHEATHE);
  884.                             events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 7000, 0, PHASE_INTRO);
  885.                             events.ScheduleEvent(EVENT_INTRO_EMOTE_1, 13000, 0, PHASE_INTRO);
  886.                             events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 18000, 0, PHASE_INTRO);
  887.                             events.ScheduleEvent(EVENT_INTRO_CAST_FREEZE, 31000, 0, PHASE_INTRO);
  888.                             break;
  889.                         case EVENT_EMOTE_CAST_SHOUT:
  890.                             DoCast(me, SPELL_EMOTE_SHOUT_NO_SHEATH, false);
  891.                             break;
  892.                         case EVENT_INTRO_EMOTE_1:
  893.                             me->HandleEmoteCommand(EMOTE_ONESHOT_POINT_NOSHEATHE);
  894.                             break;
  895.                         case EVENT_INTRO_CAST_FREEZE:
  896.                             Talk(SAY_LK_INTRO_3);
  897.                             DoCastAOE(SPELL_ICE_LOCK, false);
  898.                             events.ScheduleEvent(EVENT_FINISH_INTRO, 1000, 0, PHASE_INTRO);
  899.                             break;
  900.                         case EVENT_FINISH_INTRO:
  901.                             me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
  902.                             me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
  903.                             me->SetReactState(REACT_AGGRESSIVE);
  904.                             events.SetPhase(PHASE_ONE);
  905.                             me->SetInCombatWithZone();
  906.                             break;
  907.                         case EVENT_SUMMON_SHAMBLING_HORROR:
  908.                             DoCast(me, SPELL_SUMMON_SHAMBLING_HORROR);
  909.                             SendMusicToPlayers(MUSIC_SPECIAL);
  910.                             events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 60000, 0, PHASE_ONE);
  911.                             break;
  912.                         case EVENT_SUMMON_DRUDGE_GHOUL:
  913.                             DoCast(me, SPELL_SUMMON_DRUDGE_GHOULS);
  914.                             events.ScheduleEvent(EVENT_SUMMON_DRUDGE_GHOUL, 30000, 0, PHASE_ONE);
  915.                             break;
  916.                         case EVENT_INFEST:
  917.                             DoCast(me, SPELL_INFEST);
  918.                             events.ScheduleEvent(EVENT_INFEST, urand(21000, 24000), 0, (events.GetPhaseMask() & PHASE_MASK_ONE) ? PHASE_ONE : PHASE_TWO);
  919.                             break;
  920.                         case EVENT_NECROTIC_PLAGUE:
  921.                             if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, NecroticPlagueTargetCheck(me, NECROTIC_PLAGUE_LK, NECROTIC_PLAGUE_PLR)))
  922.                             {
  923.                                 Talk(EMOTE_NECROTIC_PLAGUE_WARNING, target->GetGUID());
  924.                                 DoCast(target, SPELL_NECROTIC_PLAGUE);
  925.                             }
  926.                             events.ScheduleEvent(EVENT_NECROTIC_PLAGUE, urand(30000, 33000), 0, PHASE_ONE);
  927.                             break;
  928.                         case EVENT_SHADOW_TRAP:
  929.                             if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
  930.                                 DoCast(target, SPELL_SHADOW_TRAP);
  931.                             events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500, 0, PHASE_ONE);
  932.                             break;
  933.                         case EVENT_SOUL_REAPER:
  934.                             DoCastVictim(SPELL_SOUL_REAPER);
  935.                             events.ScheduleEvent(EVENT_SOUL_REAPER, urand(33000, 35000), 0, PHASE_TWO_THREE);
  936.                             break;
  937.                         case EVENT_DEFILE:
  938.                             if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_HARVEST_SOUL_VALKYR))
  939.                             {
  940.                                 Talk(EMOTE_DEFILE_WARNING);
  941.                                 DoCast(target, SPELL_DEFILE);
  942.                             }
  943.                             events.ScheduleEvent(EVENT_DEFILE, urand(32000, 35000), 0, PHASE_TWO_THREE);
  944.                             break;
  945.                         case EVENT_HARVEST_SOUL:
  946.                             Talk(SAY_LK_HARVEST_SOUL);
  947.                             if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, SpellTargetSelector(me, SPELL_HARVEST_SOUL)))
  948.                                 DoCast(target, SPELL_HARVEST_SOUL);
  949.                             events.ScheduleEvent(EVENT_HARVEST_SOUL, 75000, 0, PHASE_THREE);
  950.                             break;
  951.                         case EVENT_PAIN_AND_SUFFERING:
  952.                             if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
  953.                                 me->CastSpell(target, SPELL_PAIN_AND_SUFFERING, TRIGGERED_NONE);
  954.                             events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, urand(1500, 4000), 0, PHASE_TRANSITION);
  955.                             break;
  956.                         case EVENT_SUMMON_ICE_SPHERE:
  957.                             DoCastAOE(SPELL_SUMMON_ICE_SPHERE);
  958.                             events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, urand(7500, 8500), 0, PHASE_TRANSITION);
  959.                             break;
  960.                         case EVENT_SUMMON_RAGING_SPIRIT:
  961.                             if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
  962.                                 me->CastSpell(target, SPELL_RAGING_SPIRIT, TRIGGERED_NONE);
  963.                             events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, urand(22000, 23000), 0, PHASE_TRANSITION);
  964.                             break;
  965.                         case EVENT_QUAKE:
  966.                             events.SetPhase(PHASE_TWO);
  967.                             me->ClearUnitState(UNIT_STAT_CASTING);  // clear state to ensure check in DoCastAOE passes
  968.                             DoCastAOE(SPELL_QUAKE);
  969.                             SendMusicToPlayers(MUSIC_SPECIAL);
  970.                             Talk(SAY_LK_QUAKE);
  971.                             break;
  972.                         case EVENT_QUAKE_2:
  973.                             events.SetPhase(PHASE_THREE);
  974.                             me->ClearUnitState(UNIT_STAT_CASTING);  // clear state to ensure check in DoCastAOE passes
  975.                             DoCastAOE(SPELL_QUAKE);
  976.                             SendMusicToPlayers(MUSIC_SPECIAL);
  977.                             Talk(SAY_LK_QUAKE);
  978.                             break;
  979.                         case EVENT_SUMMON_VALKYR:
  980.                             SendMusicToPlayers(MUSIC_SPECIAL);
  981.                             Talk(SAY_LK_SUMMON_VALKYR);
  982.                             DoCastAOE(SUMMON_VALKYR);
  983.                             events.ScheduleEvent(EVENT_SUMMON_VALKYR, urand(45000, 50000), 0, PHASE_TWO);
  984.                             break;
  985.                         case EVENT_START_ATTACK:
  986.                             me->SetReactState(REACT_AGGRESSIVE);
  987.                             if (events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE)
  988.                                 events.SetPhase(PHASE_THREE);
  989.                             break;
  990.                         case EVENT_VILE_SPIRITS:
  991.                             SendMusicToPlayers(MUSIC_SPECIAL);
  992.                             DoCastAOE(SPELL_VILE_SPIRITS);
  993.                             events.ScheduleEvent(EVENT_VILE_SPIRITS, urand(35000, 40000), EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);
  994.                             break;
  995.                         case EVENT_WICKED_SPIRITS:
  996.                             DoCastAOE(SPELL_VILE_SPIRITS);
  997.                             events.ScheduleEvent(EVENT_WICKED_SPIRITS, urand(35000, 40000), 0, PHASE_FROSTMOURNE);
  998.                             break;
  999.                         case EVENT_HARVEST_SOULS:
  1000.                             Talk(SAY_LK_HARVEST_SOUL);
  1001.                             DoCastAOE(SPELL_HARVEST_SOULS);
  1002.                             events.ScheduleEvent(EVENT_HARVEST_SOULS, urand(100000, 110000), 0, PHASE_THREE);
  1003.                             events.SetPhase(PHASE_FROSTMOURNE); // will stop running UpdateVictim (no evading)
  1004.                             me->SetReactState(REACT_PASSIVE);
  1005.                             me->AttackStop();
  1006.                             events.ScheduleEvent(EVENT_WICKED_SPIRITS, events.GetNextEventTime(EVENT_VILE_SPIRITS) - events.GetTimer(), 0, PHASE_FROSTMOURNE);
  1007.                             events.DelayEvents(50000, EVENT_GROUP_VILE_SPIRITS);
  1008.                             events.RescheduleEvent(EVENT_DEFILE, 50000, 0, PHASE_THREE);
  1009.                             events.RescheduleEvent(EVENT_SOUL_REAPER, urand(57000, 62000), 0, PHASE_THREE);
  1010.                             events.ScheduleEvent(EVENT_START_ATTACK, 49000);
  1011.                             events.ScheduleEvent(EVENT_FROSTMOURNE_HEROIC, 6500);
  1012.                             break;
  1013.                         case EVENT_FROSTMOURNE_HEROIC:
  1014.                             if (TempSummon* terenas = me->GetMap()->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE_H, TerenasSpawnHeroic, NULL, 50000))
  1015.                             {
  1016.                                 terenas->AI()->DoAction(ACTION_FROSTMOURNE_INTRO);
  1017.                                 std::list<Creature*> triggers;
  1018.                                 GetCreatureListWithEntryInGrid(triggers, terenas, NPC_WORLD_TRIGGER_INFINITE_AOI, 100.0f);
  1019.                                 if (!triggers.empty())
  1020.                                 {
  1021.                                     triggers.sort(Trinity::ObjectDistanceOrderPred(terenas, true));
  1022.                                     Unit* spawner = triggers.front();
  1023.                                     spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_1, true);  // summons bombs randomly
  1024.                                     spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_2, true);  // summons bombs on players
  1025.                                 }
  1026.  
  1027.                                 for (SummonList::iterator i = summons.begin(); i != summons.end(); ++i)
  1028.                                 {
  1029.                                     Creature* summon = ObjectAccessor::GetCreature(*me, *i);
  1030.                                     if (summon && summon->GetEntry() == NPC_VILE_SPIRIT)
  1031.                                         TeleportSpirit(summon);
  1032.                                 }
  1033.                             }
  1034.                             break;
  1035.                         case EVENT_OUTRO_TALK_1:
  1036.                             Talk(SAY_LK_OUTRO_1);
  1037.                             DoCastAOE(SPELL_FURY_OF_FROSTMOURNE_NO_REZ, true);
  1038.                             break;
  1039.                         case EVENT_OUTRO_TALK_2:
  1040.                             Talk(SAY_LK_OUTRO_2);
  1041.                             DoCastAOE(SPELL_EMOTE_QUESTION_NO_SHEATH);
  1042.                             break;
  1043.                         case EVENT_OUTRO_EMOTE_TALK:
  1044.                             me->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NOSHEATHE);
  1045.                             break;
  1046.                         case EVENT_OUTRO_TALK_3:
  1047.                             if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
  1048.                                 me->SetFacing(0.0f, tirion);
  1049.                             Talk(SAY_LK_OUTRO_3);
  1050.                             break;
  1051.                         case EVENT_OUTRO_MOVE_CENTER:
  1052.                             me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_1, CenterPosition);
  1053.                             break;
  1054.                         case EVENT_OUTRO_TALK_4:
  1055.                             me->SetFacing(0.01745329f);
  1056.                             Talk(SAY_LK_OUTRO_4);
  1057.                             break;
  1058.                         case EVENT_OUTRO_RAISE_DEAD:
  1059.                             DoCastAOE(SPELL_RAISE_DEAD);
  1060.                             me->ClearUnitState(UNIT_STAT_CASTING);
  1061.                             SendMusicToPlayers(MUSIC_FINAL);
  1062.                             break;
  1063.                         case EVENT_OUTRO_TALK_5:
  1064.                             Talk(SAY_LK_OUTRO_5);
  1065.                             if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
  1066.                                 tirion->AI()->DoAction(ACTION_OUTRO);
  1067.                             break;
  1068.                         case EVENT_OUTRO_TALK_6:
  1069.                             Talk(SAY_LK_OUTRO_6);
  1070.                             if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
  1071.                                 tirion->SetFacing(0.0f, me);
  1072.                             me->ClearUnitState(UNIT_STAT_CASTING);
  1073.                             DoCastAOE(SPELL_SUMMON_BROKEN_FROSTMOURNE_3);
  1074.                             SetEquipmentSlots(false, EQUIP_UNEQUIP);
  1075.                             break;
  1076.                         case EVENT_OUTRO_SOUL_BARRAGE:
  1077.                             DoCastAOE(SPELL_SOUL_BARRAGE);
  1078.                             sCreatureTextMgr->SendSound(me, SOUND_PAIN, CHAT_MSG_MONSTER_YELL, 0, TEXT_RANGE_NORMAL, TEAM_OTHER, false);
  1079.                             // set flight
  1080.                             me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
  1081.                             me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x03);
  1082.                             me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_2, OutroFlying);
  1083.                             break;
  1084.                         case EVENT_OUTRO_TALK_7:
  1085.                             Talk(SAY_LK_OUTRO_7);
  1086.                             break;
  1087.                         case EVENT_OUTRO_TALK_8:
  1088.                             Talk(SAY_LK_OUTRO_8);
  1089.                             break;
  1090.                         case EVENT_BERSERK:
  1091.                             Talk(SAY_LK_BERSERK);
  1092.                             DoCast(me, SPELL_BERSERK2);
  1093.                             break;
  1094.                         default:
  1095.                             break;
  1096.                     }
  1097.                 }
  1098.  
  1099.                 DoMeleeAttackIfReady();
  1100.             }
  1101.  
  1102.         private:
  1103.  
  1104.             void TeleportSpirit(Creature* summon)
  1105.             {
  1106.                 float dist = me->GetObjectSize() + (15.0f - me->GetObjectSize()) * float(rand_norm());
  1107.                 float angle = float(rand_norm()) * float(2.0f * M_PI);
  1108.                 Position dest = TerenasSpawnHeroic;
  1109.                 me->MovePosition(dest, dist, angle);
  1110.                 dest.m_positionZ += 15.0f;
  1111.                 summon->UpdateEntry(NPC_WICKED_SPIRIT);
  1112.                 summon->SetReactState(REACT_PASSIVE);
  1113.                 summon->NearTeleportTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.GetOrientation());
  1114.                 summon->SetSpeed(MOVE_FLIGHT, 0.5f);
  1115.                 summon->m_Events.KillAllEvents(true);
  1116.                 summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(1000));
  1117.             }
  1118.  
  1119.             void SendMusicToPlayers(uint32 musicId) const
  1120.             {
  1121.                 WorldPacket data(SMSG_PLAY_MUSIC, 4);
  1122.                 data << uint32(musicId);
  1123.                 SendPacketToPlayers(&data);
  1124.             }
  1125.  
  1126.             void SendLightOverride(uint32 overrideId, uint32 fadeInTime) const
  1127.             {
  1128.                 WorldPacket data(SMSG_OVERRIDE_LIGHT, 12);
  1129.                 data << uint32(2488);       // Light.dbc entry (map default)
  1130.                 data << uint32(overrideId); // Light.dbc entry (override)
  1131.                 data << uint32(fadeInTime);
  1132.                 SendPacketToPlayers(&data);
  1133.             }
  1134.  
  1135.             void SendWeather(WeatherState weather) const
  1136.             {
  1137.                 WorldPacket data(SMSG_WEATHER, 9);
  1138.                 data << uint32(weather);
  1139.                 data << float(0.5f);
  1140.                 data << uint8(0);
  1141.                 SendPacketToPlayers(&data);
  1142.             }
  1143.  
  1144.             // Send packet to all players in The Frozen Throne
  1145.             void SendPacketToPlayers(WorldPacket const* data) const
  1146.             {
  1147.                 Map::PlayerList const& players = me->GetMap()->GetPlayers();
  1148.                 if (!players.isEmpty())
  1149.                     for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  1150.                         if (Player* player = itr->getSource())
  1151.                             if (player->GetAreaId() == AREA_THE_FROZEN_THRONE)
  1152.                                 player->GetSession()->SendPacket(data);
  1153.             }
  1154.  
  1155.             uint32 _necroticPlagueStack;
  1156.             uint32 _vileSpiritExplosions;
  1157.         };
  1158.  
  1159.         CreatureAI* GetAI(Creature* creature) const
  1160.         {
  1161.             return GetIcecrownCitadelAI<boss_the_lich_kingAI>(creature);
  1162.         }
  1163. };
  1164.  
  1165. class npc_tirion_fordring_tft : public CreatureScript
  1166. {
  1167.     public:
  1168.         npc_tirion_fordring_tft() : CreatureScript("npc_tirion_fordring_tft") { }
  1169.  
  1170.         struct npc_tirion_fordringAI : public ScriptedAI
  1171.         {
  1172.             npc_tirion_fordringAI(Creature* creature) : ScriptedAI(creature),
  1173.                 _instance(creature->GetInstanceScript())
  1174.             {
  1175.             }
  1176.  
  1177.             void Reset()
  1178.             {
  1179.                 _events.Reset();
  1180.                 if (_instance->GetBossState(DATA_THE_LICH_KING) == DONE)
  1181.                     me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
  1182.             }
  1183.  
  1184.             void MovementInform(uint32 type, uint32 id)
  1185.             {
  1186.                 if (type != POINT_MOTION_TYPE)
  1187.                     return;
  1188.  
  1189.                 switch (id)
  1190.                 {
  1191.                     case POINT_TIRION_INTRO:
  1192.                         me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
  1193.                         if (Creature* theLichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
  1194.                             theLichKing->AI()->DoAction(ACTION_START_ENCOUNTER);
  1195.                         break;
  1196.                     case POINT_TIRION_OUTRO_1:
  1197.                         _events.ScheduleEvent(EVENT_OUTRO_JUMP, 1, 0, PHASE_OUTRO);
  1198.                         break;
  1199.                 }
  1200.             }
  1201.  
  1202.             void DoAction(int32 const action)
  1203.             {
  1204.                 switch (action)
  1205.                 {
  1206.                     case ACTION_CONTINUE_INTRO:
  1207.                         Talk(SAY_TIRION_INTRO_1);
  1208.                         _events.ScheduleEvent(EVENT_INTRO_TALK_1, 34000, 0, PHASE_INTRO);
  1209.                         break;
  1210.                     case ACTION_OUTRO:
  1211.                         _events.SetPhase(PHASE_OUTRO);
  1212.                         _events.ScheduleEvent(EVENT_OUTRO_TALK_1, 7000, 0, PHASE_OUTRO);
  1213.                         _events.ScheduleEvent(EVENT_OUTRO_BLESS, 18000, 0, PHASE_OUTRO);
  1214.                         _events.ScheduleEvent(EVENT_OUTRO_REMOVE_ICE, 23000, 0, PHASE_OUTRO);
  1215.                         _events.ScheduleEvent(EVENT_OUTRO_MOVE_1, 25000, 0, PHASE_OUTRO);
  1216.                         break;
  1217.                 }
  1218.             }
  1219.  
  1220.             void SpellHit(Unit* /*caster*/, SpellInfo const* spell)
  1221.             {
  1222.                 if (spell->Id == SPELL_ICE_LOCK)
  1223.                     me->SetFacing(3.085098f);
  1224.                 else if (spell->Id == SPELL_BROKEN_FROSTMOURNE_KNOCK)
  1225.                     SetEquipmentSlots(true);    // remove glow on ashbringer
  1226.             }
  1227.  
  1228.             void sGossipSelect(Player* /*player*/, uint32 sender, uint32 action)
  1229.             {
  1230.                 if (me->GetCreatureInfo()->GossipMenuId == sender && !action)
  1231.                 {
  1232.                     _events.SetPhase(PHASE_INTRO);
  1233.                     me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
  1234.                     me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
  1235.                     me->GetMotionMaster()->MovePoint(POINT_TIRION_INTRO, TirionIntro);
  1236.                 }
  1237.             }
  1238.  
  1239.             void JustReachedHome()
  1240.             {
  1241.                 me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
  1242.  
  1243.                 if (_instance->GetBossState(DATA_THE_LICH_KING) == DONE)
  1244.                     return;
  1245.  
  1246.                 me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
  1247.             }
  1248.  
  1249.             void UpdateAI(uint32 const diff)
  1250.             {
  1251.                 if (!UpdateVictim() && !(_events.GetPhaseMask() & (PHASE_MASK_INTRO | PHASE_MASK_OUTRO)))
  1252.                     return;
  1253.  
  1254.                 _events.Update(diff);
  1255.  
  1256.                 if (me->HasUnitState(UNIT_STAT_CASTING))
  1257.                     return;
  1258.  
  1259.                 while (uint32 eventId = _events.ExecuteEvent())
  1260.                 {
  1261.                     switch (eventId)
  1262.                     {
  1263.                         case EVENT_INTRO_TALK_1:
  1264.                             Talk(SAY_TIRION_INTRO_2);
  1265.                             _events.ScheduleEvent(EVENT_INTRO_EMOTE_1, 2000, 0, PHASE_INTRO);
  1266.                             _events.ScheduleEvent(EVENT_INTRO_CHARGE, 5000, 0, PHASE_INTRO);
  1267.                             break;
  1268.                         case EVENT_INTRO_EMOTE_1:
  1269.                             me->HandleEmoteCommand(EMOTE_ONESHOT_POINT_NOSHEATHE);
  1270.                             break;
  1271.                         case EVENT_INTRO_CHARGE:
  1272.                             me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
  1273.                             me->GetMotionMaster()->MovePoint(POINT_TIRION_CHARGE, TirionCharge);
  1274.                             break;
  1275.                         case EVENT_OUTRO_TALK_1:
  1276.                             Talk(SAY_TIRION_OUTRO_1);
  1277.                             break;
  1278.                         case EVENT_OUTRO_BLESS:
  1279.                             DoCast(me, SPELL_LIGHTS_BLESSING);
  1280.                             break;
  1281.                         case EVENT_OUTRO_REMOVE_ICE:
  1282.                             me->RemoveAurasDueToSpell(SPELL_ICE_LOCK);
  1283.                             SetEquipmentSlots(false, EQUIP_ASHBRINGER_GLOWING);
  1284.                             if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
  1285.                             {
  1286.                                 me->SetFacing(0.0f, lichKing);
  1287.                                 lichKing->AI()->DoAction(ACTION_PLAY_MUSIC);
  1288.                             }
  1289.                             break;
  1290.                         case EVENT_OUTRO_MOVE_1:
  1291.                             me->GetMotionMaster()->MovePoint(POINT_TIRION_OUTRO_1, OutroPosition1);
  1292.                             break;
  1293.                         case EVENT_OUTRO_JUMP:
  1294.                             DoCastAOE(SPELL_JUMP);
  1295.                             break;
  1296.                         default:
  1297.                             break;
  1298.                     }
  1299.                 }
  1300.  
  1301.                 DoMeleeAttackIfReady();
  1302.             }
  1303.  
  1304.         private:
  1305.             EventMap _events;
  1306.             InstanceScript* _instance;
  1307.         };
  1308.  
  1309.         CreatureAI* GetAI(Creature* creature) const
  1310.         {
  1311.             return GetIcecrownCitadelAI<npc_tirion_fordringAI>(creature);
  1312.         }
  1313. };
  1314.  
  1315. class npc_shambling_horror_icc : public CreatureScript
  1316. {
  1317.     public:
  1318.         npc_shambling_horror_icc() :  CreatureScript("npc_shambling_horror_icc") { }
  1319.  
  1320.         struct npc_shambling_horror_iccAI : public ScriptedAI
  1321.         {
  1322.             npc_shambling_horror_iccAI(Creature* creature) : ScriptedAI(creature)
  1323.             {
  1324.                 _frenzied = false;
  1325.             }
  1326.  
  1327.             void Reset()
  1328.             {
  1329.                 _events.Reset();
  1330.                 _events.ScheduleEvent(EVENT_SHOCKWAVE, urand(20000, 25000));
  1331.                 _events.ScheduleEvent(EVENT_ENRAGE, urand(11000, 14000));
  1332.             }
  1333.  
  1334.             void DamageTaken(Unit* /*attacker*/, uint32& damage)
  1335.             {
  1336.                 if (!_frenzied && IsHeroic() && me->HealthBelowPctDamaged(20, damage))
  1337.                 {
  1338.                     _frenzied = true;
  1339.                     DoCast(me, SPELL_FRENZY, true);
  1340.                 }
  1341.             }
  1342.  
  1343.             void UpdateAI(uint32 const diff)
  1344.             {
  1345.                 if (!UpdateVictim())
  1346.                     return;
  1347.  
  1348.                 _events.Update(diff);
  1349.  
  1350.                 if (me->HasUnitState(UNIT_STAT_CASTING))
  1351.                     return;
  1352.  
  1353.                 while (uint32 eventId = _events.ExecuteEvent())
  1354.                 {
  1355.                     switch (eventId)
  1356.                     {
  1357.                         case EVENT_SHOCKWAVE:
  1358.                             DoCast(me, SPELL_SHOCKWAVE);
  1359.                             _events.ScheduleEvent(EVENT_SHOCKWAVE, urand(20000, 25000));
  1360.                             break;
  1361.                         case EVENT_ENRAGE:
  1362.                             DoCast(me, SPELL_ENRAGE);
  1363.                             _events.ScheduleEvent(EVENT_ENRAGE, urand(20000, 25000));
  1364.                             break;
  1365.                         default:
  1366.                             break;
  1367.                     }
  1368.                 }
  1369.  
  1370.                 DoMeleeAttackIfReady();
  1371.             }
  1372.  
  1373.         private:
  1374.             EventMap _events;
  1375.             bool _frenzied;
  1376.         };
  1377.  
  1378.         CreatureAI* GetAI(Creature* creature) const
  1379.         {
  1380.             return GetIcecrownCitadelAI<npc_shambling_horror_iccAI>(creature);
  1381.         }
  1382. };
  1383.  
  1384. class npc_raging_spirit : public CreatureScript
  1385. {
  1386.     public:
  1387.         npc_raging_spirit() : CreatureScript("npc_raging_spirit") { }
  1388.  
  1389.         struct npc_raging_spiritAI : public ScriptedAI
  1390.         {
  1391.             npc_raging_spiritAI(Creature* creature) : ScriptedAI(creature),
  1392.                 _instance(creature->GetInstanceScript())
  1393.             {
  1394.             }
  1395.  
  1396.             void Reset()
  1397.             {
  1398.                 _events.Reset();
  1399.                 _events.ScheduleEvent(EVENT_SOUL_SHRIEK, urand(12000, 15000));
  1400.                 DoCast(me, SPELL_PLAGUE_AVOIDANCE, true);
  1401.                 DoCast(me, SPELL_RAGING_SPIRIT_VISUAL, true);
  1402.                 if (TempSummon* summon = me->ToTempSummon())
  1403.                     if (Unit* summoner = summon->GetSummoner())
  1404.                         summoner->CastSpell(me, SPELL_RAGING_SPIRIT_VISUAL_CLONE, true);
  1405.                 DoCast(me, SPELL_BOSS_HITTIN_YA, true);
  1406.             }
  1407.  
  1408.             void IsSummonedBy(Unit* /*summoner*/)
  1409.             {
  1410.                 // player is the spellcaster so register summon manually
  1411.                 if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
  1412.                     lichKing->AI()->JustSummoned(me);
  1413.             }
  1414.  
  1415.             void JustDied(Unit* /*killer*/)
  1416.             {
  1417.                 if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
  1418.                     lichKing->AI()->SummonedCreatureDespawn(me);
  1419.                 if (TempSummon* summon = me->ToTempSummon())
  1420.                     summon->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN);
  1421.             }
  1422.  
  1423.             void UpdateAI(uint32 const diff)
  1424.             {
  1425.                 if (!UpdateVictim())
  1426.                     return;
  1427.  
  1428.                 _events.Update(diff);
  1429.  
  1430.                 if (me->HasUnitState(UNIT_STAT_CASTING))
  1431.                     return;
  1432.  
  1433.                 while (uint32 eventId = _events.ExecuteEvent())
  1434.                 {
  1435.                     switch (eventId)
  1436.                     {
  1437.                         case EVENT_SOUL_SHRIEK:
  1438.                             DoCastAOE(SPELL_SOUL_SHRIEK);
  1439.                             _events.ScheduleEvent(EVENT_SOUL_SHRIEK, urand(12000, 15000));
  1440.                             break;
  1441.                         default:
  1442.                             break;
  1443.                     }
  1444.                 }
  1445.  
  1446.                 DoMeleeAttackIfReady();
  1447.             }
  1448.  
  1449.         private:
  1450.             EventMap _events;
  1451.             InstanceScript* _instance;
  1452.         };
  1453.  
  1454.         CreatureAI* GetAI(Creature* creature) const
  1455.         {
  1456.             return GetIcecrownCitadelAI<npc_raging_spiritAI>(creature);
  1457.         }
  1458. };
  1459.  
  1460. class npc_valkyr_shadowguard : public CreatureScript
  1461. {
  1462.     public:
  1463.         npc_valkyr_shadowguard() : CreatureScript("npc_valkyr_shadowguard") { }
  1464.  
  1465.         struct npc_valkyr_shadowguardAI : public ScriptedAI
  1466.         {
  1467.             npc_valkyr_shadowguardAI(Creature* creature) : ScriptedAI(creature),
  1468.                 _grabbedPlayer(0), _instance(creature->GetInstanceScript())
  1469.             {
  1470.             }
  1471.  
  1472.             void Reset()
  1473.             {
  1474.                 _events.Reset();
  1475.                 me->SetReactState(REACT_PASSIVE);
  1476.                 DoCast(me, SPELL_WINGS_OF_THE_DAMNED, false);
  1477.                 me->SetSpeed(MOVE_FLIGHT, 0.642857f, true);
  1478.             }
  1479.  
  1480.             void IsSummonedBy(Unit* /*summoner*/)
  1481.             {
  1482.                 _events.Reset();
  1483.                 _events.ScheduleEvent(EVENT_GRAB_PLAYER, 2500);
  1484.             }
  1485.  
  1486.             void DamageTaken(Unit* /*attacker*/, uint32& damage)
  1487.             {
  1488.                 if (!IsHeroic())
  1489.                     return;
  1490.  
  1491.                 if (!me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
  1492.                     return;
  1493.  
  1494.                 if (me->HealthBelowPctDamaged(50, damage))
  1495.                 {
  1496.                     _events.Reset();
  1497.                     DoCastAOE(SPELL_EJECT_ALL_PASSENGERS);
  1498.                     me->GetMotionMaster()->MoveTargetedHome();
  1499.                     me->ClearUnitState(UNIT_STAT_EVADE);
  1500.                 }
  1501.             }
  1502.  
  1503.             void JustReachedHome()
  1504.             {
  1505.                 // schedule siphon life event (heroic only)
  1506.                 DoZoneInCombat();
  1507.                 _events.Reset();
  1508.                 _events.ScheduleEvent(EVENT_LIFE_SIPHON, 2000);
  1509.             }
  1510.  
  1511.             void AttackStart(Unit* /*target*/)
  1512.             {
  1513.             }
  1514.  
  1515.             void MovementInform(uint32 type, uint32 id)
  1516.             {
  1517.                 if (type != POINT_MOTION_TYPE)
  1518.                     return;
  1519.  
  1520.                 switch (id)
  1521.                 {
  1522.                     case POINT_DROP_PLAYER:
  1523.                         DoCastAOE(SPELL_EJECT_ALL_PASSENGERS);
  1524.                         me->DespawnOrUnsummon(1000);
  1525.                         break;
  1526.                     case POINT_CHARGE:
  1527.                         if (Player* target = ObjectAccessor::GetPlayer(*me, _grabbedPlayer))
  1528.                         {
  1529.                             me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  1530.                             if (GameObject* platform = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_ARTHAS_PLATFORM)))
  1531.                             {
  1532.                                 std::list<Creature*> triggers;
  1533.                                 GetCreatureListWithEntryInGrid(triggers, me, NPC_WORLD_TRIGGER, 150.0f);
  1534.                                 triggers.remove_if(HeightDifferenceCheck(platform, 5.0f, true));
  1535.                                 if (triggers.empty())
  1536.                                     return;
  1537.  
  1538.                                 triggers.sort(Trinity::ObjectDistanceOrderPred(me));
  1539.                                 DoCast(target, SPELL_VALKYR_CARRY);
  1540.                                 _dropPoint.Relocate(triggers.front());
  1541.                                 _events.ScheduleEvent(EVENT_MOVE_TO_DROP_POS, 1500);
  1542.  
  1543.                             }
  1544.                         }
  1545.                         else
  1546.                             me->DespawnOrUnsummon();
  1547.                         break;
  1548.                     default:
  1549.                         break;
  1550.                 }
  1551.             }
  1552.  
  1553.             void SetGUID(uint64 guid, int32 /* = 0*/)
  1554.             {
  1555.                 _grabbedPlayer = guid;
  1556.             }
  1557.  
  1558.             void UpdateAI(uint32 const diff)
  1559.             {
  1560.                 if (!UpdateVictim())
  1561.                     return;
  1562.  
  1563.                 _events.Update(diff);
  1564.  
  1565.                 if (me->HasUnitState(UNIT_STAT_CASTING))
  1566.                     return;
  1567.  
  1568.                 while (uint32 eventId = _events.ExecuteEvent())
  1569.                 {
  1570.                     switch (eventId)
  1571.                     {
  1572.                         case EVENT_GRAB_PLAYER:
  1573.                             if (!_grabbedPlayer)
  1574.                             {
  1575.                                 DoCastAOE(SPELL_VALKYR_TARGET_SEARCH);
  1576.                                 _events.ScheduleEvent(EVENT_GRAB_PLAYER, 2000);
  1577.                             }
  1578.                             break;
  1579.                         case EVENT_MOVE_TO_DROP_POS:
  1580.                             me->GetMotionMaster()->MovePoint(POINT_DROP_PLAYER, _dropPoint);
  1581.                             break;
  1582.                         case EVENT_LIFE_SIPHON:
  1583.                             if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
  1584.                                 DoCast(target, SPELL_LIFE_SIPHON);
  1585.                             _events.ScheduleEvent(EVENT_LIFE_SIPHON, 2500);
  1586.                             break;
  1587.                         default:
  1588.                             break;
  1589.                     }
  1590.                 }
  1591.  
  1592.                 // no melee attacks
  1593.             }
  1594.  
  1595.         private:
  1596.             EventMap _events;
  1597.             Position _dropPoint;
  1598.             uint64 _grabbedPlayer;
  1599.             InstanceScript* _instance;
  1600.         };
  1601.  
  1602.         CreatureAI* GetAI(Creature* creature) const
  1603.         {
  1604.             return GetIcecrownCitadelAI<npc_valkyr_shadowguardAI>(creature);
  1605.         }
  1606. };
  1607.  
  1608. class npc_strangulate_vehicle : public CreatureScript
  1609. {
  1610.     public:
  1611.         npc_strangulate_vehicle() : CreatureScript("npc_strangulate_vehicle") { }
  1612.  
  1613.         struct npc_strangulate_vehicleAI : public ScriptedAI
  1614.         {
  1615.             npc_strangulate_vehicleAI(Creature* creature) : ScriptedAI(creature),
  1616.                 _instance(creature->GetInstanceScript())
  1617.             {
  1618.             }
  1619.  
  1620.             void IsSummonedBy(Unit* summoner)
  1621.             {
  1622.                 me->SetFacing(0.0f, summoner);
  1623.                 DoCast(summoner, SPELL_HARVEST_SOUL_VEHICLE);
  1624.                 _events.Reset();
  1625.                 _events.ScheduleEvent(EVENT_MOVE_TO_LICH_KING, 2000);
  1626.                 _events.ScheduleEvent(EVENT_TELEPORT, 6000);
  1627.  
  1628.                 // this will let us easily access all creatures of this entry on heroic mode when its time to teleport back
  1629.                 if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
  1630.                     lichKing->AI()->JustSummoned(me);
  1631.             }
  1632.  
  1633.             void DoAction(int32 const action)
  1634.             {
  1635.                 if (action != ACTION_TELEPORT_BACK)
  1636.                     return;
  1637.  
  1638.                 if (TempSummon* summ = me->ToTempSummon())
  1639.                     if (Unit* summoner = summ->GetSummoner())
  1640.                         DoCast(summoner, SPELL_HARVEST_SOUL_TELEPORT_BACK);
  1641.  
  1642.                 if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
  1643.                     lichKing->AI()->SummonedCreatureDespawn(me);
  1644.             }
  1645.  
  1646.             void UpdateAI(uint32 const diff)
  1647.             {
  1648.                 UpdateVictim();
  1649.  
  1650.                 _events.Update(diff);
  1651.  
  1652.                 while (uint32 eventId = _events.ExecuteEvent())
  1653.                 {
  1654.                     switch (eventId)
  1655.                     {
  1656.                         case EVENT_TELEPORT:
  1657.                             me->GetMotionMaster()->Clear(false);
  1658.                             me->GetMotionMaster()->MoveIdle();
  1659.                             if (TempSummon* summ = me->ToTempSummon())
  1660.                             {
  1661.                                 if (Unit* summoner = summ->GetSummoner())
  1662.                                 {
  1663.                                     summoner->CastSpell((Unit*)NULL, SPELL_HARVEST_SOUL_VISUAL, true);
  1664.                                     summoner->ExitVehicle(summoner);
  1665.                                     if (!IsHeroic())
  1666.                                         summoner->CastSpell(summoner, SPELL_HARVEST_SOUL_TELEPORT, true);
  1667.                                     else
  1668.                                     {
  1669.                                         summoner->CastSpell(summoner, SPELL_HARVEST_SOULS_TELEPORT, true);
  1670.                                         summoner->RemoveAurasDueToSpell(HARVEST_SOUL, 0, 0, AURA_REMOVE_BY_EXPIRE);
  1671.                                     }
  1672.                                 }
  1673.                             }
  1674.  
  1675.                             _events.ScheduleEvent(EVENT_DESPAWN_SELF, 65000);
  1676.                             break;
  1677.                         case EVENT_MOVE_TO_LICH_KING:
  1678.                             if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
  1679.                             {
  1680.                                 if (me->GetExactDist(lichKing) > 10.0f)
  1681.                                 {
  1682.                                     Position pos;
  1683.                                     lichKing->GetNearPosition(pos, float(rand_norm()) * 5.0f  + 7.5f, lichKing->GetAngle(me));
  1684.                                     me->GetMotionMaster()->MovePoint(0, pos);
  1685.                                 }
  1686.                             }
  1687.                             break;
  1688.                         case EVENT_DESPAWN_SELF:
  1689.                             if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
  1690.                                 lichKing->AI()->SummonedCreatureDespawn(me);
  1691.                             me->DespawnOrUnsummon(1);
  1692.                             break;
  1693.                         default:
  1694.                             break;
  1695.                     }
  1696.                 }
  1697.             }
  1698.  
  1699.         private:
  1700.             EventMap _events;
  1701.             InstanceScript* _instance;
  1702.         };
  1703.  
  1704.         CreatureAI* GetAI(Creature* creature) const
  1705.         {
  1706.             return GetIcecrownCitadelAI<npc_strangulate_vehicleAI>(creature);
  1707.         }
  1708. };
  1709.  
  1710. class npc_terenas_menethil : public CreatureScript
  1711. {
  1712.     public:
  1713.         npc_terenas_menethil() : CreatureScript("npc_terenas_menethil") { }
  1714.  
  1715.         struct npc_terenas_menethilAI : public ScriptedAI
  1716.         {
  1717.             npc_terenas_menethilAI(Creature* creature) : ScriptedAI(creature),
  1718.                 _instance(creature->GetInstanceScript())
  1719.             {
  1720.             }
  1721.  
  1722.             bool CanAIAttack(Unit const* target) const
  1723.             {
  1724.                 return target->GetEntry() != NPC_THE_LICH_KING;
  1725.             }
  1726.  
  1727.             void DoAction(int32 const action)
  1728.             {
  1729.                 switch (action)
  1730.                 {
  1731.                     case ACTION_FROSTMOURNE_INTRO:
  1732.                         me->setActive(true);
  1733.                         if (!IsHeroic())
  1734.                             me->SetHealth(me->GetMaxHealth() / 2);
  1735.                         DoCast(me, SPELL_LIGHTS_FAVOR);
  1736.                         _events.Reset();
  1737.                         _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_1, 2000, PHASE_FROSTMOURNE);
  1738.                         _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_2, 11000, PHASE_FROSTMOURNE);
  1739.                         if (!IsHeroic())
  1740.                         {
  1741.                             _events.ScheduleEvent(EVENT_DESTROY_SOUL, 60000, PHASE_FROSTMOURNE);
  1742.                             _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_3, 25000);
  1743.                         }
  1744.                         break;
  1745.                     case ACTION_TELEPORT_BACK:
  1746.                         me->CastSpell((Unit*)NULL, SPELL_RESTORE_SOUL, TRIGGERED_NONE);
  1747.                         me->DespawnOrUnsummon(3000);
  1748.                         break;
  1749.                     default:
  1750.                         break;
  1751.                 }
  1752.             }
  1753.  
  1754.             void EnterEvadeMode()
  1755.             {
  1756.                 // no running back home
  1757.                 if (!me->isAlive())
  1758.                     return;
  1759.  
  1760.                 me->DeleteThreatList();
  1761.                 me->CombatStop(false);
  1762.             }
  1763.  
  1764.             void DamageTaken(Unit* /*attacker*/, uint32& damage)
  1765.             {
  1766.                 if (damage >= me->GetHealth())
  1767.                 {
  1768.                     damage = me->GetHealth() - 1;
  1769.                     if (!me->HasAura(SPELL_TERENAS_LOSES_INSIDE) && !IsHeroic())
  1770.                     {
  1771.                         me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  1772.                         DoCast(SPELL_TERENAS_LOSES_INSIDE);
  1773.                         _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1000);
  1774.                         if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f))
  1775.                         {
  1776.                             warden->CastSpell((Unit*)NULL, SPELL_DESTROY_SOUL, TRIGGERED_NONE);
  1777.                             warden->DespawnOrUnsummon(2000);
  1778.                         }
  1779.  
  1780.                         me->DespawnOrUnsummon(2000);
  1781.                     }
  1782.                 }
  1783.             }
  1784.  
  1785.             void IsSummonedBy(Unit* /*summoner*/)
  1786.             {
  1787.                 _events.Reset();
  1788.                 _events.SetPhase(PHASE_OUTRO);
  1789.                 if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
  1790.                     me->SetFacing(0.0f, lichKing);
  1791.  
  1792.                 _events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_1, 2000, 0, PHASE_OUTRO);
  1793.                 _events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_2, 14000, 0, PHASE_OUTRO);
  1794.             }
  1795.  
  1796.             void UpdateAI(uint32 const diff)
  1797.             {
  1798.                 UpdateVictim();
  1799.  
  1800.                 _events.Update(diff);
  1801.  
  1802.                 while (uint32 eventId = _events.ExecuteEvent())
  1803.                 {
  1804.                     switch (eventId)
  1805.                     {
  1806.                         case EVENT_FROSTMOURNE_TALK_1:
  1807.                             Talk(SAY_TERENAS_INTRO_1);
  1808.                             if (IsHeroic())
  1809.                                 DoCastAOE(SPELL_RESTORE_SOULS);
  1810.                             break;
  1811.                         case EVENT_FROSTMOURNE_TALK_2:
  1812.                             Talk(SAY_TERENAS_INTRO_2);
  1813.                             break;
  1814.                         case EVENT_FROSTMOURNE_TALK_3:
  1815.                             Talk(SAY_TERENAS_INTRO_3);
  1816.                             break;
  1817.                         case EVENT_OUTRO_TERENAS_TALK_1:
  1818.                             Talk(SAY_TERENAS_OUTRO_1);
  1819.                             break;
  1820.                         case EVENT_OUTRO_TERENAS_TALK_2:
  1821.                             Talk(SAY_TERENAS_OUTRO_2);
  1822.                             DoCastAOE(SPELL_MASS_RESURRECTION);
  1823.                             if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
  1824.                             {
  1825.                                 lichKing->AI()->DoAction(ACTION_FINISH_OUTRO);
  1826.                                 lichKing->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
  1827.                                 if (Creature* tirion = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
  1828.                                     tirion->AI()->AttackStart(lichKing);
  1829.                             }
  1830.                             break;
  1831.                         case EVENT_DESTROY_SOUL:
  1832.                             me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  1833.                             if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f))
  1834.                                 warden->CastSpell((Unit*)NULL, SPELL_DESTROY_SOUL, TRIGGERED_NONE);
  1835.                             DoCast(SPELL_TERENAS_LOSES_INSIDE);
  1836.                             _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1000);
  1837.                             break;
  1838.                         case EVENT_TELEPORT_BACK:
  1839.                             if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
  1840.                                 lichKing->AI()->DoAction(ACTION_TELEPORT_BACK);
  1841.                             break;
  1842.                         default:
  1843.                             break;
  1844.                     }
  1845.                 }
  1846.  
  1847.                 // fighting Spirit Warden
  1848.                 if (me->isInCombat())
  1849.                     DoMeleeAttackIfReady();
  1850.             }
  1851.  
  1852.         private:
  1853.             EventMap _events;
  1854.             InstanceScript* _instance;
  1855.         };
  1856.  
  1857.         CreatureAI* GetAI(Creature* creature) const
  1858.         {
  1859.             return GetIcecrownCitadelAI<npc_terenas_menethilAI>(creature);
  1860.         }
  1861. };
  1862.  
  1863. class npc_spirit_warden : public CreatureScript
  1864. {
  1865.     public:
  1866.         npc_spirit_warden() : CreatureScript("npc_spirit_warden") { }
  1867.  
  1868.         struct npc_spirit_wardenAI : public ScriptedAI
  1869.         {
  1870.             npc_spirit_wardenAI(Creature* creature) : ScriptedAI(creature),
  1871.                 _instance(creature->GetInstanceScript())
  1872.             {
  1873.             }
  1874.  
  1875.             void Reset()
  1876.             {
  1877.                 _events.Reset();
  1878.                 _events.ScheduleEvent(EVENT_SOUL_RIP, urand(12000, 15000));
  1879.                 DoCast(SPELL_DARK_HUNGER);
  1880.             }
  1881.  
  1882.             void JustDied(Unit* /*killer*/)
  1883.             {
  1884.                 if (Creature* terenas = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_TERENAS_MENETHIL)))
  1885.                     terenas->AI()->DoAction(ACTION_TELEPORT_BACK);
  1886.             }
  1887.  
  1888.             void UpdateAI(uint32 const diff)
  1889.             {
  1890.                 if (!UpdateVictim())
  1891.                     return;
  1892.  
  1893.                 _events.Update(diff);
  1894.  
  1895.                 while (uint32 eventId = _events.ExecuteEvent())
  1896.                 {
  1897.                     switch (eventId)
  1898.                     {
  1899.                         case EVENT_SOUL_RIP:
  1900.                             DoCastVictim(SPELL_SOUL_RIP);
  1901.                             _events.ScheduleEvent(EVENT_SOUL_RIP, urand(23000, 27000));
  1902.                             break;
  1903.                         default:
  1904.                             break;
  1905.                     }
  1906.                 }
  1907.  
  1908.                 DoMeleeAttackIfReady();
  1909.             }
  1910.  
  1911.         private:
  1912.             EventMap _events;
  1913.             InstanceScript* _instance;
  1914.         };
  1915.  
  1916.         CreatureAI* GetAI(Creature* creature) const
  1917.         {
  1918.             return GetIcecrownCitadelAI<npc_spirit_wardenAI>(creature);
  1919.         }
  1920. };
  1921.  
  1922. class npc_spirit_bomb : public CreatureScript
  1923. {
  1924.     public:
  1925.         npc_spirit_bomb() : CreatureScript("npc_spirit_bomb") { }
  1926.  
  1927.         struct npc_spirit_bombAI : public CreatureAI
  1928.         {
  1929.             npc_spirit_bombAI(Creature* creature) : CreatureAI(creature)
  1930.             {
  1931.             }
  1932.  
  1933.             void IsSummonedBy(Unit* /*summoner*/)
  1934.             {
  1935.                 float destX, destY, destZ;
  1936.                 me->GetPosition(destX, destY);
  1937.                 destZ = 1055.0f;    // approximation, gets more precise later
  1938.                 me->UpdateGroundPositionZ(destX, destY, destZ);
  1939.                 me->GetMotionMaster()->MovePoint(POINT_GROUND, destX, destY, destZ);
  1940.             }
  1941.  
  1942.             void MovementInform(uint32 type, uint32 point)
  1943.             {
  1944.                 if (type != POINT_MOTION_TYPE || point != POINT_GROUND)
  1945.                     return;
  1946.  
  1947.                 me->RemoveAllAuras();
  1948.                 DoCastAOE(SPELL_EXPLOSION);
  1949.                 me->DespawnOrUnsummon(1000);
  1950.             }
  1951.  
  1952.             void AttackStart(Unit* /*victim*/)
  1953.             {
  1954.             }
  1955.  
  1956.             void UpdateAI(uint32 const /*diff*/)
  1957.             {
  1958.                 UpdateVictim();
  1959.                 // no melee attacks
  1960.             }
  1961.         };
  1962.  
  1963.         CreatureAI* GetAI(Creature* creature) const
  1964.         {
  1965.             return GetIcecrownCitadelAI<npc_spirit_bombAI>(creature);
  1966.         }
  1967. };
  1968.  
  1969. class npc_broken_frostmourne : public CreatureScript
  1970. {
  1971.     public:
  1972.         npc_broken_frostmourne() : CreatureScript("npc_broken_frostmourne") { }
  1973.  
  1974.         struct npc_broken_frostmourneAI : public CreatureAI
  1975.         {
  1976.             npc_broken_frostmourneAI(Creature* creature) : CreatureAI(creature)
  1977.             {
  1978.             }
  1979.  
  1980.             void Reset()
  1981.             {
  1982.                 _events.Reset();
  1983.             }
  1984.  
  1985.             void IsSummonedBy(Unit* /*summoner*/)
  1986.             {
  1987.                 _events.SetPhase(PHASE_OUTRO);
  1988.                 _events.ScheduleEvent(EVENT_OUTRO_KNOCK_BACK, 3000, 0, PHASE_OUTRO);
  1989.             }
  1990.  
  1991.             void DoAction(int32 const action)
  1992.             {
  1993.                 if (action == ACTION_SUMMON_TERENAS)
  1994.                     _events.ScheduleEvent(EVENT_OUTRO_SUMMON_TERENAS, 6000, 0, PHASE_OUTRO);
  1995.             }
  1996.  
  1997.             void UpdateAI(uint32 const diff)
  1998.             {
  1999.                 UpdateVictim();
  2000.  
  2001.                 _events.Update(diff);
  2002.  
  2003.                 while (uint32 eventId = _events.ExecuteEvent())
  2004.                 {
  2005.                     switch (eventId)
  2006.                     {
  2007.                         case EVENT_OUTRO_KNOCK_BACK:
  2008.                             DoCastAOE(SPELL_BROKEN_FROSTMOURNE_KNOCK);
  2009.                             break;
  2010.                         case EVENT_OUTRO_SUMMON_TERENAS:
  2011.                             DoCastAOE(SPELL_SUMMON_TERENAS);
  2012.                             break;
  2013.                         default:
  2014.                             break;
  2015.                     }
  2016.                 }
  2017.  
  2018.                 // no melee attacks
  2019.             }
  2020.  
  2021.         private:
  2022.             EventMap _events;
  2023.         };
  2024.  
  2025.         CreatureAI* GetAI(Creature* creature) const
  2026.         {
  2027.             return GetIcecrownCitadelAI<npc_broken_frostmourneAI>(creature);
  2028.         }
  2029. };
  2030.  
  2031. class spell_the_lich_king_infest : public SpellScriptLoader
  2032. {
  2033.     public:
  2034.         spell_the_lich_king_infest() :  SpellScriptLoader("spell_the_lich_king_infest") { }
  2035.  
  2036.         class spell_the_lich_king_infest_AuraScript : public AuraScript
  2037.         {
  2038.             PrepareAuraScript(spell_the_lich_king_infest_AuraScript);
  2039.  
  2040.             void OnPeriodic(AuraEffect const* /*aurEff*/)
  2041.             {
  2042.                 if (GetUnitOwner()->HealthAbovePct(90))
  2043.                 {
  2044.                     PreventDefaultAction();
  2045.                     Remove(AURA_REMOVE_BY_ENEMY_SPELL);
  2046.                 }
  2047.             }
  2048.  
  2049.             void OnUpdate(AuraEffect* aurEff)
  2050.             {
  2051.                 // multiply, starting from 2nd tick
  2052.                 if (aurEff->GetTickNumber() == 1)
  2053.                     return;
  2054.  
  2055.                 aurEff->SetAmount(int32(aurEff->GetAmount() * 1.15f));
  2056.             }
  2057.  
  2058.             void Register()
  2059.             {
  2060.                 OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_infest_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
  2061.                 OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_the_lich_king_infest_AuraScript::OnUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
  2062.             }
  2063.         };
  2064.  
  2065.         AuraScript* GetAuraScript() const
  2066.         {
  2067.             return new spell_the_lich_king_infest_AuraScript();
  2068.         }
  2069. };
  2070.  
  2071. class spell_the_lich_king_necrotic_plague : public SpellScriptLoader
  2072. {
  2073.     public:
  2074.         spell_the_lich_king_necrotic_plague() :  SpellScriptLoader("spell_the_lich_king_necrotic_plague") { }
  2075.  
  2076.         class spell_the_lich_king_necrotic_plague_AuraScript : public AuraScript
  2077.         {
  2078.             PrepareAuraScript(spell_the_lich_king_necrotic_plague_AuraScript);
  2079.  
  2080.             bool Validate(SpellInfo const* /*spell*/)
  2081.             {
  2082.                 if (!sSpellMgr->GetSpellInfo(SPELL_NECROTIC_PLAGUE_JUMP))
  2083.                     return false;
  2084.                 return true;
  2085.             }
  2086.  
  2087.             void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  2088.             {
  2089.                 switch (GetTargetApplication()->GetRemoveMode())
  2090.                 {
  2091.                     case AURA_REMOVE_BY_ENEMY_SPELL:
  2092.                     case AURA_REMOVE_BY_EXPIRE:
  2093.                     case AURA_REMOVE_BY_DEATH:
  2094.                         break;
  2095.                     default:
  2096.                         return;
  2097.                 }
  2098.  
  2099.                 CustomSpellValues values;
  2100.                 //values.AddSpellMod(SPELLVALUE_AURA_STACK, 2);
  2101.                 values.AddSpellMod(SPELLVALUE_MAX_TARGETS, 1);
  2102.                 GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID());
  2103.                 if (Unit* caster = GetCaster())
  2104.                     caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
  2105.             }
  2106.  
  2107.             void Register()
  2108.             {
  2109.                 AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
  2110.             }
  2111.         };
  2112.  
  2113.         AuraScript* GetAuraScript() const
  2114.         {
  2115.             return new spell_the_lich_king_necrotic_plague_AuraScript();
  2116.         }
  2117. };
  2118.  
  2119. class spell_the_lich_king_necrotic_plague_jump : public SpellScriptLoader
  2120. {
  2121.     public:
  2122.         spell_the_lich_king_necrotic_plague_jump() :  SpellScriptLoader("spell_the_lich_king_necrotic_plague_jump") { }
  2123.  
  2124.         class spell_the_lich_king_necrotic_plague_SpellScript : public SpellScript
  2125.         {
  2126.             PrepareSpellScript(spell_the_lich_king_necrotic_plague_SpellScript);
  2127.  
  2128.             bool Load()
  2129.             {
  2130.                 _hadAura = false;
  2131.                 return true;
  2132.             }
  2133.  
  2134.             void SelectTarget(std::list<Unit*>& targets)
  2135.             {
  2136.                 targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
  2137.                 if (targets.size() < 2)
  2138.                     return;
  2139.  
  2140.                 targets.resize(1);
  2141.             }
  2142.  
  2143.             void CheckAura()
  2144.             {
  2145.                 if (GetHitUnit()->HasAura(GetSpellInfo()->Id))
  2146.                     _hadAura = true;
  2147.             }
  2148.  
  2149.             void AddMissingStack()
  2150.             {
  2151.                 if (GetHitAura() && !_hadAura && GetSpellValue()->EffectBasePoints[EFFECT_1] != AURA_REMOVE_BY_ENEMY_SPELL)
  2152.                     GetHitAura()->ModStackAmount(1);
  2153.             }
  2154.  
  2155.             void Register()
  2156.             {
  2157.                 BeforeHit += SpellHitFn(spell_the_lich_king_necrotic_plague_SpellScript::CheckAura);
  2158.                 OnHit += SpellHitFn(spell_the_lich_king_necrotic_plague_SpellScript::AddMissingStack);
  2159.             }
  2160.  
  2161.             bool _hadAura;
  2162.         };
  2163.  
  2164.         class spell_the_lich_king_necrotic_plague_AuraScript : public AuraScript
  2165.         {
  2166.             PrepareAuraScript(spell_the_lich_king_necrotic_plague_AuraScript);
  2167.  
  2168.             bool Load()
  2169.             {
  2170.                 _lastAmount = 0;
  2171.                 return true;
  2172.             }
  2173.  
  2174.             void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  2175.             {
  2176.                 if (Unit* caster = GetCaster())
  2177.                     caster->GetAI()->SetData(DATA_PLAGUE_STACK, GetStackAmount());
  2178.             }
  2179.  
  2180.             void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
  2181.             {
  2182.                 _lastAmount = aurEff->GetAmount();
  2183.                 switch (GetTargetApplication()->GetRemoveMode())
  2184.                 {
  2185.                     case AURA_REMOVE_BY_EXPIRE:
  2186.                     case AURA_REMOVE_BY_DEATH:
  2187.                         break;
  2188.                     default:
  2189.                         return;
  2190.                 }
  2191.  
  2192.                 CustomSpellValues values;
  2193.                 values.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount());
  2194.                 GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID());
  2195.                 if (Unit* caster = GetCaster())
  2196.                     caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
  2197.             }
  2198.  
  2199.             void OnDispel(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
  2200.             {
  2201.                 _lastAmount = aurEff->GetAmount();
  2202.             }
  2203.  
  2204.             void AfterDispel(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
  2205.             {
  2206.                 // this means the stack increased so don't process as if dispelled
  2207.                 if (aurEff->GetAmount() > _lastAmount)
  2208.                     return;
  2209.  
  2210.                 CustomSpellValues values;
  2211.                 values.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount());
  2212.                 values.AddSpellMod(SPELLVALUE_BASE_POINT1, AURA_REMOVE_BY_ENEMY_SPELL); // add as marker (spell has no effect 1)
  2213.                 GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID());
  2214.                 if (Unit* caster = GetCaster())
  2215.                     caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
  2216.  
  2217.                 Remove(AURA_REMOVE_BY_ENEMY_SPELL);
  2218.             }
  2219.  
  2220.             void Register()
  2221.             {
  2222.                 OnEffectApply += AuraEffectApplyFn(spell_the_lich_king_necrotic_plague_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
  2223.                 AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
  2224.                 AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::OnDispel, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAPPLY);
  2225.                 AfterEffectApply += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::AfterDispel, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAPPLY);
  2226.             }
  2227.  
  2228.             int32 _lastAmount;
  2229.         };
  2230.  
  2231.         SpellScript* GetSpellScript() const
  2232.         {
  2233.             return new spell_the_lich_king_necrotic_plague_SpellScript();
  2234.         }
  2235.  
  2236.         AuraScript* GetAuraScript() const
  2237.         {
  2238.             return new spell_the_lich_king_necrotic_plague_AuraScript();
  2239.         }
  2240. };
  2241.  
  2242. class spell_the_lich_king_shadow_trap_visual : public SpellScriptLoader
  2243. {
  2244.     public:
  2245.         spell_the_lich_king_shadow_trap_visual() : SpellScriptLoader("spell_the_lich_king_shadow_trap_visual") { }
  2246.  
  2247.         class spell_the_lich_king_shadow_trap_visual_AuraScript : public AuraScript
  2248.         {
  2249.             PrepareAuraScript(spell_the_lich_king_shadow_trap_visual_AuraScript);
  2250.  
  2251.             void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  2252.             {
  2253.                 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
  2254.                     GetTarget()->CastSpell(GetTarget(), SPELL_SHADOW_TRAP_AURA, TRIGGERED_NONE);
  2255.             }
  2256.  
  2257.             void Register()
  2258.             {
  2259.                 AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_shadow_trap_visual_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
  2260.             }
  2261.         };
  2262.  
  2263.         AuraScript* GetAuraScript() const
  2264.         {
  2265.             return new spell_the_lich_king_shadow_trap_visual_AuraScript();
  2266.         }
  2267. };
  2268.  
  2269. class spell_the_lich_king_shadow_trap_periodic : public SpellScriptLoader
  2270. {
  2271.     public:
  2272.         spell_the_lich_king_shadow_trap_periodic() : SpellScriptLoader("spell_the_lich_king_shadow_trap_periodic") { }
  2273.  
  2274.         class spell_the_lich_king_shadow_trap_periodic_SpellScript : public SpellScript
  2275.         {
  2276.             PrepareSpellScript(spell_the_lich_king_shadow_trap_periodic_SpellScript);
  2277.  
  2278.             void CheckTargetCount(std::list<Unit*>& targets)
  2279.             {
  2280.                 if (targets.empty())
  2281.                     return;
  2282.  
  2283.                 GetCaster()->CastSpell((Unit*)NULL, SPELL_SHADOW_TRAP_KNOCKBACK, true);
  2284.             }
  2285.  
  2286.             void Register()
  2287.             {
  2288.                 OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_shadow_trap_periodic_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
  2289.             }
  2290.         };
  2291.  
  2292.         SpellScript* GetSpellScript() const
  2293.         {
  2294.             return new spell_the_lich_king_shadow_trap_periodic_SpellScript();
  2295.         }
  2296. };
  2297.  
  2298. class spell_the_lich_king_quake : public SpellScriptLoader
  2299. {
  2300.     public:
  2301.         spell_the_lich_king_quake() : SpellScriptLoader("spell_the_lich_king_quake") { }
  2302.  
  2303.         class spell_the_lich_king_quake_SpellScript : public SpellScript
  2304.         {
  2305.             PrepareSpellScript(spell_the_lich_king_quake_SpellScript);
  2306.  
  2307.             bool Load()
  2308.             {
  2309.                 return GetCaster()->GetInstanceScript() != NULL;
  2310.             }
  2311.  
  2312.             void FilterTargets(std::list<Unit*>& unitList)
  2313.             {
  2314.                 if (GameObject* platform = ObjectAccessor::GetGameObject(*GetCaster(), GetCaster()->GetInstanceScript()->GetData64(DATA_ARTHAS_PLATFORM)))
  2315.                     unitList.remove_if(HeightDifferenceCheck(platform, 5.0f, false));
  2316.             }
  2317.  
  2318.             void HandleSendEvent(SpellEffIndex /*effIndex*/)
  2319.             {
  2320.                 if (GetCaster()->IsAIEnabled)
  2321.                     GetCaster()->GetAI()->DoAction(ACTION_START_ATTACK);
  2322.             }
  2323.  
  2324.             void Register()
  2325.             {
  2326.                 OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
  2327.                 OnEffectHit += SpellEffectFn(spell_the_lich_king_quake_SpellScript::HandleSendEvent, EFFECT_1, SPELL_EFFECT_SEND_EVENT);
  2328.             }
  2329.         };
  2330.  
  2331.         SpellScript* GetSpellScript() const
  2332.         {
  2333.             return new spell_the_lich_king_quake_SpellScript();
  2334.         }
  2335. };
  2336.  
  2337. class spell_the_lich_king_ice_burst_target_search : public SpellScriptLoader
  2338. {
  2339.     public:
  2340.         spell_the_lich_king_ice_burst_target_search() : SpellScriptLoader("spell_the_lich_king_ice_burst_target_search") { }
  2341.  
  2342.         class spell_the_lich_king_ice_burst_target_search_SpellScript : public SpellScript
  2343.         {
  2344.             PrepareSpellScript(spell_the_lich_king_ice_burst_target_search_SpellScript);
  2345.  
  2346.             bool Validate(SpellInfo const* /*spell*/)
  2347.             {
  2348.                 if (!sSpellMgr->GetSpellInfo(SPELL_ICE_BURST))
  2349.                     return false;
  2350.                 return true;
  2351.             }
  2352.  
  2353.             void CheckTargetCount(std::list<Unit*>& unitList)
  2354.             {
  2355.                 if (unitList.empty())
  2356.                     return;
  2357.  
  2358.                 // if there is at least one affected target cast the explosion
  2359.                 GetCaster()->CastSpell(GetCaster(), SPELL_ICE_BURST, true);
  2360.                 if (GetCaster()->GetTypeId() == TYPEID_UNIT)
  2361.                     GetCaster()->ToCreature()->DespawnOrUnsummon(500);
  2362.             }
  2363.  
  2364.             void Register()
  2365.             {
  2366.                 OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_ice_burst_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
  2367.             }
  2368.         };
  2369.  
  2370.         SpellScript* GetSpellScript() const
  2371.         {
  2372.             return new spell_the_lich_king_ice_burst_target_search_SpellScript();
  2373.         }
  2374. };
  2375.  
  2376. class spell_the_lich_king_raging_spirit : public SpellScriptLoader
  2377. {
  2378.     public:
  2379.         spell_the_lich_king_raging_spirit() : SpellScriptLoader("spell_the_lich_king_raging_spirit") { }
  2380.  
  2381.         class spell_the_lich_king_raging_spirit_SpellScript : public SpellScript
  2382.         {
  2383.             PrepareSpellScript(spell_the_lich_king_raging_spirit_SpellScript);
  2384.  
  2385.             bool Validate(SpellInfo const* /*spell*/)
  2386.             {
  2387.                 if (!sSpellMgr->GetSpellInfo(SPELL_LIFE_SIPHON_HEAL))
  2388.                     return false;
  2389.                 return true;
  2390.             }
  2391.  
  2392.             void HandleScript(SpellEffIndex effIndex)
  2393.             {
  2394.                 PreventHitDefaultEffect(effIndex);
  2395.                 GetHitUnit()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
  2396.             }
  2397.  
  2398.             void Register()
  2399.             {
  2400.                 OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_raging_spirit_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  2401.             }
  2402.         };
  2403.  
  2404.         SpellScript* GetSpellScript() const
  2405.         {
  2406.             return new spell_the_lich_king_raging_spirit_SpellScript();
  2407.         }
  2408. };
  2409.  
  2410. class ExactDistanceCheck
  2411. {
  2412.     public:
  2413.         ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) {}
  2414.  
  2415.         bool operator()(Unit* unit)
  2416.         {
  2417.             return _source->GetExactDist2d(unit) > _dist;
  2418.         }
  2419.  
  2420.     private:
  2421.         Unit* _source;
  2422.         float _dist;
  2423. };
  2424.  
  2425. class spell_the_lich_king_defile : public SpellScriptLoader
  2426. {
  2427.     public:
  2428.         spell_the_lich_king_defile() : SpellScriptLoader("spell_the_lich_king_defile") { }
  2429.  
  2430.         class spell_the_lich_king_defile_SpellScript : public SpellScript
  2431.         {
  2432.             PrepareSpellScript(spell_the_lich_king_defile_SpellScript);
  2433.  
  2434.             void CorrectRange(std::list<Unit*>& targets)
  2435.             {
  2436.                 targets.remove_if(ExactDistanceCheck(GetCaster(), 10.0f * GetCaster()->GetFloatValue(OBJECT_FIELD_SCALE_X)));
  2437.             }
  2438.  
  2439.             void ChangeDamageAndGrow()
  2440.             {
  2441.                 SetHitDamage(int32(GetHitDamage() * GetCaster()->GetFloatValue(OBJECT_FIELD_SCALE_X)));
  2442.                 // HACK: target player should cast this spell on defile
  2443.                 // however with current aura handling auras cast by different units
  2444.                 // cannot stack on the same aura object increasing the stack count
  2445.                 GetCaster()->CastSpell(GetCaster(), SPELL_DEFILE_GROW, true);
  2446.             }
  2447.  
  2448.             void Register()
  2449.             {
  2450.                 OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
  2451.                 OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
  2452.                 OnHit += SpellHitFn(spell_the_lich_king_defile_SpellScript::ChangeDamageAndGrow);
  2453.             }
  2454.         };
  2455.  
  2456.         SpellScript* GetSpellScript() const
  2457.         {
  2458.             return new spell_the_lich_king_defile_SpellScript();
  2459.         }
  2460. };
  2461.  
  2462. class spell_the_lich_king_summon_into_air : public SpellScriptLoader
  2463. {
  2464.     public:
  2465.         spell_the_lich_king_summon_into_air() : SpellScriptLoader("spell_the_lich_king_summon_into_air") { }
  2466.  
  2467.         class spell_the_lich_king_summon_into_air_SpellScript : public SpellScript
  2468.         {
  2469.             PrepareSpellScript(spell_the_lich_king_summon_into_air_SpellScript);
  2470.  
  2471.             void ModDestHeight(SpellEffIndex effIndex)
  2472.             {
  2473.                 static Position const offset = {0.0f, 0.0f, 15.0f, 0.0f};
  2474.                 WorldLocation* dest = const_cast<WorldLocation*>(GetTargetDest());
  2475.                 dest->RelocateOffset(offset);
  2476.                 // spirit bombs get higher
  2477.                 if (GetSpellInfo()->Effects[effIndex].MiscValue == NPC_SPIRIT_BOMB)
  2478.                     dest->RelocateOffset(offset);
  2479.             }
  2480.  
  2481.             void Register()
  2482.             {
  2483.                 OnEffectLaunch += SpellEffectFn(spell_the_lich_king_summon_into_air_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
  2484.             }
  2485.         };
  2486.  
  2487.         SpellScript* GetSpellScript() const
  2488.         {
  2489.             return new spell_the_lich_king_summon_into_air_SpellScript();
  2490.         }
  2491. };
  2492.  
  2493. class spell_the_lich_king_soul_reaper : public SpellScriptLoader
  2494. {
  2495.     public:
  2496.         spell_the_lich_king_soul_reaper() :  SpellScriptLoader("spell_the_lich_king_soul_reaper") { }
  2497.  
  2498.         class spell_the_lich_king_soul_reaper_AuraScript : public AuraScript
  2499.         {
  2500.             PrepareAuraScript(spell_the_lich_king_soul_reaper_AuraScript);
  2501.  
  2502.             bool Validate(SpellInfo const* /*spell*/)
  2503.             {
  2504.                 if (!sSpellMgr->GetSpellInfo(SPELL_SOUL_REAPER_BUFF))
  2505.                     return false;
  2506.                 return true;
  2507.             }
  2508.  
  2509.             void OnPeriodic(AuraEffect const* /*aurEff*/)
  2510.             {
  2511.                 if (Unit* caster = GetCaster())
  2512.                     GetTarget()->CastSpell(caster, SPELL_SOUL_REAPER_BUFF, true);
  2513.             }
  2514.  
  2515.             void Register()
  2516.             {
  2517.                 OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_soul_reaper_AuraScript::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE);
  2518.             }
  2519.         };
  2520.  
  2521.         AuraScript* GetAuraScript() const
  2522.         {
  2523.             return new spell_the_lich_king_soul_reaper_AuraScript();
  2524.         }
  2525. };
  2526.  
  2527. class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader
  2528. {
  2529.     public:
  2530.         spell_the_lich_king_valkyr_target_search() : SpellScriptLoader("spell_the_lich_king_valkyr_target_search") { }
  2531.  
  2532.         class spell_the_lich_king_valkyr_target_search_SpellScript : public SpellScript
  2533.         {
  2534.             PrepareSpellScript(spell_the_lich_king_valkyr_target_search_SpellScript);
  2535.  
  2536.             bool Validate(SpellInfo const* /*spell*/)
  2537.             {
  2538.                 if (!sSpellMgr->GetSpellInfo(SPELL_ICE_BURST))
  2539.                     return false;
  2540.                 return true;
  2541.             }
  2542.  
  2543.             bool Load()
  2544.             {
  2545.                 _target = NULL;
  2546.                 return true;
  2547.             }
  2548.  
  2549.             void SelectTarget(std::list<Unit*>& unitList)
  2550.             {
  2551.                 if (unitList.empty())
  2552.                     return;
  2553.  
  2554.                 unitList.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
  2555.                 if (unitList.empty())
  2556.                     return;
  2557.  
  2558.                 _target = SelectRandomContainerElement(unitList);
  2559.                 unitList.clear();
  2560.                 unitList.push_back(_target);
  2561.                 GetCaster()->GetAI()->SetGUID(_target->GetGUID());
  2562.             }
  2563.  
  2564.             void ReplaceTarget(std::list<Unit*>& unitList)
  2565.             {
  2566.                 unitList.clear();
  2567.                 if (_target)
  2568.                     unitList.push_back(_target);
  2569.             }
  2570.  
  2571.             void HandleScript(SpellEffIndex effIndex)
  2572.             {
  2573.                 PreventHitDefaultEffect(effIndex);
  2574.                 GetCaster()->CastSpell(GetHitUnit(), SPELL_CHARGE, true);
  2575.             }
  2576.  
  2577.             void Register()
  2578.             {
  2579.                 OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_valkyr_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
  2580.                 OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_valkyr_target_search_SpellScript::ReplaceTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
  2581.                 OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_valkyr_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  2582.             }
  2583.  
  2584.             Unit* _target;
  2585.         };
  2586.  
  2587.         SpellScript* GetSpellScript() const
  2588.         {
  2589.             return new spell_the_lich_king_valkyr_target_search_SpellScript();
  2590.         }
  2591. };
  2592.  
  2593. class spell_the_lich_king_eject_all_passengers : public SpellScriptLoader
  2594. {
  2595.     public:
  2596.         spell_the_lich_king_eject_all_passengers() : SpellScriptLoader("spell_the_lich_king_eject_all_passengers") { }
  2597.  
  2598.         class spell_the_lich_king_eject_all_passengers_SpellScript : public SpellScript
  2599.         {
  2600.             PrepareSpellScript(spell_the_lich_king_eject_all_passengers_SpellScript);
  2601.  
  2602.             bool Load()
  2603.             {
  2604.                 return GetCaster()->IsVehicle();
  2605.             }
  2606.  
  2607.             void HandleDummy(SpellEffIndex effIndex)
  2608.             {
  2609.                 PreventHitDefaultEffect(effIndex);
  2610.                 GetCaster()->GetVehicleKit()->RemoveAllPassengers();
  2611.             }
  2612.  
  2613.             void Register()
  2614.             {
  2615.                 OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_eject_all_passengers_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
  2616.             }
  2617.         };
  2618.  
  2619.         SpellScript* GetSpellScript() const
  2620.         {
  2621.             return new spell_the_lich_king_eject_all_passengers_SpellScript();
  2622.         }
  2623. };
  2624.  
  2625. class spell_the_lich_king_cast_back_to_caster : public SpellScriptLoader
  2626. {
  2627.     public:
  2628.         spell_the_lich_king_cast_back_to_caster() :  SpellScriptLoader("spell_the_lich_king_cast_back_to_caster") { }
  2629.  
  2630.         class spell_the_lich_king_cast_back_to_caster_SpellScript : public SpellScript
  2631.         {
  2632.             PrepareSpellScript(spell_the_lich_king_cast_back_to_caster_SpellScript);
  2633.  
  2634.             void HandleScript(SpellEffIndex /*effIndex*/)
  2635.             {
  2636.                 GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
  2637.             }
  2638.  
  2639.             void Register()
  2640.             {
  2641.                 OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_cast_back_to_caster_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  2642.             }
  2643.         };
  2644.  
  2645.         SpellScript* GetSpellScript() const
  2646.         {
  2647.             return new spell_the_lich_king_cast_back_to_caster_SpellScript();
  2648.         }
  2649. };
  2650.  
  2651. class spell_the_lich_king_life_siphon : public SpellScriptLoader
  2652. {
  2653.     public:
  2654.         spell_the_lich_king_life_siphon() : SpellScriptLoader("spell_the_lich_king_life_siphon") { }
  2655.  
  2656.         class spell_the_lich_king_life_siphon_SpellScript : public SpellScript
  2657.         {
  2658.             PrepareSpellScript(spell_the_lich_king_life_siphon_SpellScript);
  2659.  
  2660.             bool Validate(SpellInfo const* /*spell*/)
  2661.             {
  2662.                 if (!sSpellMgr->GetSpellInfo(SPELL_LIFE_SIPHON_HEAL))
  2663.                     return false;
  2664.                 return true;
  2665.             }
  2666.  
  2667.             void TriggerHeal()
  2668.             {
  2669.                 GetHitUnit()->CastCustomSpell(SPELL_LIFE_SIPHON_HEAL, SPELLVALUE_BASE_POINT0, GetHitDamage() * 10, GetCaster(), true);
  2670.             }
  2671.  
  2672.             void Register()
  2673.             {
  2674.                 AfterHit += SpellHitFn(spell_the_lich_king_life_siphon_SpellScript::TriggerHeal);
  2675.             }
  2676.         };
  2677.  
  2678.         SpellScript* GetSpellScript() const
  2679.         {
  2680.             return new spell_the_lich_king_life_siphon_SpellScript();
  2681.         }
  2682. };
  2683.  
  2684. class spell_the_lich_king_vile_spirits : public SpellScriptLoader
  2685. {
  2686.     public:
  2687.         spell_the_lich_king_vile_spirits() : SpellScriptLoader("spell_the_lich_king_vile_spirits") { }
  2688.  
  2689.         class spell_the_lich_king_vile_spirits_AuraScript : public AuraScript
  2690.         {
  2691.             PrepareAuraScript(spell_the_lich_king_vile_spirits_AuraScript);
  2692.  
  2693.             bool Load()
  2694.             {
  2695.                 _is25Man = GetUnitOwner()->GetMap()->Is25ManRaid();
  2696.                 return true;
  2697.             }
  2698.  
  2699.             void OnPeriodic(AuraEffect const* aurEff)
  2700.             {
  2701.                 if (_is25Man || ((aurEff->GetTickNumber() - 1) % 5))
  2702.                     GetTarget()->CastSpell((Unit*)NULL, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, NULL, aurEff, GetCasterGUID());
  2703.             }
  2704.  
  2705.             void Register()
  2706.             {
  2707.                 OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_vile_spirits_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
  2708.             }
  2709.  
  2710.             bool _is25Man;
  2711.         };
  2712.  
  2713.         AuraScript* GetAuraScript() const
  2714.         {
  2715.             return new spell_the_lich_king_vile_spirits_AuraScript();
  2716.         }
  2717. };
  2718.  
  2719. class spell_the_lich_king_vile_spirits_visual : public SpellScriptLoader
  2720. {
  2721.     public:
  2722.         spell_the_lich_king_vile_spirits_visual() : SpellScriptLoader("spell_the_lich_king_vile_spirits_visual") { }
  2723.  
  2724.         class spell_the_lich_king_vile_spirits_visual_SpellScript : public SpellScript
  2725.         {
  2726.             PrepareSpellScript(spell_the_lich_king_vile_spirits_visual_SpellScript);
  2727.  
  2728.             void ModDestHeight(SpellEffIndex /*effIndex*/)
  2729.             {
  2730.                 Position offset = {0.0f, 0.0f, 15.0f, 0.0f};
  2731.                 const_cast<WorldLocation*>(GetTargetDest())->RelocateOffset(offset);
  2732.             }
  2733.  
  2734.             void Register()
  2735.             {
  2736.                 OnEffectLaunch += SpellEffectFn(spell_the_lich_king_vile_spirits_visual_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_DUMMY);
  2737.             }
  2738.         };
  2739.  
  2740.         SpellScript* GetSpellScript() const
  2741.         {
  2742.             return new spell_the_lich_king_vile_spirits_visual_SpellScript();
  2743.         }
  2744. };
  2745.  
  2746. class spell_the_lich_king_vile_spirit_move_target_search : public SpellScriptLoader
  2747. {
  2748.     public:
  2749.         spell_the_lich_king_vile_spirit_move_target_search() : SpellScriptLoader("spell_the_lich_king_vile_spirit_move_target_search") { }
  2750.  
  2751.         class spell_the_lich_king_vile_spirit_move_target_search_SpellScript : public SpellScript
  2752.         {
  2753.             PrepareSpellScript(spell_the_lich_king_vile_spirit_move_target_search_SpellScript);
  2754.  
  2755.             bool Load()
  2756.             {
  2757.                 _target = NULL;
  2758.                 return GetCaster()->GetTypeId() == TYPEID_UNIT;
  2759.             }
  2760.  
  2761.             void SelectTarget(std::list<Unit*>& targets)
  2762.             {
  2763.                 if (targets.empty())
  2764.                     return;
  2765.  
  2766.                 _target = SelectRandomContainerElement(targets);
  2767.             }
  2768.  
  2769.             void HandleScript(SpellEffIndex effIndex)
  2770.             {
  2771.                 PreventHitDefaultEffect(effIndex);
  2772.                 // for this spell, all units are in target map, however it should select one to attack
  2773.                 if (GetHitUnit() != _target)
  2774.                     return;
  2775.  
  2776.                 GetCaster()->ToCreature()->AI()->AttackStart(GetHitUnit());
  2777.                 GetCaster()->AddThreat(GetHitUnit(), 100000.0f);
  2778.             }
  2779.  
  2780.             void Register()
  2781.             {
  2782.                 OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
  2783.                 OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  2784.             }
  2785.  
  2786.             Unit* _target;
  2787.         };
  2788.  
  2789.         SpellScript* GetSpellScript() const
  2790.         {
  2791.             return new spell_the_lich_king_vile_spirit_move_target_search_SpellScript();
  2792.         }
  2793. };
  2794.  
  2795. class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScriptLoader
  2796. {
  2797.     public:
  2798.         spell_the_lich_king_vile_spirit_damage_target_search() : SpellScriptLoader("spell_the_lich_king_vile_spirit_damage_target_search") { }
  2799.  
  2800.         class spell_the_lich_king_vile_spirit_damage_target_search_SpellScript : public SpellScript
  2801.         {
  2802.             PrepareSpellScript(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript);
  2803.  
  2804.             bool Load()
  2805.             {
  2806.                 return GetCaster()->GetTypeId() == TYPEID_UNIT;
  2807.             }
  2808.  
  2809.             void CheckTargetCount(std::list<Unit*>& targets)
  2810.             {
  2811.                 if (targets.empty())
  2812.                     return;
  2813.  
  2814.                 // this spell has SPELL_AURA_BLOCK_SPELL_FAMILY so every next cast of this
  2815.                 // searcher spell will be blocked
  2816.                 if (TempSummon* summon = GetCaster()->ToTempSummon())
  2817.                     if (Unit* summoner = summon->GetSummoner())
  2818.                         summoner->GetAI()->SetData(DATA_VILE, 1);
  2819.                 GetCaster()->CastSpell((Unit*)NULL, SPELL_SPIRIT_BURST, true);
  2820.                 GetCaster()->ToCreature()->DespawnOrUnsummon(3000);
  2821.                 GetCaster()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  2822.             }
  2823.  
  2824.             void Register()
  2825.             {
  2826.                 OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
  2827.             }
  2828.  
  2829.             Unit* _target;
  2830.         };
  2831.  
  2832.         SpellScript* GetSpellScript() const
  2833.         {
  2834.             return new spell_the_lich_king_vile_spirit_damage_target_search_SpellScript();
  2835.         }
  2836. };
  2837.  
  2838. class spell_the_lich_king_harvest_soul : public SpellScriptLoader
  2839. {
  2840.     public:
  2841.         spell_the_lich_king_harvest_soul() : SpellScriptLoader("spell_the_lich_king_harvest_soul") { }
  2842.  
  2843.         class spell_the_lich_king_harvest_soul_AuraScript : public AuraScript
  2844.         {
  2845.             PrepareAuraScript(spell_the_lich_king_harvest_soul_AuraScript);
  2846.  
  2847.             bool Load()
  2848.             {
  2849.                 return GetOwner()->GetInstanceScript() != NULL;
  2850.             }
  2851.  
  2852.             void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  2853.             {
  2854.                 // m_originalCaster to allow stacking from different casters, meh
  2855.                 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
  2856.                     GetTarget()->CastSpell((Unit*)NULL, SPELL_HARVESTED_SOUL, true, NULL, NULL, GetTarget()->GetInstanceScript()->GetData64(DATA_THE_LICH_KING));
  2857.             }
  2858.  
  2859.             void Register()
  2860.             {
  2861.                 AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_harvest_soul_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
  2862.             }
  2863.         };
  2864.  
  2865.         AuraScript* GetAuraScript() const
  2866.         {
  2867.             return new spell_the_lich_king_harvest_soul_AuraScript();
  2868.         }
  2869. };
  2870.  
  2871. class spell_the_lich_king_lights_favor : public SpellScriptLoader
  2872. {
  2873.     public:
  2874.         spell_the_lich_king_lights_favor() : SpellScriptLoader("spell_the_lich_king_lights_favor") { }
  2875.  
  2876.         class spell_the_lich_king_lights_favor_AuraScript : public AuraScript
  2877.         {
  2878.             PrepareAuraScript(spell_the_lich_king_lights_favor_AuraScript);
  2879.  
  2880.             void OnPeriodic(AuraEffect const* /*aurEff*/)
  2881.             {
  2882.                 if (Unit* caster = GetCaster())
  2883.                     if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1))
  2884.                         effect->RecalculateAmount(caster);
  2885.             }
  2886.  
  2887.             void CalculateBonus(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated)
  2888.             {
  2889.                 canBeRecalculated = true;
  2890.                 amount = 0;
  2891.                 if (Unit* caster = GetCaster())
  2892.                     amount = int32(caster->GetHealthPct());
  2893.             }
  2894.  
  2895.             void Register()
  2896.             {
  2897.                 OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_lights_favor_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
  2898.                 DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_the_lich_king_lights_favor_AuraScript::CalculateBonus, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
  2899.             }
  2900.         };
  2901.  
  2902.         AuraScript* GetAuraScript() const
  2903.         {
  2904.             return new spell_the_lich_king_lights_favor_AuraScript();
  2905.         }
  2906. };
  2907.  
  2908. class spell_the_lich_king_soul_rip : public SpellScriptLoader
  2909. {
  2910.     public:
  2911.         spell_the_lich_king_soul_rip() : SpellScriptLoader("spell_the_lich_king_soul_rip") { }
  2912.  
  2913.         class spell_the_lich_king_soul_rip_AuraScript : public AuraScript
  2914.         {
  2915.             PrepareAuraScript(spell_the_lich_king_soul_rip_AuraScript);
  2916.  
  2917.             void OnPeriodic(AuraEffect const* aurEff)
  2918.             {
  2919.                 PreventDefaultAction();
  2920.                 // shouldn't be needed, this is channeled
  2921.                 if (Unit* caster = GetCaster())
  2922.                     caster->CastCustomSpell(SPELL_SOUL_RIP_DAMAGE, SPELLVALUE_BASE_POINT0, 5000 * aurEff->GetTickNumber(), GetTarget(), true, NULL, aurEff, GetCasterGUID());
  2923.             }
  2924.  
  2925.             void Register()
  2926.             {
  2927.                 OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_soul_rip_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
  2928.             }
  2929.         };
  2930.  
  2931.         AuraScript* GetAuraScript() const
  2932.         {
  2933.             return new spell_the_lich_king_soul_rip_AuraScript();
  2934.         }
  2935. };
  2936.  
  2937. class spell_the_lich_king_restore_soul : public SpellScriptLoader
  2938. {
  2939.     public:
  2940.         spell_the_lich_king_restore_soul() : SpellScriptLoader("spell_the_lich_king_restore_soul") { }
  2941.  
  2942.         class spell_the_lich_king_restore_soul_SpellScript : public SpellScript
  2943.         {
  2944.             PrepareSpellScript(spell_the_lich_king_restore_soul_SpellScript);
  2945.  
  2946.             bool Load()
  2947.             {
  2948.                 _instance = GetCaster()->GetInstanceScript();
  2949.                 return _instance != NULL;
  2950.             }
  2951.  
  2952.             void HandleScript(SpellEffIndex /*effIndex*/)
  2953.             {
  2954.                 if (Creature* lichKing = ObjectAccessor::GetCreature(*GetCaster(), _instance->GetData64(DATA_THE_LICH_KING)))
  2955.                     lichKing->AI()->DoAction(ACTION_TELEPORT_BACK);
  2956.                 if (Creature* spawner = GetCaster()->FindNearestCreature(NPC_WORLD_TRIGGER_INFINITE_AOI, 50.0f))
  2957.                     spawner->RemoveAllAuras();
  2958.             }
  2959.  
  2960.             void RemoveAura()
  2961.             {
  2962.                 if (Unit* target = GetHitUnit())
  2963.                     target->RemoveAurasDueToSpell(target->GetMap()->IsHeroic() ? SPELL_HARVEST_SOULS_TELEPORT : SPELL_HARVEST_SOUL_TELEPORT);
  2964.             }
  2965.  
  2966.             void Register()
  2967.             {
  2968.                 OnEffectHit += SpellEffectFn(spell_the_lich_king_restore_soul_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
  2969.                 BeforeHit += SpellHitFn(spell_the_lich_king_restore_soul_SpellScript::RemoveAura);
  2970.             }
  2971.  
  2972.             InstanceScript* _instance;
  2973.         };
  2974.  
  2975.         SpellScript* GetSpellScript() const
  2976.         {
  2977.             return new spell_the_lich_king_restore_soul_SpellScript();
  2978.         }
  2979. };
  2980.  
  2981. class spell_the_lich_king_in_frostmourne_room : public SpellScriptLoader
  2982. {
  2983.     public:
  2984.         spell_the_lich_king_in_frostmourne_room() : SpellScriptLoader("spell_the_lich_king_in_frostmourne_room") { }
  2985.  
  2986.         class spell_the_lich_king_in_frostmourne_room_AuraScript : public AuraScript
  2987.         {
  2988.             PrepareAuraScript(spell_the_lich_king_in_frostmourne_room_AuraScript);
  2989.  
  2990.             bool Load()
  2991.             {
  2992.                 return GetOwner()->GetInstanceScript() != NULL;
  2993.             }
  2994.  
  2995.             void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  2996.             {
  2997.                 // m_originalCaster to allow stacking from different casters, meh
  2998.                 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
  2999.                     GetTarget()->CastSpell((Unit*)NULL, SPELL_HARVESTED_SOUL, true, NULL, NULL, GetTarget()->GetInstanceScript()->GetData64(DATA_THE_LICH_KING));
  3000.             }
  3001.  
  3002.             void Register()
  3003.             {
  3004.                 AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_in_frostmourne_room_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
  3005.             }
  3006.         };
  3007.  
  3008.         AuraScript* GetAuraScript() const
  3009.         {
  3010.             return new spell_the_lich_king_in_frostmourne_room_AuraScript();
  3011.         }
  3012. };
  3013.  
  3014. class spell_the_lich_king_summon_spirit_bomb : public SpellScriptLoader
  3015. {
  3016.     public:
  3017.         spell_the_lich_king_summon_spirit_bomb() : SpellScriptLoader("spell_the_lich_king_summon_spirit_bomb") { }
  3018.  
  3019.         class spell_the_lich_king_summon_spirit_bomb_SpellScript : public SpellScript
  3020.         {
  3021.             PrepareSpellScript(spell_the_lich_king_summon_spirit_bomb_SpellScript);
  3022.  
  3023.             void HandleScript(SpellEffIndex effIndex)
  3024.             {
  3025.                 PreventHitDefaultEffect(effIndex);
  3026.                 GetHitUnit()->CastSpell((Unit*)NULL, uint32(GetEffectValue()), true);
  3027.             }
  3028.  
  3029.             void Register()
  3030.             {
  3031.                 OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_summon_spirit_bomb_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  3032.             }
  3033.         };
  3034.  
  3035.         SpellScript* GetSpellScript() const
  3036.         {
  3037.             return new spell_the_lich_king_summon_spirit_bomb_SpellScript();
  3038.         }
  3039. };
  3040.  
  3041. class spell_the_lich_king_trigger_vile_spirit : public SpellScriptLoader
  3042. {
  3043.     public:
  3044.         spell_the_lich_king_trigger_vile_spirit() : SpellScriptLoader("spell_the_lich_king_trigger_vile_spirit") { }
  3045.  
  3046.         class spell_the_lich_king_trigger_vile_spirit_SpellScript : public SpellScript
  3047.         {
  3048.             PrepareSpellScript(spell_the_lich_king_trigger_vile_spirit_SpellScript);
  3049.  
  3050.             void TeleportOutside()
  3051.             {
  3052.                 Creature* target = GetHitCreature();
  3053.                 if (!target)
  3054.                     return;
  3055.  
  3056.                 Position dest;
  3057.                 Position offset;
  3058.                 TerenasSpawnHeroic.GetPositionOffsetTo(*target, offset);
  3059.                 GetCaster()->GetPosition(&dest);
  3060.                 dest.RelocateOffset(offset);
  3061.                 target->NearTeleportTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.GetOrientation());
  3062.             }
  3063.  
  3064.             void Register()
  3065.             {
  3066.                 OnHit += SpellHitFn(spell_the_lich_king_trigger_vile_spirit_SpellScript::TeleportOutside);
  3067.             }
  3068.         };
  3069.  
  3070.         SpellScript* GetSpellScript() const
  3071.         {
  3072.             return new spell_the_lich_king_trigger_vile_spirit_SpellScript();
  3073.         }
  3074. };
  3075.  
  3076. class spell_the_lich_king_jump : public SpellScriptLoader
  3077. {
  3078.     public:
  3079.         spell_the_lich_king_jump() : SpellScriptLoader("spell_the_lich_king_jump") { }
  3080.  
  3081.         class spell_the_lich_king_jump_SpellScript : public SpellScript
  3082.         {
  3083.             PrepareSpellScript(spell_the_lich_king_jump_SpellScript);
  3084.  
  3085.             void HandleScript(SpellEffIndex effIndex)
  3086.             {
  3087.                 PreventHitDefaultEffect(effIndex);
  3088.                 GetHitUnit()->RemoveAurasDueToSpell(SPELL_RAISE_DEAD);
  3089.                 GetHitUnit()->CastSpell((Unit*)NULL, SPELL_JUMP_2, true);
  3090.                 if (Creature* creature = GetHitCreature())
  3091.                     creature->AI()->DoAction(ACTION_BREAK_FROSTMOURNE);
  3092.             }
  3093.  
  3094.             void Register()
  3095.             {
  3096.                 OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_jump_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  3097.             }
  3098.         };
  3099.  
  3100.         SpellScript* GetSpellScript() const
  3101.         {
  3102.             return new spell_the_lich_king_jump_SpellScript();
  3103.         }
  3104. };
  3105.  
  3106. class spell_the_lich_king_jump_remove_aura : public SpellScriptLoader
  3107. {
  3108.     public:
  3109.         spell_the_lich_king_jump_remove_aura() : SpellScriptLoader("spell_the_lich_king_jump_remove_aura") { }
  3110.  
  3111.         class spell_the_lich_king_jump_SpellScript : public SpellScript
  3112.         {
  3113.             PrepareSpellScript(spell_the_lich_king_jump_SpellScript);
  3114.  
  3115.             void HandleScript(SpellEffIndex effIndex)
  3116.             {
  3117.                 PreventHitDefaultEffect(effIndex);
  3118.                 GetHitUnit()->RemoveAurasDueToSpell(uint32(GetEffectValue()));
  3119.             }
  3120.  
  3121.             void Register()
  3122.             {
  3123.                 OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_jump_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  3124.             }
  3125.         };
  3126.  
  3127.         SpellScript* GetSpellScript() const
  3128.         {
  3129.             return new spell_the_lich_king_jump_SpellScript();
  3130.         }
  3131. };
  3132.  
  3133. class spell_the_lich_king_play_movie : public SpellScriptLoader
  3134. {
  3135.     public:
  3136.         spell_the_lich_king_play_movie() : SpellScriptLoader("spell_the_lich_king_play_movie") { }
  3137.  
  3138.         class spell_the_lich_king_play_movie_SpellScript : public SpellScript
  3139.         {
  3140.             PrepareSpellScript(spell_the_lich_king_play_movie_SpellScript);
  3141.  
  3142.             bool Validate(SpellInfo const* /*spell*/)
  3143.             {
  3144.                 if (!sMovieStore.LookupEntry(MOVIE_FALL_OF_THE_LICH_KING))
  3145.                     return false;
  3146.                 return true;
  3147.             }
  3148.  
  3149.             void HandleScript(SpellEffIndex effIndex)
  3150.             {
  3151.                 PreventHitDefaultEffect(effIndex);
  3152.                 if (Player* player = GetHitPlayer())
  3153.                     player->SendMovieStart(MOVIE_FALL_OF_THE_LICH_KING);
  3154.             }
  3155.  
  3156.             void Register()
  3157.             {
  3158.                 OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_play_movie_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  3159.             }
  3160.         };
  3161.  
  3162.         SpellScript* GetSpellScript() const
  3163.         {
  3164.             return new spell_the_lich_king_play_movie_SpellScript();
  3165.         }
  3166. };
  3167.  
  3168. class achievement_been_waiting_long_time : public AchievementCriteriaScript
  3169. {
  3170.     public:
  3171.         achievement_been_waiting_long_time() : AchievementCriteriaScript("achievement_been_waiting_long_time") { }
  3172.  
  3173.         bool OnCheck(Player* /*source*/, Unit* target)
  3174.         {
  3175.             if (!target)
  3176.                 return false;
  3177.  
  3178.             return target->GetAI()->GetData(DATA_PLAGUE_STACK) >= 30;
  3179.         }
  3180. };
  3181.  
  3182. class achievement_neck_deep_in_vile : public AchievementCriteriaScript
  3183. {
  3184.     public:
  3185.         achievement_neck_deep_in_vile() : AchievementCriteriaScript("achievement_neck_deep_in_vile") { }
  3186.  
  3187.         bool OnCheck(Player* /*source*/, Unit* target)
  3188.         {
  3189.             if (!target)
  3190.                 return false;
  3191.  
  3192.             return !target->GetAI()->GetData(DATA_VILE);
  3193.         }
  3194. };
  3195.  
  3196. void AddSC_boss_the_lich_king()
  3197. {
  3198.     new boss_the_lich_king();
  3199.     new npc_tirion_fordring_tft();
  3200.     new npc_shambling_horror_icc();
  3201.     new npc_raging_spirit();
  3202.     new npc_valkyr_shadowguard();
  3203.     new npc_strangulate_vehicle();
  3204.     new npc_terenas_menethil();
  3205.     new npc_spirit_warden();
  3206.     new npc_spirit_bomb();
  3207.     new npc_broken_frostmourne();
  3208.     new spell_the_lich_king_infest();
  3209.     new spell_the_lich_king_necrotic_plague();
  3210.     new spell_the_lich_king_necrotic_plague_jump();
  3211.     new spell_the_lich_king_shadow_trap_visual();
  3212.     new spell_the_lich_king_shadow_trap_periodic();
  3213.     new spell_the_lich_king_quake();
  3214.     new spell_the_lich_king_ice_burst_target_search();
  3215.     new spell_the_lich_king_raging_spirit();
  3216.     new spell_the_lich_king_defile();
  3217.     new spell_the_lich_king_summon_into_air();
  3218.     new spell_the_lich_king_soul_reaper();
  3219.     new spell_the_lich_king_valkyr_target_search();
  3220.     new spell_the_lich_king_eject_all_passengers();
  3221.     new spell_the_lich_king_cast_back_to_caster();
  3222.     new spell_the_lich_king_life_siphon();
  3223.     new spell_the_lich_king_vile_spirits();
  3224.     new spell_the_lich_king_vile_spirits_visual();
  3225.     new spell_the_lich_king_vile_spirit_move_target_search();
  3226.     new spell_the_lich_king_vile_spirit_damage_target_search();
  3227.     new spell_the_lich_king_harvest_soul();
  3228.     new spell_the_lich_king_lights_favor();
  3229.     new spell_the_lich_king_soul_rip();
  3230.     new spell_the_lich_king_restore_soul();
  3231.     new spell_the_lich_king_in_frostmourne_room();
  3232.     new spell_the_lich_king_summon_spirit_bomb();
  3233.     new spell_the_lich_king_trigger_vile_spirit();
  3234.     new spell_the_lich_king_jump();
  3235.     new spell_the_lich_king_jump_remove_aura();
  3236.     new spell_trigger_spell_from_caster("spell_the_lich_king_mass_resurrection", SPELL_MASS_RESURRECTION_REAL);
  3237.     new spell_the_lich_king_play_movie();
  3238.     new achievement_been_waiting_long_time();
  3239.     new achievement_neck_deep_in_vile();
  3240. }
Advertisement
Add Comment
Please, Sign In to add comment