Guest
Public paste!

spichy

By: a guest | Sep 24th, 2009 | Syntax: C++ | Size: 49.11 KB | Hits: 106 | Expires: Never
Copy text to clipboard
  1. /* Copyright 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License as published by
  4. * the Free Software Foundation; either version 2 of the License, or
  5. * (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program; if not, write to the Free Software
  14. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. */
  16.  
  17. /* ScriptData
  18. SDName: boss_kiljaeden
  19. SD%Complete: 95
  20. SDComment: Development, needs test
  21. SDCategory: Sunwell_Plateau
  22. EndScriptData */
  23. #include "precompiled.h"
  24. #include "def_sunwell_plateau.h"
  25.  
  26. /*** Spells used during the encounter ***/
  27. /* Hand of the Deceiver's spells and cosmetics */
  28. #define SPELL_SHADOW_BOLT_VOLLEY               45575 // ~30 yard range Shadow Bolt Volley for ~2k(?) damage
  29. #define SPELL_SHADOW_INFUSION                  45772 // They gain this at 20% - Immunity to Stun/Silence and makes them look angry!
  30. #define SPELL_FELFIRE_PORTAL                   46875 // Creates a portal that spawns Felfire Fiends (LIVE FOR THE SWARM!1 FOR THE OVERMIND!)
  31. #define SPELL_SHADOW_CHANNELING                46757 // Channeling animation out of combat
  32.  
  33. /* Volatile Felfire Fiend's spells */
  34. #define SPELL_FELFIRE_FISSION                  45779 // Felfire Fiends explode when they die or get close to target.
  35.  
  36. /* Kil'Jaeden's spells and cosmetics */
  37. #define SPELL_TRANS                            23188 // Surprisingly, this seems to be the right spell.. (Where is it used?)
  38. #define SPELL_REBIRTH                          44200 // Emerge from the Sunwell
  39. #define SPELL_SOUL_FLAY_DAMAGE                 45442 // 9k Shadow damage over 3 seconds. Spammed throughout all the fight.
  40. #define SPELL_SOUL_FLAY_MOVEMENT               47106 // -50% Movement component of the above. Players cast it on selves unless this spell is fixed.
  41. #define SPELL_LEGION_LIGHTNING                 45664 // Chain Lightning, 4 targets, ~3k Shadow damage, 1.5k mana burn
  42. #define SPELL_FIRE_BLOOM                       45641 // Places a debuff on 5 raid members, which causes them to deal 2k Fire damage to nearby allies and selves. MIGHT NOT WORK
  43. #define SPELL_SINISTER_REFLECTION              45785 // Summon shadow copies of 5 raid members that fight against KJ's enemies
  44. #define SPELL_COPY_WEAPON                      41055 // }
  45. #define SPELL_COPY_WEAPON2                     41054 // }
  46. #define SPELL_COPY_OFFHAND                     45206 // }- Spells used in Sinister Reflection creation
  47. #define SPELL_COPY_OFFHAND_WEAPON              45205 // }
  48. #define SPELL_SINISTER_REFLECTION_CLASS        45893
  49. #define SPELL_SINISTER_REFLECTION_CLONE        45785 // Cause the target to become a clone of the caster.
  50. #define SPELL_SINISTER_REFLECTION_SUMMON       45891
  51. #define SPELL_SHADOW_SPIKE                     46680 // Bombard random raid members with Shadow Spikes (Very similar to Void Reaver orbs)
  52. #define SPELL_SHADOW_SPIKE_EFFECT              45885 // Inflicts 5100 to 6900% Shadow damage to an enemy and leaves it wounded, reducing the effectiveness of any healing by 50% for 10 sec.
  53. #define SPELL_SHADOW_SPIKE_VISUAL              46589
  54. #define SPELL_FLAME_DART                       45740 // Bombards the raid with flames every 3(?) seconds
  55. #define SPELL_DARKNESS_OF_A_THOUSAND_SOULS     46605 // Begins a 8-second channeling, after which he will deal 50'000 damage to the raid
  56. #define SPELL_DARKNESS_OF_A_THOUSAND_SOULS_EFFECT 45657 // Deals 47500 to 52500 Shadow damage to all enemies within reach.
  57. #define SPELL_ARMAGEDDON                       45909 // Meteor spell
  58. #define SPELL_ARMAGEDDON_VISUAL                45911 // Does the hellfire visual to indicate where the meteor missle lands
  59. #define SPELL_SACRIFICE_OF_ANVEENA             46474 // Anveena sacrifices herself, causing Kil'jaeden to take 25% increased Holy damage.
  60.  
  61. /* Anveena's spells and cosmetics (Or, generally, everything that has "Anveena" in name) */
  62. #define SPELL_ANVEENA_PRISON                   46367 // She hovers locked within a bubble
  63. #define SPELL_ANVEENA_ENERGY_DRAIN             46410 // Sunwell energy glow animation (Control mob uses this)
  64.  
  65. /* Shield Orb spells */
  66. //#define SPELL_SHADOW_BOLT                      45680 // constantly shooting Shadow Bolts at the raid (up to 3 bolts within 1 second)
  67. #define SPELL_SHADOW_BOLT                      30505 // 45680 doesn't work, use 36714(1275~1725) for worksaround, or 30505 (1063~1437)
  68.  
  69. /*** Other Spells (used by players, etc) ***/
  70. #define SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT     45839 // Possess the blue dragon from the orb to help the raid.
  71. #define SPELL_ENTROPIUS_BODY                   46819 // Visual for Entropius at the Epilogue
  72.  
  73. /*** Creatures used in the encounter ***/
  74. #define CREATURE_ANVEENA                        26046 // Embodiment of the Sunwell
  75. #define CREATURE_KALECGOS                       25319 // Helps the raid throughout the fight
  76. #define CREATURE_KILJAEDEN                      25315 // Give it to 'em KJ!
  77. #define CREATURE_HAND_OF_THE_DECEIVER           25588 // Adds found before KJ emerges
  78. #define CREATURE_FELFIRE_PORTAL                 25603 // Portal spawned be Hand of the Deceivers
  79. #define CREATURE_VOLATILE_FELFIRE_FIEND         25598 // Fiends spawned by the above portal
  80. #define CREATURE_ARMAGEDDON_TARGET              25735 // This mob casts meteor on itself.. I think
  81. #define CREATURE_SHIELD_ORB                     25502 // Shield orbs circle the room raining shadow bolts on raid
  82. #define CREATURE_THE_CORE_OF_ENTROPIUS          26262 // Used in the ending cinematic?
  83. #define CREATURE_POWER_OF_THE_BLUE_DRAGONFLIGHT 25653 // NPC that players possess when using the Orb of the Blue Dragonflight
  84.  
  85. /*** GameObjects ***/
  86. #define GAMEOBJECT_ORB_OF_THE_BLUE_DRAGONFLIGHT 188415
  87.  
  88. /*** Speech and sounds***/
  89. // These are used throughout Sunwell and Magisters(?). Players can hear this while running through the instances.
  90. #define SAY_KJ_OFFCOMBAT1                       -1580056
  91. #define SAY_KJ_OFFCOMBAT2                       -1580057
  92. #define SAY_KJ_OFFCOMBAT3                       -1580058
  93. #define SAY_KJ_OFFCOMBAT4                       -1580059
  94. #define SAY_KJ_OFFCOMBAT5                       -1580060
  95.  
  96. // Encounter speech and sounds
  97. #define SAY_KJ_EMERGE                           -1580061
  98. #define SAY_KJ_SLAY1                            -1580062
  99. #define SAY_KJ_SLAY2                            -1580063
  100. #define SAY_KJ_REFLECTION1                      -1580064
  101. #define SAY_KJ_REFLECTION2                      -1580065
  102. #define SAY_KJ_DARKNESS1                        -1580066
  103. #define SAY_KJ_DARKNESS2                        -1580067
  104. #define SAY_KJ_DARKNESS3                        -1580068
  105. #define SAY_KJ_CANNOT_WIN                       -1580070
  106. #define SAY_KJ_DENINE                           -1580069
  107. #define SAY_KJ_LOST_POWER                       -1580071
  108.  
  109. /*** Kalecgos - Anveena speech at the beginning of Phase 5; Anveena's sacrifice ***/
  110. #define SAY_KALECGOS_INTRO                      -1580072
  111. #define SAY_KALECGOS_AWAKEN                     -1580073
  112. #define SAY_ANVEENA_IMPRISONED                  -1580074
  113. #define SAY_KALECGOS_LETGO                      -1580075
  114. #define SAY_ANVEENA_LOST                        -1580076
  115. #define SAY_KALECGOS_FOCUS                      -1580077
  116. #define SAY_ANVEENA_KALEC                       -1580078
  117. #define SAY_KALECGOS_FATE                       -1580079
  118. #define SAY_ANVEENA_GOODBYE                     -1580080
  119. #define SAY_KALECGOS_GOODBYE                    -1580081
  120. #define SAY_KALECGOS_ENCOURAGE                  -1580082
  121. // Charming
  122.  
  123. /*** Error messages ***/
  124. #define ERROR_KJ_NOT_SUMMONED "SD2 ERROR: Unable to summon Kil'Jaeden for some reason"
  125.  
  126. /*** Others ***/
  127. #define FLOOR_Z        28.050388
  128. #define SHIELD_ORB_Z   39.80 // TODO: Find correct height.
  129.  
  130. enum Phase
  131. {
  132.     PHASE_NOTSTART   = 0, //
  133.     PHASE_DECEIVERS  = 1, // Fight 3 adds
  134.     PHASE_NORMAL     = 2, // Kil'Jaeden emerges from the sunwell
  135.     PHASE_DARKNESS   = 3, // At 85%, he gains few abilities; Kalecgos joins the fight
  136.     PHASE_ARMAGEDDON = 4, // At 55%, he gains even more abilities
  137.     PHASE_SACRIFICE  = 5, // At 25%, Anveena sacrifices herself into the Sunwell; at this point he becomes enraged and has *significally* shorter cooldowns.
  138. };
  139.  
  140. /*
  141. struct Speech
  142. {
  143.     char* text;
  144.     uint32 creature, timer;
  145. };
  146.  
  147. // TODO: Timers
  148. static Speech Sacrifice[]=
  149. {
  150.     {"Anveena, you must awaken, this world needs you!", CREATURE_KALECGOS, 5000},
  151.     {"I serve only the Master now.", CREATURE_ANVEENA, 5000},
  152.     {"You must let go! You must become what you were always meant to be! The time is now, Anveena!", CREATURE_KALECGOS, 8000},
  153.     {"But I'm... lost... I cannot find my way back!", CREATURE_ANVEENA, 5000},
  154.     {"Anveena, I love you! Focus on my voice, come back for me now! Only you can cleanse the Sunwell!", CREATURE_KALECGOS, 7000},
  155.     {"Kalec... Kalec?", CREATURE_ANVEENA, 2000},
  156.     {"Yes, Anveena! Let fate embrace you now!", CREATURE_KALECGOS, 3000},
  157.     {"The nightmare is over, the spell is broken! Goodbye, Kalec, my love!", CREATURE_ANVEENA, 6000},
  158.     {"Goodbye, Anveena, my love. Few will remember your name, yet this day you change the course of destiny. What was once corrupt is now pure. Heroes, do not let her sacrifice be in vain.", CREATURE_KALECGOS, 12000},
  159.     {"Aggghh! The powers of the Sunwell... turned... against me! What have you done? WHAT HAVE YOU DONE?", CREATURE_KILJAEDEN, 8000},
  160.     {"Strike now, heroes, while he is weakened! Vanquish the Deceiver!", CREATURE_KALECGOS, 5000},
  161. };
  162. */
  163. /*
  164. class AllOrbsInGrid
  165. {
  166.     public:
  167.         AllOrbsInGrid() {}
  168.         bool operator() (GameObject* go)
  169.         {
  170.             if(go->GetEntry() == GAMEOBJECT_ORB_OF_THE_BLUE_DRAGONFLIGHT)
  171.                 return true;
  172.  
  173.             return false;
  174.         }
  175. };
  176. */
  177.  
  178. /*######
  179. ## Boss Kalecgos
  180. ######*/
  181. struct MANGOS_DLL_DECL boss_kalecgosAI : public ScriptedAI
  182. {
  183.     boss_kalecgosAI(Creature* c) : ScriptedAI(c)
  184.     {
  185.         for(uint8 i = 0; i < 4; ++i)
  186.             Orb[i] = 0;
  187.  
  188.         FindOrbs();
  189.  
  190.         Reset();
  191.     }
  192.  
  193.     uint64 Orb[4];
  194.  
  195.     uint8 OrbsEmpowered;
  196.  
  197.     uint32 EmpowerTimer;
  198.  
  199.     void Reset()
  200.     {
  201.         EmpowerTimer = 0;
  202.     }
  203.  
  204.     void Aggro(Unit* who) {}
  205.  
  206.     void FindOrbs()
  207.     {
  208.         CellPair pair(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
  209.         Cell cell(pair);
  210.         cell.data.Part.reserved = ALL_DISTRICT;
  211.         cell.SetNoCreate();
  212.  
  213.         std::list<GameObject*> orbList;
  214.  
  215.  
  216.  
  217.  
  218.         CellLock<GridReadGuard> cell_lock(cell, pair);
  219.  
  220.  
  221.         if(orbList.empty())
  222.             return;
  223.  
  224.         uint8 i = 0;
  225.         for(std::list<GameObject*>::iterator itr = orbList.begin(); itr != orbList.end(); ++itr, ++i)
  226.             Orb[i] = (*itr)->GetGUID();
  227.     }
  228.  
  229.     void EmpowerOrb()
  230.     {
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.     }
  240.  
  241.     void UpdateAI(const uint32 diff) { }
  242. };
  243.  
  244.  
  245. /*######
  246. ## Mob Shield Orb
  247. ######*/
  248. struct MANGOS_DLL_DECL mob_shield_orbAI : public ScriptedAI
  249. {
  250.     mob_shield_orbAI(Creature* c) : ScriptedAI(c) {
  251.         pInstance = ((ScriptedInstance*)c->GetInstanceData());
  252.         Reset();
  253.     }
  254.     ScriptedInstance* pInstance;
  255.  
  256.     uint32 ShadowBoltTimer;
  257.     uint32 MovementTimer;
  258.     uint32 steps;
  259.  
  260.     void Reset() {
  261.         ShadowBoltTimer = 1000 + rand()%3000;
  262.         MovementTimer = 1000 + rand()%2000;
  263.         steps = 0;
  264.  
  265.         if (pInstance)
  266.         {
  267.             Map *map = m_creature->GetMap();
  268.             if (map->IsDungeon())
  269.             {
  270.                 Map::PlayerList const &PlayerList = map->GetPlayers();
  271.  
  272.                 if (PlayerList.isEmpty())
  273.                     return;
  274.  
  275.                 for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
  276.                 {
  277.                     if (i->getSource()->isAlive())
  278.                         AttackStart(i->getSource());
  279.                 }
  280.             }
  281.         }
  282.     }
  283.  
  284.     void Aggro(Unit* who) { }
  285.     //void AttackStart(Unit* who) { }
  286.     void MoveInLineOfSight(Unit* who) { }
  287.  
  288.     void UpdateAI(const uint32 diff) {
  289.  
  290.         if(ShadowBoltTimer < diff)
  291.         {
  292.                 for(uint8 i = 0; i < rand()%3; ++i)
  293.                 DoCast(SelectUnit(SELECT_TARGET_RANDOM,0), SPELL_SHADOW_BOLT);
  294.             ShadowBoltTimer = 1000 + rand()%3000;
  295.         }else ShadowBoltTimer -= diff;
  296.  
  297.         if(MovementTimer < diff)
  298.         {
  299.             if (pInstance)
  300.             {
  301.                 if(Creature* pKiljaeden = ((Creature*)Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KILJAEDEN))))
  302.                 {
  303.                     float angle = (M_PI / 10) * steps;
  304.                     float X = pKiljaeden->GetPositionX() + 22 * cos(angle);
  305.                     float Y = pKiljaeden->GetPositionY() + 22 * sin(angle);
  306.  
  307.                     m_creature->GetMotionMaster()->MovePoint(0, X, Y, SHIELD_ORB_Z);
  308.  
  309.                     steps++;
  310.                     if (steps > 19) steps = 0;
  311.                 }
  312.             }
  313.             MovementTimer = 1000;
  314.         }else MovementTimer -= diff;
  315.     }
  316. };
  317.  
  318. /*######
  319. ## Boss Kil'jaeden
  320. ######*/
  321. struct MANGOS_DLL_DECL boss_kiljaedenAI : public Scripted_NoMovementAI
  322. {
  323.     boss_kiljaedenAI(Creature* c) : Scripted_NoMovementAI(c)
  324.     {
  325.         pInstance = ((ScriptedInstance*)c->GetInstanceData());
  326.         Reset();
  327.     }
  328.  
  329.     /* GUIDs */
  330.     uint64 KalecGUID;
  331.  
  332.     /* General */
  333.     ScriptedInstance* pInstance;
  334.     uint32 Phase;
  335.  
  336.     /* Phase 2+ spells */
  337.     uint32 SoulFlayTimer;
  338.     uint32 LegionLightningTimer;
  339.     uint32 FireBloomTimer;
  340.     uint32 SummonShieldOrbTimer;
  341.  
  342.     /* Phase 3+ spells */
  343.     uint32 FlameDartTimer;
  344.     uint32 DarknessTimer;
  345.     uint32 DarknessBombTimer;
  346.     uint32 ShadowSpikeTimer;
  347.     uint32 ShadowSpikeCount;
  348.  
  349.     /* Phase 4+ spells */
  350.     uint32 ArmageddonTimer;
  351.  
  352.     void Reset()
  353.     {
  354.         KalecGUID = 99937;
  355.  
  356.         // TODO: Fix timers
  357.         SoulFlayTimer = 15000;
  358.         LegionLightningTimer = 30000;
  359.         FireBloomTimer = 30000;
  360.         SummonShieldOrbTimer = 45000;
  361.  
  362.         FlameDartTimer = 3000;
  363.         DarknessTimer = 60000;
  364.         DarknessBombTimer = 0;
  365.         ShadowSpikeTimer = 5000;
  366.         ShadowSpikeCount = 30000;
  367.  
  368.         ArmageddonTimer = 10000;
  369.  
  370.         Phase = PHASE_NOTSTART;
  371.     }
  372.  
  373.     void EnterEvadeMode()
  374.     {
  375.         Scripted_NoMovementAI::EnterEvadeMode();
  376.         Phase = PHASE_NOTSTART;
  377.  
  378.         // Reset the controller
  379.         if(pInstance)
  380.         {
  381. //            if(Creature* Control = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_KILJAEDEN_CONTROLLER))))
  382. //                ((Scripted_NoMovementAI*)Control->AI())->Reset();
  383.  
  384.  
  385.         }
  386.     }
  387.  
  388.     void MoveInLineOfSight(Unit* who) {
  389.         if (!m_creature->getVictim() && who->GetTypeId() == TYPEID_PLAYER)
  390.             AttackStart(who);
  391.     }
  392.  
  393.     void Aggro(Unit *who)
  394.     { }
  395. /*
  396.     void AttackStart(Unit* who)
  397.     {
  398.         if (!who)
  399.             return;
  400.  
  401.         if (who == m_creature || who->GetTypeId() != TYPEID_PLAYER)
  402.             return;
  403.  
  404.         if (m_creature->Attack(who, true))
  405.         {
  406.             m_creature->AddThreat(who, 0.0f);
  407.             m_creature->SetInCombatWith(who);
  408.             who->SetInCombatWith(m_creature);
  409.  
  410.             if (!InCombat)
  411.             {
  412.                 InCombat = true;
  413.                 Aggro(who);
  414.             }
  415.         }
  416.     }
  417. */
  418.     void CastSinisterReflection()
  419.     {
  420.         Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
  421.         if (target)
  422.         {
  423.             DoCast(target, SPELL_SINISTER_REFLECTION_CLASS);
  424.             DoCast(target, SPELL_SINISTER_REFLECTION_CLONE);
  425.             DoCast(target, SPELL_SINISTER_REFLECTION_SUMMON);
  426.         }
  427. //        for (uint8 i = 0; i < 4; ++i) // disadvantage is it may be duplicated target
  428. //            DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SINISTER_REFLECTION);
  429.  
  430.         switch(rand()%2)
  431.         {
  432.             case 0: DoScriptText(SAY_KJ_REFLECTION1, m_creature);break;
  433.             case 1: DoScriptText(SAY_KJ_REFLECTION2, m_creature);break;
  434.         }
  435.     } // TODO: Create copies of 5 random raid members.
  436.  
  437.     void UpdateAI(const uint32 diff)
  438.     {
  439.         if(!m_creature->SelectHostilTarget() || !m_creature->getVictim() || Phase < PHASE_NORMAL)
  440.             return;
  441.  
  442.         // *****************************************
  443.         // *********** Phase 2 spells **************
  444.         // *****************************************
  445.  
  446.         // Soul Flay : 9k damage over 3 seconds on highest aggro
  447.         if(SoulFlayTimer < diff)
  448.         {
  449.             DoCast(m_creature->getVictim(), SPELL_SOUL_FLAY_DAMAGE);
  450.             m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_SOUL_FLAY_MOVEMENT, true);
  451.             SoulFlayTimer = 3500;
  452.         }else SoulFlayTimer -= diff;
  453.  
  454.         // Legion Lightning : Lightning on random target, jumps to 3 additional players, burns 1500 mana and deals 3k damage
  455.         if(LegionLightningTimer < diff)
  456.         {
  457.             m_creature->InterruptNonMeleeSpells(true);
  458.             DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_LEGION_LIGHTNING);
  459.             LegionLightningTimer = (Phase == PHASE_SACRIFICE) ? 18000 : 30000; // 18 seconds in PHASE_SACRIFICE
  460.         }else LegionLightningTimer -= diff;
  461.  
  462.         // Fire Bloom : Places a debuff on 5 random targets; targets and all nearby allies suffer ~1.7k fire damage every 2 seconds
  463.         if(FireBloomTimer < diff)
  464.         {
  465.             m_creature->InterruptNonMeleeSpells(true);
  466.             for (uint8 i = 0; i < 5; ++i) // disadvantage is it may be duplicated target
  467.                 DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FIRE_BLOOM);
  468.             FireBloomTimer = (Phase == PHASE_SACRIFICE) ? 25000 : 40000; // 25 seconds in PHASE_SACRIFICE
  469.         }else FireBloomTimer -= diff;
  470.  
  471.         // Summon Shield Orb : Spawns a Shield Orb add and constantly shooting Shadow Bolts at the raid
  472.         if(SummonShieldOrbTimer < diff)
  473.         {
  474.             // northeast of Kil'jaeden
  475.             for(uint8 i = 1; i < Phase; ++i)
  476.                 Creature* SOrb = m_creature->SummonCreature(CREATURE_SHIELD_ORB, 1709.000, 615.000, SHIELD_ORB_Z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
  477.             SummonShieldOrbTimer = (Phase == PHASE_SACRIFICE) ? 30000 : 60000; // 30 seconds in PHASE_SACRIFICE
  478.         }else SummonShieldOrbTimer -= diff;
  479.  
  480.         // *****************************************
  481.         // *********** Phase 3 spells **************
  482.         // *****************************************
  483.         if(Phase == PHASE_NORMAL && ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 85))
  484.         {
  485.             m_creature->InterruptNonMeleeSpells(true);
  486.  
  487.             // Sinister Reflection
  488.             //CastSinisterReflection();
  489.  
  490.             // Shadow Spike
  491.             m_creature->CastSpell(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOW_SPIKE, true);
  492.             //DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOW_SPIKE);
  493.  
  494.             SummonShieldOrbTimer += 30000;
  495.             FireBloomTimer       += 30000; // Don't let other spells
  496.             LegionLightningTimer += 30000; // interrupt Shadow Spikes
  497.             FlameDartTimer       += 30000;
  498.             SoulFlayTimer         = 30000;
  499.             ShadowSpikeCount      = 30000; // shadow spike visual timer
  500.  
  501.             Phase = PHASE_DARKNESS;
  502.         }
  503.         else if(Phase <= PHASE_NORMAL) return;
  504.  
  505.         // Shadow Spike Effect Count
  506.         if (ShadowSpikeCount)
  507.             if(ShadowSpikeTimer < diff)
  508.             {
  509.                 // not working right, it damages Jil'Jaeden himself not player
  510.                 Unit* target (SelectUnit(SELECT_TARGET_RANDOM, 0));
  511.                 if (target)
  512.                 {
  513.                     // workaround
  514.                     DoCast(target, SPELL_SHADOW_SPIKE_VISUAL);
  515.                     target->CastSpell(target, SPELL_SHADOW_SPIKE_EFFECT, true);
  516.                 }
  517.  
  518.                 ShadowSpikeTimer = 5000;
  519.                 ShadowSpikeCount -= ShadowSpikeTimer;
  520.             }else ShadowSpikeTimer -= diff;
  521.  
  522.         // Flame Dart Explosion
  523.         if(FlameDartTimer < diff)
  524.         {
  525.             DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FLAME_DART);
  526.             FlameDartTimer = 3000;
  527.         }else FlameDartTimer -= diff;
  528. /* not working right
  529.         // Darkness of a Thousand Souls : Begins to channel for 8 seconds, then deals 50'000 damage to all raid members.
  530.         if(DarknessTimer < diff)
  531.         {
  532.             m_creature->InterruptNonMeleeSpells(true);
  533.             //DoCast(m_creature, SPELL_DARKNESS_OF_A_THOUSAND_SOULS);
  534.             m_creature->CastSpell(m_creature, SPELL_DARKNESS_OF_A_THOUSAND_SOULS, true);
  535.  
  536.             SummonShieldOrbTimer += 9000; // Don't let other spells
  537.             FireBloomTimer       += 9000; // interrupt Darkness of a Thousand Souls
  538.             LegionLightningTimer += 9000;
  539.             FlameDartTimer       += 9000;
  540.             if(Phase >= PHASE_ARMAGEDDON)
  541.                 ArmageddonTimer  += 9000; // Armageddon on the other hand, can be casted now, if Anveena has already sacrificed
  542.             SoulFlayTimer         = 9000;
  543.             DarknessBombTimer     = 8000; // Darkness of a Thousand Souls effect timer
  544.  
  545.             switch(rand()%3)
  546.             {
  547.                 case 0: DoScriptText(SAY_KJ_DARKNESS1, m_creature);break;
  548.                 case 1: DoScriptText(SAY_KJ_DARKNESS2, m_creature);break;
  549.                 case 2: DoScriptText(SAY_KJ_DARKNESS3, m_creature);break;
  550.             }
  551.  
  552.             DarknessTimer = (Phase == PHASE_SACRIFICE) ? 20000 + rand()%15000 : 40000 + rand()%30000;
  553.         }else DarknessTimer -= diff;
  554.  
  555.         // Darkness of a Thousand Souls Effect
  556.         if (DarknessBombTimer)
  557.             if(DarknessBombTimer < diff)
  558.             {
  559.                 DoCast(m_creature, SPELL_DARKNESS_OF_A_THOUSAND_SOULS_EFFECT);
  560.                 DarknessBombTimer = 0;
  561.             }else DarknessBombTimer -= diff;
  562. */
  563.         // *****************************************
  564.         // *********** Phase 4 spells **************
  565.         // *****************************************
  566.         if(Phase == PHASE_ARMAGEDDON && ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 55))
  567.         {
  568.             m_creature->InterruptNonMeleeSpells(true);
  569.  
  570.             // Sinister Reflection
  571.             //CastSinisterReflection();
  572.  
  573.             // Shadow Spike
  574.             m_creature->CastSpell(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOW_SPIKE, true);
  575.             //DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOW_SPIKE);
  576.  
  577.             SummonShieldOrbTimer += 30000;
  578.             FireBloomTimer       += 30000; // Don't let other spells
  579.             LegionLightningTimer += 30000; // interrupt Shadow Spikes
  580.             FlameDartTimer       += 30000;
  581.             ArmageddonTimer      += 30000;
  582.             SoulFlayTimer         = 30000;
  583.             ShadowSpikeCount      = 30000; // shadow spike visual timer
  584.  
  585.             Phase = PHASE_ARMAGEDDON;
  586.         }
  587.         else if(Phase <= PHASE_ARMAGEDDON) return;
  588.  
  589.         // Armageddon
  590.         if(ArmageddonTimer < diff)
  591.         {
  592.             if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
  593.             {
  594.                 float x, y, z;
  595.                 target->GetPosition(x, y, z);
  596.                 if(Creature* Armageddon = m_creature->SummonCreature(CREATURE_ARMAGEDDON_TARGET, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 5000))
  597.                 {
  598.                     Armageddon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  599.                     DoCast(Armageddon, SPELL_ARMAGEDDON, true);
  600.                     Armageddon->CastSpell(Armageddon, SPELL_ARMAGEDDON_VISUAL, true);
  601.                 }
  602.             }
  603.             ArmageddonTimer = 2000; // No, I'm not kidding
  604.         }else ArmageddonTimer -= diff;
  605.  
  606.  
  607.         // *****************************************
  608.         // *********** Phase 5 spells **************
  609.         // *****************************************
  610.         if(Phase == PHASE_DARKNESS && ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25))
  611.         {
  612.             m_creature->InterruptNonMeleeSpells(true);
  613.  
  614.             // Sinister Reflection
  615.             //CastSinisterReflection();
  616.  
  617.             // Shadow Spike
  618.             DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOW_SPIKE);
  619.  
  620.             SummonShieldOrbTimer += 30000;
  621.             FireBloomTimer       += 30000; // Don't let other spells
  622.             LegionLightningTimer += 30000; // interrupt Shadow Spikes
  623.             FlameDartTimer       += 30000;
  624.             ArmageddonTimer      += 30000;
  625.             SoulFlayTimer         = 30000;
  626.  
  627.             Phase = PHASE_SACRIFICE;
  628.         }
  629.         else if(Phase <= PHASE_DARKNESS) return;
  630.     }
  631.  
  632.     void KilledUnit(Unit *victim)
  633.     {
  634.         if (victim == m_creature)
  635.             return;
  636.  
  637.         switch(rand()%2)
  638.         {
  639.             case 0: DoScriptText(SAY_KJ_SLAY1, m_creature);break;
  640.             case 1: DoScriptText(SAY_KJ_SLAY2, m_creature);break;
  641.         }
  642.     }
  643.  
  644.     void JustDied(Unit* killer)  
  645.         {
  646.  
  647.  
  648.         }
  649. };
  650.  
  651. /*######
  652. ## Mob Kil'jaeden Controller , controls most of the event
  653. ######*/
  654. struct MANGOS_DLL_DECL mob_kiljaeden_controllerAI : public Scripted_NoMovementAI
  655. {
  656.     mob_kiljaeden_controllerAI(Creature* c) : Scripted_NoMovementAI(c)
  657.     {
  658.         pInstance = ((ScriptedInstance*)c->GetInstanceData());
  659.         Reset();
  660.     }
  661.  
  662.     ScriptedInstance* pInstance;
  663.     std::list<uint64> HandDeceivers;
  664.  
  665.     uint32 Phase;
  666.     uint32 event_timer;
  667.     uint32 AnveenaSpeech_timer;
  668.     uint32 AnveenaSpeechCounter;
  669.     bool DevicerChanneling;
  670.     bool AnveenaSpellCheck;
  671.  
  672.     Creature* KalecgosAnveena;
  673.  
  674.     void Reset()
  675.     {
  676.         Phase = PHASE_NOTSTART;
  677.         event_timer = 1000;
  678.         DevicerChanneling = false;
  679.         AnveenaSpellCheck = false;
  680.         AnveenaSpeech_timer = 0;
  681.         AnveenaSpeechCounter = 0;
  682.         KalecgosAnveena = NULL;
  683.  
  684.         m_creature->SetVisibility(VISIBILITY_ON);
  685.         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  686.  
  687.  
  688.  
  689.     }
  690.  
  691.     void Aggro(Unit* who) {}
  692.  
  693.     void UpdateAI(const uint32 diff)
  694.     {
  695.         if(event_timer < diff)
  696.         {
  697.             if (Phase == PHASE_NOTSTART)
  698.             {
  699.                 Creature* DeciverGUID[2];
  700.                 Unit* target = NULL;
  701.                 uint32 DeciverCount = 0;
  702.  
  703.                 for(uint8 i = 0; i < 3; ++i)
  704.                     DeciverGUID[i] = NULL;
  705.  
  706.                 FindHandDeceivers();
  707.                 for(std::list<uint64>::iterator itr = HandDeceivers.begin(); itr != HandDeceivers.end(); ++itr)
  708.                 {
  709.                     if (Creature* pCreature = ((Creature*)Unit::GetUnit(*m_creature, *itr)))
  710.                     {
  711.                         // alive & no target
  712.                         if (pCreature->isAlive() && !pCreature->getVictim())
  713.                         {
  714.                             if (DeciverCount < 3)
  715.                                 DeciverGUID[DeciverCount] = pCreature;
  716.                             DeciverCount++;
  717.                         }
  718.                         // alive & has target
  719.                         else if (pCreature->isAlive() && pCreature->getVictim())
  720.                             target = pCreature->getVictim();
  721.                         // dead, respawn
  722.                         else if (pCreature->isDead())
  723.                         {
  724.                             pCreature->RemoveCorpse();
  725.                             pCreature->Respawn();
  726.                             if (DeciverCount < 3)
  727.                                 DeciverGUID[DeciverCount] = pCreature;
  728.                             DeciverCount++;
  729.                         }
  730.                     }
  731.                 }
  732.  
  733.                 // aggro, link to others
  734.                 if (target)
  735.                 {
  736.                     for(uint8 i = 0; i < 2; ++i)
  737.                     if (DeciverGUID[i])
  738.                     {
  739.                         //((Creature*)DeciverGUID[i])->AddThreat(target, 0.0f);
  740.                         ((Creature*)DeciverGUID[i])->AI()->AttackStart(target);
  741.                     }
  742.                     if (pInstance)
  743.                         if (Creature* pAnveena = ((Creature*)Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_ANVEENA))))
  744.                             pAnveena->Relocate(1698.45, 628.03, 88.1989);
  745.                             //pAnveena->GetMotionMaster()->MovePoint(0, 1698.45, 628.03, 88.1989);
  746.  
  747.                     Phase = PHASE_DECEIVERS;
  748.                 }
  749.                 // no aggro, do channeling
  750.                 else if (!target && !DevicerChanneling)
  751.                 {
  752.                     for(uint8 i = 0; i < 3; ++i)
  753.                         if (DeciverGUID[i])
  754.                             DeciverGUID[i]->CastSpell(DeciverGUID[i], SPELL_SHADOW_CHANNELING, false);
  755.                     DevicerChanneling = true;
  756.                 }
  757.             }
  758.  
  759.             if (Phase == PHASE_DECEIVERS)
  760.             {
  761.                 bool DeciverDead;
  762.                 bool DecivernoVictim;
  763.                 FindHandDeceivers();
  764.                 for(std::list<uint64>::iterator itr = HandDeceivers.begin(); itr != HandDeceivers.end(); ++itr)
  765.                 {
  766.                     if (Creature* pCreature = ((Creature*)Unit::GetUnit(*m_creature, *itr)))
  767.                     {
  768.                         // if any is alive
  769.                         if (pCreature->isAlive())
  770.                         {
  771.                                 DeciverDead = true;
  772.  
  773.                                 // no target
  774.                             if (!pCreature->getVictim())
  775.                             {
  776.                                 Phase = PHASE_NOTSTART;
  777.                                 Reset();
  778.                                 return;
  779.                             }
  780.                         }
  781.                     }
  782.                 }
  783.  
  784.                 // if all dead, KILJAEDEN
  785.                 if (!DeciverDead)
  786.                 {
  787.                     m_creature->RemoveAurasDueToSpell(SPELL_ANVEENA_ENERGY_DRAIN);
  788.                     Phase = PHASE_NORMAL;
  789.                     AnveenaSpeech_timer = 25000; // first speech after 25 secs
  790.  
  791.                     if(Creature* KJ = DoSpawnCreature(CREATURE_KILJAEDEN, 0, 0,0, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000))
  792.                     {
  793.                         KJ->CastSpell(KJ, SPELL_REBIRTH, false);
  794.                         //KJ->AddThreat(m_creature->getVictim(), 1.0f);
  795.                         //((boss_kiljaedenAI*)KJ->AI())->AttackStart(m_creature->getVictim());
  796.                         DoScriptText(SAY_KJ_EMERGE, KJ);
  797.                         ((boss_kiljaedenAI*)KJ->AI())->Phase = PHASE_NORMAL;
  798.  
  799.  
  800.                     }
  801.                 }
  802.             }
  803.  
  804.             if (Phase >= PHASE_NORMAL)
  805.             {
  806.                 if(Creature* pKiljaeden = ((Creature*)Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KILJAEDEN))))
  807.                 {
  808.  
  809.  
  810.                        
  811.                             Phase = PHASE_NOTSTART;
  812.                             Reset();
  813.                             return;
  814.                        
  815.                 }
  816.             }
  817.  
  818.             // Anveena and Kil'jaeden spawn check
  819.             if (pInstance)
  820.             {
  821.                 Creature* pKiljaeden = ((Creature*)Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KILJAEDEN)));
  822.                 Creature* pAnveena = ((Creature*)Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_ANVEENA)));
  823.  
  824.  
  825.                
  826.                     pKiljaeden->setDeathState(JUST_DIED);
  827.                     pKiljaeden->RemoveCorpse();
  828.                
  829.  
  830.                     if((pKiljaeden->GetHealth()*100 / pKiljaeden->GetMaxHealth()) < 24 && Phase < PHASE_SACRIFICE)
  831.                     {
  832.                         Phase = PHASE_SACRIFICE;
  833.                         AnveenaSpeechCounter = 0;
  834.                         AnveenaSpeech_timer = 1000;
  835.                     }
  836.                     else if((pKiljaeden->GetHealth()*100 / pKiljaeden->GetMaxHealth()) < 54 && Phase < PHASE_ARMAGEDDON)
  837.                     {
  838.                         Phase = PHASE_ARMAGEDDON;
  839.                         AnveenaSpeechCounter = 0;
  840.                         AnveenaSpeech_timer = 1000;
  841.                     }
  842.                     else if((pKiljaeden->GetHealth()*100 / pKiljaeden->GetMaxHealth()) < 84 && Phase < PHASE_DARKNESS)
  843.                     {
  844.                         Phase = PHASE_DARKNESS;
  845.                         AnveenaSpeechCounter = 0;
  846.                         AnveenaSpeech_timer = 1000;
  847.                     }
  848.                
  849. /*
  850.                 if (Phase == PHASE_NOTSTART)
  851.                 {
  852.                     Creature* pKiljaeden = ((Creature*)Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KILJAEDEN)));
  853.                     if (pKiljaeden && pKiljaeden->isAlive()
  854.                         && pInstance && pInstance->GetData(DATA_KILJAEDEN_EVENT) == NOT_STARTED)
  855.                     {
  856.                         pKiljaeden->setDeathState(JUST_DIED);
  857.                         pKiljaeden->RemoveCorpse();
  858.                     }
  859.                 }
  860. */
  861.  
  862.                 // Phase 2 speech
  863.                 if (Phase == PHASE_NORMAL && AnveenaSpeech_timer)
  864.                 {
  865.                     if(AnveenaSpeech_timer < diff)
  866.                     {
  867.                         if (!KalecgosAnveena)
  868.                         {
  869.                             KalecgosAnveena = m_creature->SummonCreature(CREATURE_KALECGOS, 1685.79, 594.08, 120.20, 0.87, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000);
  870.                             KalecgosAnveena->GetMotionMaster()->MovePoint(0, 1705.87, 653.42, 120.20);
  871.                         }
  872.  
  873.                         if (KalecgosAnveena)
  874.                             DoScriptText(SAY_KALECGOS_INTRO, KalecgosAnveena);
  875.  
  876.                         KalecgosAnveena = NULL;
  877.                         AnveenaSpeech_timer = 0;
  878.                     }else AnveenaSpeech_timer -= diff;
  879.                 }
  880.                 // Phase 3 speech
  881.                 else if (Phase == PHASE_DARKNESS && AnveenaSpeech_timer)
  882.                 {
  883.                     if(AnveenaSpeech_timer < diff)
  884.                     {
  885.                         if (!KalecgosAnveena)
  886.                         {
  887.                             KalecgosAnveena = m_creature->SummonCreature(CREATURE_KALECGOS, 1685.79, 594.08, 120.20, 0.87, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000);
  888.                             KalecgosAnveena->GetMotionMaster()->MovePoint(0, 1705.87, 653.42, 120.20);
  889.                         }
  890.  
  891.                         switch(AnveenaSpeechCounter)
  892.                         {
  893.                             case 0:
  894.                                     if (KalecgosAnveena)
  895.                                         DoScriptText(SAY_KALECGOS_AWAKEN, KalecgosAnveena);
  896.                                         AnveenaSpeech_timer = 5000;
  897.                                     break;
  898.                             case 1:
  899.                                     if (pAnveena)
  900.                                         DoScriptText(SAY_ANVEENA_IMPRISONED, pAnveena);
  901.                                         AnveenaSpeech_timer = 5000;
  902.                                     break;
  903.                             case 2:
  904.                                     if (pKiljaeden)
  905.                                         DoScriptText(SAY_KJ_DENINE, pKiljaeden);
  906.                                         AnveenaSpeech_timer = 0;
  907.                                         KalecgosAnveena = NULL;
  908.                                     break;
  909.                         }
  910.                         AnveenaSpeechCounter++;
  911.                     }else AnveenaSpeech_timer -= diff;
  912.                 }
  913.                 // Phase 4 speech
  914.                 else if (Phase == PHASE_ARMAGEDDON && AnveenaSpeech_timer)
  915.                 {
  916.                     if(AnveenaSpeech_timer < diff)
  917.                     {
  918.                         if (!KalecgosAnveena)
  919.                         {
  920.                             KalecgosAnveena = m_creature->SummonCreature(CREATURE_KALECGOS, 1685.79, 594.08, 120.20, 0.87, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000);
  921.                             KalecgosAnveena->GetMotionMaster()->MovePoint(0, 1705.87, 653.42, 120.20);
  922.                         }
  923.  
  924.                         switch(AnveenaSpeechCounter)
  925.                         {
  926.                             case 0:
  927.                                     if (KalecgosAnveena)
  928.                                         DoScriptText(SAY_KALECGOS_LETGO, KalecgosAnveena);
  929.                                         AnveenaSpeech_timer = 7000;
  930.                                     break;
  931.                             case 1:
  932.                                     if (pAnveena)
  933.                                         DoScriptText(SAY_ANVEENA_LOST, pAnveena);
  934.                                         AnveenaSpeech_timer = 5000;
  935.                                     break;
  936.                             case 2:
  937.                                     if (pKiljaeden)
  938.                                         DoScriptText(SAY_KJ_CANNOT_WIN, pKiljaeden);
  939.                                         AnveenaSpeech_timer = 0;
  940.                                         KalecgosAnveena = NULL;
  941.                                     break;
  942.                         }
  943.                         AnveenaSpeechCounter++;
  944.                     }else AnveenaSpeech_timer -= diff;
  945.                 }
  946.                 // Phase 5 speech
  947.                 else if (Phase == PHASE_SACRIFICE && AnveenaSpeech_timer)
  948.                 {
  949.                     if(AnveenaSpeech_timer < diff)
  950.                     {
  951.                         if (!KalecgosAnveena)
  952.                         {
  953.                             KalecgosAnveena = m_creature->SummonCreature(CREATURE_KALECGOS, 1685.79, 594.08, 120.20, 0.87, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
  954.                             KalecgosAnveena->GetMotionMaster()->MovePoint(0, 1705.87, 653.42, 120.20);
  955.                         }
  956.  
  957.                         switch(AnveenaSpeechCounter)
  958.                         {
  959.                             case 0:
  960.                                 if (KalecgosAnveena)
  961.                                     DoScriptText(SAY_KALECGOS_FOCUS, KalecgosAnveena);
  962.                                 AnveenaSpeech_timer = 10000;
  963.                                 break;
  964.                             case 1:
  965.                                 if (pAnveena)
  966.                                     DoScriptText(SAY_ANVEENA_KALEC, pAnveena);
  967.                                 AnveenaSpeech_timer = 3000;
  968.                                 break;
  969.                             case 2:
  970.                                 if (KalecgosAnveena)
  971.                                     DoScriptText(SAY_KALECGOS_FATE, KalecgosAnveena);
  972.                                 AnveenaSpeech_timer = 7000;
  973.                                 break;
  974.                             case 3:
  975.                                 if (pAnveena)
  976.                                     DoScriptText(SAY_ANVEENA_GOODBYE, pAnveena);
  977.                                 AnveenaSpeech_timer = 6000;
  978.                                 break;
  979.                             case 4:
  980.                                 if (pKiljaeden && pKiljaeden->isAlive() && pAnveena && pAnveena->isAlive())
  981.                                 {
  982.                                     pAnveena->CastSpell(pKiljaeden, SPELL_SACRIFICE_OF_ANVEENA, true);
  983.                                     pAnveena->setDeathState(JUST_DIED);
  984.                                     pAnveena->RemoveCorpse();
  985.                                     DoScriptText(SAY_KJ_LOST_POWER, pKiljaeden);
  986.                                 }
  987.                                 AnveenaSpeech_timer = 13000;
  988.                                 break;
  989.                             case 5:
  990.                                 if (KalecgosAnveena)
  991.                                     DoScriptText(SAY_KALECGOS_GOODBYE, KalecgosAnveena);
  992.                                 AnveenaSpeech_timer = 14000;
  993.                                 break;
  994.                             case 6:
  995.                                 if (KalecgosAnveena)
  996.                                     DoScriptText(SAY_KALECGOS_ENCOURAGE, KalecgosAnveena);
  997.                                 AnveenaSpeech_timer = 0;
  998.                                 KalecgosAnveena = NULL;
  999.                                 break;
  1000.                         }
  1001.                         AnveenaSpeechCounter++;
  1002.                     }else AnveenaSpeech_timer -= diff;
  1003.                 }
  1004.  
  1005.                 // respawn check
  1006.                 if (Phase != PHASE_SACRIFICE)
  1007.                 {
  1008.                     if (pAnveena && !pAnveena->isAlive())
  1009.                         pAnveena->Respawn();
  1010.  
  1011.                     if (pAnveena && pAnveena->isAlive() && AnveenaSpellCheck == false)
  1012.                     {
  1013.                         DoCast(m_creature, SPELL_ANVEENA_ENERGY_DRAIN);
  1014.                         pAnveena->SetVisibility(VISIBILITY_ON);
  1015.  
  1016.                         pAnveena->CastSpell(pAnveena, SPELL_ANVEENA_PRISON, true);
  1017.                         //pAnveena->GetMotionMaster()->MovePoint(0, 1698.45, 628.03, 88.1989);
  1018.                         pAnveena->Relocate(1698.45, 628.03, 88.1989);
  1019.                         AnveenaSpellCheck = true;
  1020.                     }
  1021.                 }
  1022.             }
  1023.         }else event_timer -=diff;
  1024.     }
  1025.  
  1026.     void FindHandDeceivers()
  1027.     {
  1028.         CellPair pair(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
  1029.         Cell cell(pair);
  1030.         cell.data.Part.reserved = ALL_DISTRICT;
  1031.         cell.SetNoCreate();
  1032.  
  1033.         std::list<Creature*> DeceiverList;
  1034.  
  1035.         AllCreaturesOfEntryInRange check(m_creature, CREATURE_HAND_OF_THE_DECEIVER, 50);
  1036.         MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange> searcher(m_creature, DeceiverList, check);
  1037.         TypeContainerVisitor<MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange>, GridTypeMapContainer> visitor(searcher);
  1038.  
  1039.         CellLock<GridReadGuard> cell_lock(cell, pair);
  1040.         cell_lock->Visit(cell_lock, visitor, *(m_creature->GetMap()));
  1041.  
  1042.         if (!DeceiverList.empty())
  1043.         {
  1044.             HandDeceivers.clear();
  1045.             for(std::list<Creature*>::iterator itr = DeceiverList.begin(); itr != DeceiverList.end(); ++itr)
  1046.                 HandDeceivers.push_back((*itr)->GetGUID());
  1047.         }
  1048.     }
  1049. };
  1050.  
  1051. /*######
  1052. ## Mob Hand of the Deceiver
  1053. ######*/
  1054. struct MANGOS_DLL_DECL mob_hand_of_the_deceiverAI : public ScriptedAI
  1055. {
  1056.     mob_hand_of_the_deceiverAI(Creature* c) : ScriptedAI(c)
  1057.     {
  1058.         pInstance = ((ScriptedInstance*)c->GetInstanceData());
  1059.         Reset();
  1060.     }
  1061.  
  1062.     ScriptedInstance* pInstance;
  1063.  
  1064.     uint32 ShadowBoltVolleyTimer;
  1065.     uint32 FelfirePortalTimer;
  1066.  
  1067.     void Reset()
  1068.     {
  1069.         // TODO: Timers!
  1070.         ShadowBoltVolleyTimer = 8000 + rand()%6000; // So they don't all cast it in the same moment.
  1071.         FelfirePortalTimer = 20000;
  1072.  
  1073.         m_creature->CastSpell(m_creature, SPELL_SHADOW_CHANNELING, false);
  1074.     }
  1075.  
  1076.     void Aggro(Unit *who)
  1077.     { }
  1078.  
  1079.     void AttackStart(Unit* who)
  1080.     {
  1081.         if (!who)
  1082.             return;
  1083.  
  1084.         if (who == m_creature || who->GetTypeId() != TYPEID_PLAYER)
  1085.             return;
  1086.  
  1087.         if (m_creature->Attack(who, true))
  1088.         {
  1089.             m_creature->AddThreat(who, 0.0f);
  1090.             m_creature->SetInCombatWith(who);
  1091.             who->SetInCombatWith(m_creature);
  1092.             m_creature->InterruptNonMeleeSpells(true);
  1093.  
  1094.  
  1095.                 Aggro(who);
  1096.            
  1097.  
  1098.             DoStartMovement(who);
  1099.         }
  1100.     }
  1101.  
  1102.     void JustDied(Unit* killer) { }
  1103.  
  1104.     void UpdateAI(const uint32 diff)
  1105.     {
  1106.         if(!m_creature->getVictim() || !m_creature->SelectHostilTarget())
  1107.             return;
  1108.  
  1109.         // Gain Shadow Infusion at 20% health
  1110.         if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 20) && !m_creature->HasAura(SPELL_SHADOW_INFUSION, 0))
  1111.             DoCast(m_creature, SPELL_SHADOW_INFUSION, true);
  1112.  
  1113.         // Shadow Bolt Volley - Shoots Shadow Bolts at all enemies within 30 yards, for ~2k Shadow damage.
  1114.         if(ShadowBoltVolleyTimer < diff)
  1115.         {
  1116.             DoCast(m_creature->getVictim(), SPELL_SHADOW_BOLT_VOLLEY);
  1117.             ShadowBoltVolleyTimer = 12000;
  1118.         }else ShadowBoltVolleyTimer -= diff;
  1119.  
  1120.         // Felfire Portal - Creatres a portal, that spawns Volatile Felfire Fiends, which do suicide bombing.
  1121.         if(FelfirePortalTimer < diff)
  1122.         {
  1123.             if(Creature* Portal = DoSpawnCreature(CREATURE_FELFIRE_PORTAL, 0, 0,0, 0, TEMPSUMMON_TIMED_DESPAWN, 20000))
  1124.             {
  1125.                 // why don't use m_creature->getVictim() ???
  1126.                 std::list<HostilReference*>::iterator itr;
  1127.                 for(itr = m_creature->getThreatManager().getThreatList().begin(); itr != m_creature->getThreatManager().getThreatList().end(); ++itr)
  1128.                 {
  1129.                     Unit* pUnit = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
  1130.                     if(pUnit)
  1131.                         Portal->AddThreat(pUnit, 1.0f);
  1132.                 }
  1133.             }
  1134.             FelfirePortalTimer = 20000;
  1135.         }else FelfirePortalTimer -= diff;
  1136.  
  1137.         DoMeleeAttackIfReady();
  1138.     }
  1139. };
  1140.  
  1141. /*######
  1142. ## Mob Felfire Portal
  1143. ######*/
  1144. struct MANGOS_DLL_DECL mob_felfire_portalAI : public Scripted_NoMovementAI
  1145. {
  1146.     mob_felfire_portalAI(Creature* c) : Scripted_NoMovementAI(c)
  1147.     {
  1148.         Reset();
  1149.     }
  1150.  
  1151.     uint32 SpawnFiendTimer;
  1152.  
  1153.     void Reset() { SpawnFiendTimer = 5000; }
  1154.  
  1155.     void Aggro(Unit* who) {}
  1156.  
  1157.     void UpdateAI(const uint32 diff)
  1158.     {
  1159.         if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) return;
  1160.  
  1161.         if(SpawnFiendTimer < diff)
  1162.         {
  1163.             Creature* Fiend = DoSpawnCreature(CREATURE_VOLATILE_FELFIRE_FIEND, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 20000);
  1164.             if(Fiend)
  1165.                 Fiend->AddThreat(SelectUnit(SELECT_TARGET_RANDOM,0), 100000.0f);
  1166.             SpawnFiendTimer = 4000 + rand()%4000;
  1167.         }else SpawnFiendTimer -= diff;
  1168.     }
  1169. };
  1170.  
  1171. /*######
  1172. ## Mob Volatile Felfire Fiend
  1173. ######*/
  1174. struct MANGOS_DLL_DECL mob_volatile_felfire_fiendAI : public ScriptedAI
  1175. {
  1176.     mob_volatile_felfire_fiendAI(Creature* c) : ScriptedAI(c) { Reset(); }
  1177.  
  1178.     uint32 ExplodeTimer;
  1179.     bool LockedTarget;
  1180.  
  1181.     void Reset()
  1182.     {
  1183.         ExplodeTimer = 2000;
  1184.     }
  1185.  
  1186.     void Aggro(Unit* who) {
  1187.         m_creature->AddThreat(who, 10000000.0f);
  1188.     }
  1189.  
  1190.     void DamageTaken(Unit *done_by, uint32 &damage)
  1191.     {
  1192.         if(damage > m_creature->GetHealth())
  1193.             DoCast(m_creature, SPELL_FELFIRE_FISSION, true);
  1194.     }
  1195.  
  1196.     void UpdateAI(const uint32 diff)
  1197.     {
  1198.         if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) return;
  1199.  
  1200.         if(ExplodeTimer) // Just so it doesn't explode as soon as it spawn
  1201.         {
  1202.             if(ExplodeTimer < diff) ExplodeTimer = 0;
  1203.             else ExplodeTimer -= diff;
  1204.         }
  1205.         else if(m_creature->IsWithinDistInMap(m_creature->getVictim(), 3)) // Explode if it's close enough to it's target
  1206.         {
  1207.             DoCast(m_creature->getVictim(), SPELL_FELFIRE_FISSION);
  1208.             m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
  1209.         }
  1210.     }
  1211. };
  1212.  
  1213. CreatureAI* GetAI_boss_kiljaeden(Creature *_Creature)
  1214. {
  1215.     return new boss_kiljaedenAI (_Creature);
  1216. }
  1217.  
  1218. CreatureAI* GetAI_mob_kiljaeden_controller(Creature *_Creature)
  1219. {
  1220.     return new mob_kiljaeden_controllerAI (_Creature);
  1221. }
  1222.  
  1223. CreatureAI* GetAI_mob_hand_of_the_deceiver(Creature *_Creature)
  1224. {
  1225.     return new mob_hand_of_the_deceiverAI (_Creature);
  1226. }
  1227.  
  1228. CreatureAI* GetAI_mob_felfire_portal(Creature *_Creature)
  1229. {
  1230.     return new mob_felfire_portalAI (_Creature);
  1231. }
  1232.  
  1233. CreatureAI* GetAI_mob_volatile_felfire_fiend(Creature *_Creature)
  1234. {
  1235.     return new mob_volatile_felfire_fiendAI (_Creature);
  1236. }
  1237.  
  1238. CreatureAI* GetAI_mob_shield_orb(Creature *_Creature)
  1239. {
  1240.     return new mob_shield_orbAI (_Creature);
  1241. }
  1242.  
  1243. void AddSC_boss_Kiljaeden()
  1244. {
  1245.     Script *newscript;
  1246.  
  1247.     newscript = new Script;
  1248.     newscript->Name = "boss_kiljaeden";
  1249.     newscript->GetAI = &GetAI_boss_kiljaeden;
  1250.     newscript->RegisterSelf();
  1251.  
  1252.     newscript = new Script;
  1253.     newscript->Name = "mob_kiljaeden_controller";
  1254.     newscript->GetAI = &GetAI_mob_kiljaeden_controller;
  1255.     newscript->RegisterSelf();
  1256.  
  1257.     newscript = new Script;
  1258.     newscript->Name = "mob_hand_of_the_deceiver";
  1259.     newscript->GetAI = &GetAI_mob_hand_of_the_deceiver;
  1260.     newscript->RegisterSelf();
  1261.  
  1262.     newscript = new Script;
  1263.     newscript->Name = "mob_felfire_portal";
  1264.     newscript->GetAI = &GetAI_mob_felfire_portal;
  1265.     newscript->RegisterSelf();
  1266.  
  1267.     newscript = new Script;
  1268.     newscript->Name = "mob_volatile_felfire_fiend";
  1269.     newscript->GetAI = &GetAI_mob_volatile_felfire_fiend;
  1270.     newscript->RegisterSelf();
  1271.  
  1272.     newscript = new Script;
  1273.     newscript->Name = "mob_shield_orb";
  1274.     newscript->GetAI = &GetAI_mob_shield_orb;
  1275.     newscript->RegisterSelf();
  1276. };