mferrill

ICC Final Battle --Trinity

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