Index: /trunk/src/game/SpellEffects.cpp
===================================================================
--- /trunk/src/game/SpellEffects.cpp (revision 56)
+++ /trunk/src/game/SpellEffects.cpp (revision 57)
@@ -4666,13 +4666,4 @@
         }
 
-        // Dreaming Glory
-        case 28698:
-        {
-            if(!unitTarget)
-                return;
-            unitTarget->CastSpell(unitTarget, 28694, true);
-            break;
-        }
-
         // Netherbloom
         case 28702:
@@ -4747,20 +4738,4 @@
                 }
             }
-            break;
-        }
-        case 41126:                                         // Flame Crash
-        {
-            if(!unitTarget)
-                return;
-
-           unitTarget->CastSpell(unitTarget, 41131, true);
-           break;
-        }
-        case 44876:                                         // Force Cast - Portal Effect: Sunwell Isle
-        {
-            if(!unitTarget)
-                return;
-
-            unitTarget->CastSpell(unitTarget, 44870, true);
             break;
         }
@@ -4791,12 +4766,30 @@
             break;
         }
+
+    }
+
+    if(!unitTarget || !unitTarget->isAlive()) // can we remove this check?
+    {
+        sLog.outError("Spell %u in EffectScriptEffect does not have unitTarget", m_spellInfo->Id);
+        return;
+    }
+
+    switch(m_spellInfo->Id)
+    {
+        // Dreaming Glory
+        case 28698: unitTarget->CastSpell(unitTarget, 28694, true); break;
+        // Needle Spine
+        case 39835: unitTarget->CastSpell(unitTarget, 39968, true); break;
+        // Draw Soul
+        case 40904: unitTarget->CastSpell(m_caster, 40903, true); break;
+        // Flame Crash
+        case 41126: unitTarget->CastSpell(unitTarget, 41131, true); break;
+        // Force Cast - Portal Effect: Sunwell Isle
+        case 44876: unitTarget->CastSpell(unitTarget, 44870, true); break;
         //5,000 Gold
         case 46642:
         {
-            if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
-                return;
-
-            ((Player*)unitTarget)->ModifyMoney(50000000);
-
+            if(unitTarget->GetTypeId() == TYPEID_PLAYER)
+                ((Player*)unitTarget)->ModifyMoney(50000000);
             break;
         }
@@ -4810,6 +4803,4 @@
             case 0x800000:
             {
-                if(!unitTarget || !unitTarget->isAlive())
-                    return;
                 uint32 spellId2 = 0;
 
@@ -4862,7 +4853,4 @@
 
     // normal DB scripted effect
-    if(!unitTarget)
-        return;
-
     sLog.outDebug("Spell ScriptStart spellid %u in EffectScriptEffect ", m_spellInfo->Id);
     sWorld.ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget);
Index: /trunk/src/game/SpellAuras.cpp
===================================================================
--- /trunk/src/game/SpellAuras.cpp (revision 44)
+++ /trunk/src/game/SpellAuras.cpp (revision 57)
@@ -1651,6 +1651,19 @@
 //                    // Prismatic Shield
 //                    case 40879: break;
-//                    // Aura of Desire
-//                    case 41350: break;
+                    // Aura of Desire
+                    case 41350:
+                    {
+                        Unit::AuraList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT);
+                        for(Unit::AuraList::const_iterator i = mMod.begin(); i != mMod.end(); ++i)
+                        {
+                            if ((*i)->GetId() == 41350)
+                            {
+                                (*i)->ApplyModifier(false);
+                                (*i)->GetModifier()->m_amount -= 5;
+                                (*i)->ApplyModifier(true);
+                                break;
+                            }
+                        }                        
+                    }break;
 //                    // Dementia
 //                    case 41404: break;
@@ -5615,4 +5628,19 @@
                         break;
                     }
+                    case 41337:// aura of anger
+                    {                        
+                        Unit::AuraList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+                        for(Unit::AuraList::const_iterator i = mMod.begin(); i != mMod.end(); ++i)
+                        {
+                            if ((*i)->GetId() == 41337)
+                            {
+                                (*i)->ApplyModifier(false);
+                                (*i)->GetModifier()->m_amount += 5;
+                                (*i)->ApplyModifier(true);
+                                break;
+                            }
+                        }                        
+                        m_modifier.m_amount += 100;
+                    }break;
                     default:
                         break;
Index: /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp (revision 48)
+++ /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp (revision 57)
@@ -18,5 +18,5 @@
 SDName: boss_illidan_stormrage
 SD%Complete: 90
-SDComment:
+SDComment: Somewhat of a workaround for Parasitic Shadowfiend, unable to summon GOs for Cage Trap.
 SDCategory: Black Temple
 EndScriptData */
@@ -24,9 +24,13 @@
 #include "precompiled.h"
 #include "def_black_temple.h"
-#include "WorldPacket.h"
+
+#define GETGO(obj, guid)      GameObject* obj = GameObject::GetGameObject(*m_creature, guid)
+#define GETUNIT(unit, guid)   Unit* unit = Unit::GetUnit(*m_creature, guid)
+#define GETCRE(cre, guid)     Creature* cre = (Creature*)Unit::GetUnit(*m_creature, guid)
+#define HPPCT(unit)           unit->GetHealth()*100 / unit->GetMaxHealth()
 
 /************* Quotes and Sounds ***********************/
 // Gossip for when a player clicks Akama
-#define GOSSIP_ITEM          "We are ready to face Illidan"
+#define GOSSIP_ITEM           "We are ready to face Illidan"
 
 // Yells for/by Akama
@@ -64,60 +68,71 @@
 /************** Spells *************/
 // Normal Form
-#define SPELL_SHEAR                     41032               // Reduces Max. Health by 60% for 7 seconds. Can stack 19 times. 1.5 second cast
-#define SPELL_FLAME_CRASH               40832               // Summons an invis/unselect passive mob that has an aura of flame in a circle around him.
-#define SPELL_DRAW_SOUL                 40904               // 5k Shadow Damage in front of him. Heals Illidan for 100k health (script effect)
-#define SPELL_PARASITIC_SHADOWFIEND     41917               // DoT of 3k Shadow every 2 seconds. Lasts 10 seconds. (Script effect: Summon 2 parasites once the debuff has ticked off)
-#define SPELL_SUMMON_PARASITICS         41915               // Summons 2 Parasitic Shadowfiends on the target. It's supposed to be cast as soon as the Parasitic Shadowfiend debuff is gone, but the spells aren't linked :(
-#define SPELL_AGONIZING_FLAMES          40932               // 4k fire damage initial to target and anyone w/i 5 yards. PHASE 3 ONLY
-#define SPELL_ENRAGE                    40683               // Increases damage by 50% and attack speed by 30%. 20 seconds, PHASE 5 ONLY
+#define SPELL_SHEAR                     37335 // 41032 is bugged, cannot be block/dodge/parry// Reduces Max. Health by 60% for 7 seconds. Can stack 19 times. 1.5 second cast
+#define SPELL_FLAME_CRASH               40832 // Summons an invis/unselect passive mob that has an aura of flame in a circle around him.
+#define SPELL_DRAW_SOUL                 40904 // 5k Shadow Damage in front of him. Heals Illidan for 100k health (script effect)
+#define SPELL_PARASITIC_SHADOWFIEND     41917 // DoT of 3k Shadow every 2 seconds. Lasts 10 seconds. (Script effect: Summon 2 parasites once the debuff has ticked off)
+#define SPELL_SUMMON_PARASITICS         41915 // Summons 2 Parasitic Shadowfiends on the target. It's supposed to be cast as soon as the Parasitic Shadowfiend debuff is gone, but the spells aren't linked :(
+#define SPELL_AGONIZING_FLAMES          40932 // 4k fire damage initial to target and anyone w/i 5 yards. PHASE 3 ONLY
+#define SPELL_ENRAGE                    40683 // Increases damage by 50% and attack speed by 30%. 20 seconds, PHASE 5 ONLY
 // Flying (Phase 2)
-#define SPELL_THROW_GLAIVE              39635               // Throws a glaive on the ground
-#define SPELL_THROW_GLAIVE2             39849               // Animation for the above spell
-#define SPELL_GLAIVE_RETURNS            39873               // Glaive flies back to Illidan
-#define SPELL_FIREBALL                  40598               // 2.5k-3.5k damage in 10 yard radius. 2 second cast time.
-#define SPELL_DARK_BARRAGE              40585               // 10 second channeled spell, 3k shadow damage per second.
+#define SPELL_THROW_GLAIVE              39635 // Throws a glaive on the ground
+#define SPELL_THROW_GLAIVE2             39849 // Animation for the above spell
+#define SPELL_GLAIVE_RETURNS            39873 // Glaive flies back to Illidan
+#define SPELL_FIREBALL                  40598 // 2.5k-3.5k damage in 10 yard radius. 2 second cast time.
+#define SPELL_DARK_BARRAGE              40585 // 10 second channeled spell, 3k shadow damage per second.
 // Demon Form
-#define SPELL_DEMON_TRANSFORM_1         40511               // First phase of animations for transforming into Dark Illidan (fall to ground)
-#define SPELL_DEMON_TRANSFORM_2         40398               // Second phase of animations (kneel)
-#define SPELL_DEMON_TRANSFORM_3         40510               // Final phase of animations (stand up and roar)
-#define SPELL_DEMON_FORM                40506               // Transforms into Demon Illidan. Has an Aura of Dread on him.
-#define SPELL_SHADOW_BLAST              41078               // 8k - 11k Shadow Damage. Targets highest threat. Has a splash effect, damaging anyone in 20 yards of the target.
-#define SPELL_FLAME_BURST               41126               // Hurls fire at entire raid for ~3.5k damage every 10 seconds. Resistable. (Does not work: Script effect)
-#define SPELL_FLAME_BURST_EFFECT        41131               // The actual damage. Handled by core (41126 triggers 41131)
+#define SPELL_DEMON_TRANSFORM_1         40511 // First phase of animations for transforming into Dark Illidan (fall to ground)
+#define SPELL_DEMON_TRANSFORM_2         40398 // Second phase of animations (kneel)
+#define SPELL_DEMON_TRANSFORM_3         40510 // Final phase of animations (stand up and roar)
+#define SPELL_DEMON_FORM                40506 // Transforms into Demon Illidan. Has an Aura of Dread on him.
+#define SPELL_SHADOW_BLAST              41078 // 8k - 11k Shadow Damage. Targets highest threat. Has a splash effect, damaging anyone in 20 yards of the target.
+#define SPELL_FLAME_BURST               41126 // Hurls fire at entire raid for ~3.5k damage every 10 seconds. Resistable. (Does not work: Script effect)
+#define SPELL_FLAME_BURST_EFFECT        41131 // The actual damage. Have each player cast it on itself (workaround)
 // Other Illidan spells
-#define SPELL_KNEEL                     39656               // Before beginning encounter, this is how he appears (talking to Wilson).
-#define SPELL_SHADOW_PRISON             40647               // Illidan casts this spell to immobilize entire raid when he summons Maiev.
-#define SPELL_DEATH                     41220               // This spell doesn't do anything except stun Illidan and set him on his knees.
-#define SPELL_BERSERK                   45078               // Damage increased by 500%, attack speed by 150%
-
-// Non-Illidan spells
-#define SPELL_AKAMA_DOOR_CHANNEL        41268               // Akama's channel spell on the door before the Temple Summit
-#define SPELL_DEATHSWORN_DOOR_CHANNEL   41269               // Olum and Udalo's channel spell on the door before the Temple Summit
-#define SPELL_AKAMA_DOOR_FAIL           41271               // Not sure where this is really used...
-#define SPELL_HEALING_POTION            40535               // Akama uses this to heal himself to full.
-#define SPELL_AZZINOTH_CHANNEL          39857               // Glaives cast it on Flames. Not sure if this is the right spell.
-#define SPELL_SHADOW_DEMON_PASSIVE      41079               // Adds the "shadowform" aura to Shadow Demons.
-#define SPELL_CONSUME_SOUL              41080               // Once the Shadow Demons reach their target, they use this to kill them
-#define SPELL_PARALYZE                  41083               // Shadow Demons cast this on their target
-#define SPELL_PURPLE_BEAM               39123               // Purple Beam connecting Shadow Demon to their target
-#define SPELL_CAGE_TRAP_DUMMY           40761               // Put this in DB for cage trap GO.
-#define SPELL_EYE_BLAST_TRIGGER         40017               // This summons Demon Form every few seconds and deals ~20k damage in its radius
-#define SPELL_EYE_BLAST                 39908               // This does the blue flamey animation.
-#define SPELL_FLAME_CRASH_EFFECT        40836               // Firey blue ring of circle that the other flame crash summons
-#define SPELL_BLAZE_EFFECT              40610               // Green flame on the ground, triggers damage (5k) every few seconds
-#define SPELL_BLAZE_SUMMON              40637               // Summons the Blaze creature
-#define SPELL_DEMON_FIRE                40029               // Blue fire trail left by Eye Blast. Deals 2k per second if players stand on it.
-#define SPELL_CAGED                     40695               // Caged Trap triggers will cast this on Illidan if he is within 3 yards
-#define SPELL_CAGE_TRAP_SUMMON          40694               // Summons a Cage Trap GO (bugged) on the ground along with a Cage Trap Disturb Trigger mob (working)
-#define SPELL_CAGE_TRAP_BEAM            40713               // 8 Triggers on the ground in an octagon cast spells like this on Illidan 'caging him'
-#define SPELL_FLAME_BLAST               40631               // Flames of Azzinoth use this. Frontal cone AoE 7k-9k damage.
-#define SPELL_CHARGE                    40602               // Flames of Azzinoth charges whoever is too far from them. They enrage after this. For simplicity, we'll use the same enrage as Illidan.
-#define SPELL_TELEPORT_VISUAL           41232               // Teleport visual for Maiev
-#define SPELL_SHADOWFIEND_PASSIVE       41913               // Passive aura for shadowfiends
+#define SPELL_KNEEL                     39656 // Before beginning encounter, this is how he appears (talking to skully).
+#define SPELL_SHADOW_PRISON             40647 // Illidan casts this spell to immobilize entire raid when he summons Maiev.
+#define SPELL_DEATH                     41220 // This spell doesn't do anything except stun Illidan and set him on his knees.
+#define SPELL_BERSERK                   45078 // Damage increased by 500%, attack speed by 150%
+#define SPELL_DUAL_WIELD                42459
+//Phase Normal spells
+#define SPELL_FLAME_CRASH_EFFECT        40836 // Firey blue ring of circle that the other flame crash summons
+#define SPELL_SHADOWFIEND_PASSIVE       41913 // Passive aura for shadowfiends
+#define SPELL_SHADOW_DEMON_PASSIVE      41079 // Adds the "shadowform" aura to Shadow Demons.
+#define SPELL_CONSUME_SOUL              41080 // Once the Shadow Demons reach their target, they use this to kill them
+#define SPELL_PARALYZE                  41083 // Shadow Demons cast this on their target
+#define SPELL_PURPLE_BEAM               39123 // Purple Beam connecting Shadow Demon to their target
+//Phase Flight spells
+#define SPELL_AZZINOTH_CHANNEL          39857 // Glaives cast it on Flames. Not sure if this is the right spell.
+#define SPELL_EYE_BLAST_TRIGGER         40017 // This summons Demon Form every few seconds and deals ~20k damage in its radius
+#define SPELL_EYE_BLAST                 39908 // This does the blue flamey animation.
+#define SPELL_BLAZE_EFFECT              40610 // Green flame on the ground, triggers damage (5k) every few seconds
+#define SPELL_BLAZE_SUMMON              40637 // Summons the Blaze creature
+#define SPELL_DEMON_FIRE                40029 // Blue fire trail left by Eye Blast. Deals 2k per second if players stand on it.
+#define SPELL_FLAME_BLAST               40631 // Flames of Azzinoth use this. Frontal cone AoE 7k-9k damage.
+#define SPELL_CHARGE                    41581 //40602 // Flames of Azzinoth charges whoever is too far from them. They enrage after this. For simplicity, we'll use the same enrage as Illidan.
+#define SPELL_FLAME_ENRAGE              45078
+//Akama spells
+#define SPELL_AKAMA_DOOR_CHANNEL        41268 // Akama's channel spell on the door before the Temple Summit
+#define SPELL_DEATHSWORN_DOOR_CHANNEL   41269 // Olum and Udalo's channel spell on the door before the Temple Summit
+#define SPELL_AKAMA_DOOR_FAIL           41271 // Not sure where this is really used...
+#define SPELL_HEALING_POTION            40535 // Akama uses this to heal himself to full.
+#define SPELL_CHAIN_LIGHTNING           40536 // 6938 to 8062 for 5 targets
+//Maiev spells
+#define SPELL_CAGE_TRAP_DUMMY           40761 // Put this in DB for cage trap GO.
+#define SPELL_CAGED                     40695 // Caged Trap triggers will cast this on Illidan if he is within 3 yards
+#define SPELL_CAGE_TRAP_SUMMON          40694 // Summons a Cage Trap GO (bugged) on the ground along with a Cage Trap Disturb Trigger mob (working)
+#define SPELL_CAGE_TRAP_BEAM            40713 // 8 Triggers on the ground in an octagon cast spells like this on Illidan 'caging him'
+#define SPELL_TELEPORT_VISUAL           41232 // Teleport visual for Maiev
+#define SPELL_SHADOW_STRIKE             40685 // 4375 to 5625 every 3 seconds for 12 seconds
+#define SPELL_THROW_DAGGER              41152 // 5400 to 6600 damage, need dagger
+#define SPELL_FAN_BLADES                39954 // bugged visual
 
 // Other defines
-#define CENTER_X            676.740
+#define CENTER_X            676.740 
 #define CENTER_Y            305.297
 #define CENTER_Z            353.192
+
+#define FLAME_ENRAGE_DISTANCE   30
+#define FLAME_CHARGE_DISTANCE   50
 
 /**** Creature Summon and Recognition IDs ****/
@@ -142,12 +157,79 @@
 
 /*** Phase Names ***/
-enum Phase
-{
-    PHASE_NORMAL            =   1,
-    PHASE_FLIGHT            =   2,
-    PHASE_NORMAL_2          =   3,
-    PHASE_DEMON             =   4,
-    PHASE_NORMAL_MAIEV      =   5,
-    PHASE_DEMON_SEQUENCE    =   6,
+enum PhaseIllidan
+{
+    PHASE_NULL                  =   0,
+    PHASE_NORMAL                =   1,
+    PHASE_FLIGHT                =   2,
+    PHASE_NORMAL_2              =   3,
+    PHASE_DEMON                 =   4,
+    PHASE_NORMAL_MAIEV          =   5,
+    PHASE_TALK_SEQUENCE         =   6,
+    PHASE_FLIGHT_SEQUENCE       =   7,
+    PHASE_TRANSFORM_SEQUENCE    =   8,
+};//Maiev uses the same phase
+
+enum PhaseAkama
+{
+    PHASE_AKAMA_NULL        =   0,
+    PHASE_CHANNEL           =   1,
+    PHASE_WALK              =   2,
+    PHASE_TALK              =   3,
+    PHASE_FIGHT_ILLIDAN     =   4,
+    PHASE_FIGHT_MINIONS     =   5,
+    PHASE_RETURN            =   6,
+};
+
+enum EventIllidan
+{
+    EVENT_NULL                  =   0,
+    EVENT_BERSERK               =   1,
+    //normal phase
+    EVENT_TAUNT                 =   2,
+    EVENT_SHEAR                 =   3,
+    EVENT_FLAME_CRASH           =   4,
+    EVENT_PARASITIC_SHADOWFIEND =   5,
+    EVENT_PARASITE_CHECK        =   6,
+    EVENT_DRAW_SOUL             =   7,
+    EVENT_AGONIZING_FLAMES      =   8,
+    EVENT_TRANSFORM_NORMAL      =   9,
+    EVENT_ENRAGE                =   10,
+    //flight phase
+    EVENT_FIREBALL              =   2,
+    EVENT_DARK_BARRAGE          =   3,
+    EVENT_EYE_BLAST             =   4,
+    EVENT_MOVE_POINT            =   5,
+    //demon phase
+    EVENT_SHADOW_BLAST          =   2,
+    EVENT_FLAME_BURST           =   3,
+    EVENT_SHADOWDEMON           =   4,
+    EVENT_TRANSFORM_DEMON       =   5,
+    //sequence phase
+    EVENT_TALK_SEQUENCE         =   2,
+    EVENT_FLIGHT_SEQUENCE       =   2,
+    EVENT_TRANSFORM_SEQUENCE    =   2,
+};
+
+enum EventMaiev
+{
+    EVENT_MAIEV_NULL            =   0,
+    EVENT_MAIEV_STEALTH         =   1,
+    EVENT_MAIEV_TAUNT           =   2,
+    EVENT_MAIEV_SHADOW_STRIKE   =   3,
+    EVENT_MAIEV_THROW_DAGGER    =   4,
+    EVENT_MAIEV_TRAP            =   5,
+};
+
+static EventIllidan MaxTimer[]=
+{
+    EVENT_NULL,
+    EVENT_DRAW_SOUL,
+    EVENT_MOVE_POINT,
+    EVENT_TRANSFORM_NORMAL,
+    EVENT_TRANSFORM_DEMON,
+    EVENT_ENRAGE,
+    EVENT_TALK_SEQUENCE,
+    EVENT_FLIGHT_SEQUENCE,
+    EVENT_TRANSFORM_SEQUENCE
 };
 
@@ -163,5 +245,5 @@
 {
     {11463, "Akama... your duplicity is hardly surprising. I should have slaughtered you and your malformed brethren long ago.", ILLIDAN_STORMRAGE, 8000, 0, true},
-    {0, NULL, ILLIDAN_STORMRAGE, 5000, 396, true},
+    {0, NULL, ILLIDAN_STORMRAGE, 5000, 396, true}, 
     {11389, "We've come to end your reign, Illidan. My people and all of Outland shall be free!", AKAMA, 7000, 25, true},
     {0, NULL, AKAMA, 5000, 66, true},
@@ -171,18 +253,17 @@
     {11466, "You are not prepared!", ILLIDAN_STORMRAGE, 3000, 406, true},
     {0, NULL, EMPTY, 1000, 0, true},
-    {0, NULL, EMPTY, 0, 0, false},
+    {0, NULL, EMPTY, 0, 0, false},//9
     {11476, "Is this it, mortals? Is this all the fury you can muster?", ILLIDAN_STORMRAGE, 8000, 0, true},
     {11491, "Their fury pales before mine, Illidan. We have some unsettled business between us.", MAIEV_SHADOWSONG, 8000, 5, true},
-    {11477, "Maiev... How is this even possible?", ILLIDAN_STORMRAGE, 7000, 1, true},
+    {11477, "Maiev... How is this even possible?", ILLIDAN_STORMRAGE, 5000, 1, true},
     {11492, "Ah... my long hunt is finally over. Today, Justice will be done!", MAIEV_SHADOWSONG, 8000, 15, true},
-    {11470, "Feel the hatred of ten thousand years!", ILLIDAN_STORMRAGE, 1000, 0, false},
-    {11496, "Ahh... It is finished. You are beaten.", MAIEV_SHADOWSONG, 6000, 0, true},
-    {                                                       // Emote dead for now. Kill him later
-        11478, "You have won... Maiev...but the huntress... is nothing...without the hunt... you... are nothing... without me..", ILLIDAN_STORMRAGE, 22000, 65, true
-    },
+    {11470, "Feel the hatred of ten thousand years!", ILLIDAN_STORMRAGE, 1000, 0, false},//14
+    {11496, "Ahh... It is finished. You are beaten.", MAIEV_SHADOWSONG, 6000, 0, true},//15
+    {11478, "You have won... Maiev...but the huntress... is nothing...without the hunt... you... are nothing... without me..", ILLIDAN_STORMRAGE, 30000, 65, true}, // Emote dead for now. Kill him later
     {11497, "He is right. I feel nothing... I am nothing... Farewell, champions.", MAIEV_SHADOWSONG, 9000, 0, true},
-    {11498, NULL, MAIEV_SHADOWSONG, 0, true},
+    {11498, NULL, MAIEV_SHADOWSONG, 5000, 0, true},
+    {11498, NULL, EMPTY, 1000, 0, true},//19 Maiev disappear
     {11387, "The Light will fill these dismal halls once again. I swear it.", AKAMA, 8000, 0, true},
-    {0, NULL, EMPTY, 1000, 0, false}
+    {0, NULL, EMPTY, 1000, 0, false}//21
 };
 
@@ -206,5 +287,12 @@
 {
     float x, y, z;
-    uint32 id;
+};
+
+static Locations HoverPosition[]=
+{
+    {657, 340, 355},
+    {657, 275, 355},
+    {705, 275, 355},
+    {705, 340, 355}
 };
 
@@ -212,5 +300,5 @@
 {
     {695.105, 305.303, 354.256},
-    {659.338, 305.303, 354.256},
+    {659.338, 305.303, 354.256},//the distance between two glaives is 36
     {700.105, 305.303, 354.256},
     {664.338, 305.303, 354.256}
@@ -219,47 +307,32 @@
 static Locations EyeBlast[]=
 {
-    {650.697, 320.128, 353.730},
-    {652.799, 275.091, 353.367},
-    {701.527, 273.815, 353.230},
-    {709.865, 325.654, 353.322}
+    {677, 350, 354},//start point, pass through glaive point
+    {677, 260, 354}
 };
 
 static Locations AkamaWP[]=
 {
-    { 770.01, 304.50, 312.29 },                             // Bottom of the first stairs, at the doors
-    { 780.66, 304.50, 319.74 },                             // Top of the first stairs
-    { 790.13, 319.68, 319.76 },                             // Bottom of the second stairs (left from the entrance)
-    { 787.17, 347.38, 341.42 },                             // Top of the second stairs
-    { 781.34, 350.31, 341.44 },                             // Bottom of the third stairs
-    { 762.60, 361.06, 353.60 },                             // Top of the third stairs
-    { 756.35, 360.52, 353.27 },                             // Before the door-thingy
-    { 743.82, 342.21, 353.00 },                             // Somewhere further
-    { 732.69, 305.13, 353.00 },                             // In front of Illidan
-    { 738.11, 365.44, 353.00 },                             // in front of the door-thingy (the other one!)
-    { 792.18, 366.62, 341.42 },                             // Down the first flight of stairs
-    { 796.84, 304.89, 319.76 },                             // Down the second flight of stairs
-    { 782.01, 304.55, 319.76 }                              // Final location - back at the initial gates. This is where he will fight the minions!
+    {770.01, 304.50, 312.29}, // Bottom of the first stairs, at the doors
+    {780.66, 304.50, 319.74}, // Top of the first stairs
+    {790.13, 319.68, 319.76}, // Bottom of the second stairs (left from the entrance)
+    {787.17, 347.38, 341.42}, // Top of the second stairs
+    {781.34, 350.31, 341.44}, // Bottom of the third stairs
+    {762.60, 361.06, 353.60}, // Top of the third stairs
+    {756.35, 360.52, 353.27}, // Before the door-thingy
+    {743.82, 342.21, 353.00}, // Somewhere further
+    {732.69, 305.13, 353.00}, // In front of Illidan - (8)
+    {738.11, 365.44, 353.00}, // in front of the door-thingy (the other one!)
+    {792.18, 366.62, 341.42}, // Down the first flight of stairs
+    {796.84, 304.89, 319.76}, // Down the second flight of stairs
+    {782.01, 304.55, 319.76}  // Final location - back at the initial gates. This is where he will fight the minions! (12)
 };
 // 755.762, 304.0747, 312.1769 -- This is where Akama should be spawned
 static Locations SpiritSpawns[]=
 {
-    {755.5426, 309.9156, 312.2129, SPIRIT_OF_UDALO},
-    {755.5426, 298.7923, 312.0834, SPIRIT_OF_OLUM}
-};
-
-struct WayPoints
-{
-    WayPoints(uint32 _id, float _x, float _y, float _z)
-    {
-        id = _id;
-        x = _x;
-        y = _y;
-        z = _z;
-    }
-    uint32 id;
-    float x, y, z;
-};
-
-struct Animation                                            // For the demon transformation
+    {755.5426, 309.9156, 312.2129},
+    {755.5426, 298.7923, 312.0834}
+};
+
+struct Animation // For the demon transformation
 {
     uint32 aura, unaura, timer, size, displayid, phase;
@@ -269,20 +342,22 @@
 static Animation DemonTransformation[]=
 {
-    {SPELL_DEMON_TRANSFORM_1, 0, 1300, 0, 0, 6, true},
+    {SPELL_DEMON_TRANSFORM_1, 0, 1000, 0, 0, 6, true},
     {SPELL_DEMON_TRANSFORM_2, SPELL_DEMON_TRANSFORM_1, 4000, 0, 0, 6, true},
-    {SPELL_DEMON_FORM, 0, 3000, 1073741824, 21322, 6, false},
+    {0, 0, 3000, 1073741824, 21322, 6, false},//stunned, cannot cast demon form
     {SPELL_DEMON_TRANSFORM_3, SPELL_DEMON_TRANSFORM_2, 3500, 0, 0, 6, false},
-    {0, 0, 0, 0, 0, 4, false},
-    {SPELL_DEMON_TRANSFORM_1, 0, 1500, 0, 0, 6, false},
+    {SPELL_DEMON_FORM, SPELL_DEMON_TRANSFORM_3, 0, 0, 0, 4, false},
+    {SPELL_DEMON_TRANSFORM_1, 0, 1000, 0, 0, 6, false},
     {SPELL_DEMON_TRANSFORM_2, SPELL_DEMON_TRANSFORM_1, 4000, 0, 0, 6, false},
     {0, SPELL_DEMON_FORM, 3000, 1069547520, 21135, 6, false},
     {SPELL_DEMON_TRANSFORM_3, SPELL_DEMON_TRANSFORM_2, 3500, 0, 0, 6, true},
-    {0, 0, 0, 0, 0, 8, true}
-};
-
-/**** Demon Fire will be used for Eye Blast. Illidan needs to have access to it's vars and functions, so we'll set it here ****/
-struct TRINITY_DLL_DECL demonfireAI : public ScriptedAI
-{
-    demonfireAI(Creature *c) : ScriptedAI(c)
+    {0, SPELL_DEMON_TRANSFORM_3, 0, 0, 0, 8, true}
+};
+
+
+
+/************************************** Illidan's AI ***************************************/
+struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
+{
+    boss_illidan_stormrageAI(Creature* c) : ScriptedAI(c)
     {
         pInstance = ((ScriptedInstance*)c->GetInstanceData());
@@ -292,146 +367,788 @@
     ScriptedInstance* pInstance;
 
+    PhaseIllidan Phase;
+    EventIllidan Event;
+    uint32 Timer[EVENT_ENRAGE + 1];
+
+    uint32 TalkCount;
+    uint32 TransformCount;
+    uint32 FlightCount;
+
+    uint32 HoverPoint;
+
+    uint64 AkamaGUID;
+    uint64 MaievGUID;
+    uint64 FlameGUID[2];
+    uint64 GlaiveGUID[2];
+
+    std::list<uint64> ParasiteTargets; // for safety, do not use Unit*
+
+    void Reset();
+
+    void JustSummoned(Creature* summon)//, TempSummonType type)
+    {
+        if(summon->GetCreatureInfo()->Entry == FLAME_CRASH)
+        {
+        //    type = TEMPSUMMON_TIMED_DESPAWN;
+        }
+        //error_log("justsummoned %d %d", summon->GetCreatureInfo()->Entry, summon->GetGUID());
+    }
+
+    void SummonedCreatureDespawn(Creature* summon)
+    {
+        if(summon->GetCreatureInfo()->Entry == FLAME_OF_AZZINOTH)
+        {
+            for(uint8 i = 0; i < 2; i++)
+                if(summon->GetGUID() == FlameGUID[i])
+                    FlameGUID[i] = 0;
+
+            if(!FlameGUID[0] && !FlameGUID[1])
+            {
+                m_creature->InterruptNonMeleeSpells(true);
+                EnterPhase(PHASE_FLIGHT_SEQUENCE);
+            }
+        }
+    }
+
+    void MovementInform(uint32 MovementType, uint32 Data)
+    {
+        if(FlightCount == 7) //change hover point
+        {
+            if(m_creature->getVictim())
+            {
+                m_creature->SetInFront(m_creature->getVictim());
+                m_creature->StopMoving();
+            }
+            EnterPhase(PHASE_FLIGHT);
+        }
+        else 
+            Timer[EVENT_FLIGHT_SEQUENCE] = 1000;    
+    }
+
+    void Aggro(Unit *who)
+    {
+        DoZoneInCombat();
+    }
+
+    void AttackStart(Unit *who)
+    {
+        if(!who || Phase >= PHASE_TALK_SEQUENCE)
+            return;
+
+        if (who->isTargetableForAttack())
+        {
+            if(Phase == PHASE_FLIGHT || Phase == PHASE_DEMON)
+                m_creature->Attack(who, false);
+            else
+                DoStartAttackAndMovement(who);
+
+            if (!InCombat)
+            {
+                Aggro(who);
+                InCombat = true;
+            }
+        }
+    }
+
+    void MoveInLineOfSight(Unit *who) {}
+
+    void JustDied(Unit *killer)
+    {
+        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+        if(!pInstance)
+            return;
+
+        pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, DONE); // Completed
+
+        for(uint8 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L + 1; ++i)
+        {
+            GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i));
+            if(Door)
+                Door->SetUInt32Value(GAMEOBJECT_STATE, 0); // Open Doors
+        }
+    }
+
+    void KilledUnit(Unit *victim)
+    {
+        if(victim == m_creature) return;
+
+        switch(rand()%2)
+        {
+        case 0:
+            DoYell(SAY_KILL1, LANG_UNIVERSAL, victim);
+            DoPlaySoundToSet(m_creature, SOUND_KILL1);
+            break;
+        case 1:
+            DoYell(SAY_KILL2, LANG_UNIVERSAL, victim);
+            DoPlaySoundToSet(m_creature, SOUND_KILL2);
+            break;
+        }
+    }
+
+    void DamageTaken(Unit *done_by, uint32 &damage)
+    {
+        if(damage >= m_creature->GetHealth() && done_by != m_creature)
+            damage = 0;
+        if(done_by->GetGUID() == MaievGUID)
+            done_by->AddThreat(m_creature, -(3*(float)damage)/4); // do not let maiev tank him
+    }
+
+    void SpellHit(Unit *caster, const SpellEntry *spell)
+    {
+        if(spell->Id == SPELL_GLAIVE_RETURNS) // Re-equip our warblades!
+        {
+            if(!m_creature->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY))
+                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479);
+            else
+                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
+            m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
+        }
+    }
+
+    void AddParasiteTarget(uint64 targetGUID)
+    {
+        for(std::list<uint64>::iterator tIter = ParasiteTargets.begin(); tIter != ParasiteTargets.end(); tIter++)
+        {
+            if(*tIter == targetGUID)
+                return;
+        }
+        ParasiteTargets.push_back(targetGUID);
+
+        if(Phase == PHASE_NORMAL || Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV)
+            Timer[EVENT_PARASITE_CHECK] += 1000;
+    }
+
+    void DeleteFromThreatList(uint64 TargetGUID)
+    {
+        for(std::list<HostilReference*>::iterator itr = m_creature->getThreatManager().getThreatList().begin(); itr != m_creature->getThreatManager().getThreatList().end(); ++itr)
+        {
+            if((*itr)->getUnitGuid() == TargetGUID)
+            {
+                (*itr)->removeReference();
+                break;
+            }
+        }
+    }
+
+    void Talk(uint32 count)
+    {
+        Timer[EVENT_TALK_SEQUENCE] = Conversation[count].timer;
+
+        Creature* creature = NULL;
+        if(Conversation[count].creature == ILLIDAN_STORMRAGE)
+            creature = m_creature;
+        else if(Conversation[count].creature == AKAMA)
+            creature = ((Creature*)Unit::GetUnit((*m_creature), AkamaGUID));
+        else if(Conversation[count].creature == MAIEV_SHADOWSONG)
+            creature = ((Creature*)Unit::GetUnit((*m_creature), MaievGUID));
+
+        if(creature)
+        {
+            if(Conversation[count].emote)
+                creature->HandleEmoteCommand(Conversation[count].emote); // Make the creature do some animation!
+            if(Conversation[count].text)
+                creature->Yell(Conversation[count].text, LANG_UNIVERSAL, 0); // Have the creature yell out some text
+            if(Conversation[count].sound)
+                DoPlaySoundToSet(creature, Conversation[count].sound); // Play some sound on the creature
+        }
+    }
+
+    void EnterPhase(PhaseIllidan NextPhase);
+    void CastEyeBlast();
+    void SummonFlamesOfAzzinoth();
+    void SummonMaiev();
+    void SummonShadowDemon()
+    {
+        Creature* ShadowDemon = NULL;
+        Unit* target = NULL;
+        for(uint8 i = 0; i < 4; i++)
+        {
+            ShadowDemon = DoSpawnCreature(SHADOW_DEMON, 0,0,0,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,25000);
+            if(ShadowDemon)
+            {
+                target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+                if(target && target->GetTypeId() == TYPEID_PLAYER) // only on players.
+                {
+                    ShadowDemon->AddThreat(target, 5000000.0f);
+                    ShadowDemon->AI()->AttackStart(target);
+                }
+                DoZoneInCombat(ShadowDemon);
+            }
+        }
+    }
+    void HandleTalkSequence();
+    void HandleFlightSequence()
+    {
+        switch(FlightCount)
+        {
+        case 1://lift off
+            m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
+            //m_creature->GetMotionMaster()->Clear(false);
+            m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
+            //m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ());
+            m_creature->StopMoving();
+            DoYell(SAY_TAKEOFF, LANG_UNIVERSAL, NULL);
+            DoPlaySoundToSet(m_creature, SOUND_TAKEOFF);
+            Timer[EVENT_FLIGHT_SEQUENCE] = 3000;
+            break;
+        case 2://move to center
+            //m_creature->GetMotionMaster()->Clear(false);
+            m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+            m_creature->GetMotionMaster()->MovePoint(0, CENTER_X + 5, CENTER_Y, CENTER_Z); //+5, for SPELL_THROW_GLAIVE bug
+            m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+            Timer[EVENT_FLIGHT_SEQUENCE] = 0;
+            break;
+        case 3://throw one glaive
+            {
+                uint8 i=1;
+                Creature* Glaive = m_creature->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+                if(Glaive)
+                {
+                    GlaiveGUID[i] = Glaive->GetGUID();
+                    Glaive->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+                    Glaive->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
+                    Glaive->setFaction(m_creature->getFaction());
+                    DoCast(Glaive, SPELL_THROW_GLAIVE2);
+                }
+            }
+            Timer[EVENT_FLIGHT_SEQUENCE] = 700;
+            break;
+        case 4://throw another
+            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
+            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+            {
+                uint8 i=0;
+                Creature* Glaive = m_creature->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+                if(Glaive)
+                {
+                    GlaiveGUID[i] = Glaive->GetGUID();
+                    Glaive->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+                    Glaive->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
+                    Glaive->setFaction(m_creature->getFaction());
+                    DoCast(Glaive, SPELL_THROW_GLAIVE, true);
+                }
+            }
+            Timer[EVENT_FLIGHT_SEQUENCE] = 5000;
+            break;
+        case 5://summon flames
+            SummonFlamesOfAzzinoth();
+            Timer[EVENT_FLIGHT_SEQUENCE] = 3000;
+            break;
+        case 6://fly to hover point
+            m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+            m_creature->GetMotionMaster()->MovePoint(0, HoverPosition[HoverPoint].x, HoverPosition[HoverPoint].y, HoverPosition[HoverPoint].z);
+            m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+            Timer[EVENT_FLIGHT_SEQUENCE] = 0;
+            break;
+        case 7://return to center
+            m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+            m_creature->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, CENTER_Z);
+            m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+            Timer[EVENT_FLIGHT_SEQUENCE] = 0;
+            break;
+        case 8://glaive return
+            for(uint8 i = 0; i < 2; i++)
+            {
+                if(GlaiveGUID[i])
+                {
+                    Unit* Glaive = Unit::GetUnit((*m_creature), GlaiveGUID[i]);
+                    if(Glaive)
+                    {
+                        Glaive->CastSpell(m_creature, SPELL_GLAIVE_RETURNS, false); // Make it look like the Glaive flies back up to us
+                        Glaive->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); // disappear but not die for now
+                    }
+                }
+            }
+            Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
+            break;
+        case 9://land
+            //m_creature->GetMotionMaster()->Clear(false);
+            m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+            //m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ());
+            m_creature->StopMoving();
+            m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
+            for(uint8 i = 0; i < 2; i++)
+            {
+                if(GlaiveGUID[i])
+                {
+                    if(GETUNIT(Glaive, GlaiveGUID[i]))
+                    {
+                        Glaive->SetVisibility(VISIBILITY_OFF);
+                        Glaive->setDeathState(JUST_DIED); // Despawn the Glaive
+                    }
+                    GlaiveGUID[i] = 0;
+                }
+            }
+            Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
+            break;
+        case 10://attack
+            DoResetThreat();
+            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
+            //m_creature->GetMotionMaster()->Clear();
+            m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
+            EnterPhase(PHASE_NORMAL_2);
+            break;
+        default:
+            break;
+        }
+        FlightCount++;
+    }
+
+    void HandleTransformSequence()
+    {
+        if(DemonTransformation[TransformCount].unaura)
+            m_creature->RemoveAurasDueToSpell(DemonTransformation[TransformCount].unaura);
+
+        if(DemonTransformation[TransformCount].aura)
+            DoCast(m_creature, DemonTransformation[TransformCount].aura, true);
+
+        if(DemonTransformation[TransformCount].displayid)
+            m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, DemonTransformation[TransformCount].displayid); // It's morphin time!
+
+        if(DemonTransformation[TransformCount].equip)
+        {
+            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Requip warglaives if needed
+            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
+            m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
+        }
+        else
+        {
+            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); // Unequip warglaives if needed
+            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+        }
+
+        switch(TransformCount)
+        {
+        case 2:
+            DoResetThreat();
+            break;
+        case 4:
+            EnterPhase(PHASE_DEMON);
+            break;
+        case 7:
+            DoResetThreat();
+            break;
+        case 9:
+            if(MaievGUID)
+                EnterPhase(PHASE_NORMAL_MAIEV); // Depending on whether we summoned Maiev, we switch to either phase 5 or 3
+            else
+                EnterPhase(PHASE_NORMAL_2);
+            break;
+        default:
+            break;
+        }
+        if(Phase == PHASE_TRANSFORM_SEQUENCE)
+            Timer[EVENT_TRANSFORM_SEQUENCE] = DemonTransformation[TransformCount].timer;        
+        TransformCount++;
+    }
+
+    void UpdateAI(const uint32 diff)
+    {
+        if((!m_creature->SelectHostilTarget() || !m_creature->getVictim()) && Phase < PHASE_TALK_SEQUENCE)
+            return;
+
+        Event = EVENT_NULL;
+        for(uint32 i = 1; i <= MaxTimer[Phase]; i++)
+            if(Timer[i])
+                if(Timer[i] <= diff)
+                {
+                    if(!Event)
+                        Event = (EventIllidan)i;
+                }
+                else Timer[i] -= diff;
+
+                switch(Phase)
+                {
+                case PHASE_NORMAL:
+                    if(HPPCT(m_creature) < 65)
+                        EnterPhase(PHASE_FLIGHT_SEQUENCE);
+                    break;
+
+                case PHASE_NORMAL_2:
+                    if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30)
+                        EnterPhase(PHASE_TALK_SEQUENCE);
+                    break;
+
+                case PHASE_NORMAL_MAIEV:
+                    if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 1)
+                        EnterPhase(PHASE_TALK_SEQUENCE);
+                    break;
+
+                case PHASE_TALK_SEQUENCE:
+                    if(Event == EVENT_TALK_SEQUENCE)
+                        HandleTalkSequence();
+                    break;
+
+                case PHASE_FLIGHT_SEQUENCE:
+                    if(Event == EVENT_FLIGHT_SEQUENCE)
+                        HandleFlightSequence();
+                    break;
+
+                case PHASE_TRANSFORM_SEQUENCE:
+                    if(Event == EVENT_TRANSFORM_SEQUENCE)
+                        HandleTransformSequence();
+                    break;
+                }
+
+                if(m_creature->IsNonMeleeSpellCasted(false))
+                    return;
+
+                if(Phase == PHASE_NORMAL || Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV && !m_creature->HasAura(SPELL_CAGED, 0))
+                {
+                    switch(Event)
+                    {
+                        //PHASE_NORMAL
+                    case EVENT_BERSERK:
+                        DoYell(SAY_ENRAGE, LANG_UNIVERSAL, NULL);
+                        DoPlaySoundToSet(m_creature, SOUND_ENRAGE);
+                        DoCast(m_creature, SPELL_BERSERK, true);
+                        Timer[EVENT_BERSERK] = 5000;//The buff actually lasts forever.
+                        break;
+
+                    case EVENT_TAUNT:
+                        {
+                            uint32 random = rand()%4;
+                            char* yell = RandomTaunts[random].text;
+                            uint32 soundid = RandomTaunts[random].sound;
+                            if(yell)
+                                DoYell(yell, LANG_UNIVERSAL, NULL);
+                            if(soundid)
+                                DoPlaySoundToSet(m_creature, soundid);
+                        }
+                        Timer[EVENT_TAUNT] = 32000;
+                        break;
+
+                    case EVENT_SHEAR:
+                        DoCast(m_creature->getVictim(), SPELL_SHEAR);
+                        Timer[EVENT_SHEAR] = 25000 + (rand()%16 * 1000);
+                        break;
+
+                    case EVENT_FLAME_CRASH:
+                        DoCast(m_creature->getVictim(), SPELL_FLAME_CRASH);
+                        Timer[EVENT_FLAME_CRASH] = 35000;
+                        break;
+
+                    case EVENT_PARASITIC_SHADOWFIEND:
+                        {
+                            Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
+                            if(!target) target = m_creature->getVictim();
+                            if(target->GetTypeId() == TYPEID_PLAYER && !target->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0))
+                            {
+                                target->CastSpell(target, SPELL_PARASITIC_SHADOWFIEND, true); // do not miss
+                                ParasiteTargets.push_back(target->GetGUID());
+                                Timer[EVENT_PARASITE_CHECK] += 1000; // do not check immediately
+                            }
+                            Timer[EVENT_PARASITIC_SHADOWFIEND] = 40000;
+                        }
+                        break;
+
+                    case EVENT_PARASITE_CHECK:
+                        for(std::list<uint64>::iterator tIter = ParasiteTargets.begin(); tIter != ParasiteTargets.end();)
+                        {
+                            Unit* target = Unit::GetUnit((*m_creature), *tIter);
+                            if(!target || !target->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0))
+                            {
+                                if(target && target->isAlive())
+                                    target->CastSpell(target, SPELL_SUMMON_PARASITICS, true);
+                                std::list<uint64>::iterator tIter2 = tIter;
+                                ++tIter;
+                                ParasiteTargets.erase(tIter2);
+                            }
+                            else
+                                ++tIter;
+                        }
+                        if(ParasiteTargets.empty())
+                            Timer[EVENT_PARASITE_CHECK] = 0;
+                        else
+                            Timer[EVENT_PARASITE_CHECK] = 1000;
+                        break;
+
+                    case EVENT_DRAW_SOUL:
+                        DoCast(m_creature->getVictim(), SPELL_DRAW_SOUL);
+                        Timer[EVENT_DRAW_SOUL] = 55000;          
+                        break;
+
+                        //PHASE_NORMAL_2
+                    case EVENT_AGONIZING_FLAMES:
+                        DoCast(SelectUnit(SELECT_TARGET_RANDOM,0), SPELL_AGONIZING_FLAMES);
+                        Timer[EVENT_AGONIZING_FLAMES] = 0;
+                        break;
+
+                    case EVENT_TRANSFORM_NORMAL:
+                        EnterPhase(PHASE_TRANSFORM_SEQUENCE);
+                        break;
+
+                        //PHASE_NORMAL_MAIEV
+                    case EVENT_ENRAGE:
+                        DoCast(m_creature, SPELL_ENRAGE);
+                        Timer[EVENT_ENRAGE] = 0;
+                        break;
+
+                    default:
+                        break;
+                    }
+                    DoMeleeAttackIfReady();
+                }
+
+                if(Phase == PHASE_FLIGHT)
+                {
+                    switch(Event)
+                    {
+                    case EVENT_FIREBALL:
+                        DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FIREBALL);
+                        Timer[EVENT_FIREBALL] = 3000;
+                        break;
+
+                    case EVENT_DARK_BARRAGE:
+                        DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DARK_BARRAGE);
+                        Timer[EVENT_DARK_BARRAGE] = 0;
+                        break;
+
+                    case EVENT_EYE_BLAST:
+                        CastEyeBlast(); 
+                        Timer[EVENT_EYE_BLAST] = 0;
+                        break;
+
+                    case EVENT_MOVE_POINT:
+                        Phase = PHASE_FLIGHT_SEQUENCE;
+                        Timer[EVENT_FLIGHT_SEQUENCE] = 0;//do not start Event when changing hover point
+                        for (uint8 i = 0; i <= rand()%3; i++)
+                        {
+                            HoverPoint++;
+                            if(HoverPoint > 3)
+                                HoverPoint = 0;
+                        }
+                        m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+                        m_creature->GetMotionMaster()->MovePoint(0, HoverPosition[HoverPoint].x, HoverPosition[HoverPoint].y, HoverPosition[HoverPoint].z);
+                        m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+                        break;
+
+                    default:
+                        break;
+                    }
+                }
+
+                if(Phase == PHASE_DEMON)
+                {
+                    switch(Event)
+                    {
+                    case EVENT_SHADOW_BLAST:
+                        m_creature->GetMotionMaster()->Clear(false);
+                        if(!m_creature->IsWithinDistInMap(m_creature->getVictim(), 50)||!m_creature->IsWithinLOSInMap(m_creature->getVictim()))
+                            m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), 30);
+                        else
+                            m_creature->GetMotionMaster()->MoveIdle();
+                        DoCast(m_creature->getVictim(), SPELL_SHADOW_BLAST);
+                        Timer[EVENT_SHADOW_BLAST] = 4000;
+                        break;
+                    case EVENT_SHADOWDEMON:
+                        SummonShadowDemon();
+                        Timer[EVENT_SHADOWDEMON] = 0;
+                        Timer[EVENT_FLAME_BURST] += 10000;
+                        break;
+                    case EVENT_FLAME_BURST:
+                        DoCast(m_creature, SPELL_FLAME_BURST);
+                        Timer[EVENT_FLAME_BURST] = 15000;
+                        break;
+                    case EVENT_TRANSFORM_DEMON:
+                        EnterPhase(PHASE_TRANSFORM_SEQUENCE);
+                        break;
+                    default:
+                        break;
+                    }
+                }
+    }
+};
+
+/********************************** End of Illidan AI ******************************************/
+
+//This is used to sort the players by distance in preparation for being charged by the flames.
+struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
+{
+    const Unit* MainTarget;
+    TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {};
+    // functor for operator ">"
+    bool operator()(const Unit* _Left, const Unit* _Right) const
+    {
+        return (MainTarget->GetDistance(_Left) > MainTarget->GetDistance(_Right));
+    }
+};
+
+struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI
+{
+    flame_of_azzinothAI(Creature *c) : ScriptedAI(c) {Reset();}
+
+    uint32 FlameBlastTimer;
+    uint32 CheckTimer;
+    uint64 GlaiveGUID;
+
+    void Reset()
+    {
+        FlameBlastTimer = 15000;
+        CheckTimer = 5000;
+        GlaiveGUID = 0;
+    }
+
+    void Aggro(Unit *who) {}
+
+    void ChargeCheck()
+    {        
+        // Get the Threat List
+        std::list<HostilReference *> m_threatlist = m_creature->getThreatManager().getThreatList();
+
+        if(!m_threatlist.size()) return; // He doesn't have anyone in his threatlist, useless to continue
+
+        std::list<Unit *> targets;
+        std::list<HostilReference *>::iterator itr = m_threatlist.begin();
+        for( ; itr!= m_threatlist.end(); ++itr) //store the threat list in a different container
+        {
+            Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
+            if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER && target->GetPositionZ()>350) //only on alive players
+                targets.push_back(target);
+        }
+
+        if (!targets.size())
+            return;
+
+        //Sort the list of players
+        targets.sort(TargetDistanceOrder(m_creature));
+        //Resize so we only get the furthest target
+        targets.resize(1);
+
+        Unit* target = (*targets.begin());
+        if(target && (!m_creature->IsWithinDistInMap(target, FLAME_CHARGE_DISTANCE)))
+        {
+            m_creature->AttackStop();
+            m_creature->GetMotionMaster()->Clear(false);
+            float x, y, z; // is it possible to fix charge?
+            target->GetContactPoint(m_creature, x, y, z);
+            m_creature->Relocate(x,y,z);
+            m_creature->SendMonsterMove(x, y, z, 0, MOVEMENTFLAG_WALK_MODE, 1);
+            //m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
+            m_creature->StopMoving();
+            //DoCast(target, SPELL_CHARGE);
+            m_creature->AddThreat(target, 5000000.0f);
+            DoTextEmote("sets its gaze on $N!", target);
+        }
+    }
+
+    void EnrageCheck()
+    {
+        if(GETUNIT(Glaive, GlaiveGUID))
+        {
+            if(!m_creature->IsWithinDistInMap(Glaive, FLAME_ENRAGE_DISTANCE))
+            {
+                Glaive->InterruptNonMeleeSpells(true);
+                DoCast(m_creature, SPELL_FLAME_ENRAGE, true);
+                DoResetThreat();
+                Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+                if(target && target->isAlive())
+                {
+                    m_creature->AddThreat(m_creature->getVictim(), 5000000.0f);
+                    AttackStart(m_creature->getVictim());
+                }
+            }
+            else if(!m_creature->HasAura(SPELL_AZZINOTH_CHANNEL, 0))
+            {
+                Glaive->CastSpell(m_creature, SPELL_AZZINOTH_CHANNEL, false);
+                m_creature->RemoveAurasDueToSpell(SPELL_FLAME_ENRAGE);
+            }
+        }
+    }
+
+    void SetGlaiveGUID(uint64 guid){ GlaiveGUID = guid; }
+
+    void UpdateAI(const uint32 diff)
+    {
+        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+            return;
+
+        if(FlameBlastTimer < diff)
+        {
+            DoCast(m_creature->getVictim(), SPELL_BLAZE_SUMMON, true); //appear at victim
+            DoCast(m_creature->getVictim(), SPELL_FLAME_BLAST);
+            FlameBlastTimer = 15000; //10000 is official-like?
+            DoZoneInCombat(); //in case someone is revived
+        }else FlameBlastTimer -= diff;
+
+        if(CheckTimer < diff)
+        {
+            ChargeCheck();
+            EnrageCheck();
+            CheckTimer = 5000;
+        }else CheckTimer -= diff;
+
+        DoMeleeAttackIfReady();
+    }
+};
+
+
+
+/******* Functions and vars for Akama's AI ******/
+struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI
+{
+    npc_akama_illidanAI(Creature* c) : ScriptedAI(c)
+    {
+        pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        Reset();
+    }
+
+    ScriptedInstance* pInstance;
+
+    PhaseAkama Phase;
+    bool Event;
+    uint32 Timer;
+
     uint64 IllidanGUID;
-
-    bool IsTrigger;
-
-    uint32 CheckTimer;
-    uint32 DemonFireTimer;
-    uint32 DespawnTimer;
+    uint64 ChannelGUID;
+    uint64 SpiritGUID[2];
+    uint64 GateGUID;
+    uint64 DoorGUID[2];
+
+    uint32 ChannelCount;
+    uint32 WalkCount;
+    uint32 TalkCount;
 
     void Reset()
     {
-        IllidanGUID = 0;
-
-        IsTrigger = false;
-
-        CheckTimer = 2000;
-        DemonFireTimer = 0;
-        DespawnTimer = 45000;
-    }
-
-    void Aggro(Unit *who) {}
-    void AttackStart(Unit* who) { }
-    void MoveInLineOfSight(Unit *who){ }
-
-    void UpdateAI(const uint32 diff)
-    {
-        if(IsTrigger)
-            return;
-
-        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-
-        if(CheckTimer < diff)
-        {
-            if(!IllidanGUID && pInstance)
-            {
-                IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE);
-                if(IllidanGUID)
-                {
-                    Unit* Illidan = Unit::GetUnit((*m_creature), IllidanGUID);
-                    if(Illidan && !Illidan->HasUnitMovementFlag(MOVEMENTFLAG_LEVITATING))
-                        m_creature->setDeathState(JUST_DIED);
-                }
-            }
-            CheckTimer = 2000;
-        }else CheckTimer -= diff;
-
-        if(DemonFireTimer < diff)
-        {
-            DoCast(m_creature, SPELL_DEMON_FIRE);
-            DemonFireTimer = 30000;
-        }else DemonFireTimer -= diff;
-
-        if(DespawnTimer < diff)
-            m_creature->setDeathState(JUST_DIED);
-        else DespawnTimer -= diff;
-
-        DoMeleeAttackIfReady();
-    }
-};
-
-/******* Functions and vars for Akama's AI ******/
-struct TRINITY_DLL_SPEC npc_akama_illidanAI : public ScriptedAI
-{
-    npc_akama_illidanAI(Creature* c) : ScriptedAI(c)
-    {
-        pInstance = ((ScriptedInstance*)c->GetInstanceData());
-        WayPointList.clear();
-        Reset();
-    }
-
-    /* Instance Data */
-    ScriptedInstance* pInstance;
-
-    /* Timers */
-    uint32 ChannelTimer;
-    uint32 TalkTimer;
-    uint32 WalkTimer;
-    uint32 SummonMinionTimer;
-
-    /* GUIDs */
-    uint64 IllidanGUID;
-    uint64 PlayerGUID;
-    uint64 SpiritGUID[2];
-    uint64 ChannelGUID;
-
-    bool IsTalking;
-    bool StartChanneling;
-    bool DoorOpen;
-    bool FightMinions;
-    bool IsReturningToIllidan;
-    bool IsWalking;
-    uint32 TalkCount;
-    uint32 ChannelCount;
-
-    std::list<WayPoints> WayPointList;
-    std::list<WayPoints>::iterator WayPoint;
-
-    void BeginEvent(uint64 PlayerGUID);
-    void Aggro(Unit *who) {}
-
-    void Reset()
-    {
         if(pInstance)
         {
             pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, NOT_STARTED);
-            GameObject* Gate = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_GATE));
-            if( Gate && !Gate->GetGoState() )
-                Gate->SetGoState(1);                        // close door if already open (when raid wipes or something)
-
-            for(uint8 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L + 1; ++i)
-            {
-                GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i));
-                if(Door)
-                    Door->SetGoState(0);
-            }
-        }
-
-        IllidanGUID = 0;
-        PlayerGUID  = 0;
+
+            IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE);
+            GateGUID = pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_GATE);
+            DoorGUID[0] = pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_DOOR_R);
+            DoorGUID[1] = pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_DOOR_L);
+
+            if(GETGO(Gate, GateGUID))
+                Gate->SetUInt32Value(GAMEOBJECT_STATE, 1);
+            for(uint8 i = 0; i < 2; i++)
+                if(GETGO(Door, DoorGUID[i]))
+                    Door->SetUInt32Value(GAMEOBJECT_STATE, 1);
+        }
+        else
+        {
+            IllidanGUID = 0;
+            GateGUID = 0;
+            DoorGUID[0] = 0;
+            DoorGUID[1] = 0;
+        }
+
         ChannelGUID = 0;
-        for(uint8 i = 0; i < 2; ++i) SpiritGUID[i] = 0;
-
-        ChannelTimer = 0;
+        SpiritGUID[0] = 0;
+        SpiritGUID[1] = 0;
+
+        Phase = PHASE_AKAMA_NULL;
+        Timer = 0;
+
         ChannelCount = 0;
-        SummonMinionTimer = 2000;
-
-        WalkTimer = 0;
-
-        TalkTimer = 0;
+        WalkCount = 0;
         TalkCount = 0;
 
         KillAllElites();
 
-        IsReturningToIllidan = false;
-        FightMinions = false;
-        IsTalking = false;
-        StartChanneling = false;
-        DoorOpen = false;
-
-        m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0);      // Database sometimes has strange values..
+        m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0); // Database sometimes has strange values..
         m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
-        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-        m_creature->SetVisibility(VISIBILITY_ON);
     }
 
@@ -439,9 +1156,19 @@
     void EnterEvadeMode()
     {
-        InCombat = false;
-
+        m_creature->InterruptNonMeleeSpells(true);
         m_creature->RemoveAllAuras();
         m_creature->DeleteThreatList();
         m_creature->CombatStop();
+        InCombat = false;
+    }
+
+    void Aggro(Unit *who) {}
+
+    void MovementInform(uint32 MovementType, uint32 Data) {Timer = 1;}
+
+    void DamageTaken(Unit *done_by, uint32 &damage)
+    {
+        if(damage > m_creature->GetHealth() || done_by->GetGUID() != IllidanGUID)
+            damage = 0;
     }
 
@@ -455,1479 +1182,517 @@
                 pUnit->setDeathState(JUST_DIED);
         }
-    }
-
-    void ReturnToIllidan()
-    {
-        KillAllElites();
-        InCombat = false;
-        FightMinions = false;
-        IsReturningToIllidan = true;
-        WayPoint = WayPointList.begin();
-        m_creature->SetSpeed(MOVE_RUN, 2.0f);
+        EnterEvadeMode();
+    }
+
+    void BeginTalk()
+    {
+        pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, IN_PROGRESS);
+
+        for(uint8 i = 0; i < 2; i++)
+            if(GETGO(Door, DoorGUID[i]))
+                Door->SetUInt32Value(GAMEOBJECT_STATE, 1);
+
+        if(GETCRE(Illidan, IllidanGUID))
+        {
+            Illidan->RemoveAurasDueToSpell(SPELL_KNEEL);
+            m_creature->SetInFront(Illidan);
+            Illidan->SetInFront(m_creature);
+            m_creature->StopMoving();
+            Illidan->StopMoving();
+            ((boss_illidan_stormrageAI*)Illidan->AI())->AkamaGUID = m_creature->GetGUID();
+            ((boss_illidan_stormrageAI*)Illidan->AI())->EnterPhase(PHASE_TALK_SEQUENCE);
+        }
+    }
+
+    void BeginChannel()
+    {
+        float x, y, z;
+        if(GETGO(Gate, GateGUID))
+            Gate->GetPosition(x, y, z);
+
+        if(Creature* Channel = m_creature->SummonCreature(ILLIDAN_DOOR_TRIGGER, x, y, z+5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000))
+        {
+            ChannelGUID = Channel->GetGUID();
+            Channel->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); // Invisible but spell visuals can still be seen.
+            m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+            DoCast(Channel, SPELL_AKAMA_DOOR_FAIL);
+        }
+
+        for(uint8 i = 0; i < 2; ++i)
+            if(Creature* Spirit = m_creature->SummonCreature(i ? SPIRIT_OF_OLUM : SPIRIT_OF_UDALO, SpiritSpawns[i].x, SpiritSpawns[i].y, SpiritSpawns[i].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000))
+            {
+                Spirit->SetVisibility(VISIBILITY_OFF);
+                SpiritGUID[i] = Spirit->GetGUID();
+            }
+    }
+
+    void BeginWalk()
+    {
         m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
-        IsWalking = true;
-    }
-
-    void AddWaypoint(uint32 id, float x, float y, float z)
-    {
-        WayPoints AkamaWP(id, x, y, z);
-        WayPointList.push_back(AkamaWP);
-    }
-
-    void DamageTaken(Unit *done_by, uint32 &damage)
-    {
-        if(damage > m_creature->GetHealth() && (done_by->GetGUID() != m_creature->GetGUID()))
-        {
-            damage = 0;
-            DoCast(m_creature, SPELL_HEALING_POTION);
-        }
-    }
-
-    void BeginDoorEvent(Player* player)
-    {
-        if(!pInstance)
-            return;
-
-        outstring_log("SD2: Akama - Door event initiated by player %s", player->GetName());
-        PlayerGUID = player->GetGUID();
-
-        GameObject* Gate = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_GATE));
-        if(Gate)
-        {
-            float x,y,z;
-            Gate->GetPosition(x, y, z);
-            Creature* Channel = m_creature->SummonCreature(ILLIDAN_DOOR_TRIGGER, x, y, z+5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000);
-            if(Channel)
-            {
-                ChannelGUID = Channel->GetGUID();
-                // Invisible but spell visuals can still be seen.
-                Channel->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
-                Channel->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-                float PosX, PosY, PosZ;
-                m_creature->GetPosition(PosX, PosY, PosZ);
-                for(uint8 i = 0; i < 2; ++i)
+        m_creature->SetSpeed(MOVE_RUN, 1.0f);
+        m_creature->GetMotionMaster()->MovePoint(0, AkamaWP[WalkCount].x, AkamaWP[WalkCount].y, AkamaWP[WalkCount].z);
+    }
+
+    void EnterPhase(PhaseAkama NextPhase)
+    {
+        if(!pInstance)  return;
+        switch(NextPhase)
+        {
+        case PHASE_CHANNEL:
+            BeginChannel();
+            Timer = 5000;
+            ChannelCount = 0;
+            break;
+        case PHASE_WALK:
+            if(Phase == PHASE_CHANNEL)
+                WalkCount = 0;
+            else if(Phase == PHASE_TALK)
+            {
+                if(GETCRE(Illidan, IllidanGUID))
+                    ((boss_illidan_stormrageAI*)Illidan->AI())->DeleteFromThreatList(m_creature->GetGUID());
+                EnterEvadeMode();
+                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+                WalkCount++;
+            }
+            BeginWalk();
+            Timer = 0;
+            break;
+        case PHASE_TALK:
+            if(Phase == PHASE_WALK)
+            {
+                BeginTalk();
+                Timer = 0;
+            }
+            else if(Phase == PHASE_FIGHT_ILLIDAN)
+            {
+                Timer = 1;
+                TalkCount = 0;
+            }
+            break;
+        case PHASE_FIGHT_ILLIDAN:
+            if(GETUNIT(Illidan, IllidanGUID))
+            {
+                m_creature->AddThreat(Illidan, 10000000.0f);
+                m_creature->GetMotionMaster()->MoveChase(Illidan);
+            }
+            Timer = 30000; //chain lightning
+            break;
+        case PHASE_FIGHT_MINIONS:
+            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+            Timer = 10000 + rand()%6000;//summon minion
+            break;
+        case PHASE_RETURN:
+            m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+            KillAllElites();
+            WalkCount = 0;
+            BeginWalk();
+            Timer = 1;
+            break;
+        default:
+            break;
+        }
+        Phase = NextPhase;
+        Event = false;
+    }
+
+    void HandleTalkSequence()
+    {
+        switch(TalkCount)
+        {
+        case 0:
+            if(GETCRE(Illidan, IllidanGUID))
+            {
+                ((boss_illidan_stormrageAI*)Illidan->AI())->Timer[EVENT_TAUNT] += 30000;
+                Illidan->Yell(SAY_AKAMA_MINION, LANG_UNIVERSAL, 0);
+                DoPlaySoundToSet(Illidan, SOUND_AKAMA_MINION);
+            }
+            Timer = 8000;
+            break;
+        case 1:
+            DoYell(SAY_AKAMA_LEAVE, LANG_UNIVERSAL, NULL);
+            DoPlaySoundToSet(m_creature, SOUND_AKAMA_LEAVE);
+            Timer = 3000;
+            break;
+        case 2:
+            EnterPhase(PHASE_WALK);
+            break;
+        }
+        TalkCount++;
+    }
+
+    void HandleChannelSequence()
+    {
+        Unit* Channel, *Spirit[2];
+        if(ChannelCount <= 5)
+        {
+            Channel = Unit::GetUnit((*m_creature), ChannelGUID);
+            Spirit[0] = Unit::GetUnit((*m_creature), SpiritGUID[0]);
+            Spirit[1] = Unit::GetUnit((*m_creature), SpiritGUID[1]);
+            if(!Channel || !Spirit[0] || !Spirit[1])
+                return;
+        }
+
+        switch(ChannelCount)
+        {
+        case 0: // channel failed
+            m_creature->InterruptNonMeleeSpells(true);
+            Timer = 2000;
+            break;
+        case 1: // spirit appear
+            Spirit[0]->SetVisibility(VISIBILITY_ON);
+            Spirit[1]->SetVisibility(VISIBILITY_ON);
+            Timer = 2000;
+            break;
+        case 2: // spirit help
+            DoCast(Channel, SPELL_AKAMA_DOOR_CHANNEL);
+            Spirit[0]->CastSpell(Channel, SPELL_DEATHSWORN_DOOR_CHANNEL,false);
+            Spirit[1]->CastSpell(Channel, SPELL_DEATHSWORN_DOOR_CHANNEL,false);
+            Timer = 5000;
+            break;
+        case 3: //open the gate
+            m_creature->InterruptNonMeleeSpells(true);
+            Spirit[0]->InterruptNonMeleeSpells(true);
+            Spirit[1]->InterruptNonMeleeSpells(true);
+            if(GETGO(Gate, GateGUID))
+                Gate->SetUInt32Value(GAMEOBJECT_STATE, 0);
+            Timer = 2000;
+            break;
+        case 4:
+            m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
+            Timer = 2000;
+            break;
+        case 5:
+            DoYell(SAY_AKAMA_BEWARE, LANG_UNIVERSAL, NULL);
+            DoPlaySoundToSet(m_creature, SOUND_AKAMA_BEWARE);
+            Channel->setDeathState(JUST_DIED);
+            Spirit[0]->setDeathState(JUST_DIED);
+            Spirit[1]->setDeathState(JUST_DIED);
+            Timer = 3000;
+            break;
+        case 6:
+            EnterPhase(PHASE_WALK);
+            break;
+        default:
+            break;
+        }
+        ChannelCount++;
+    }
+
+    void HandleWalkSequence()
+    {
+        switch(WalkCount)
+        {
+        case 6:
+            for(uint8 i = 0; i < 2; i++)
+                if(GETGO(Door, DoorGUID[i]))
+                    Door->SetUInt32Value(GAMEOBJECT_STATE, 0);
+            break;
+        case 8:
+            if(Phase == PHASE_WALK)
+                EnterPhase(PHASE_TALK);
+            else
+                EnterPhase(PHASE_FIGHT_ILLIDAN);
+            break;
+        case 12:
+            EnterPhase(PHASE_FIGHT_MINIONS);
+            break;
+        }
+
+        if(Phase == PHASE_WALK)
+        {
+            Timer = 0;
+            WalkCount++;
+            m_creature->GetMotionMaster()->MovePoint(WalkCount, AkamaWP[WalkCount].x, AkamaWP[WalkCount].y, AkamaWP[WalkCount].z);
+        }
+    }
+
+    void UpdateAI(const uint32 diff)
+    {
+        Event = false;
+        if(Timer)
+        {
+            if(Timer <= diff)
+                Event = true;
+            else Timer -= diff;
+        }
+
+        if(Event)
+        {
+            switch(Phase)
+            {
+            case PHASE_CHANNEL:
+                HandleChannelSequence();
+                break;
+            case PHASE_TALK:
+                HandleTalkSequence();
+                break;
+            case PHASE_WALK:
+            case PHASE_RETURN:
+                HandleWalkSequence();
+                break;
+            case PHASE_FIGHT_ILLIDAN:
                 {
-                    Creature* Spirit = m_creature->SummonCreature(SpiritSpawns[i].id, SpiritSpawns[i].x, SpiritSpawns[i].y, SpiritSpawns[i].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000);
-                    if(Spirit)
+                    GETUNIT(Illidan, IllidanGUID);
+                    if(Illidan && HPPCT(Illidan) < 90)
+                        EnterPhase(PHASE_TALK);
+                    else
                     {
-                        Spirit->SetVisibility(VISIBILITY_OFF);
-                        SpiritGUID[i] = Spirit->GetGUID();
+                        DoCast(m_creature->getVictim(), SPELL_CHAIN_LIGHTNING);
+                        Timer = 30000;
                     }
-                }
-                StartChanneling = true;
-                m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
-                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-                DoCast(Channel, SPELL_AKAMA_DOOR_FAIL);
-            }
-        }
-    }
-
-    void MovementInform(uint32 type, uint32 id)
-    {
-        if(type != POINT_MOTION_TYPE || !IsWalking)
-            return;
-
-        if(WayPoint->id != id)
-            return;
-
-        switch(id)
-        {
-            case 6:
-                if(!IsReturningToIllidan)
-                {                                           // open the doors that close the summit
-                    for(uint32 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L+1; ++i)
+                }break;
+            case PHASE_FIGHT_MINIONS:
+                {
+                    float x, y, z;
+                    m_creature->GetPosition(x, y, z);
+                    Creature* Elite = m_creature->SummonCreature(ILLIDARI_ELITE, x+rand()%10, y+rand()%10, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000);
+                    //Creature* Elite = m_creature->SummonCreature(ILLIDARI_ELITE, x, y, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000);
+                    if(Elite)
                     {
-                        GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i));
-                        if(Door)
-                            Door->SetGoState(0);
+                        Elite->AI()->AttackStart(m_creature);
+                        Elite->AddThreat(m_creature, 1000000.0f);
+                        AttackStart(Elite);
                     }
-                }
-            case 7:
-                if(IsReturningToIllidan)
-                {
-                    IsWalking = false;
-                    if(IllidanGUID)
-                    {
-                        Unit* Illidan = Unit::GetUnit((*m_creature), IllidanGUID);
-                        if(Illidan)
-                        {
-                            float dx = Illidan->GetPositionX() + rand()%15;
-                            float dy = Illidan->GetPositionY() + rand()%15;
-                            m_creature->GetMotionMaster()->MovePoint(13, dx, dy, Illidan->GetPositionZ());
-                            m_creature->SetUInt64Value(UNIT_FIELD_TARGET, IllidanGUID);
-                        }
-                    }
+                    Timer = 10000 + rand()%6000;
+                    GETUNIT(Illidan, IllidanGUID);
+                    if(Illidan && HPPCT(Illidan) < 10)
+                        EnterPhase(PHASE_RETURN);
                 }
                 break;
-            case 8:
-                m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-                if(!IsReturningToIllidan)
+            default:
+                break;
+            }
+        }
+
+        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+            return;
+
+        if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 20)
+            DoCast(m_creature, SPELL_HEALING_POTION);
+
+        DoMeleeAttackIfReady();
+    }
+};
+
+
+struct TRINITY_DLL_DECL boss_maievAI : public ScriptedAI
+{
+    boss_maievAI(Creature *c) : ScriptedAI(c) { Reset(); };
+
+    uint64 IllidanGUID;
+
+    PhaseIllidan Phase;
+    EventMaiev Event;
+    uint32 Timer[5];
+    uint32 MaxTimer;
+
+    void Reset()
+    {
+        MaxTimer = 0;
+        Phase = PHASE_NORMAL_MAIEV;
+        IllidanGUID = 0;
+        Timer[EVENT_MAIEV_STEALTH] = 0;
+        Timer[EVENT_MAIEV_TAUNT] = 22000 + rand()%21 * 1000;
+        Timer[EVENT_MAIEV_SHADOW_STRIKE] = 30000;
+        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 44850);
+        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 0);
+        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 2, 45738);
+    }
+
+    void Aggro(Unit *who) {}
+    void MoveInLineOfSight(Unit *who) {}
+    void EnterEvadeMode() {}
+    void GetIllidanGUID(uint64 guid) { IllidanGUID = guid; }
+
+    void DamageTaken(Unit *done_by, uint32 &damage)
+    {
+        if(done_by->GetGUID() != IllidanGUID )
+            damage = 0;
+        else
+        {
+            GETUNIT(Illidan, IllidanGUID);
+            if(Illidan && Illidan->getVictim() == m_creature)
+                damage = m_creature->GetMaxHealth()/10;
+            if(damage >= m_creature->GetHealth())
+                damage = 0;
+        }
+    }
+
+    void AttackStart(Unit *who)
+    {
+        if(!who || Timer[EVENT_MAIEV_STEALTH])
+            return;
+
+        if (who->isTargetableForAttack())
+        {
+            if(Phase == PHASE_TALK_SEQUENCE)
+                m_creature->Attack(who, false);
+            else if(Phase == PHASE_DEMON || Phase == PHASE_TRANSFORM_SEQUENCE )
+            {
+                GETUNIT(Illidan, IllidanGUID);
+                if(Illidan && m_creature->IsWithinDistInMap(Illidan, 25))
+                    BlinkToPlayer();//Do not let dread aura hurt her.
+                m_creature->Attack(who, false);
+            }
+            else
+                DoStartAttackAndMovement(who);
+
+            if (!InCombat)
+            {
+                Aggro(who);
+                InCombat = true;
+            }
+        }
+    }
+
+    void EnterPhase(PhaseIllidan NextPhase)//This is in fact Illidan's phase.
+    {
+        switch(NextPhase)
+        {
+        case PHASE_TALK_SEQUENCE:
+            if(Timer[EVENT_MAIEV_STEALTH])
+            {
+                m_creature->SetHealth(m_creature->GetMaxHealth());
+                m_creature->SetVisibility(VISIBILITY_ON);
+                Timer[EVENT_MAIEV_STEALTH] = 0;
+            }
+            m_creature->InterruptNonMeleeSpells(false);
+            m_creature->GetMotionMaster()->Clear(false);
+            //m_creature->GetMotionMaster()->MoveIdle();
+            m_creature->AttackStop();
+            m_creature->SetUInt64Value(UNIT_FIELD_TARGET, IllidanGUID);
+            MaxTimer = 0;
+            break;
+        case PHASE_TRANSFORM_SEQUENCE:
+            MaxTimer = 4;
+            Timer[EVENT_MAIEV_TAUNT] += 10000;
+            Timer[EVENT_MAIEV_THROW_DAGGER] = 2000;
+            break;
+        case PHASE_DEMON:
+            break;
+        case PHASE_NORMAL_MAIEV:
+            MaxTimer = 4;
+            Timer[EVENT_MAIEV_TAUNT] += 10000;
+            Timer[EVENT_MAIEV_TRAP] = 22000;
+            break;
+        default:
+            break;
+        }
+        if(Timer[EVENT_MAIEV_STEALTH])
+            MaxTimer = 1;
+        Phase = NextPhase;
+    }
+
+    void BlinkTo(float x, float y, float z)
+    {
+        m_creature->AttackStop();
+        m_creature->InterruptNonMeleeSpells(false);
+        m_creature->GetMotionMaster()->Clear(false);
+        //m_creature->GetMotionMaster()->MoveIdle();
+        m_creature->Relocate(x, y, z);
+        m_creature->SendMonsterMove(x, y, z, 0, 0, 0);
+        DoCast(m_creature, SPELL_TELEPORT_VISUAL, true);
+    }
+
+    void BlinkToPlayer()
+    {
+        if(GETCRE(Illidan, IllidanGUID))
+        {
+            Unit* target = ((boss_illidan_stormrageAI*)Illidan->AI())->SelectUnit(SELECT_TARGET_RANDOM, 0);
+
+            if(!target || !m_creature->IsWithinDistInMap(target, 80) || Illidan->IsWithinDistInMap(target, 20))
+            {
+                uint8 pos = rand()%4;
+                BlinkTo(HoverPosition[pos].x, HoverPosition[pos].y, HoverPosition[pos].z);
+            }
+            else
+            {
+                float x, y, z;
+                target->GetPosition(x, y, z);
+                BlinkTo(x, y, z);
+            }
+        }
+    }
+
+    void UpdateAI(const uint32 diff)
+    {
+        if((!m_creature->SelectHostilTarget() || !m_creature->getVictim()) && !Timer[1])
+            return;
+
+        Event = EVENT_MAIEV_NULL;
+        for(uint8 i = 1; i <= MaxTimer; i++)
+            if(Timer[i])
+            {
+                if(Timer[i] <= diff)
+                    Event = (EventMaiev)i;
+                else Timer[i] -= diff;
+            }
+
+            switch(Event)
+            {
+            case EVENT_MAIEV_STEALTH:
                 {
-                    IsWalking = false;
-                    BeginEvent(PlayerGUID);
-                }
+                    m_creature->SetHealth(m_creature->GetMaxHealth());
+                    m_creature->SetVisibility(VISIBILITY_ON);
+                    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+                    Timer[EVENT_MAIEV_STEALTH] = 0;
+                    BlinkToPlayer();
+                    EnterPhase(Phase);
+                }break;
+            case EVENT_MAIEV_TAUNT:
+                {
+                    uint32 random = rand()%4;
+                    char* text = MaievTaunts[random].text;
+                    uint32 sound = MaievTaunts[random].sound;
+                    DoYell(text, LANG_UNIVERSAL, NULL);
+                    DoPlaySoundToSet(m_creature, sound);
+                    Timer[EVENT_MAIEV_TAUNT] = 22000 + rand()%21 * 1000;
+                }break;
+            case EVENT_MAIEV_SHADOW_STRIKE:
+                DoCast(m_creature->getVictim(), SPELL_SHADOW_STRIKE);
+                Timer[EVENT_MAIEV_SHADOW_STRIKE] = 60000;
                 break;
-            case 12:
-                IsWalking = false;
-                FightMinions = true;
-                m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-                break;
-        }
-
-        ++WayPoint;
-        WalkTimer = 200;
-    }
-
-    void DeleteFromThreatList()
-    {
-        if(!IllidanGUID) return;                            // If we do not have Illidan's GUID, do not proceed
-                                                            // Create a pointer to Illidan
-        Creature* Illidan = ((Creature*)Unit::GetUnit((*m_creature), IllidanGUID));
-        if(!Illidan) return;                                // No use to continue if Illidan does not exist
-        std::list<HostilReference*>::iterator itr = Illidan->getThreatManager().getThreatList().begin();
-        for( ; itr != Illidan->getThreatManager().getThreatList().end(); ++itr)
-        {
-            // Loop through threatlist till our GUID is found in it.
-            if((*itr)->getUnitGuid() == m_creature->GetGUID())
-            {
-                (*itr)->removeReference();                  // Delete ourself from his threatlist.
-                return;                                     // No need to continue anymore.
-            }
-        }
-
-        // Now we delete our threatlist to prevent attacking anyone for now
-        m_creature->DeleteThreatList();
-    }
-
-    void UpdateAI(const uint32 diff)
-    {
-        if(IllidanGUID)
-        {
-            Creature* Illidan = ((Creature*)Unit::GetUnit((*m_creature), IllidanGUID));
-            if(Illidan)
-            {
-                if(Illidan->IsInEvadeMode() && !m_creature->IsInEvadeMode())
-                    EnterEvadeMode();
-
-                if(((Illidan->GetHealth()*100 / Illidan->GetMaxHealth()) < 85) && InCombat && !FightMinions)
+            case EVENT_MAIEV_TRAP:
+                if(Phase == PHASE_NORMAL_MAIEV)
                 {
-                    if(TalkTimer < diff)
-                    {
-                        switch(TalkCount)
-                        {
-                            case 0:
-                                Illidan->Yell(SAY_AKAMA_MINION, LANG_UNIVERSAL, 0);
-                                DoPlaySoundToSet(Illidan, SOUND_AKAMA_MINION);
-                                TalkTimer = 8000;
-                                TalkCount = 1;
-                                break;
-                            case 1:
-                                DoYell(SAY_AKAMA_LEAVE, LANG_UNIVERSAL, NULL);
-                                DoPlaySoundToSet(m_creature, SOUND_AKAMA_LEAVE);
-                                TalkTimer = 3000;
-                                TalkCount = 2;
-                                break;
-                            case 2:
-                                IsTalking = true;
-                                TalkTimer = 2000;
-                                m_creature->RemoveAllAuras();
-                                m_creature->CombatStop();
-                                m_creature->AttackStop();
-                                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-                                TalkCount = 3;
-                                break;
-                            case 3:
-                                DeleteFromThreatList();
-                                IsWalking = true;
-                                WayPoint = WayPointList.begin();
-                                std::advance(WayPoint, 9);
-                                m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
-                                break;
-                        }
-                    }else TalkTimer -= diff;
-                }
-
-                if(((Illidan->GetHealth()*100 / Illidan->GetMaxHealth()) < 4) && !IsReturningToIllidan)
-                    ReturnToIllidan();
-            }
-        }else
-        {
-            if(pInstance)
-                IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE);
-        }
-
-        if(IsWalking && WalkTimer)
-        {
-            if(WalkTimer <= diff)
-            {
-                if(WayPoint == WayPointList.end())
-                    return;
-                m_creature->GetMotionMaster()->MovePoint(WayPoint->id, WayPoint->x, WayPoint->y,WayPoint->z);
-                WalkTimer = 0;
-            }else WalkTimer -= diff;
-        }
-
-        if(StartChanneling)
-        {
-            if(ChannelTimer < diff)
-            {
-                switch(ChannelCount)
-                {
-                    case 3:
-                        if(!DoorOpen)
-                        {
-                            m_creature->InterruptNonMeleeSpells(true);
-                            for(uint8 i = 0; i < 2; ++i)
-                            {
-                                if(SpiritGUID[i])
-                                {
-                                    Unit* Spirit = Unit::GetUnit((*m_creature), SpiritGUID[i]);
-                                    if(Spirit)
-                                        Spirit->InterruptNonMeleeSpells(true);
-                                }
-                            }
-                            GameObject* Gate = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_GATE));
-                            if(Gate)
-                                Gate->SetGoState(0);
-                            ChannelCount++;
-                            ChannelTimer = 5000;
-                        }
-                        break;
-                    case 4:
-                        m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
-                        ChannelTimer = 2000;
-                        ChannelCount++;
-                        break;
-                    case 5:
-                        DoYell(SAY_AKAMA_BEWARE, LANG_UNIVERSAL, NULL);
-                        DoPlaySoundToSet(m_creature, SOUND_AKAMA_BEWARE);
-                        if(ChannelGUID)
-                        {
-                            Unit* ChannelTarget = Unit::GetUnit((*m_creature), ChannelGUID);
-                            if(ChannelTarget)
-                                ChannelTarget->setDeathState(JUST_DIED);
-                        }
-                        for(uint8 i = 0; i < 2; ++i)
-                        {
-                            if(SpiritGUID[i])
-                            {
-                                Unit* Spirit = Unit::GetUnit((*m_creature), SpiritGUID[i]);
-                                if(Spirit)
-                                    Spirit->setDeathState(JUST_DIED);
-                            }
-                        }
-                        ChannelTimer = 6000;
-                        ChannelCount++;
-                        break;
-                    case 6:
-                        StartChanneling = false;
-                        if(WayPointList.empty())
-                        {
-                            error_log("SD2: Akama has no waypoints to start with!");
-                            return;
-                        }
-
-                        WayPoint = WayPointList.begin();
-                        m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
-                        m_creature->GetMotionMaster()->MovePoint(WayPoint->id, WayPoint->x, WayPoint->y, WayPoint->z);
-                        IsWalking = true;
-                        break;
-                    default:
-                        if(ChannelGUID)
-                        {
-                            Unit* Channel = Unit::GetUnit((*m_creature), ChannelGUID);
-                            if(Channel)
-                            {
-                                m_creature->InterruptNonMeleeSpells(true);
-
-                                for(uint8 i = 0; i < 2; ++i)
-                                {
-                                    if(SpiritGUID[i])
-                                    {
-                                        Unit* Spirit = Unit::GetUnit((*m_creature), SpiritGUID[i]);
-                                        if(Spirit)
-                                        {
-                                            Spirit->InterruptNonMeleeSpells(true);
-                                            if(ChannelCount%2 == 0)
-                                            {
-                                                Spirit->CastSpell(Channel, SPELL_DEATHSWORN_DOOR_CHANNEL,false);
-                                                DoCast(Channel, SPELL_AKAMA_DOOR_CHANNEL);
-                                            }
-                                            else
-                                            {
-                                                if(Spirit->GetVisibility() == VISIBILITY_OFF)
-                                                    Spirit->SetVisibility(VISIBILITY_ON);
-                                            }
-                                        }
-                                    }
-                                }
-                                if(ChannelCount < 3)
-                                    ChannelCount++;
-                                ChannelTimer = 10000;
-                            }
-                            break;
-                        }
-                }
-            }else ChannelTimer -= diff;
-        }
-
-        if(FightMinions)
-        {
-            if(SummonMinionTimer < diff)
-            {
-                if(IllidanGUID)
-                {
-                    Creature* Illidan = ((Creature*)Unit::GetUnit((*m_creature), IllidanGUID));
-                    if(!Illidan || Illidan->IsInEvadeMode())
-                    {
-                        Reset();
-                        EnterEvadeMode();
-                        return;
-                    }
-                }
-
-                float x,y,z;
-                m_creature->GetPosition(x,y,z);
-                Creature* Elite = m_creature->SummonCreature(ILLIDARI_ELITE, x+rand()%10, y+rand()%10, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000);
-                if(Elite)
-                {
-                    Elite->AI()->AttackStart(m_creature);
-                    Elite->AddThreat(m_creature, 1000000.0f);
-                    AttackStart(Elite);
-                }
-                SummonMinionTimer = 10000 + rand()%6000;
-            }else SummonMinionTimer -= diff;
-        }
-
-        // If we don't have a target, or is talking, or has run away, return
-        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) return;
-
-        DoMeleeAttackIfReady();
-    }
-};
-
-/************* Custom check used for Agonizing Flames ***************/
-class AgonizingFlamesTargetCheck
-{
-    public:
-        AgonizingFlamesTargetCheck(Unit const* unit) : pUnit(unit) {}
-        bool operator() (Player* plr)
-        {
-            // Faster than square rooting
-            if(!plr->isGameMaster() && pUnit->GetDistance2d(plr) > 225)
-                return true;
-
-            return false;
-        }
-
-    private:
-        Unit const* pUnit;
-};
-
-/************************************** Illidan's AI ***************************************/
-struct TRINITY_DLL_SPEC boss_illidan_stormrageAI : public ScriptedAI
-{
-    boss_illidan_stormrageAI(Creature* c) : ScriptedAI(c)
-    {
-        pInstance = ((ScriptedInstance*)c->GetInstanceData());
-        Reset();
-    }
-
-    /** Instance Data **/
-    ScriptedInstance* pInstance;
-
-    /** Generic **/
-    bool IsTalking;
-    bool HasSummoned;
-    bool RefaceVictim;
-    bool InformAkama;
-    uint32 Phase;
-    uint32 GlobalTimer;
-    uint32 TalkCount;
-    uint32 DemonFormSequence;
-
-    /** GUIDs **/
-    uint64 FlameGUID[2];
-    uint64 GlaiveGUID[2];
-    uint64 AkamaGUID;
-    uint64 MaievGUID;
-
-    /** Timers **/
-    uint32 ShearTimer;
-    uint32 DrawSoulTimer;
-    uint32 FlameCrashTimer;
-    uint32 ParasiticShadowFiendTimer;
-    uint32 FireballTimer;
-    uint32 EyeBlastTimer;
-    uint32 DarkBarrageTimer;
-    uint32 SummonBladesTimer;                               // Animate summoning the Blades of Azzinoth in Phase 2
-    uint32 SummonFlamesTimer;                               // Summon Flames of Azzinoth in Phase 2
-    uint32 CheckFlamesTimer;                                // This is used to check the status of the Flames to see if we should begin entering Phase 3 or not.
-    uint32 RetrieveBladesTimer;                             // Animate retrieving the Blades of Azzinoth in Phase 2 -> 3 transition
-    uint32 LandTimer;                                       // This is used at the end of phase 2 to signal Illidan landing after Flames are dead
-    uint32 AgonizingFlamesTimer;
-    uint32 ShadowBlastTimer;
-    uint32 FlameBurstTimer;
-    uint32 ShadowDemonTimer;
-    uint32 TalkTimer;
-    uint32 TransformTimer;
-    uint32 EnrageTimer;
-    uint32 CageTimer;
-    uint32 LayTrapTimer;
-    uint32 AnimationTimer;
-    uint32 TauntTimer;                                      // This is used for his random yells
-    uint32 FaceVictimTimer;
-    uint32 BerserkTimer;
-
-    void Reset()
-    {
-        Phase = PHASE_NORMAL;
-
-        // Check if any flames/glaives are alive/existing. Kill if alive and set GUIDs to 0
-        for(uint8 i = 0; i < 2; i++)
-        {
-            if(FlameGUID[i])
-            {
-                Unit* Flame = Unit::GetUnit((*m_creature), FlameGUID[i]);
-                if(Flame)
-                    Flame->setDeathState(JUST_DIED);
-                FlameGUID[i] = 0;
-            }
-
-            if(GlaiveGUID[i])
-            {
-                Unit* Glaive = Unit::GetUnit((*m_creature), GlaiveGUID[i]);
-                if(Glaive)
-                    Glaive->setDeathState(JUST_DIED);
-                GlaiveGUID[i] = 0;
-            }
-        }
-
-        if(AkamaGUID)
-        {
-            Creature* Akama = ((Creature*)Unit::GetUnit((*m_creature), AkamaGUID));
-            if(Akama)
-            {
-                if(!Akama->isAlive())
-                    Akama->Respawn();
-                ((npc_akama_illidanAI*)Akama->AI())->Reset();
-                ((npc_akama_illidanAI*)Akama->AI())->EnterEvadeMode();
-                Akama->GetMotionMaster()->MoveTargetedHome();
-            }
-        }
-
-        InformAkama = false;
-        RefaceVictim = false;
-        HasSummoned = false;
-        AkamaGUID = 0;
-        MaievGUID = 0;
-
-        FaceVictimTimer = 1000;
-        BerserkTimer = 1500000;
-        GlobalTimer = 0;
-        DemonFormSequence = 0;
-
-        /** Normal Form **/
-        ShearTimer = 20000 + (rand()%11 * 1000);            // 20 to 30 seconds
-        FlameCrashTimer = 30000;                            //30 seconds
-        ParasiticShadowFiendTimer = 25000;                  // 25 seconds
-        DrawSoulTimer = 50000;                              // 50 seconds
-
-        /** Phase 2 **/
-        SummonBladesTimer = 10000;
-        SummonFlamesTimer = 20000;                          // Phase 2 timers may be incorrect
-        FireballTimer = 5000;
-        DarkBarrageTimer = 45000;
-        EyeBlastTimer = 30000;
-        CheckFlamesTimer = 5000;
-        RetrieveBladesTimer = 5000;
-        LandTimer = 0;
-
-        /** Phase 3+ **/
-        AgonizingFlamesTimer = 35000;                       // Phase 3+ timers may be incorrect
-        ShadowBlastTimer = 3000;
-        FlameBurstTimer = 10000;
-        ShadowDemonTimer = 30000;
-        TransformTimer = 90000;
-        EnrageTimer = 40000;
-        CageTimer = 30000;
-        LayTrapTimer = CageTimer + 2000;
-        AnimationTimer = 0;
-
-        TauntTimer = 30000;                                 // This timer may be off.
-
-        m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 21135);
-        m_creature->InterruptNonMeleeSpells(false);
-        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-                                                            // Unequip warglaives if needed
-        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
-        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
-        m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
-
-        IsTalking = false;
-
-        TalkCount = 0;
-        TalkTimer = 0;
-
-        if(pInstance)
-            pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, NOT_STARTED);
-    }
-
-    void Aggro(Unit *who) { DoZoneInCombat(); }
-
-    void AttackStart(Unit *who)
-    {
-        if(!who || IsTalking || Phase == 2 || Phase == 4 || Phase == 6 || m_creature->HasAura(SPELL_KNEEL, 0))
-            return;
-
-        if (who->isTargetableForAttack() && who!= m_creature)
-        {
-            //Begin melee attack if we are within range
-            DoStartAttackAndMovement(who);
-        }
-    }
-
-    void MoveInLineOfSight(Unit *who)
-    {
-        if (!who || m_creature->getVictim() || IsTalking || m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
-            return;
-
-        if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
-        {
-            if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
-                return;
-
-            float attackRadius = m_creature->GetAttackDistance(who);
-            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who))
-            {
-                if(who->HasStealthAura())
-                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
-
-                DoStartAttackAndMovement(who);
-            }
-        }
-    }
-
-    void JustDied(Unit *killer)
-    {
-        IsTalking = false;
-        TalkCount = 0;
-        TalkTimer = 0;
-
-        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-
-        if(!pInstance)
-            return;
-                                                            // Completed
-        pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, DONE);
-
-        for(uint8 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L + 1; ++i)
-        {
-            GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i));
-            if(Door)
-                Door->SetGoState(0);                        // Open Doors
-        }
-
-    }
-
-    void KilledUnit(Unit *victim)
-    {
-        if(victim == m_creature) return;
-
-        switch(rand()%2)
-        {
-            case 0:
-                DoYell(SAY_KILL1, LANG_UNIVERSAL, victim);
-                DoPlaySoundToSet(m_creature, SOUND_KILL1);
-                break;
-            case 1:
-                DoYell(SAY_KILL2, LANG_UNIVERSAL, victim);
-                DoPlaySoundToSet(m_creature, SOUND_KILL2);
-                break;
-        }
-    }
-
-    void DamageTaken(Unit *done_by, uint32 &damage)
-    {
-        if(damage > m_creature->GetHealth())                // Don't let ourselves be slain before we do our death speech
-        {
-            damage = 0;
-            m_creature->SetHealth(m_creature->GetMaxHealth()/100);
-        }
-    }
-
-    void Cast(Unit* victim, uint32 Spell, bool triggered = false)
-    {
-        if(!victim)
-            return;
-
-        RefaceVictim = true;
-        m_creature->SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID());
-        m_creature->CastSpell(victim, Spell, triggered);
-    }
-
-    /** This will handle the cast of eye blast **/
-    void CastEyeBlast()
-    {
-        m_creature->InterruptNonMeleeSpells(false);
-
-        DarkBarrageTimer += 10000;
-
-        DoYell(SAY_EYE_BLAST, LANG_UNIVERSAL, NULL);
-        DoPlaySoundToSet(m_creature, SOUND_EYE_BLAST);
-
-        uint32 initial = rand()%4;
-        uint32 final = 0;
-        if(initial < 3)
-            final = initial+1;
-
-        float initial_X = EyeBlast[initial].x;
-        float initial_Y = EyeBlast[initial].y;
-        float initial_Z = EyeBlast[initial].z;
-
-        float final_X = EyeBlast[final].x;
-        float final_Y = EyeBlast[final].y;
-        float final_Z = EyeBlast[final].z;
-
-        for(uint8 i = 0; i < 2; ++i)
-        {
-            Creature* Trigger = NULL;
-            Trigger = m_creature->SummonCreature(DEMON_FIRE, initial_X, initial_Y, initial_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 20000);
-            if(Trigger)
-            {
-                ((demonfireAI*)Trigger->AI())->IsTrigger = true;
-                Trigger->GetMotionMaster()->MovePoint(0, final_X, final_Y, final_Z);
-
-                if(!i)
-                    Trigger->CastSpell(Trigger, SPELL_EYE_BLAST_TRIGGER, true);
-                else
-                {
-                    Trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-                    m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Trigger->GetGUID());
-                    DoCast(Trigger, SPELL_EYE_BLAST);
-                }
-            }
-        }
-    }
-
-    // It's only cast on players that are greater than 15 yards away from Illidan. If no one is found, cast it on MT instead (since selecting someone in that 15 yard radius would cause the flames to hit the MT anyway).
-    void CastAgonizingFlames()
-    {
-        // We'll use grid searching for this, using a custom searcher that selects a player that is at a distance >15 yards
-        Player* target = NULL;
-
-        CellPair pair(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
-        Cell cell(pair);
-        cell.data.Part.reserved = ALL_DISTRICT;
-        cell.SetNoCreate();
-
-        AgonizingFlamesTargetCheck check(m_creature);
-        Trinity::PlayerSearcher<AgonizingFlamesTargetCheck> searcher(target, check);
-        TypeContainerVisitor
-            <Trinity::PlayerSearcher<AgonizingFlamesTargetCheck>, GridTypeMapContainer> visitor(searcher);
-
-        CellLock<GridReadGuard> cell_lock(cell, pair);
-        cell_lock->Visit(cell_lock, visitor, *(m_creature->GetMap()));
-
-        if(target)
-            DoCast(target, SPELL_AGONIZING_FLAMES);
-        else
-            DoCast(m_creature->getVictim(), SPELL_AGONIZING_FLAMES);
-    }
-
-    void Talk(uint32 count)
-    {
-        if(!m_creature->isAlive()) return;
-        uint32 sound = Conversation[count].sound;
-        char* text = NULL;
-        if(Conversation[count].text)
-            text = Conversation[count].text;
-        TalkTimer = Conversation[count].timer;
-        uint32 emote = Conversation[count].emote;
-        IsTalking = Conversation[count].Talk;
-        Creature* creature = NULL;
-        uint64 GUID = 0;
-        if(Conversation[count].creature == ILLIDAN_STORMRAGE)
-            creature = m_creature;
-        else if(Conversation[count].creature == AKAMA)
-        {
-            if(!AkamaGUID)
-            {
-                if(pInstance)
-                {
-                    AkamaGUID = pInstance->GetData64(DATA_AKAMA);
-                    if(!AkamaGUID)
-                        return;
-                    GUID = AkamaGUID;
-                }
-            }
-            else GUID = AkamaGUID;
-        }
-        else if(Conversation[count].creature == MAIEV_SHADOWSONG)
-        {
-            if(!MaievGUID)
-                return;
-            GUID = MaievGUID;
-        }
-        else if(Conversation[count].creature == EMPTY)      // This is just for special cases without speech/sounds/emotes.
-            return;
-
-        if(GUID)                                            // Now we check if we actually specified a GUID, if so:
-                                                            // we grab a pointer to that creature
-            creature = ((Creature*)Unit::GetUnit((*m_creature), GUID));
-
-        if(creature)
-        {
-            creature->HandleEmoteCommand(emote);            // Make the creature do some animation!
-            if(text)
-                creature->Yell(text, LANG_UNIVERSAL, 0);    // Have the creature yell out some text
-            if(sound)
-                DoPlaySoundToSet(creature, sound);          // Play some sound on the creature
-        }
-    }
-
-    void Move(float X, float Y, float Z, Creature* _Creature)
-    {
-        _Creature->GetMotionMaster()->MovePoint(0, X, Y, Z);
-    }
-
-    void HandleDemonTransformAnimation(uint32 count)
-    {
-        uint32 unaura = DemonTransformation[count].unaura;
-        uint32 aura = DemonTransformation[count].aura;
-        uint32 displayid = DemonTransformation[count].displayid;
-        AnimationTimer = DemonTransformation[count].timer;
-        uint32 size = DemonTransformation[count].size;
-
-        m_creature->InterruptNonMeleeSpells(false);
-
-        if(DemonTransformation[count].phase != 8)
-        {
-            m_creature->GetMotionMaster()->Clear();
-            m_creature->GetMotionMaster()->MoveIdle();
-        }
-
-        if(unaura)
-            m_creature->RemoveAurasDueToSpell(unaura);
-
-        if(aura)
-            DoCast(m_creature, aura, true);
-
-        if(displayid)
-                                                            // It's morphin time!
-            m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, displayid);
-        /*if(size)
-            m_creature->SetUInt32Value(OBJECT_FIELD_SCALE_X, size); // Let us grow! (or shrink)*/
-
-        if(DemonTransformation[count].equip)
-        {
-                                                            // Requip warglaives if needed
-            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479);
-            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
-        }
-        else
-        {
-                                                            // Unequip warglaives if needed
-            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
-            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
-        }
-
-        if(DemonTransformation[count].phase != 8)
-            Phase = DemonTransformation[count].phase;       // Set phase properly
-        else
-        {
-                                                            // Refollow and attack our old victim
-            m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
-            if(MaievGUID) Phase = PHASE_NORMAL_MAIEV;       // Depending on whether we summoned Maiev, we switch to either phase 5 or 3
-            else Phase = PHASE_NORMAL_2;
-        }
-
-        if(count == 7)
-        {
-            DoResetThreat();
-            m_creature->RemoveAurasDueToSpell( SPELL_DEMON_FORM );
-        }
-        else if(count == 4)
-        {
-            DoResetThreat();
-            if(!m_creature->HasAura(SPELL_DEMON_FORM, 0))
-                DoCast(m_creature, SPELL_DEMON_FORM, true);
-        }
-    }
-
-    /** To reduce the amount of code in UpdateAI, we can seperate them into different functions and simply call them from UpdateAI **/
-    void EnterPhase2()
-    {
-        DoYell(SAY_TAKEOFF, LANG_UNIVERSAL, NULL);
-        DoPlaySoundToSet(m_creature, SOUND_TAKEOFF);
-
-        SummonBladesTimer = 10000;                          // Summon Glaives when this decrements
-        SummonFlamesTimer = 20000;                          // Summon Flames when this decrements
-        GlobalTimer += 20000;
-        LandTimer = 0;
-        Phase = PHASE_FLIGHT;
-        m_creature->RemoveAllAuras();
-        m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
-                                                            // So players don't shoot us down
-        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-                                                            // Animate our take off!
-        m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
-                                                            // We now hover!
-        m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
-        m_creature->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, CENTER_Z);
-        for(uint8 i = 0; i < 2; ++i)
-        {
-            Creature* Glaive = m_creature->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
-            if(Glaive)
-            {
-                GlaiveGUID[i] = Glaive->GetGUID();          // We need this to remove them later on
-                Glaive->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-                Glaive->SetVisibility(VISIBILITY_OFF);
-                Glaive->setFaction(m_creature->getFaction());
-            }
-        }
-    }
-
-    void SummonBladesOfAzzinoth()
-    {
-        m_creature->GetMotionMaster()->Clear(false);
-
-        LandTimer = 0;
-        RetrieveBladesTimer = 0;
-
-        DoCast(m_creature, SPELL_THROW_GLAIVE2);            // Make it look like we're throwing the glaives on the ground
-                                                            // We no longer wear the glaives!
-        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
-                                                            // since they are now channeling the flames (or will be)
-        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
-        for(uint8 i = 0; i < 2; ++i)
-        {
-            Creature* Glaive = NULL;
-            Glaive = ((Creature*)Unit::GetUnit((*m_creature), GlaiveGUID[i]));
-            if(Glaive)
-            {
-                DoCast(Glaive, SPELL_THROW_GLAIVE, true);
-                Glaive->SetVisibility(VISIBILITY_ON);
-            }
-        }
-    }
-
-    void SummonFlamesOfAzzinoth()
-    {
-        DoYell(SAY_SUMMONFLAMES, LANG_UNIVERSAL, NULL);
-        DoPlaySoundToSet(m_creature, SOUND_SUMMONFLAMES);
-
-        for(uint8 i = 0; i < 2; ++i)
-        {
-            Creature* Flame = NULL;
-            Creature* Glaive = NULL;
-            Glaive = ((Creature*)Unit::GetUnit((*m_creature), GlaiveGUID[i]));
-            if(Glaive)
-            {
-                Flame = m_creature->SummonCreature(FLAME_OF_AZZINOTH, GlaivePosition[i+2].x, GlaivePosition[i+2].y, GlaivePosition[i+2].z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000);
-                if(Flame)
-                {
-                                                            // Just in case the database has it as a different faction
-                    Flame->setFaction(m_creature->getFaction());
-                                                            // Attack our target!
-                    Flame->AI()->AttackStart(m_creature->getVictim());
-                    FlameGUID[i] = Flame->GetGUID();        // Record GUID in order to check if they're dead later on to move to the next phase
-                                                            // Glaives do some random Beam type channel on it.
-                    Glaive->CastSpell(Flame, SPELL_AZZINOTH_CHANNEL, true);
-                    if(m_creature->getVictim())
-                        Flame->AI()->AttackStart(m_creature->getVictim());
+                    BlinkToPlayer();
+                    DoCast(m_creature, SPELL_CAGE_TRAP_SUMMON);
+                    Timer[EVENT_MAIEV_TRAP] = 22000;
                 }
                 else
                 {
-                    DoTextEmote("is unable to summon a Flame of Azzinoth.", NULL);
-                    error_log("SD2 ERROR: Illidan Stormrage AI: Unable to summon Flame of Azzinoth (entry: 22997), please check your database");
-                    EnterEvadeMode();
+                    if(!m_creature->IsWithinDistInMap(m_creature->getVictim(), 40))
+                        m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), 30);
+                    DoCast(m_creature->getVictim(), SPELL_THROW_DAGGER);
+                    Timer[EVENT_MAIEV_THROW_DAGGER] = 2000;
                 }
-            }
-            else
-            {
-                DoTextEmote("is unable to summon a Blade of Azzinoth.", NULL);
-                error_log("SD2 ERROR: Illidan Stormrage AI: Unable to summon Blade of Azzinoth (entry: 22996), please check your database");
-            }
-        }
-        DoResetThreat();                                    // And now reset our threatlist
-        HasSummoned = true;
-    }
-
-    void SummonMaiev()
-    {
-        TauntTimer += 4000;
-        GlobalTimer += 4000;
-
-        m_creature->InterruptNonMeleeSpells(false);         // Interrupt any of our spells
-        Creature* Maiev = NULL;                             // Summon Maiev near Illidan
-        Maiev = m_creature->SummonCreature(MAIEV_SHADOWSONG, m_creature->GetPositionX() + 10, m_creature->GetPositionY() + 5, m_creature->GetPositionZ()+2, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
-        if(Maiev)
-        {
-            m_creature->GetMotionMaster()->Clear(false);    // Stop moving, it's rude to walk and talk!
-            m_creature->GetMotionMaster()->MoveIdle();
-                                                            // Just in case someone is unaffected by Shadow Prison
-            m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-            DoCast(m_creature, SPELL_SHADOW_PRISON, true);
-            TalkCount = 10;
-            IsTalking = true;                               // We are now talking/
-            Maiev->SetVisibility(VISIBILITY_OFF);           // Leave her invisible until she has to talk
-            Maiev->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-            MaievGUID = Maiev->GetGUID();
-        }
-        else                                                // If Maiev cannot be summoned, reset the encounter and post some errors to the console.
-        {
-            EnterEvadeMode();
-            DoTextEmote("is unable to summon Maiev Shadowsong and enter Phase 4. Resetting Encounter.", NULL);
-            error_log("SD2 ERROR: Unable to summon Maiev Shadowsong (entry: 23197). Check your database to see if you have the proper SQL for Maiev Shadowsong (entry: 23197)");
-        }
-    }
-
-    void InitializeDeath()
-    {
-        m_creature->RemoveAllAuras();
-        DoCast(m_creature, SPELL_DEATH);                    // Animate his kneeling + stun him
-                                                            // Don't let the players interrupt our talk!
-        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-        m_creature->GetMotionMaster()->Clear(false);        // No moving!
-        m_creature->GetMotionMaster()->MoveIdle();
-        if(MaievGUID)
-        {
-            Creature* Maiev = ((Creature*)Unit::GetUnit((*m_creature), MaievGUID));
-            if(Maiev)
-            {
-                Maiev->CombatStop();                        // Maiev shouldn't do anything either. No point in her attacking us =]
-                Maiev->GetMotionMaster()->Clear(false);     // Stop her from moving as well
-                Maiev->GetMotionMaster()->MoveIdle();
-                float distance = 10.0f;
-                float dx = m_creature->GetPositionX() + (distance*cos(m_creature->GetOrientation()));
-                float dy = m_creature->GetPositionY() + (distance*sin(m_creature->GetOrientation()));
-                Maiev->Relocate(dx,dy,Maiev->GetPositionZ());
-                Maiev->SendMonsterMove(dx,dy,Maiev->GetPositionZ(), 0, 0, 0);
-                Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true);
-                Maiev->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
-            }
-        }
-        IsTalking = true;
-        TalkCount++;
-    }
-
-    void UpdateAI(const uint32 diff)
-    {
-        /*** This section will handle the conversations ***/
-        if(IsTalking)                                       // Somewhat more efficient using a function rather than a long switch
-        {
-            if(TalkTimer < diff)
-            {
-                switch(TalkCount)                           // This is only for specialized cases
-                {
-                    case 0:
-                                                            // Time to stand up!
-                        m_creature->RemoveAurasDueToSpell( SPELL_KNEEL );
-                        break;
-                    case 8:
-                                                            // Equip our warglaives!
-                        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479);
-                        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
-                        m_creature->setFaction(14);         // Hostile if we weren't before
-                        break;
-                    case 9:
-                        if(AkamaGUID)
-                        {
-                            Creature* Akama = ((Creature*)Unit::GetUnit((*m_creature), AkamaGUID));
-                            if(Akama)
-                            {
-                                Akama->GetMotionMaster()->Clear(false);
-                                                            // Akama runs to us!
-                                Akama->GetMotionMaster()->MoveChase(m_creature);
-                                m_creature->GetMotionMaster()->Clear(false);
-                                                            // We run to Akama!
-                                m_creature->GetMotionMaster()->MoveChase(Akama);
-                                Akama->AddThreat(m_creature, 1000000.0f);
-                                AttackStart(Akama);         // Start attacking Akama
-                                ((npc_akama_illidanAI*)Akama->AI())->IsTalking = false;
-                                                            // Akama starts attacking us
-                                ((npc_akama_illidanAI*)Akama->AI())->AttackStart(m_creature);
-                            }
-                        }
-                                                            // We are now attackable!
-                        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-                        break;
-                    case 11:
-                        if(MaievGUID)
-                        {
-                            Unit* Maiev = Unit::GetUnit((*m_creature), MaievGUID);
-                            if(Maiev)
-                            {
-                                                            // Maiev is now visible
-                                Maiev->SetVisibility(VISIBILITY_ON);
-                                                            // onoz she looks like she teleported!
-                                Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true);
-                                                            // Have her face us
-                                Maiev->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
-                                                            // Face her, so it's not rude =P
-                                m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Maiev->GetGUID());
-                            }
-                        }
-                        break;
-                    case 14:
-                        if(MaievGUID)
-                        {
-                            Creature* Maiev = ((Creature*)Unit::GetUnit((*m_creature), MaievGUID));
-                            if(Maiev)
-                            {
-                                Maiev->GetMotionMaster()->Clear(false);
-                                Maiev->GetMotionMaster()->MoveChase(m_creature);
-                                                            // Have Maiev add a lot of threat on us so that players don't pull her off if they damage her via AOE
-                                Maiev->AddThreat(m_creature, 10000000.0f);
-                                                            // Force Maiev to attack us.
-                                Maiev->AI()->AttackStart(m_creature);
-                                Maiev->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-                            }
-                        }
-                        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-                        m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
-                        IsTalking = false;
-                        FaceVictimTimer = 2000;
-                        RefaceVictim = true;
-                        break;
-                    case 20:                                // Kill ourself.
-                        if(MaievGUID)
-                        {
-                            Creature* Maiev = ((Creature*)Unit::GetUnit((*m_creature), MaievGUID));
-                            if(Maiev)                       // Make Maiev leave
-                            {
-                                Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true);
-                                Maiev->setDeathState(JUST_DIED);
-                            }
-                        }
-                        IsTalking = false;
-                        if(m_creature->getVictim())
-                            m_creature->getVictim()->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE,SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-                        else
-                                                            // Now we kill ourself
-                            m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-                        break;
-                }
-                Talk(TalkCount);                            // This function does most of the talking
-                TalkCount++;
-            }else TalkTimer -= diff;
-        }
-
-        // If we don't have a target, return.
-        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim() || IsTalking)
-            return;
-
-        // If we are 'caged', then we shouldn't do anything such as cast spells or transform into Demon Form.
-        if(m_creature->HasAura(SPELL_CAGED, 0))
-        {
-            EnrageTimer = 40000;                            // Just so that he doesn't immediately enrage after he stops being caged.
-            CageTimer = 30000;
-            return;
-        }
-
-        // Berserk Timer - flat 25 minutes
-        if(!m_creature->HasAura(SPELL_BERSERK, 0) && Phase != PHASE_DEMON_SEQUENCE)
-            if(BerserkTimer < diff)
-        {
-            DoYell(SAY_ENRAGE, LANG_UNIVERSAL, NULL);
-            DoPlaySoundToSet(m_creature, SOUND_ENRAGE);
-            DoCast(m_creature, SPELL_BERSERK, true);
-        }else BerserkTimer -= diff;
-
-        if(RefaceVictim)
-            if(FaceVictimTimer < diff)
-        {
-            m_creature->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->getVictim()->GetGUID());
-            FaceVictimTimer = 1000;
-            RefaceVictim = false;
-        }else FaceVictimTimer -= diff;
-
-        /** Signal to change to phase 2 **/
-        if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 65) && (Phase == PHASE_NORMAL))
-            EnterPhase2();
-
-        /** Signal to summon Maiev **/
-        if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 30) && !MaievGUID &&
-            ((Phase != PHASE_DEMON) || (Phase != PHASE_DEMON_SEQUENCE)))
-            SummonMaiev();
-
-        /** Time for the death speech **/
-        if((m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 1) && (!IsTalking) &&
-            ((Phase != PHASE_DEMON) || (Phase != PHASE_DEMON_SEQUENCE)))
-            InitializeDeath();
-
-        /***** Spells for Phase 1, 3 and 5 (Normal Form) ******/
-        if(Phase == PHASE_NORMAL || Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV)
-        {
-            if(TauntTimer < diff)                           // His random taunt/yell timer.
-            {
-                uint32 random = rand()%4;
-                char* yell = RandomTaunts[random].text;
-                uint32 soundid = RandomTaunts[random].sound;
-                if(yell)
-                    DoYell(yell, LANG_UNIVERSAL, NULL);
-                if(soundid)
-                    DoPlaySoundToSet(m_creature, soundid);
-                TauntTimer = 32000;
-            }else TauntTimer -= diff;
-
-            if(GlobalTimer < diff)                          // Global Timer so that spells do not overlap.
-            {
-                if(ShearTimer < diff)
-                {
-                    DoCast(m_creature->getVictim(), SPELL_SHEAR);
-                    ShearTimer = 25000 + (rand()%16 * 1000);
-                    GlobalTimer += 2000;
-                }else ShearTimer -= diff;
-
-                if(FlameCrashTimer < diff)
-                {
-                    // It spawns multiple flames sometimes. Therefore, we'll do this manually.
-                    //DoCast(m_creature->getVictim(), SPELL_FLAME_CRASH);
-                    DoSpawnCreature(FLAME_CRASH, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 40000);
-                    FlameCrashTimer = 35000;
-                    GlobalTimer += 2000;
-                }else FlameCrashTimer -= diff;
-
-                if(ParasiticShadowFiendTimer < diff)
-                {
-                    Unit* target = NULL;
-                    target = SelectUnit(SELECT_TARGET_RANDOM,1);
-                    if(target && target->isAlive() && !target->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0))
-                    {
-                        Cast(target, SPELL_PARASITIC_SHADOWFIEND);
-                        ParasiticShadowFiendTimer = 40000;
-                    }
-                }else ParasiticShadowFiendTimer -= diff;
-
-                if(DrawSoulTimer < diff)
-                {
-                    DoCast(m_creature->getVictim(), SPELL_DRAW_SOUL);
-                    DrawSoulTimer = 55000;
-                    GlobalTimer += 3000;
-                }else DrawSoulTimer -= diff;
-            }else GlobalTimer -= diff;
-
-            if(!IsTalking)
+                break;
+            default:
+                break;
+            }
+
+            if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 50)
+            {
+                m_creature->SetVisibility(VISIBILITY_OFF);
+                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+                if(GETCRE(Illidan, IllidanGUID))
+                    ((boss_illidan_stormrageAI*)Illidan->AI())->DeleteFromThreatList(m_creature->GetGUID());
+                m_creature->AttackStop();
+                Timer[EVENT_MAIEV_STEALTH] = 60000; //reappear after 1 minute
+                MaxTimer = 1;
+            }
+
+            if(Phase == PHASE_NORMAL_MAIEV)
                 DoMeleeAttackIfReady();
-        }
-
-        /*** Phase 2 ***/
-        if(Phase == PHASE_FLIGHT)
-        {
-            // Check if we have summoned or not.
-            if(!HasSummoned)
-            {
-                if(SummonBladesTimer)
-                    if(SummonBladesTimer <= diff)
-                {
-                    SummonBladesOfAzzinoth();
-                    SummonBladesTimer = 0;
-                }else SummonBladesTimer -= diff;
-
-                if(SummonFlamesTimer < diff)
-                {
-                    SummonFlamesOfAzzinoth();
-                }else SummonFlamesTimer -= diff;
-            }
-
-            if(!m_creature->GetMotionMaster()->empty() && (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE))
-                m_creature->GetMotionMaster()->Clear(false);
-
-            if(HasSummoned)
-            {
-                if(CheckFlamesTimer)
-                    if(CheckFlamesTimer <= diff)
-                {
-                    // Check if flames are dead or non-existant. If so, set GUID to 0.
-                    for(uint8 i = 0; i < 2; i++)
-                    {
-                        if(FlameGUID[i])
-                        {
-                            Unit* Flame = NULL;
-                            Flame = Unit::GetUnit((*m_creature), FlameGUID[i]);
-
-                            // If the flame dies, or somehow the pointer becomes invalid, reset GUID to 0.
-                            if(!Flame || !Flame->isAlive())
-                                FlameGUID[i] = 0;
-                        }
-                    }
-                    CheckFlamesTimer = 500;
-                }else CheckFlamesTimer -= diff;
-
-                // If both flames are dead/non-existant, kill glaives and change to phase 3.
-                if(!FlameGUID[0] && !FlameGUID[1] && CheckFlamesTimer)
-                {
-                    RetrieveBladesTimer = 5000;             // Prepare for re-equipin!
-                    CheckFlamesTimer = 0;
-                }
-
-                if(RetrieveBladesTimer)
-                    if(RetrieveBladesTimer <= diff)         // Time to get back our glaives!
-                {
-                                                            // Interrupt any spells we might be doing *cough* DArk Barrage *cough*
-                    m_creature->InterruptNonMeleeSpells(false);
-                    for(uint8 i = 0; i < 2; i++)
-                    {
-                        if(GlaiveGUID[i])
-                        {
-                            Unit* Glaive = NULL;
-                            Glaive = Unit::GetUnit((*m_creature), GlaiveGUID[i]);
-                            if(Glaive)
-                            {
-                                                            // Make it look like the Glaive flies back up to us
-                                Glaive->CastSpell(m_creature, SPELL_GLAIVE_RETURNS, true);
-                                                            // Despawn the Glaive
-                                Glaive->setDeathState(JUST_DIED);
-                            }
-                            GlaiveGUID[i] = 0;
-                        }
-                    }
-                                                            // Re-equip our warblades!
-                    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479);
-                    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
-                    LandTimer = 5000;                       // Prepare for landin'!
-                    RetrieveBladesTimer = 0;
-                }else RetrieveBladesTimer -= diff;
-
-                if(LandTimer)
-                {
-                    if(LandTimer <= diff)                   // Time to land!
-                    {
-                        DoResetThreat();
-                                                            // anndddd touchdown!
-                        m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
-                        m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
-                        Phase = PHASE_NORMAL_2;
-                                                            // We should let the raid fight us =)
-                        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-                        m_creature->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->getVictim()->GetGUID());
-                                                            // Chase our victim!
-                        m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
-                    }else LandTimer -= diff;
-                    return;                                 // Do not continue past this point if LandTimer is not 0 and we are in phase 2.
-                }
-            }
-
-            if(GlobalTimer < diff)
-            {
-                if(FireballTimer < diff)
-                {
-                    Cast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FIREBALL);
-                    FireballTimer = 5000;
-                }else FireballTimer -= diff;
-
-                if(DarkBarrageTimer < diff)
-                {
-                    m_creature->InterruptNonMeleeSpells(false);
-                    DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DARK_BARRAGE);
-                    DarkBarrageTimer = 35000;
-                    GlobalTimer += 9000;
-                }else DarkBarrageTimer -= diff;
-
-                if(EyeBlastTimer < diff)
-                {
-                    CastEyeBlast();
-                    EyeBlastTimer = 30000;
-                }else EyeBlastTimer -= diff;
-            }else GlobalTimer -= diff;
-        }
-
-        /** Phase 3,5 spells only**/
-        if(Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV)
-        {
-            if(GlobalTimer < diff)
-            {
-                if(AgonizingFlamesTimer < diff)
-                {
-                    CastAgonizingFlames();
-                    AgonizingFlamesTimer = 60000;
-                }else AgonizingFlamesTimer -= diff;
-            }else GlobalTimer -= diff;
-
-            if(TransformTimer < diff)
-            {
-                uint32 CurHealth = m_creature->GetHealth()*100 / m_creature->GetMaxHealth();
-                // Prevent Illidan from morphing if less than 32% or 5%, as this may cause issues with the phase transition or death speech
-                if((CurHealth < 32 && !MaievGUID) || (CurHealth < 5))
-                    return;
-
-                Phase = PHASE_DEMON_SEQUENCE;               // Transform sequence
-                DemonFormSequence = 0;
-                AnimationTimer = 0;
-                DoYell(SAY_MORPH, LANG_UNIVERSAL, NULL);
-                DoPlaySoundToSet(m_creature, SOUND_MORPH);
-                TransformTimer = 60000;
-                FlameBurstTimer = 10000;
-                ShadowDemonTimer = 30000;
-                m_creature->GetMotionMaster()->Clear(false);// Stop moving
-            }else TransformTimer -= diff;
-        }
-
-        /** Phase 4 spells only (Demon Form) **/
-        if(Phase == PHASE_DEMON)
-        {
-            // Stop moving if we are by clearing movement generators.
-            if(!m_creature->GetMotionMaster()->empty())
-                m_creature->GetMotionMaster()->Clear(false);
-
-            if(TransformTimer < diff)
-            {
-                Phase = PHASE_DEMON_SEQUENCE;
-                DemonFormSequence = 5;
-                AnimationTimer = 100;
-                TransformTimer = 60000;
-            }else TransformTimer -= diff;
-
-            if(ShadowDemonTimer < diff)
-            {
-                m_creature->InterruptNonMeleeSpells(false);
-                Creature* ShadowDemon = NULL;
-                for(uint8 i = 0; i < 4; i++)
-                {
-                    Unit* target = NULL;
-                    target = SelectUnit(SELECT_TARGET_RANDOM,0);
-                                                            // only on players.
-                    if(target && target->GetTypeId() == TYPEID_PLAYER)
-                    {
-                        ShadowDemon = DoSpawnCreature(SHADOW_DEMON, 0,0,0,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,25000);
-                        if(ShadowDemon)
-                        {
-                            ShadowDemon->AddThreat(target, 5000000.0f);
-                            ShadowDemon->AI()->AttackStart(target);
-                            DoZoneInCombat(ShadowDemon);
-                        }
-                    }
-                }
-                ShadowDemonTimer = 60000;
-            }else ShadowDemonTimer -= diff;
-
-            if(GlobalTimer < diff)
-            {
-                if(ShadowBlastTimer < diff)
-                {
-                    Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);
-                    if(target && target->isAlive())
-                    {
-                        m_creature->SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID());
-                        DoCast(target, SPELL_SHADOW_BLAST);
-                        ShadowBlastTimer = 4000;
-                        GlobalTimer += 1500;
-                    }
-                    if(!m_creature->HasAura(SPELL_DEMON_FORM, 0))
-                        DoCast(m_creature, SPELL_DEMON_FORM, true);
-                }else ShadowBlastTimer -= diff;
-
-                if(FlameBurstTimer < diff)
-                {
-                    DoCast(m_creature, SPELL_FLAME_BURST);
-                    FlameBurstTimer = 15000;
-                }else FlameBurstTimer -= diff;
-            }else GlobalTimer -= diff;
-        }
-
-        /** Phase 5 timers. Enrage spell **/
-        if(Phase == PHASE_NORMAL_MAIEV)
-        {
-            if(EnrageTimer < diff)
-            {
-                DoCast(m_creature, SPELL_ENRAGE);
-                EnrageTimer = 40000;
-                CageTimer = 30000;
-                TransformTimer += 10000;
-            }else EnrageTimer -= diff;
-
-            // We'll handle Cage Trap in Illidan's script for simplicity's sake
-            if(CageTimer < diff)
-            {
-                if(MaievGUID)
-                {
-                    Unit* Maiev = Unit::GetUnit((*m_creature), MaievGUID);
-                    Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
-                    if(!Maiev || !target || (target->GetTypeId() != TYPEID_PLAYER))
-                        return;
-                    float X, Y, Z;
-                    target->GetPosition(X, Y, Z);
-                    Maiev->Relocate(X, Y, Z, Maiev->GetOrientation());
-                                                            // Make it look like she 'teleported'
-                    Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true);
-                                                            // summon the trap!
-                    Maiev->CastSpell(Maiev, SPELL_CAGE_TRAP_SUMMON, false);
-                }
-                CageTimer = 15000;
-            }else CageTimer -= diff;
-        }
-
-        if(Phase == PHASE_DEMON_SEQUENCE)                   // Demonic Transformation
-        {
-            if(AnimationTimer < diff)
-            {
-                HandleDemonTransformAnimation(DemonFormSequence);
-                DemonFormSequence++;
-            }else AnimationTimer -= diff;
-        }
-    }
-};
-
-/*********************** End of Illidan AI ******************************************/
-
-void npc_akama_illidanAI::BeginEvent(uint64 PlayerGUID)
-{
-    debug_log("SD2: Akama - Illidan Introduction started. Illidan event properly begun.");
-    if(pInstance)
-    {
-        IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE);
-        pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, IN_PROGRESS);
-    }
-
-    if(pInstance)
-        for(uint8 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L+1; ++i)
-    {
-        GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i));
-        if(Door)
-            Door->SetGoState(1);
-    }
-
-    if(IllidanGUID)
-    {
-        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-        Creature* Illidan = ((Creature*)Unit::GetUnit((*m_creature), IllidanGUID));
-        if(Illidan)
-        {
-            Illidan->RemoveAurasDueToSpell(SPELL_KNEEL);    // Time for Illidan to stand up.
-                                                            // First line of Akama-Illidan convo
-            ((boss_illidan_stormrageAI*)Illidan->AI())->TalkCount = 0;
-                                                            // Begin Talking
-            ((boss_illidan_stormrageAI*)Illidan->AI())->IsTalking = true;
-            ((boss_illidan_stormrageAI*)Illidan->AI())->AkamaGUID = m_creature->GetGUID();
-            m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Illidan->GetGUID());
-            Illidan->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
-            IsTalking = true;                               // Prevent Akama from starting to attack him
-                                                            // Prevent players from talking again
-            m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
-            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-            Illidan->GetMotionMaster()->Clear(false);
-            Illidan->GetMotionMaster()->MoveIdle();
-            m_creature->GetMotionMaster()->Clear(false);
-            m_creature->GetMotionMaster()->MoveIdle();
-
-            if(PlayerGUID)
-            {
-                Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
-                if(player)
-                    Illidan->AddThreat(player, 100.0f);
-            }
-        }
-    }
-}
+    }
+};
+
 
 bool GossipSelect_npc_akama_at_illidan(Player *player, Creature *_Creature, uint32 sender, uint32 action)
 {
-    if(action == GOSSIP_ACTION_INFO_DEF)                    // Time to begin the event
+    if(action == GOSSIP_ACTION_INFO_DEF) // Time to begin the Event
     {
         player->CLOSE_GOSSIP_MENU();
-        ((npc_akama_illidanAI*)_Creature->AI())->BeginDoorEvent(player);
+        ((npc_akama_illidanAI*)_Creature->AI())->EnterPhase(PHASE_CHANNEL);
     }
     return true;
@@ -1942,69 +1707,9 @@
 }
 
-struct TRINITY_DLL_SPEC boss_maievAI : public ScriptedAI
-{
-    boss_maievAI(Creature *c) : ScriptedAI(c)
-    {
-        pInstance = ((ScriptedInstance*)c->GetInstanceData());
-        Reset();
-    };
-
-    uint32 TauntTimer;
+struct TRINITY_DLL_DECL cage_trap_triggerAI : public ScriptedAI
+{
+    cage_trap_triggerAI(Creature *c) : ScriptedAI(c) {Reset();}
+
     uint64 IllidanGUID;
-
-    ScriptedInstance* pInstance;
-
-    void Reset()
-    {
-        TauntTimer = 12000;
-        IllidanGUID = 0;
-    }
-
-    void Aggro(Unit *who) {}
-
-    void UpdateAI(const uint32 diff)
-    {
-        if(!IllidanGUID)
-        {
-            if(pInstance)
-                IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE);
-        }else
-        {
-            Creature* Illidan = NULL;
-            Illidan = ((Creature*)Unit::GetUnit((*m_creature), IllidanGUID));
-            if(!Illidan || !Illidan->isAlive() || Illidan->IsInEvadeMode())
-            {
-                m_creature->SetVisibility(VISIBILITY_OFF);
-                m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-            }
-            else if(Illidan && ((Illidan->GetHealth()*100 / Illidan->GetMaxHealth()) < 2))
-                return;
-        }
-
-        // Return if we don't have a target
-        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
-            return;
-
-        if(TauntTimer < diff)
-        {
-            uint32 random = rand()%4;
-            char* text = MaievTaunts[random].text;
-            uint32 sound = MaievTaunts[random].sound;
-            DoYell(text, LANG_UNIVERSAL, NULL);
-            DoPlaySoundToSet(m_creature, sound);
-            TauntTimer = 22000 + rand()%21 * 1000;
-        }else TauntTimer -= diff;
-
-        DoMeleeAttackIfReady();
-    }
-};
-
-struct TRINITY_DLL_DECL cage_trap_triggerAI : public ScriptedAI
-{
-    cage_trap_triggerAI(Creature *c) : ScriptedAI(c) {Reset();}
-
-    uint64 IllidanGUID;
-    uint64 CageTrapGUID;
-
     uint32 DespawnTimer;
 
@@ -2015,5 +1720,4 @@
     {
         IllidanGUID = 0;
-        CageTrapGUID = 0;
 
         Active = false;
@@ -2034,7 +1738,7 @@
         if(who && (who->GetTypeId() != TYPEID_PLAYER))
         {
-            if(who->GetEntry() == ILLIDAN_STORMRAGE)        // Check if who is Illidan
-            {
-                if(!IllidanGUID && m_creature->IsWithinDistInMap(who, 3) && !who->HasAura(SPELL_CAGED, 0))
+            if(who->GetEntry() == ILLIDAN_STORMRAGE) // Check if who is Illidan
+            {
+                if(!IllidanGUID && m_creature->IsWithinDistInMap(who, 3) && (!who->HasAura(SPELL_CAGED, 0)))
                 {
                     IllidanGUID = who->GetGUID();
@@ -2042,9 +1746,7 @@
                     DespawnTimer = 5000;
                     if(who->HasAura(SPELL_ENRAGE, 0))
-                                                            // Dispel his enrage
-                        who->RemoveAurasDueToSpell(SPELL_ENRAGE);
-
-                    if(GameObject* CageTrap = GameObject::GetGameObject(*m_creature, CageTrapGUID))
-                        CageTrap->SetLootState(GO_JUST_DEACTIVATED);
+                        who->RemoveAurasDueToSpell(SPELL_ENRAGE); // Dispel his enrage
+                    //if(GameObject* CageTrap = GameObject::GetGameObject(*m_creature, CageTrapGUID))
+                    //    CageTrap->SetLootState(GO_JUST_DEACTIVATED);
                 }
             }
@@ -2057,13 +1759,13 @@
             if(DespawnTimer < diff)
                 m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-        else DespawnTimer -= diff;
-
-        //if(IllidanGUID && !SummonedBeams)
-        //{
-        //    if(Unit* Illidan = Unit::GetUnit(*m_creature, IllidanGUID)
-        //    {
-        //        //TODO: Find proper spells and properly apply 'caged' Illidan effect
-        //    }
-        //}
+            else DespawnTimer -= diff;
+
+            //if(IllidanGUID && !SummonedBeams)
+            //{
+            //    if(Unit* Illidan = Unit::GetUnit(*m_creature, IllidanGUID)
+            //    {
+            //        //TODO: Find proper spells and properly apply 'caged' Illidan effect
+            //    }
+            //}
     }
 };
@@ -2090,129 +1792,35 @@
     cell_lock->Visit(cell_lock, cSearcher, *(plr->GetMap()));
 
-    if(!trigger)
-    {
-        plr->GetSession()->SendNotification("SD2: Summon failed. This trap is now useless.", LANG_UNIVERSAL, 0);
-        error_log("SD2: Cage Trap- Unable to find trigger. This Cage Trap is now useless");
-        return false;
-    }
-
     ((cage_trap_triggerAI*)trigger->AI())->Active = true;
-    go->SetGoState(0);
+    go->SetUInt32Value(GAMEOBJECT_STATE, 0);
     return true;
 }
 
-//This is used to sort the players by distance in preparation for being charged by the flames.
-struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
-{
-    const Unit* MainTarget;
-    TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {};
-    // functor for operator ">"
-    bool operator()(const Unit* _Left, const Unit* _Right) const
-    {
-        return (MainTarget->GetDistance(_Left) > MainTarget->GetDistance(_Right));
-    }
-};
-
-struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI
-{
-    flame_of_azzinothAI(Creature *c) : ScriptedAI(c) {Reset();}
-
-    uint32 FlameBlastTimer;
-    uint32 SummonBlazeTimer;
-    uint32 ChargeTimer;
+struct TRINITY_DLL_DECL shadow_demonAI : public ScriptedAI
+{
+    shadow_demonAI(Creature *c) : ScriptedAI(c) {Reset();}
+
+    uint64 TargetGUID;
+
+    void Aggro(Unit *who) {}
 
     void Reset()
     {
-        FlameBlastTimer = 15000 + rand()%15000;
-        SummonBlazeTimer = 10000 + rand()%20000;
-        ChargeTimer = 5000;
-    }
-
-    void Aggro(Unit *who) {}
-
-    void Charge()
-    {
-        // Get the Threat List
-        std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
-
-        if(!m_threatlist.size()) return;                    // He doesn't have anyone in his threatlist, useless to continue
-
-        std::list<Unit*> targets;
-        std::list<HostilReference *>::iterator itr = m_threatlist.begin();
-        for( ; itr!= m_threatlist.end(); ++itr)             //store the threat list in a different container
-        {
-            Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
-            //only on alive players
-            if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER )
-                targets.push_back( target);
-        }
-
-        //Sort the list of players
-        targets.sort(TargetDistanceOrder(m_creature));
-        //Resize so we only get the furthest target
-        targets.resize(1);
-
-        Unit* target = (*targets.begin());
-        if(target && (!m_creature->IsWithinDistInMap(target, 40)))
-        {
-            DoCast(m_creature, SPELL_ENRAGE, true);
-            DoCast(target, SPELL_CHARGE);
-        }
+        TargetGUID = 0;
+        DoCast(m_creature, SPELL_SHADOW_DEMON_PASSIVE, true);
+    }
+
+    void JustDied(Unit *killer)
+    {
+        Unit* target = Unit::GetUnit((*m_creature), TargetGUID);
+        if(target)
+            target->RemoveAurasDueToSpell(SPELL_PARALYZE);
     }
 
     void UpdateAI(const uint32 diff)
     {
-        // Return if we don't have a target
-        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
-            return;
-
-        if(FlameBlastTimer < diff)
-        {
-            DoCast(m_creature->getVictim(), SPELL_FLAME_BLAST);
-            FlameBlastTimer = 30000;
-        }else FlameBlastTimer -= diff;
-
-        if(SummonBlazeTimer < diff)
-        {
-            DoCast(m_creature, SPELL_BLAZE_SUMMON);
-            SummonBlazeTimer = 30000 + rand()%20000;
-        }else SummonBlazeTimer -= diff;
-
-        if(ChargeTimer < diff)
-        {
-            Charge();
-            ChargeTimer = 5000;
-        }else ChargeTimer -= diff;
-
-        DoMeleeAttackIfReady();
-    }
-};
-
-struct TRINITY_DLL_DECL shadow_demonAI : public ScriptedAI
-{
-    shadow_demonAI(Creature *c) : ScriptedAI(c) {Reset();}
-
-    uint64 TargetGUID;
-
-    void Reset() { TargetGUID = 0; }
-
-    void Aggro(Unit *who) {}
-
-    void JustDied(Unit *killer)
-    {
-        if(TargetGUID)
-        {
-            Unit* target = Unit::GetUnit((*m_creature), TargetGUID);
-            if(target)
-                target->RemoveAurasDueToSpell(SPELL_PARALYZE);
-        }
-    }
-
-    void UpdateAI(const uint32 diff)
-    {
         if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) return;
 
-        // Only cast the below on players.
-        if(m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER) return;
+        if(m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER) return; // Only cast the below on players.
 
         if(!m_creature->getVictim()->HasAura(SPELL_PARALYZE, 0))
@@ -2220,5 +1828,4 @@
             TargetGUID = m_creature->getVictim()->GetGUID();
             m_creature->AddThreat(m_creature->getVictim(), 10000000.0f);
-            DoCast(m_creature, SPELL_SHADOW_DEMON_PASSIVE, true);
             DoCast(m_creature->getVictim(), SPELL_PURPLE_BEAM, true);
             DoCast(m_creature->getVictim(), SPELL_PARALYZE, true);
@@ -2230,65 +1837,131 @@
 };
 
-struct TRINITY_DLL_DECL flamecrashAI : public ScriptedAI
-{
-    flamecrashAI(Creature *c) : ScriptedAI(c) {Reset();}
-
-    uint32 FlameCrashTimer;
+// Shadowfiends interact with Illidan, setting more targets in Illidan's hashmap
+struct TRINITY_DLL_DECL mob_parasitic_shadowfiendAI : public ScriptedAI
+{
+    mob_parasitic_shadowfiendAI(Creature* c) : ScriptedAI(c)
+    {
+        pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        Reset();
+    }
+
+    ScriptedInstance* pInstance;
+    uint64 IllidanGUID;
+    uint32 CheckTimer;
+
+    void Reset()
+    {        
+        if(pInstance)
+            IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE);
+        else
+            IllidanGUID = 0;
+
+        CheckTimer = 5000;
+        DoCast(m_creature, SPELL_SHADOWFIEND_PASSIVE, true);
+    }
+
+    void Aggro(Unit* who) {}
+    void MoveInLineOfSight(Unit *who){}
+
+    void DoMeleeAttackIfReady()
+    {
+        if( m_creature->isAttackReady() && m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
+        {
+            if(!m_creature->getVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0))
+            {
+                m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_PARASITIC_SHADOWFIEND, true); //do not stack
+                if(GETCRE(Illidan, IllidanGUID))
+                    ((boss_illidan_stormrageAI*)Illidan->AI())->AddParasiteTarget(m_creature->getVictim()->GetGUID());
+            }
+            m_creature->AttackerStateUpdate(m_creature->getVictim());
+            m_creature->resetAttackTimer();
+        }
+    }
+
+    void UpdateAI(const uint32 diff)
+    {
+        if(!m_creature->getVictim())
+        {
+            if(GETCRE(Illidan, IllidanGUID))
+            {
+                if(Illidan->getVictim() && !Illidan->getVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0))
+                    AttackStart(Illidan->getVictim());
+                else
+                    AttackStart(((boss_illidan_stormrageAI*)Illidan->AI())->SelectUnit(SELECT_TARGET_RANDOM, 1));
+            }
+        }
+        else
+            DoMeleeAttackIfReady();
+
+        if(CheckTimer < diff)
+        {
+            GETUNIT(Illidan, IllidanGUID);
+            if(!Illidan || ((Creature*)Illidan)->IsInEvadeMode())
+            {
+                m_creature->SetVisibility(VISIBILITY_OFF);
+                m_creature->setDeathState(JUST_DIED);
+                return;
+            }else CheckTimer = 5000;
+        }else CheckTimer -= diff;
+    }
+};
+
+struct TRINITY_DLL_DECL demonfireAI : public ScriptedAI
+{
+    demonfireAI(Creature *c) : ScriptedAI(c) 
+    {
+        pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        Reset();
+    }
+
+    ScriptedInstance* pInstance;
+    uint64 IllidanGUID;
+    bool IsTrigger;
+    bool DemonFire;
+    uint32 CheckTimer;
     uint32 DespawnTimer;
 
     void Reset()
     {
-        FlameCrashTimer = 3000 +rand()%5000;
-        DespawnTimer = 60000;
-    }
-
-    void Aggro(Unit *who){ return; }
-
-    void AttackStart(Unit *who) { }
-
-    void MoveInLineOfSight(Unit *who){ }
+        if(pInstance)
+            IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE);
+        else
+            IllidanGUID = 0;
+
+        IsTrigger = false;
+        DemonFire = false;
+
+        CheckTimer = 5000;
+        DespawnTimer = 78000; //spell duration, core bug, cannot despawn self
+    }
+
+    void Aggro(Unit *who) {}
+    void AttackStart(Unit* who) {}
+    void MoveInLineOfSight(Unit *who){}
 
     void UpdateAI(const uint32 diff)
     {
-        if(FlameCrashTimer < diff)
-        {
-            DoCast(m_creature, SPELL_FLAME_CRASH_EFFECT);
-            FlameCrashTimer = 15000;
-        }else FlameCrashTimer -= diff;
+        if(IsTrigger)
+            return;
+
+        if(!DemonFire)
+            DoCast(m_creature, SPELL_DEMON_FIRE); //duration 60s
+
+        if(CheckTimer < diff)
+        {
+            GETUNIT(Illidan, IllidanGUID);
+            if(!Illidan || !Illidan->HasUnitMovementFlag(MOVEMENTFLAG_LEVITATING))
+            {
+                m_creature->SetVisibility(VISIBILITY_OFF);
+                m_creature->setDeathState(JUST_DIED);
+                return;
+            }else CheckTimer = 5000;
+        }else CheckTimer -= diff;
 
         if(DespawnTimer < diff)
         {
-            m_creature->SetVisibility(VISIBILITY_OFF);      // So that players don't see the sparkly effect when we die.
-            m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+            m_creature->SetVisibility(VISIBILITY_OFF);
+            m_creature->setDeathState(JUST_DIED);
         }else DespawnTimer -= diff;
-    }
-};
-
-// Shadowfiends interact with Illidan, setting more targets in Illidan's hashmap
-struct TRINITY_DLL_SPEC mob_parasitic_shadowfiendAI : public ScriptedAI
-{
-    mob_parasitic_shadowfiendAI(Creature* c) : ScriptedAI(c)
-    {
-        Reset();
-    }
-
-    void Reset() {}
-
-    void Aggro(Unit* who) {}
-
-    void DoMeleeAttackIfReady()
-    {
-        //If we are within range melee the target
-        if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
-        {
-            //Make sure our attack is ready and we aren't currently casting
-            if( m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false))
-            {
-                if(!m_creature->getVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0))
-                    DoCast(m_creature->getVictim(), SPELL_PARASITIC_SHADOWFIEND, true);
-                m_creature->AttackerStateUpdate(m_creature->getVictim());
-                m_creature->resetAttackTimer();
-            }
-        }
     }
 };
@@ -2303,41 +1976,405 @@
     void Reset()
     {
-        BlazeTimer = 2000;
-        DespawnTimer = 15000;
-    }
-
-    void Aggro(Unit *who){ }
-
+        BlazeTimer = 3000;  
+        DespawnTimer = 60000; // Spell duration = 1 min
+        //((TemporarySummon*)m_creature)->Summon(TEMPSUMMON_TIMED_DESPAWN, 0, false);
+    }
+
+    void Aggro(Unit *who) {}
     void AttackStart(Unit* who) { }
-
     void MoveInLineOfSight(Unit *who){ }
 
     void UpdateAI(const uint32 diff)
     {
-        if(BlazeTimer < diff)
-        {
-            DoCast(m_creature, SPELL_BLAZE_EFFECT);
-            BlazeTimer = 15000;
-        }else BlazeTimer -= diff;
+        if(BlazeTimer)
+            if(BlazeTimer <= diff)
+            {
+                DoCast(m_creature, SPELL_BLAZE_EFFECT);//duration 60s
+                BlazeTimer = 0;
+            }else BlazeTimer -= diff;
 
         if(DespawnTimer < diff)
         {
             m_creature->SetVisibility(VISIBILITY_OFF);
-            m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+            m_creature->setDeathState(JUST_DIED);
         }else DespawnTimer -= diff;
     }
 };
 
+struct TRINITY_DLL_DECL flamecrashAI : public ScriptedAI
+{
+    flamecrashAI(Creature *c) : ScriptedAI(c) {Reset();}
+
+    uint32 DespawnTimer;
+
+    void Reset()
+    {
+        DoCast(m_creature, SPELL_FLAME_CRASH_EFFECT);//duration inf
+        DespawnTimer = 120000; // summon spell duration
+    }
+
+    void Aggro(Unit *who) {}
+    void AttackStart(Unit *who) { }
+    void MoveInLineOfSight(Unit *who){ }
+
+    void UpdateAI(const uint32 diff)
+    {
+        if(DespawnTimer < diff)
+        {
+            m_creature->SetVisibility(VISIBILITY_OFF);
+            m_creature->setDeathState(JUST_DIED);
+        }else DespawnTimer -= diff;
+    }
+};
+
 struct TRINITY_DLL_DECL blade_of_azzinothAI : public ScriptedAI
 {
-    blade_of_azzinothAI(Creature* c) : ScriptedAI(c) { Reset(); }
-
+    blade_of_azzinothAI(Creature* c) : ScriptedAI(c) {}
     void Reset() {}
-    // Do-Nothing-But-Stand-There
-    void Aggro(Unit* who) { }
+    void Aggro(Unit *who) {}
     void AttackStart(Unit* who) { }
     void MoveInLineOfSight(Unit* who) { }
 
-};
+    void SpellHit(Unit *caster, const SpellEntry *spell)
+    {
+        if(spell->Id == SPELL_THROW_GLAIVE2 || spell->Id == SPELL_THROW_GLAIVE)
+            m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 21431);//appear when hit by Illidan's glaive
+    }
+};
+
+void boss_illidan_stormrageAI::Reset()
+{
+    if(pInstance)
+        pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, NOT_STARTED);
+
+    for(uint8 i = 0; i < 2; i++)
+    {
+        if(FlameGUID[i])
+        {
+            if(GETUNIT(Flame, FlameGUID[i]))
+                Flame->setDeathState(JUST_DIED);
+            FlameGUID[i] = 0;
+        }
+
+        if(GlaiveGUID[i])
+        {
+            if(GETUNIT(Glaive, GlaiveGUID[i]))
+                Glaive->setDeathState(JUST_DIED);
+            GlaiveGUID[i] = 0;
+        }
+    }
+
+    if(AkamaGUID)
+    {
+        if(GETCRE(Akama, AkamaGUID))
+        {
+            if(!Akama->isAlive())
+                Akama->Respawn();
+            else
+            {
+                ((npc_akama_illidanAI*)Akama->AI())->EnterEvadeMode();
+                Akama->GetMotionMaster()->MoveTargetedHome();
+                ((npc_akama_illidanAI*)Akama->AI())->Reset();
+            }
+        }
+        AkamaGUID = 0;
+    }
+
+    if(MaievGUID)
+    {
+        GETUNIT(Maiev, MaievGUID);
+        if(Maiev && Maiev->isAlive())
+        {
+            Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true);
+            Maiev->setDeathState(JUST_DIED);
+        }
+        MaievGUID = 0;
+    }
+
+    Phase = PHASE_NULL;
+    Event = EVENT_NULL;
+    Timer[EVENT_BERSERK] = 1500000;
+
+    HoverPoint = 0;
+    TalkCount = 0;
+    FlightCount = 0;
+    TransformCount = 0;
+
+    ParasiteTargets.clear();
+
+    m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 21135);
+    m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+    m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
+    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+    m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+
+    DoCast(m_creature, SPELL_DUAL_WIELD, true);
+}
+
+void boss_illidan_stormrageAI::HandleTalkSequence()
+{
+    switch(TalkCount)
+    {
+    case 0:
+        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+        break;
+    case 8:
+        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Equip our warglaives!
+        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
+        m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
+        m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+        break;
+    case 9:
+        if(GETCRE(Akama, AkamaGUID))
+        {
+            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
+            m_creature->AddThreat(Akama, 100.0f);
+            ((npc_akama_illidanAI*)Akama->AI())->EnterPhase(PHASE_FIGHT_ILLIDAN);
+            EnterPhase(PHASE_NORMAL);
+        }
+        break;
+    case 10:
+        SummonMaiev();
+        break;
+    case 11:
+        if(GETUNIT(Maiev, MaievGUID))
+        {
+            Maiev->SetVisibility(VISIBILITY_ON); // Maiev is now visible
+            Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true); // onoz she looks like she teleported!
+            Maiev->SetInFront(m_creature); // Have her face us
+            m_creature->SetInFront(Maiev); // Face her, so it's not rude =P
+            Maiev->StopMoving();
+            m_creature->StopMoving();
+        }break;
+    case 14:
+        if(GETCRE(Maiev, MaievGUID))
+        {
+            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
+            Maiev->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
+            Maiev->AddThreat(m_creature, 10000000.0f); // Have Maiev add a lot of threat on us so that players don't pull her off if they damage her via AOE
+            Maiev->AI()->AttackStart(m_creature); // Force Maiev to attack us.
+            EnterPhase(PHASE_NORMAL_MAIEV);
+        }break;
+    case 15:
+        DoCast(m_creature, SPELL_DEATH); // Animate his kneeling + stun him
+        break;
+    case 17:
+        if(GETUNIT(Akama, AkamaGUID))
+        {
+            if(!m_creature->IsWithinDistInMap(Akama, 15))
+            {
+                float x, y, z;
+                m_creature->GetPosition(x, y, z);
+                x += 10; y += 10;
+                Akama->GetMotionMaster()->Clear(false);
+                //Akama->GetMotionMaster()->MoveIdle();
+                Akama->Relocate(x, y, z);
+                Akama->SendMonsterMove(x, y, z, 0, 0, 0);//Illidan must not die until Akama arrives.
+                Akama->GetMotionMaster()->MoveChase(m_creature);
+            }
+        }
+        break;
+    case 19: // Make Maiev leave
+        if(GETUNIT(Maiev, MaievGUID))
+        {
+            Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true);
+            Maiev->setDeathState(JUST_DIED);
+            m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD);
+        }
+        break;
+    case 21: // Kill ourself.
+        m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+        break;
+    default:
+        break;
+    }
+    if(Phase == PHASE_TALK_SEQUENCE)
+        Talk(TalkCount); // This function does most of the talking
+    TalkCount++;
+}
+
+
+void boss_illidan_stormrageAI::CastEyeBlast()
+{
+    m_creature->InterruptNonMeleeSpells(false);
+
+    DoYell(SAY_EYE_BLAST, LANG_UNIVERSAL, NULL);
+    DoPlaySoundToSet(m_creature, SOUND_EYE_BLAST);
+
+    float distx, disty, dist[2];
+    for(uint8 i = 0; i < 2; ++i)
+    {
+        distx = EyeBlast[i].x - HoverPosition[HoverPoint].x;
+        disty = EyeBlast[i].y - HoverPosition[HoverPoint].y;
+        dist[i] = distx * distx + disty * disty;
+    }
+    Locations initial = EyeBlast[dist[0] < dist[1] ? 0 : 1];
+    for(uint8 i = 0; i < 2; ++i)
+    {
+        distx = GlaivePosition[i].x - HoverPosition[HoverPoint].x;
+        disty = GlaivePosition[i].y - HoverPosition[HoverPoint].y;
+        dist[i] = distx * distx + disty * disty;
+    }
+    Locations final = GlaivePosition[dist[0] < dist[1] ? 0 : 1];
+
+    final.x = 2 * final.x - initial.x;
+    final.y = 2 * final.y - initial.y;
+
+    for(uint8 i = 0; i < 2; ++i)//core bug, two buff do not coexist
+    {
+        Creature* Trigger = NULL;
+        Trigger = m_creature->SummonCreature(DEMON_FIRE, initial.x, initial.y, initial.z, 0, TEMPSUMMON_TIMED_DESPAWN, 13000);
+        if(Trigger)
+        {
+            ((demonfireAI*)Trigger->AI())->IsTrigger = true;
+            Trigger->SetSpeed(MOVE_WALK, 3);
+            Trigger->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
+            Trigger->GetMotionMaster()->MovePoint(0, final.x, final.y, final.z);
+
+            if(!i)
+                Trigger->CastSpell(Trigger, SPELL_EYE_BLAST_TRIGGER, true);
+            else
+            {
+                Trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+                m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Trigger->GetGUID());
+                DoCast(Trigger, SPELL_EYE_BLAST);
+            }
+        }
+    }
+}
+
+void boss_illidan_stormrageAI::SummonFlamesOfAzzinoth()
+{
+    DoYell(SAY_SUMMONFLAMES, LANG_UNIVERSAL, NULL);
+    DoPlaySoundToSet(m_creature, SOUND_SUMMONFLAMES);
+
+    for(uint8 i = 0; i < 2; ++i)
+    {
+        if(GETUNIT(Glaive, GlaiveGUID[i]))
+        {
+            Creature* Flame = m_creature->SummonCreature(FLAME_OF_AZZINOTH, GlaivePosition[i+2].x, GlaivePosition[i+2].y, GlaivePosition[i+2].z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000);
+            if(Flame)
+            {
+                Flame->setFaction(m_creature->getFaction()); // Just in case the database has it as a different faction
+                Flame->SetMeleeDamageSchool(SPELL_SCHOOL_FIRE);
+                Flame->AI()->AttackStart(m_creature->getVictim()); // Attack our target!
+                FlameGUID[i] = Flame->GetGUID(); // Record GUID in order to check if they're dead later on to move to the next phase
+                ((flame_of_azzinothAI*)Flame->AI())->SetGlaiveGUID(GlaiveGUID[i]);
+                DoZoneInCombat(Flame);
+                Glaive->CastSpell(Flame, SPELL_AZZINOTH_CHANNEL, false); // Glaives do some random Beam type channel on it.
+            }
+        }
+    }
+}
+
+void boss_illidan_stormrageAI::SummonMaiev()
+{
+    DoCast(m_creature, SPELL_SHADOW_PRISON, true);
+    Creature* Maiev = m_creature->SummonCreature(MAIEV_SHADOWSONG, m_creature->GetPositionX() + 10, m_creature->GetPositionY() + 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+    if(Maiev)
+    {
+        Maiev->SetVisibility(VISIBILITY_OFF); // Leave her invisible until she has to talk
+        Maiev->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+        MaievGUID = Maiev->GetGUID();
+        ((boss_maievAI*)Maiev->AI())->GetIllidanGUID(m_creature->GetGUID());
+        ((boss_maievAI*)Maiev->AI())->EnterPhase(PHASE_TALK_SEQUENCE);
+    }
+    else // If Maiev cannot be summoned, reset the encounter and post some errors to the console.
+    {
+        EnterEvadeMode();
+        DoTextEmote("is unable to summon Maiev Shadowsong and enter Phase 4. Resetting Encounter.", NULL);
+        error_log("SD2 ERROR: Unable to summon Maiev Shadowsong (entry: 23197). Check your database to see if you have the proper SQL for Maiev Shadowsong (entry: 23197)");
+    }
+}
+
+
+void boss_illidan_stormrageAI::EnterPhase(PhaseIllidan NextPhase)
+{
+    DoZoneInCombat();
+    switch(NextPhase)
+    {
+    case PHASE_NORMAL:
+    case PHASE_NORMAL_2:
+    case PHASE_NORMAL_MAIEV:
+        AttackStart(m_creature->getVictim());
+        Timer[EVENT_TAUNT] = 32000;
+        Timer[EVENT_SHEAR] = 10000 + rand()%15 * 1000;
+        Timer[EVENT_FLAME_CRASH] = 20000;
+        Timer[EVENT_PARASITIC_SHADOWFIEND] = 25000;
+        Timer[EVENT_PARASITE_CHECK] = 0;
+        Timer[EVENT_DRAW_SOUL] = 30000;
+        if(NextPhase == PHASE_NORMAL)
+            break;
+        Timer[EVENT_AGONIZING_FLAMES] = 35000;
+        Timer[EVENT_TRANSFORM_NORMAL] = 60000;
+        if(NextPhase == PHASE_NORMAL_2)
+            break;
+        Timer[EVENT_ENRAGE] = 30000 + rand()%10 * 1000;
+        break;
+    case PHASE_FLIGHT:
+        Timer[EVENT_FIREBALL] = 1000;
+        if(!(rand()%4))
+            Timer[EVENT_DARK_BARRAGE] = 10000;
+        Timer[EVENT_EYE_BLAST] = 10000 + rand()%15 * 1000;
+        Timer[EVENT_MOVE_POINT] = 20000 + rand()%20 * 1000;
+        break;
+    case PHASE_DEMON:
+        Timer[EVENT_SHADOW_BLAST] = 1000;
+        Timer[EVENT_FLAME_BURST] = 10000;
+        Timer[EVENT_SHADOWDEMON] = 30000;
+        Timer[EVENT_TRANSFORM_DEMON] = 60000;
+        AttackStart(m_creature->getVictim());
+        break;
+    case PHASE_TALK_SEQUENCE:
+        Timer[EVENT_TALK_SEQUENCE] = 100;
+        m_creature->RemoveAllAuras();
+        m_creature->InterruptNonMeleeSpells(false);
+        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
+        m_creature->GetMotionMaster()->Clear(false);
+        //m_creature->GetMotionMaster()->MoveIdle();
+        m_creature->AttackStop();
+        break;
+    case PHASE_FLIGHT_SEQUENCE:
+        if(Phase == PHASE_FLIGHT) //land
+            Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
+        else //lift off
+        {
+            FlightCount = 1;
+            Timer[EVENT_FLIGHT_SEQUENCE] = 1;
+            m_creature->RemoveAllAuras();
+            m_creature->InterruptNonMeleeSpells(false);
+            m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
+            m_creature->GetMotionMaster()->Clear(false);
+            //m_creature->GetMotionMaster()->MoveIdle();
+            m_creature->AttackStop();
+        }
+        break;
+    case PHASE_TRANSFORM_SEQUENCE:
+        if(Phase == PHASE_DEMON)
+            Timer[EVENT_TRANSFORM_SEQUENCE] = 500;
+        else
+        {
+            TransformCount = 0;
+            Timer[EVENT_TRANSFORM_SEQUENCE] = 500;
+            DoYell(SAY_MORPH, LANG_UNIVERSAL, NULL);
+            DoPlaySoundToSet(m_creature, SOUND_MORPH);
+        }
+        m_creature->GetMotionMaster()->Clear();
+        //m_creature->GetMotionMaster()->MoveIdle();
+        m_creature->AttackStop();
+        break;
+    default:
+        break;
+    }
+    if(MaievGUID)
+    {
+        GETCRE(Maiev, MaievGUID);
+        if(Maiev && Maiev->isAlive())
+            ((boss_maievAI*)Maiev->AI())->EnterPhase(NextPhase);
+    }
+    Phase = NextPhase;
+    Event = EVENT_NULL;
+}
 
 CreatureAI* GetAI_boss_illidan_stormrage(Creature *_Creature)
@@ -2348,10 +2385,5 @@
 CreatureAI* GetAI_npc_akama_at_illidan(Creature *_Creature)
 {
-    npc_akama_illidanAI* Akama_AI = new npc_akama_illidanAI(_Creature);
-
-    for(uint8 i = 0; i < 13; ++i)
-        Akama_AI->AddWaypoint(i, AkamaWP[i].x, AkamaWP[i].y, AkamaWP[i].z);
-
-    return ((CreatureAI*)Akama_AI);
+    return new npc_akama_illidanAI(_Creature);
 }
 
Index: /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_mother_shahraz.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_mother_shahraz.cpp (revision 48)
+++ /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_mother_shahraz.cpp (revision 57)
@@ -33,5 +33,5 @@
 #define SPELL_SILENCING_SHRIEK  40823
 #define SPELL_ENRAGE            23537
-#define SPELL_SABER_LASH        43267
+#define SPELL_SABER_LASH        40810//43267
 #define SPELL_SABER_LASH_IMM    43690
 #define SPELL_TELEPORT_VISUAL   40869
@@ -116,4 +116,5 @@
     uint32 FatalAttractionExplodeTimer;
     uint32 ShriekTimer;
+	uint32 SaberTimer;
     uint32 RandomYellTimer;
     uint32 EnrageTimer;
@@ -130,5 +131,5 @@
             TargetGUID[i] = 0;
 
-        BeamTimer = 60000;                                  // Timers may be incorrect
+        BeamTimer = 20000; // Timers may be incorrect
         BeamCount = 0;
         CurrentBeam = 0;                                    // 0 - Sinister, 1 - Vile, 2 - Wicked, 3 - Sinful
@@ -137,4 +138,5 @@
         FatalAttractionExplodeTimer = 70000;
         ShriekTimer = 30000;
+		SaberTimer = 35000;
         RandomYellTimer = 70000 + rand()%41 * 1000;
         EnrageTimer = 600000;
@@ -302,6 +304,12 @@
         {
             DoCast(m_creature->getVictim(), SPELL_SILENCING_SHRIEK);
-            ShriekTimer = 30000;
+            ShriekTimer = 25000+rand()%10 * 1000;
         }else ShriekTimer -= diff;
+
+		if(SaberTimer < diff)
+        {
+            DoCast(m_creature->getVictim(), SPELL_SABER_LASH);
+            SaberTimer = 25000+rand()%10 * 1000;
+        }else SaberTimer -= diff;
 
         //Enrage
Index: /trunk/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp (revision 48)
+++ /trunk/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp (revision 57)
@@ -127,10 +127,13 @@
             case 185905:                                    // Gate leading to Temple Summit
                 IllidanGate = go->GetGUID();
+                go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND);
                 break;
             case 186261:                                    // Right door at Temple Summit
                 IllidanDoor[0] = go->GetGUID();
+                go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND);
                 break;
             case 186262:                                    // Left door at Temple Summit
                 IllidanDoor[1] = go->GetGUID();
+                go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND);
                 break;
         }
Index: /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp (revision 48)
+++ /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp (revision 57)
@@ -17,6 +17,6 @@
 /* ScriptData
 SDName: Boss_Warlord_Najentus
-SD%Complete: 90
-SDComment: Using a creature workaround instead of a GO for Impaling Spine.
+SD%Complete: 95
+SDComment:
 SDCategory: Black Temple
 EndScriptData */
@@ -59,59 +59,18 @@
 
 //Spells
-#define SPELL_CRASHINGWAVE             40100
 #define SPELL_NEEDLE_SPINE             39835
 #define SPELL_NEEDLE_AOE               39968
 #define SPELL_TIDAL_BURST              39878
-#define SPELL_TIDAL_SHIELD             39872                // Not going to use this since Hurl Spine doesn't dispel it.
+#define SPELL_TIDAL_SHIELD             39872
 #define SPELL_IMPALING_SPINE           39837
 #define SPELL_CREATE_NAJENTUS_SPINE    39956
 #define SPELL_HURL_SPINE               39948
-#define SPELL_SHIELD_VISUAL            37136
 #define SPELL_BERSERK                  45078
 
-#define DISPLAYID_SPINE         7362
-
-struct TRINITY_DLL_DECL mob_najentus_spineAI : public ScriptedAI
-{
-    mob_najentus_spineAI(Creature *c) : ScriptedAI(c)
-    {
-        Reset();
-    }
-
-    uint64 SpineVictimGUID;
-
-    void Reset() {  SpineVictimGUID = 0; }
-
-    void SetSpineVictimGUID(uint64 guid){ SpineVictimGUID = guid; }
-
-    void JustDied(Unit *killer)
-    {
-        // Make the killer have the Najentus Spine item to pierce Tidal Shield
-        if(killer)
-            killer->CastSpell(killer, SPELL_CREATE_NAJENTUS_SPINE, true);
-    }
-
-    void DamageTaken(Unit *done_by, uint32 &damage)
-    {
-        if(damage < m_creature->GetHealth()) return;
-
-        // Remove the Impaling Spine DoT from whoever was affected
-        if(SpineVictimGUID)
-        {
-            Unit* victim = Unit::GetUnit((*m_creature), SpineVictimGUID);
-            if(victim && ((victim->HasAura(SPELL_IMPALING_SPINE, 0)) || (victim->HasAura(SPELL_IMPALING_SPINE, 1)) || (victim->HasAura(SPELL_IMPALING_SPINE, 2))))
-                victim->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE);
-        }
-    }
-
-    void Aggro(Unit* who) {}
-    void AttackStart(Unit* who) {}
-    void MoveInLineOfSight(Unit* who) {}
-    void UpdateAI(const uint32 diff) {}
-};
+#define GOBJECT_SPINE                  185584
 
 struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI
 {
-    boss_najentusAI(Creature *c) : ScriptedAI(c)
+    boss_najentusAI(Creature *c) : ScriptedAI(c) 
     {
         pInstance = ((ScriptedInstance*)c->GetInstanceData());
@@ -120,5 +79,5 @@
 
     ScriptedInstance* pInstance;
-    uint32 CrashingWaveTimer;
+
     uint32 NeedleSpineTimer;
     uint32 EnrageTimer;
@@ -126,61 +85,39 @@
     uint32 TidalShieldTimer;
     uint32 ImpalingSpineTimer;
-    uint32 CheckTimer;                                      // This timer checks if Najentus is Tidal Shielded and if so, regens health. If not, sets IsShielded to false
-    uint32 DispelShieldTimer;                               // This shield is only supposed to last 30 seconds, but the SPELL_SHIELD_VISUAL lasts forever
 
     uint64 SpineTargetGUID;
-    uint64 SpineGUID;
-
-    bool IsShielded;
 
     void Reset()
     {
-        IsShielded = false;
-
-        CrashingWaveTimer = 28000;
-        NeedleSpineTimer = 10000;
         EnrageTimer = 480000;
         SpecialYellTimer = 45000 + (rand()%76)*1000;
-        TidalShieldTimer = 60000;
-        ImpalingSpineTimer = 45000;
-        CheckTimer = 2000;
-        DispelShieldTimer = 30000;
+
+        ResetTimer();
 
         SpineTargetGUID = 0;
-        SpineGUID = 0;
 
         if(pInstance)
-        {
-            if(m_creature->isAlive())
-            {
-                pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, NOT_STARTED);
-                ToggleGate(true);
-            }
-            else  ToggleGate(false);
+            pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, NOT_STARTED);
+    }
+
+    void KilledUnit(Unit *victim)
+    {
+        switch(rand()%2)
+        {
+        case 0:
+            DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature, SOUND_SLAY1);
+            break;
+        case 1:
+            DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature, SOUND_SLAY2);
+            break;
         }
     }
 
-    void KilledUnit(Unit *victim)
-    {
-        switch(rand()%2)
-        {
-            case 0:
-                DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature, SOUND_SLAY1);
-                break;
-            case 1:
-                DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature, SOUND_SLAY2);
-                break;
-        }
-    }
-
     void JustDied(Unit *victim)
     {
         if(pInstance)
-        {
             pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, DONE);
-            ToggleGate(false);
-        }
 
         DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
@@ -188,31 +125,12 @@
     }
 
-    void ToggleGate(bool close)
-    {
-        if(GameObject* Gate = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_GAMEOBJECT_NAJENTUS_GATE)))
-            if(close)   Gate->SetGoState(0);                // Closed
-        else        Gate->SetGoState(2);                    // Opened
-    }
-
     void SpellHit(Unit *caster, const SpellEntry *spell)
     {
-        if(IsShielded)
-        {
-            if(spell->Id == SPELL_HURL_SPINE)
-            {
-                if(m_creature->HasAura(SPELL_SHIELD_VISUAL, 0))
-                    m_creature->RemoveAurasDueToSpell(SPELL_SHIELD_VISUAL);
-                if(m_creature->HasAura(SPELL_TIDAL_SHIELD, 0))
-                    m_creature->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD);
-                DoCast(m_creature->getVictim(), SPELL_TIDAL_BURST);
-                IsShielded = false;
-            }
+        if(spell->Id == SPELL_HURL_SPINE && m_creature->HasAura(SPELL_TIDAL_SHIELD, 0))
+        {
+            m_creature->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD);
+            m_creature->CastSpell(m_creature, SPELL_TIDAL_BURST, true);
+            ResetTimer();
         }
-    }
-
-    void DamageTaken(Unit *done_by, uint32 &damage)
-    {
-        if(IsShielded)
-            damage = 0;
     }
 
@@ -224,88 +142,42 @@
         DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
         DoPlaySoundToSet(m_creature, SOUND_AGGRO);
-
         DoZoneInCombat();
     }
 
-    // This is a workaround since we cannot summon GameObjects at will.
-    // Instead, we create a custom creature on top of the player.
-    // When someone kills the creature, the killer gets the "Naj'entus Spine" item.
-    // This item is the only item that should be able to pierce Tidal Shield
-    void DoImpalingSpineWorkaround(Unit* target)
-    {
-        Creature* Spine = NULL;
-        Spine = m_creature->SummonCreature(500000, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 10000);
-        if(Spine)
-        {
-            Spine->setFaction(m_creature->getFaction());
-            ((mob_najentus_spineAI*)Spine->AI())->SetSpineVictimGUID(target->GetGUID());
-            SpineTargetGUID = target->GetGUID();
-        }
-    }
-
-    bool RemoveImpalingSpine(uint64 guid)
-    {
-        if(!IsShielded || guid == SpineTargetGUID) return false;
-
-        if(SpineTargetGUID)
-        {
-            Unit* target = Unit::GetUnit((*m_creature), SpineTargetGUID);
-            if(target && target->HasAura(SPELL_IMPALING_SPINE, 0))
-            {
-                target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE);
-                return true;
-            }
-        }
-
-        return false;
+    bool RemoveImpalingSpine()
+    {
+        if(!SpineTargetGUID) return false;
+        Unit* target = Unit::GetUnit(*m_creature, SpineTargetGUID);
+        if(target && target->HasAura(SPELL_IMPALING_SPINE, 1))
+            target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE);
+        SpineTargetGUID=0;
+        return true;
+    }
+
+    void ResetTimer(uint32 inc = 0)
+    {
+        NeedleSpineTimer = 10000 + inc;
+        TidalShieldTimer = 60000 + inc;
+        ImpalingSpineTimer = 20000 + inc;
     }
 
     void UpdateAI(const uint32 diff)
     {
-        //Return since we have no target
         if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
             return;
 
-        if(CheckTimer < diff)
-        {
-            // if(m_creature->HasAura(SPELL_TIDAL_SHIELD, 0))
-            if(m_creature->HasAura(SPELL_SHIELD_VISUAL, 0))
-                m_creature->SetHealth(m_creature->GetHealth() + (m_creature->GetMaxHealth()/100));
-            else
-                IsShielded = false;
-
-            CheckTimer = 2000;
-        }else CheckTimer -= diff;
-
-        if(IsShielded)
-        {
-            m_creature->GetMotionMaster()->Clear(false);
-            m_creature->GetMotionMaster()->MoveIdle();
-            if(!m_creature->HasAura(SPELL_SHIELD_VISUAL, 0))
-                DoCast(m_creature, SPELL_SHIELD_VISUAL);
-            if(DispelShieldTimer < diff)
-            {
-                m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
-                if(m_creature->HasAura(SPELL_SHIELD_VISUAL, 0))
-                    m_creature->RemoveAurasDueToSpell(SPELL_SHIELD_VISUAL);
-                IsShielded = false;
-            }else DispelShieldTimer -= diff;
-
-            return;                                         // Don't cast or do anything while Shielded
-        }
-
-        // Crashing Wave
-        if(CrashingWaveTimer < diff)
-        {
-            DoCast(m_creature->getVictim(), SPELL_CRASHINGWAVE);
-            CrashingWaveTimer = 28500;
-        }else CrashingWaveTimer -= diff;
-
-        if(!m_creature->HasAura(SPELL_BERSERK, 0))
-            if(EnrageTimer < diff)
+        if(TidalShieldTimer < diff)
+        {
+            m_creature->InterruptNonMeleeSpells(false);
+            DoCast(m_creature, SPELL_TIDAL_SHIELD, true);
+            ResetTimer(45000);
+        }else TidalShieldTimer -= diff;
+
+        if(EnrageTimer < diff)
         {
             DoYell(SAY_ENRAGE, LANG_UNIVERSAL, NULL);
             DoPlaySoundToSet(m_creature, SOUND_ENRAGE);
-            DoCast(m_creature, SPELL_BERSERK);
+            m_creature->CastSpell(m_creature, SPELL_BERSERK, true);
+            EnrageTimer = 600000;
         }else EnrageTimer -= diff;
 
@@ -316,12 +188,9 @@
             {
                 Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
-                if(!target)
-                    target = m_creature->getVictim();
-
-                DoCast(target, SPELL_NEEDLE_AOE, true);
-                DoCast(target, SPELL_NEEDLE_SPINE);
-            }
-
-            NeedleSpineTimer = 60000;
+                if(!target) target = m_creature->getVictim();
+                m_creature->CastSpell(target, SPELL_NEEDLE_SPINE, true);
+            }
+            m_creature->SetInFront(m_creature->getVictim());
+            NeedleSpineTimer = 30000;
         }else NeedleSpineTimer -= diff;
 
@@ -330,11 +199,11 @@
             switch(rand()%2)
             {
-                case 0:
-                    DoPlaySoundToSet(m_creature, SOUND_SPECIAL1);
-                    break;
-                case 1:
-                    DoYell(SAY_SPECIAL2, LANG_UNIVERSAL, NULL);
-                    DoPlaySoundToSet(m_creature, SOUND_SPECIAL2);
-                    break;
+            case 0:
+                DoPlaySoundToSet(m_creature, SOUND_SPECIAL1);
+                break;
+            case 1:
+                DoYell(SAY_SPECIAL2, LANG_UNIVERSAL, NULL);
+                DoPlaySoundToSet(m_creature, SOUND_SPECIAL2);
+                break;
             }
             SpecialYellTimer = 25000 + (rand()%76)*1000;
@@ -344,41 +213,24 @@
         {
             Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
-            if(!target)
-                target = m_creature->getVictim();
-
-            if(target && (target->GetTypeId() == TYPEID_PLAYER))
-            {
-                DoCast(target, SPELL_IMPALING_SPINE);
-                //DoImpalingSpineWorkaround(target);
-                SpineTargetGUID = target->GetGUID();
-                ImpalingSpineTimer = 45000;
-
-                switch(rand()%2)
-                {
-                    case 0:
-                        DoYell(SAY_NEEDLE1, LANG_UNIVERSAL, NULL);
-                        DoPlaySoundToSet(m_creature, SOUND_NEEDLE1);
-                        break;
-                    case 1:
-                        DoYell(SAY_NEEDLE2, LANG_UNIVERSAL, NULL);
-                        DoPlaySoundToSet(m_creature, SOUND_NEEDLE2);
-                        break;
-                }
-            }
+            if(!target) target = m_creature->getVictim();
+            m_creature->CastSpell(target, SPELL_IMPALING_SPINE, true);
+            m_creature->SetInFront(m_creature->getVictim());
+            SpineTargetGUID = target->GetGUID();
+            m_creature->SummonGameObject(GOBJECT_SPINE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), m_creature->GetOrientation(), 0, 0, 0, 0, 30);
+
+            switch(rand()%2)
+            {
+            case 0:
+                DoYell(SAY_NEEDLE1, LANG_UNIVERSAL, NULL);
+                DoPlaySoundToSet(m_creature, SOUND_NEEDLE1);
+                break;
+            case 1:
+                DoYell(SAY_NEEDLE2, LANG_UNIVERSAL, NULL);
+                DoPlaySoundToSet(m_creature, SOUND_NEEDLE2);
+                break;
+            }
+            ImpalingSpineTimer = 21000;
         }else ImpalingSpineTimer -= diff;
 
-        if(TidalShieldTimer < diff)
-        {
-            m_creature->InterruptNonMeleeSpells(false);
-            DoCast(m_creature, SPELL_SHIELD_VISUAL, true);
-            // DoCast(m_creature, SPELL_TIDAL_SHIELD);
-            m_creature->GetMotionMaster()->Clear(false);
-            m_creature->GetMotionMaster()->MoveIdle();
-            IsShielded = true;
-            TidalShieldTimer = 60000;
-            CheckTimer = 2000;
-            DispelShieldTimer = 30000;
-        }else TidalShieldTimer -= diff;
-
         DoMeleeAttackIfReady();
     }
@@ -387,26 +239,13 @@
 bool GOHello_go_najentus_spine(Player *player, GameObject* _GO)
 {
-    ScriptedInstance* pInstance = ((ScriptedInstance*)_GO->GetInstanceData());
-    if(pInstance)
-    {
-        uint64 NajentusGUID = pInstance->GetData64(DATA_HIGHWARLORDNAJENTUS);
-        if(NajentusGUID)
-        {
-            Creature* Najentus = ((Creature*)Unit::GetUnit((*_GO), NajentusGUID));
-            if(Najentus)
-            {
-                if(((boss_najentusAI*)Najentus->AI())->RemoveImpalingSpine(player->GetGUID()))
-                    return true;
-            }else error_log("ERROR: Na'entus Spine GameObject unable to find Naj'entus");
-        }else error_log("ERROR: Invalid GUID acquired for Naj'entus by Naj'entus Spine GameObject");
-    }
-    else error_log("ERROR: Naj'entus Spine spawned in invalid instance or location");
-
+    if(ScriptedInstance* pInstance = (ScriptedInstance*)_GO->GetInstanceData())
+        if(Creature* Najentus = (Creature*)Unit::GetUnit(*_GO, pInstance->GetData64(DATA_HIGHWARLORDNAJENTUS)))
+            if(((boss_najentusAI*)Najentus->AI())->RemoveImpalingSpine())
+            {
+                player->CastSpell(player, SPELL_CREATE_NAJENTUS_SPINE, true);
+                _GO->SetLootState(GO_NOT_READY);
+                _GO->SetRespawnTime(0);
+            }
     return true;
-}
-
-CreatureAI* GetAI_mob_najentus_spine(Creature *_Creature)
-{
-    return new mob_najentus_spineAI (_Creature);
 }
 
@@ -425,9 +264,4 @@
 
     newscript = new Script;
-    newscript->Name = "mob_najentus_spine";
-    newscript->GetAI = GetAI_mob_najentus_spine;
-    m_scripts[nrscripts++] = newscript;
-
-    newscript = new Script;
     newscript->Name = "go_najentus_spine";
     newscript->pGOHello = &GOHello_go_najentus_spine;
Index: /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp (revision 48)
+++ /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp (revision 57)
@@ -117,4 +117,6 @@
         FireballTimer = 500;
         GeyserTimer = 0;
+        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
     }
 
@@ -122,20 +124,7 @@
     void AttackStart(Unit* who) {}
     void MoveInLineOfSight(Unit* who) {}
-    void SetSupremusGUID(uint64 guid) { SupremusGUID = guid; }
 
     void UpdateAI(const uint32 diff)
     {
-        if(CheckTimer < diff)
-        {
-            if(SupremusGUID)
-            {
-                Unit* Supremus = NULL;
-                Supremus = Unit::GetUnit((*m_creature), SupremusGUID);
-                if(Supremus && (!Supremus->isAlive()))
-                    m_creature->DealDamage(m_creature, m_creature->GetHealth(), 0, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-            }
-            CheckTimer = 2000;
-        }else CheckTimer -= diff;
-
         if(GeyserTimer < diff)
         {
@@ -143,4 +132,10 @@
             GeyserTimer = 18000;
         }else GeyserTimer -= diff;
+
+        if(FireballTimer < diff)
+        {
+            DoCast(m_creature, SPELL_VOLCANIC_FIREBALL, true);
+            FireballTimer = 1000;
+        }else FireballTimer -= diff;
     }
 };
@@ -272,5 +267,5 @@
             if(BerserkTimer < diff)
                 DoCast(m_creature, SPELL_BERSERK);
-        else BerserkTimer -= diff;
+            else BerserkTimer -= diff;
 
         if(SummonFlameTimer < diff)
@@ -333,13 +328,5 @@
                 if(target)
                 {
-                    Creature* Volcano = NULL;
-                    Volcano = SummonCreature(CREATURE_VOLCANO, target);
-
-                    if(Volcano)
-                    {
-                        DoCast(target, SPELL_VOLCANIC_ERUPTION);
-                        ((npc_volcanoAI*)Volcano->AI())->SetSupremusGUID(m_creature->GetGUID());
-                    }
-
+                    DoCast(target, SPELL_VOLCANIC_ERUPTION);
                     DoTextEmote("roars and the ground begins to crack open!", NULL);
                     SummonVolcanoTimer = 10000;
@@ -356,4 +343,5 @@
                 PhaseSwitchTimer = 60000;
                 m_creature->SetSpeed(MOVE_RUN, 1.0f);
+                DoZoneInCombat();
             }
             else
@@ -365,4 +353,5 @@
                 PhaseSwitchTimer = 60000;
                 m_creature->SetSpeed(MOVE_RUN, 0.9f);
+                DoZoneInCombat();
             }
         }else PhaseSwitchTimer -= diff;
Index: /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp (revision 48)
+++ /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp (revision 57)
@@ -1,22 +1,22 @@
 /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
 
 /* ScriptData
 SDName: Boss_Reliquary_of_Souls
 SD%Complete: 90
-SDComment: Persistent Area Auras for each Essence (Aura of Suffering, Aura of Desire, Aura of Anger) requires core support.
+SDComment:
 SDCategory: Black Temple
 EndScriptData */
@@ -24,4 +24,5 @@
 #include "precompiled.h"
 #include "def_black_temple.h"
+#include "Spell.h"
 
 //Sound'n'speech
@@ -35,6 +36,6 @@
 #define SUFF_SAY_SLAY2      "I didn't ask for this!"
 #define SUFF_SOUND_SLAY2    11418
-#define SUFF_SAY_SLAY3      "The pain is only beginning!"
-#define SUFF_SOUND_SLAY3    11419
+#define SUFF_SAY_ENRAGE     "The pain is only beginning!"
+#define SUFF_SOUND_ENRAGE   11419
 #define SUFF_SAY_RECAP      "I don't want to go back!"
 #define SUFF_SOUND_RECAP    11420
@@ -61,6 +62,6 @@
 #define ANGER_SAY_FREED     "Beware... I live."
 #define ANGER_SOUND_FREED   11399
-#define ANGER_SAY_FREED2    "So... foolish."
-#define ANGER_SOUND_FREED2  11400
+#define ANGER_SAY_SCREAM    "So... foolish."
+#define ANGER_SOUND_SCREAM  11400
 #define ANGER_SOUND_SLAY1   11401
 #define ANGER_SAY_SLAY2     "Enough. No more."
@@ -75,11 +76,14 @@
 //Spells
 #define AURA_OF_SUFFERING               41292
-#define AURA_OF_SUFFERING_ARMOR         42017
-#define ESSENCE_OF_SUFFERING_PASSIVE    41296
+#define AURA_OF_SUFFERING_ARMOR         42017 // linked aura, need core support
+#define ESSENCE_OF_SUFFERING_PASSIVE    41296 // periodic trigger 41294
+#define ESSENCE_OF_SUFFERING_PASSIVE2   41623 
+#define SPELL_FIXATE_TARGET             41294 // dummy, select target
+#define SPELL_FIXATE_TAUNT              41295 // force taunt
 #define SPELL_ENRAGE                    41305
 #define SPELL_SOUL_DRAIN                41303
-#define SPELL_FIXATE                    41295
 
 #define AURA_OF_DESIRE                  41350
+#define AURA_OF_DESIRE_DAMAGE           41352
 #define SPELL_RUNE_SHIELD               41431
 #define SPELL_DEADEN                    41410
@@ -87,15 +91,15 @@
 
 #define AURA_OF_ANGER                   41337
-#define SPELL_SELF_SEETHE               41364
+#define SPELL_SELF_SEETHE               41364 // force cast 41520
 #define SPELL_ENEMY_SEETHE              41520
 #define SPELL_SOUL_SCREAM               41545
-#define SPELL_SPITE                     41377
+#define SPELL_SPITE_TARGET              41376 // cast 41377 after 6 sec
+#define SPELL_SPITE_DAMAGE              41377
 
 #define ENSLAVED_SOUL_PASSIVE           41535
 #define SPELL_SOUL_RELEASE              41542
-#define SPELL_RESTORE_MANA              32848
-#define SPELL_RESTORE_HEALTH            25329
 
 #define CREATURE_ENSLAVED_SOUL          23469
+#define NUMBER_ENSLAVED_SOUL            8
 
 struct Position
@@ -120,29 +124,10 @@
     uint64 ReliquaryGUID;
 
-    void Reset()
-    {
-        ReliquaryGUID = 0;
-    }
-
-    void Aggro(Unit* who) {}
-
-    void DamageTaken(Unit *done_by, uint32 &damage)
-    {
-        if(damage >= m_creature->GetHealth())
-        {
-            if(done_by->GetTypeId() == TYPEID_PLAYER)
-            {
-                done_by->CastSpell(done_by, SPELL_RESTORE_HEALTH, true);
-                if(done_by->GetMaxPower(POWER_MANA) > 0)
-                {
-                    if((done_by->GetPower(POWER_MANA) / done_by->GetMaxPower(POWER_MANA)) < 70)
-                    {
-                        uint32 mana = done_by->GetPower(POWER_MANA) + (uint32)(done_by->GetMaxPower(POWER_MANA)*0.3);
-                        done_by->SetPower(POWER_MANA, mana);
-                    }else done_by->SetPower(POWER_MANA, done_by->GetMaxPower(POWER_MANA));
-                }
-            }
-            DoCast(done_by, SPELL_SOUL_RELEASE);
-        }
+    void Reset() {ReliquaryGUID = 0;}
+
+    void Aggro(Unit* who)
+    {
+        m_creature->CastSpell(m_creature, ENSLAVED_SOUL_PASSIVE, true);
+        DoZoneInCombat();
     }
 
@@ -152,7 +137,8 @@
 struct TRINITY_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI
 {
-    boss_reliquary_of_soulsAI(Creature *c) : ScriptedAI(c)
+    boss_reliquary_of_soulsAI(Creature *c) : ScriptedAI(c) 
     {
         pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        EssenceGUID = 0;
         Reset();
     }
@@ -160,19 +146,12 @@
     ScriptedInstance* pInstance;
 
-    uint64 SufferingGUID;
-    uint64 DesireGUID;
-    uint64 AngerGUID;
-
+    uint64 EssenceGUID;
+
+    uint32 Phase;
+    uint32 Counter;
+    uint32 Timer;
+
+    uint32 SoulCount;
     uint32 SoulDeathCount;
-    // 0 = Out of Combat, 1 = Not started, 2 = Suffering, 3 = Souls, 4 = Desire, 5 = Souls, 6 = Anger
-    uint32 Phase;
-    uint32 SummonEssenceTimer;
-    uint32 DespawnEssenceTimer;
-    uint32 SoulCount;
-    uint32 SummonSoulTimer;
-    uint32 AnimationTimer;
-
-    bool IsDead;
-    bool EndingPhase;
 
     void Reset()
@@ -181,53 +160,47 @@
             pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, NOT_STARTED);
 
-        DespawnEssences();
-
-        SufferingGUID = 0;
-        DesireGUID = 0;
-        AngerGUID = 0;
-
-        SoulDeathCount = 0;
+        if(EssenceGUID)
+        {
+            if(Unit* Essence = Unit::GetUnit(*m_creature, EssenceGUID))
+            {
+                Essence->SetVisibility(VISIBILITY_OFF);
+                Essence->setDeathState(DEAD);
+            }
+            EssenceGUID = 0;
+        }
+
         Phase = 0;
-        SummonEssenceTimer = 8000;
-        DespawnEssenceTimer = 2000;
-        SoulCount = 0;
-        SummonSoulTimer = 1000;
-        AnimationTimer = 8000;
-
-        IsDead = false;
-        EndingPhase = false;
-
-        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
         m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0);
-        m_creature->GetMotionMaster()->Clear(false);
-    }
-
-    void Aggro(Unit* who) { }
-
-    void AttackStart(Unit* who) { }
+    }
+
+    void Aggro(Unit* who)
+    {
+        m_creature->AddThreat(who, 10000.0f);
+        DoZoneInCombat();
+        if(pInstance)
+            pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, IN_PROGRESS);
+
+        Phase = 1;
+        Counter = 0;
+        Timer = 0;
+    }
 
     void MoveInLineOfSight(Unit *who)
     {
-        if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
-        {
+        if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) )
+        {
+            if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
+                return;
+
             float attackRadius = m_creature->GetAttackDistance(who);
-            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
+            if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) )
             {
-                if(who->HasStealthAura())
-                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
-
-                if(!InCombat)
+                who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+
+                if (!InCombat)
                 {
-                    if(pInstance)
-                        pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, IN_PROGRESS);
-
-                    Phase = 1;
-                                                            // I R ANNNGRRRY!
-                    m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,375);
-                    SummonEssenceTimer = 8000;
-                    AnimationTimer = 5100;
-                    m_creature->AddThreat(who, 1.0f);
-
+                    Aggro(who);
                     InCombat = true;
                 }
@@ -236,51 +209,19 @@
     }
 
-    void SummonSoul()
+    void AttackStart(Unit*) {}
+
+    bool SummonSoul()
     {
         uint32 random = rand()%6;
         float x = Coords[random].x;
         float y = Coords[random].y;
-        Creature* Soul = m_creature->SummonCreature(CREATURE_ENSLAVED_SOUL, x, y, m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
-        Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
-        if (target && Soul)
+        Creature* Soul = m_creature->SummonCreature(CREATURE_ENSLAVED_SOUL, x, y, m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 0);
+        if(!Soul) return false;
+        if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
         {
             ((npc_enslaved_soulAI*)Soul->AI())->ReliquaryGUID = m_creature->GetGUID();
-            Soul->CastSpell(Soul, ENSLAVED_SOUL_PASSIVE, true);
-            Soul->AddThreat(target, 1.0f);
-            SoulCount++;
-        }
-    }
-
-    void MergeThreatList(Creature* target)
-    {
-        if(!target) return;
-
-        std::list<HostilReference*>& m_threatlist = target->getThreatManager().getThreatList();
-        std::list<HostilReference*>::iterator itr = m_threatlist.begin();
-        for( ; itr != m_threatlist.end(); itr++)
-        {
-            Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());
-            if(pUnit)
-            {
-                m_creature->AddThreat(pUnit, 1.0f);         // This is so that we make sure the unit is in Reliquary's threat list before we reset the unit's threat.
-                m_creature->getThreatManager().modifyThreatPercent(pUnit, -100);
-                float threat = target->getThreatManager().getThreat(pUnit);
-                m_creature->AddThreat(pUnit, threat);       // This makes it so that the unit has the same amount of threat in Reliquary's threatlist as in the target creature's (One of the Essences).
-            }
-        }
-    }
-
-    void DespawnEssences()
-    {
-        // Despawn Essences
-        Unit* Essence = NULL;
-        if(SufferingGUID)
-            Essence = ((Creature*)Unit::GetUnit((*m_creature), SufferingGUID));
-        else if(DesireGUID)
-            Essence = ((Creature*)Unit::GetUnit((*m_creature), DesireGUID));
-        else if(AngerGUID)
-            Essence = ((Creature*)Unit::GetUnit((*m_creature), AngerGUID));
-        if(Essence && Essence->isAlive())
-            Essence->setDeathState(JUST_DIED);
+            Soul->AI()->AttackStart(target);
+        }else EnterEvadeMode();
+        return true;
     }
 
@@ -298,275 +239,106 @@
             return;
 
-        // Reset if event is begun and we don't have a threatlist
-        if(Phase && m_creature->getThreatManager().getThreatList().empty())
+        if(m_creature->getThreatManager().getThreatList().empty()) // Reset if event is begun and we don't have a threatlist
+        {
             EnterEvadeMode();
-
-        if(Phase == 1)
-        {
-            if(AnimationTimer < diff)
+            return;
+        }
+
+        Creature* Essence;
+        if(EssenceGUID)
+        {
+            Essence = (Creature*)Unit::GetUnit(*m_creature, EssenceGUID);
+            if(!Essence)
             {
-                // Release the cube
-                m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374);
-                AnimationTimer = 8300;
-            }else AnimationTimer -= diff;
-
-            if(SummonEssenceTimer < diff)
+                EnterEvadeMode();
+                return;
+            }
+        }
+
+        if(Timer < diff)
+        {
+            switch(Counter)
             {
-                // Ribs: open
-                m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373);
-                Creature* EssenceSuffering = NULL;
-                EssenceSuffering = m_creature->SummonCreature(23418, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000);
-
-                if(EssenceSuffering)
+            case 0:
+                m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,375);  // I R ANNNGRRRY!
+                Timer = 3000;
+                break;
+            case 1:
+                Timer = 2800;
+                m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374);  // Release the cube
+                break;
+            case 2:
+                Timer = 5000;
+                if(Creature* Summon = DoSpawnCreature(23417+Phase, 0, 0, 0, 0, TEMPSUMMON_DEAD_DESPAWN, 0))
                 {
-                    EssenceSuffering->Yell(SUFF_SAY_FREED, LANG_UNIVERSAL, 0);
-                    DoPlaySoundToSet(m_creature, SUFF_SOUND_FREED);
-                    Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);
-                    if(target)
+                    m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373);  // Ribs: open
+                    Summon->AI()->AttackStart(SelectUnit(SELECT_TARGET_TOPAGGRO, 0));
+                    EssenceGUID = Summon->GetGUID();
+                }else EnterEvadeMode();
+                break;
+            case 3:
+                Timer = 1000;
+                if(Phase == 3)
+                {
+                    if(!Essence->isAlive())
+                        m_creature->CastSpell(m_creature, 7, true);
+                    else return;
+                }
+                else
+                {
+                    if(Essence->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
                     {
-                        EssenceSuffering->AddThreat(target, 1.0f);
-                        EssenceSuffering->AI()->AttackStart(target);
-                    }
-                    SufferingGUID = EssenceSuffering->GetGUID();
+                        Essence->AI()->EnterEvadeMode();
+                        Essence->GetMotionMaster()->MoveFollow(m_creature, 0, 0);
+                    }else return;
                 }
-
-                EndingPhase = false;
-                Phase = 2;
-            }else SummonEssenceTimer -= diff;
-        }
-
-        if(Phase == 2)
-        {
-            if(SufferingGUID)
-            {
-                Creature* EssenceSuffering = NULL;
-                EssenceSuffering = ((Creature*)Unit::GetUnit((*m_creature), SufferingGUID));
-
-                if(!EssenceSuffering || (!EssenceSuffering->isAlive()))
-                    EnterEvadeMode();
-
-                if(!EndingPhase)
+                break;
+            case 4:
+                Timer = 1500;
+                if(Essence->IsWithinDistInMap(m_creature, 10))
+                    Essence->SetUInt32Value(UNIT_NPC_EMOTESTATE, 374); //rotate and disappear
+                else
+                    return;
+                break;
+            case 5:
+                if(Phase == 1)
                 {
-                    if(EssenceSuffering)
-                    {
-                        if(EssenceSuffering->GetHealth() < (EssenceSuffering->GetMaxHealth()*0.1))
-                        {
-                            MergeThreatList(EssenceSuffering);
-                            EssenceSuffering->RemoveAllAuras();
-                            EssenceSuffering->DeleteThreatList();
-                            EssenceSuffering->GetMotionMaster()->MoveFollow(m_creature,0.0f,0.0f);
-                            EssenceSuffering->Yell(SUFF_SAY_RECAP,LANG_UNIVERSAL,0);
-                            DoPlaySoundToSet(m_creature, SUFF_SOUND_RECAP);
-                            EssenceSuffering->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-                            DespawnEssenceTimer = 4000;
-                            AnimationTimer = 2200;
-                            EndingPhase = true;
-                        }
-                    }
+                    Essence->Yell(SUFF_SAY_AFTER,LANG_UNIVERSAL,0);
+                    DoPlaySoundToSet(Essence, SUFF_SOUND_AFTER);
                 }
-
-                if((EndingPhase) && (EssenceSuffering) && (EssenceSuffering->isAlive()))
+                else
                 {
-                    if(AnimationTimer < diff)
-                    {
-                        // Return
-                        EssenceSuffering->SetUInt32Value(UNIT_NPC_EMOTESTATE,374);
-                        AnimationTimer = 10000;
-                    }else AnimationTimer -= diff;
-
-                    if(DespawnEssenceTimer < diff)
-                    {
-                        EssenceSuffering->DeleteThreatList();
-                        EssenceSuffering->Yell(SUFF_SAY_AFTER,LANG_UNIVERSAL,0);
-                        DoPlaySoundToSet(m_creature, SUFF_SOUND_AFTER);
-                        EssenceSuffering->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
-                        EssenceSuffering->setFaction(35);
-                        m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0);
-                        SummonEssenceTimer = 20000;         //60000;
-                        AnimationTimer = 18200;             //58100;
-                        SoulDeathCount = 0;
-                        SoulCount = 0;
-                        SummonSoulTimer = 1000;
-                        EndingPhase = false;
-                        Phase = 3;
-                        SufferingGUID = 0;
-                    }else DespawnEssenceTimer -= diff;
+                    Essence->Yell(DESI_SAY_AFTER,LANG_UNIVERSAL,0);
+                    DoPlaySoundToSet(Essence, DESI_SOUND_AFTER);
                 }
-            }
-        }
-
-        if(Phase == 3)
-        {
-            if(SoulCount < 36)
-            {
-                if(SummonSoulTimer < diff)
+                Essence->SetVisibility(VISIBILITY_OFF);
+                Essence->setDeathState(DEAD);
+                m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0);
+                EssenceGUID = 0;
+                SoulCount = 0;
+                SoulDeathCount = 0;
+                Timer = 3000;            
+                break;
+            case 6:
+                if(SoulCount < NUMBER_ENSLAVED_SOUL)
                 {
-                    SummonSoul();
-                    SummonSoulTimer = 500;
-                }else SummonSoulTimer -= diff;
-            }
-
-            if(SoulDeathCount >= SoulCount)
-            {
-                if(AnimationTimer < diff)
+                    if(SummonSoul())
+                        SoulCount++;
+                    Timer = 500;
+                    return;
+                }break;
+            case 7:
+                if(SoulDeathCount >= SoulCount)
                 {
-                    // Release the cube
-                    m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374);
-                    AnimationTimer = 10000;
-                }else AnimationTimer -= diff;
-
-                if(SummonEssenceTimer < diff)
-                {
-                    // Ribs: open
-                    m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373);
-                    Creature* EssenceDesire = NULL;
-                    EssenceDesire = m_creature->SummonCreature(23419, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000);
-
-                    if(EssenceDesire)
-                    {
-                        EssenceDesire->Yell(DESI_SAY_FREED, LANG_UNIVERSAL, NULL);
-                        DoPlaySoundToSet(m_creature, DESI_SOUND_FREED);
-                        Unit* target = NULL;
-                        target = SelectUnit(SELECT_TARGET_RANDOM, 0);
-                        if(target)
-                        {
-                            EssenceDesire->AddThreat(target, 1.0f);
-                            EssenceDesire->AI()->AttackStart(target);
-                        }
-                        DesireGUID = EssenceDesire->GetGUID();
-                        SoulDeathCount = 0;
-                    }
-
-                    Phase = 4;
-                }else SummonEssenceTimer -= diff;
-            }
-        }
-
-        if(Phase == 4)
-        {
-            if(DesireGUID)
-            {
-                Creature* EssenceDesire = NULL;
-                EssenceDesire = ((Creature*)Unit::GetUnit((*m_creature), DesireGUID));
-
-                if(!EssenceDesire || !EssenceDesire->isAlive())
-                    EnterEvadeMode();
-
-                if(!EndingPhase && EssenceDesire)
-                {
-                    if(EssenceDesire->GetHealth() < (EssenceDesire->GetMaxHealth()*0.1))
-                    {
-                        MergeThreatList(EssenceDesire);
-                        EssenceDesire->GetMotionMaster()->MoveFollow(m_creature,0.0f,0.0f);
-                        EssenceDesire->RemoveAllAuras();
-                        EssenceDesire->DeleteThreatList();
-                        EssenceDesire->Yell(DESI_SAY_RECAP,LANG_UNIVERSAL,0);
-                        DoPlaySoundToSet(m_creature, DESI_SOUND_RECAP);
-                        EssenceDesire->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-                        DespawnEssenceTimer = 4000;
-                        AnimationTimer = 2200;
-                        EndingPhase = true;
-                    }
+                    Counter = 1;
+                    Phase++;
+                    Timer = 5000;
                 }
-
-                if(EndingPhase && EssenceDesire)
-                {
-                    if(EssenceDesire->isAlive())
-                    {
-                        if(AnimationTimer < diff)
-                        {
-                            // Return
-                            EssenceDesire->SetUInt32Value(UNIT_NPC_EMOTESTATE,374);
-                            AnimationTimer = 10000;
-                        }else AnimationTimer -= diff;
-
-                        if(DespawnEssenceTimer < diff)
-                        {
-                            EssenceDesire->DeleteThreatList();
-                            EssenceDesire->setFaction(35);
-                            EssenceDesire->Yell(DESI_SAY_AFTER, LANG_UNIVERSAL, 0);
-                            DoPlaySoundToSet(m_creature, DESI_SOUND_AFTER);
-                            EssenceDesire->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
-                            m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0);
-                            SummonEssenceTimer = 20000;
-                            AnimationTimer = 18200;
-                            SoulDeathCount = 0;
-                            SoulCount = 0;
-                            SummonSoulTimer = 1000;
-                            EndingPhase = false;
-                            Phase = 5;
-                            DesireGUID = 0;
-                        }else DespawnEssenceTimer -= diff;
-                    }
-                }
-            }
-        }
-
-        if(Phase == 5)
-        {
-            if(SoulCount < 36)
-            {
-                if(SummonSoulTimer < diff)
-                {
-                    SummonSoul();
-                    SummonSoulTimer = 500;
-                }else SummonSoulTimer -= diff;
-            }
-
-            if(SoulDeathCount >= SoulCount)
-            {
-                if(AnimationTimer < diff)
-                {
-                    // Release the cube
-                    m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374);
-                    AnimationTimer = 10000;
-                }else AnimationTimer -= diff;
-
-                if(SummonEssenceTimer < diff)
-                {
-                    // Ribs: open
-                    m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373);
-                    Creature* EssenceAnger = NULL;
-                    EssenceAnger = m_creature->SummonCreature(23420, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000);
-
-                    if(EssenceAnger)
-                    {
-                        Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);
-                        if(target)
-                        {
-                            EssenceAnger->AddThreat(target, 1.0f);
-                            EssenceAnger->AI()->AttackStart(target);
-                        }
-                        AngerGUID = EssenceAnger->GetGUID();
-                        DoPlaySoundToSet(m_creature, ANGER_SOUND_FREED);
-                        EssenceAnger->Yell(ANGER_SAY_FREED, LANG_UNIVERSAL, 0);
-                        SoulDeathCount = 0;
-                    }
-
-                    Phase = 6;
-                }else SummonEssenceTimer -= diff;
-            }
-        }
-
-        if(Phase == 6)
-        {
-            if(AngerGUID)
-            {
-                Creature* EssenceAnger = NULL;
-                EssenceAnger = ((Creature*)Unit::GetUnit((*m_creature), AngerGUID));
-
-                if(!EssenceAnger)
-                    EnterEvadeMode();
-
-                if(m_creature->isAlive() && EssenceAnger)
-                {
-                    if(!EssenceAnger->isAlive())
-                    {
-                        AngerGUID = 0;
-                        m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-                    }
-                }
-            }
-        }
+                return;
+            default:
+                break;
+            }
+            Counter++;
+        }else Timer -= diff;
     }
 };
@@ -594,4 +366,5 @@
     uint32 EnrageTimer;
     uint32 SoulDrainTimer;
+    uint32 AuraTimer;
 
     void Reset()
@@ -600,22 +373,18 @@
 
         AggroYellTimer = 5000;
-        FixateTimer = 5000;
+        FixateTimer = 8000;
         EnrageTimer = 30000;
-        SoulDrainTimer = 150000;
+        SoulDrainTimer = 45000;
+        AuraTimer = 5000;
     }
 
     void DamageTaken(Unit *done_by, uint32 &damage)
     {
-        if((damage >= m_creature->GetHealth()) && (done_by != m_creature))
+        if(damage >= m_creature->GetHealth())
         {
             damage = 0;
-            // 10% of total health, signalling time to return
-            m_creature->SetHealth(m_creature->GetMaxHealth()/10);
-            if(StatAuraGUID)
-            {
-                Unit* pUnit = Unit::GetUnit((*m_creature), StatAuraGUID);
-                if(pUnit)
-                    pUnit->RemoveAurasDueToSpell(AURA_OF_SUFFERING_ARMOR);
-            }
+            m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+            m_creature->Yell(SUFF_SAY_RECAP,LANG_UNIVERSAL,0);
+            DoPlaySoundToSet(m_creature, SUFF_SOUND_RECAP);
         }
     }
@@ -623,30 +392,25 @@
     void Aggro(Unit *who)
     {
+        m_creature->Yell(SUFF_SAY_FREED, LANG_UNIVERSAL, 0);
+        DoPlaySoundToSet(m_creature, SUFF_SOUND_FREED);
         DoZoneInCombat();
-        DoCast(who, AURA_OF_SUFFERING, true);
-        DoCast(m_creature, ESSENCE_OF_SUFFERING_PASSIVE, true);
+        m_creature->CastSpell(m_creature, AURA_OF_SUFFERING, true); // linked aura need core support
+        m_creature->CastSpell(m_creature, ESSENCE_OF_SUFFERING_PASSIVE, true);
+        m_creature->CastSpell(m_creature, ESSENCE_OF_SUFFERING_PASSIVE2, true);
     }
 
     void KilledUnit(Unit *victim)
     {
-        switch(rand()%3)
-        {
-            case 0:
-                DoYell(SUFF_SAY_SLAY1,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY1);
-                break;
-            case 1:
-                DoYell(SUFF_SAY_SLAY2,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY2);
-                break;
-            case 2:
-                DoYell(SUFF_SAY_SLAY3,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY3);
-                break;
-        }
-    }
-
-    void JustDied(Unit* killer)
-    {
+        switch(rand()%2)
+        {
+        case 0:
+            DoYell(SUFF_SAY_SLAY1,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY1);
+            break;
+        case 1:
+            DoYell(SUFF_SAY_SLAY2,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY2);
+            break;
+        }
     }
 
@@ -655,5 +419,5 @@
         std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
         if(m_threatlist.empty())
-            return;                                         // No point continuing if empty threatlist.
+            return; // No point continuing if empty threatlist.
         std::list<Unit*> targets;
         std::list<HostilReference*>::iterator itr = m_threatlist.begin();
@@ -661,16 +425,13 @@
         {
             Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());
-                                                            // Only alive players
-            if(pUnit && pUnit->isAlive() && (pUnit->GetTypeId() == TYPEID_PLAYER))
+            if(pUnit && pUnit->isAlive() && (pUnit->GetTypeId() == TYPEID_PLAYER)) // Only alive players
                 targets.push_back(pUnit);
         }
         if(targets.empty())
-            return;                                         // No targets added for some reason. No point continuing.
-        targets.sort(TargetDistanceOrder(m_creature));      // Sort players by distance.
-        targets.resize(1);                                  // Only need closest target.
-        Unit* target = targets.front();                     // Get the first target.
-                                                            // Add threat equivalent to threat on victim.
-        m_creature->AddThreat(target, m_creature->getThreatManager().getThreat(m_creature->getVictim()));
-        DoCast(target, SPELL_FIXATE);
+            return; // No targets added for some reason. No point continuing.
+        targets.sort(TargetDistanceOrder(m_creature)); // Sort players by distance.
+        targets.resize(1); // Only need closest target.
+        Unit* target = targets.front(); // Get the first target.
+        target->CastSpell(m_creature, SPELL_FIXATE_TAUNT, true);
     }
 
@@ -678,33 +439,6 @@
     {
         //Return since we have no target
-        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+        if (!m_creature->SelectHostilTarget() && !m_creature->getVictim())
             return;
-
-        if(m_creature->GetHealth() <= (m_creature->GetMaxHealth()*0.1))
-        {
-            if(StatAuraGUID)
-            {
-                Unit* pUnit = NULL;
-                pUnit = Unit::GetUnit((*m_creature), StatAuraGUID);
-                if(pUnit)
-                    pUnit->RemoveAurasDueToSpell(AURA_OF_SUFFERING_ARMOR);
-            }
-        }
-
-        if(m_creature->GetHealth() <= (m_creature->GetMaxHealth()*0.1))
-        {
-            if(m_creature->getVictim())
-                m_creature->DeleteThreatList();             // Delete our threatlist if below 10% as we should no longer attack.
-            return;
-        }
-
-        // Prevent overlapping yells
-        if(AggroYellTimer)
-            if(AggroYellTimer < diff)
-        {
-            DoYell(SUFF_SAY_AGGRO, LANG_UNIVERSAL, NULL);
-            DoPlaySoundToSet(m_creature, SUFF_SOUND_AGGRO);
-            AggroYellTimer = 0;
-        }else AggroYellTimer -= diff;
 
         //Supposed to be cast on nearest target
@@ -713,4 +447,9 @@
             CastFixate();
             FixateTimer = 5000;
+            if(!(rand()%16))
+            {
+                DoYell(SUFF_SAY_AGGRO,LANG_UNIVERSAL,NULL);
+                DoPlaySoundToSet(m_creature, SUFF_SOUND_AGGRO);
+            }
         }else FixateTimer -= diff;
 
@@ -719,13 +458,11 @@
             DoCast(m_creature, SPELL_ENRAGE);
             EnrageTimer = 60000;
+            DoYell(SUFF_SAY_ENRAGE,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature, SUFF_SOUND_ENRAGE);
         }else EnrageTimer -= diff;
 
         if(SoulDrainTimer < diff)
         {
-            Unit* target = NULL;
-            target = SelectUnit(SELECT_TARGET_RANDOM, 0);
-
-            if(target)
-                DoCast(target, SPELL_SOUL_DRAIN);
+            DoCast(m_creature, SPELL_SOUL_DRAIN);
             SoulDrainTimer = 60000;
         }else SoulDrainTimer -= diff;
@@ -734,9 +471,9 @@
     }
 };
+
 struct TRINITY_DLL_DECL boss_essence_of_desireAI : public ScriptedAI
 {
     boss_essence_of_desireAI(Creature *c) : ScriptedAI(c) {Reset();}
 
-    uint32 AggroYellTimer;
     uint32 RuneShieldTimer;
     uint32 DeadenTimer;
@@ -745,26 +482,46 @@
     void Reset()
     {
-        AggroYellTimer = 5000;
         RuneShieldTimer = 60000;
-        DeadenTimer = 15000;
-        SoulShockTimer = 40000;
+        DeadenTimer = 30000;
+        SoulShockTimer = 5000;
+        m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_CONFUSE, true);
     }
 
     void DamageTaken(Unit *done_by, uint32 &damage)
     {
-        if((damage >= m_creature->GetHealth()) && (done_by != m_creature))
+        if(done_by == m_creature)
+            return;
+
+        if(damage >= m_creature->GetHealth())
         {
             damage = 0;
-            // 10% of total health, signalling time to return
-            m_creature->SetHealth(m_creature->GetMaxHealth()/10);
+            m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+            m_creature->Yell(DESI_SAY_RECAP,LANG_UNIVERSAL,0);
+            DoPlaySoundToSet(m_creature, DESI_SOUND_RECAP);
         }
         else
         {
-            if(done_by && (done_by->GetTypeId() == TYPEID_PLAYER) && done_by->isAlive())
-                done_by->DealDamage(done_by, damage/2, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-        }
-    }
-
-    void Aggro(Unit *who) { DoZoneInCombat(); }
+            int32 bp0 = damage / 2;
+            m_creature->CastCustomSpell(done_by, AURA_OF_DESIRE_DAMAGE, &bp0, NULL, NULL, true);
+        }
+    }
+
+    void SpellHit(Unit *caster, const SpellEntry *spell)
+    {
+        if(m_creature->m_currentSpells[CURRENT_GENERIC_SPELL])
+            for(uint8 i = 0; i < 3; ++i)
+                if(spell->Effect[i] == SPELL_EFFECT_INTERRUPT_CAST)
+                    if(m_creature->m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id == SPELL_SOUL_SHOCK 
+                        || m_creature->m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id == SPELL_DEADEN)
+                        m_creature->InterruptSpell(CURRENT_GENERIC_SPELL, false);
+    }
+
+    void Aggro(Unit *who)
+    {
+        m_creature->Yell(DESI_SAY_FREED, LANG_UNIVERSAL, 0);
+        DoPlaySoundToSet(m_creature, DESI_SOUND_FREED);
+        DoZoneInCombat();
+        DoCast(m_creature, AURA_OF_DESIRE, true);
+    }
 
     void KilledUnit(Unit *victim)
@@ -772,79 +529,50 @@
         switch(rand()%3)
         {
-            case 0:
-                DoYell(DESI_SAY_SLAY1,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY1);
-                break;
-            case 1:
-                DoYell(DESI_SAY_SLAY2,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY2);
-                break;
-            case 2:
-                DoYell(DESI_SAY_SLAY3,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY3);
-                break;
-        }
-    }
-
-    void MoveInLineOfSight(Unit *who)
-    {
-        if (!who || m_creature->getVictim())
+        case 0:
+            DoYell(DESI_SAY_SLAY1,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY1);
+            break;
+        case 1:
+            DoYell(DESI_SAY_SLAY2,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY2);
+            break;
+        case 2:
+            DoYell(DESI_SAY_SLAY3,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY3);
+            break;
+        }
+    }
+
+    void UpdateAI(const uint32 diff)
+    {
+        if (!m_creature->SelectHostilTarget() && !m_creature->getVictim())
             return;
 
-        if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
-        {
-            float attackRadius = m_creature->GetAttackDistance(who);
-            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
-            {
-                if(who->HasStealthAura())
-                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
-
-                //Begin melee attack if we are within range
-                DoStartAttackAndMovement(who);
-
-                if (!InCombat)
-                {
-                    DoCast(who, AURA_OF_DESIRE);
-                }
-            }
-        }
-    }
-
-    void UpdateAI(const uint32 diff)
-    {
-        //Return since we have no target
-        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
-            return;
-
-        if(m_creature->GetHealth() <= (m_creature->GetMaxHealth()*0.1))
-        {
-            if(m_creature->getVictim())
-                m_creature->DeleteThreatList();             // Delete our threatlist if below 10% as we should no longer attack.
-            return;
-        }
-
         if(RuneShieldTimer < diff)
         {
-            DoCast(m_creature, SPELL_RUNE_SHIELD);
+            m_creature->InterruptNonMeleeSpells(false);
+            m_creature->CastSpell(m_creature, SPELL_RUNE_SHIELD, true);
+            SoulShockTimer += 2000;
+            DeadenTimer += 2000;
             RuneShieldTimer = 60000;
         }else RuneShieldTimer -= diff;
 
+        if(SoulShockTimer < diff)
+        {
+            DoCast(m_creature->getVictim(), SPELL_SOUL_SHOCK);
+            SoulShockTimer = 5000;
+        }else SoulShockTimer -= diff;
+
         if(DeadenTimer < diff)
         {
+            m_creature->InterruptNonMeleeSpells(false);
             DoCast(m_creature->getVictim(), SPELL_DEADEN);
-            DeadenTimer = 30000 + rand()%30001;
-        }else DeadenTimer -= diff;
-
-        if(SoulShockTimer < diff)
-        {
-            DoCast(m_creature->getVictim(), SPELL_SOUL_SHOCK);
-            SoulShockTimer = 40000;
-            if(rand()%2 == 0)
+            DeadenTimer = 25000 + rand()%10000;
+            if(!(rand()%2))
             {
                 DoYell(DESI_SAY_SPEC,LANG_UNIVERSAL,NULL);
                 DoPlaySoundToSet(m_creature, DESI_SOUND_SPEC);
             }
-
-        }else SoulShockTimer -= diff;
+        }else DeadenTimer -= diff;
 
         DoMeleeAttackIfReady();
@@ -858,9 +586,10 @@
     uint64 AggroTargetGUID;
 
-    uint32 AggroYellTimer;
     uint32 CheckTankTimer;
     uint32 SoulScreamTimer;
     uint32 SpiteTimer;
 
+    std::list<uint64> SpiteTargetGUID;
+
     bool CheckedAggro;
 
@@ -869,9 +598,10 @@
         AggroTargetGUID = 0;
 
-        AggroYellTimer = 5000;
         CheckTankTimer = 5000;
         SoulScreamTimer = 10000;
         SpiteTimer = 30000;
 
+        SpiteTargetGUID.clear();
+
         CheckedAggro = false;
     }
@@ -879,30 +609,8 @@
     void Aggro(Unit *who)
     {
+        m_creature->Yell(ANGER_SAY_FREED, LANG_UNIVERSAL, 0);
+        DoPlaySoundToSet(m_creature, ANGER_SOUND_FREED);
         DoZoneInCombat();
-        DoCast(m_creature->getVictim(), AURA_OF_ANGER, true);
-    }
-
-    void MoveInLineOfSight(Unit *who)
-    {
-        if (!who || m_creature->getVictim())
-            return;
-
-        if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
-        {
-            float attackRadius = m_creature->GetAttackDistance(who);
-            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
-            {
-                if(who->HasStealthAura())
-                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
-
-                //Begin melee attack if we are within range
-                DoStartAttackAndMovement(who);
-
-                if (!InCombat)
-                {
-                    DoCast(who, AURA_OF_ANGER);
-                }
-            }
-        }
+        DoCast(m_creature, AURA_OF_ANGER, true);
     }
 
@@ -917,12 +625,51 @@
         switch(rand()%2)
         {
-            case 0:
-                DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY1);
-                break;
-            case 1:
-                DoYell(ANGER_SAY_SLAY2,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY2);
-                break;
-        }
+        case 0:
+            DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY1);
+            break;
+        case 1:
+            DoYell(ANGER_SAY_SLAY2,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY2);
+            break;
+        }
+    }
+
+    void SelectSpiteTarget(uint32 num, float max_range = 999)
+    {
+        if(!num) return;
+
+        CellPair p(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
+        Cell cell(p);
+        cell.data.Part.reserved = ALL_DISTRICT;
+        cell.SetNoCreate();
+
+        std::list<Unit *> tempUnitMap;
+
+        {
+            Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(m_creature, m_creature, max_range);
+            Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(tempUnitMap, u_check);
+
+            TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
+            TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher);
+
+            CellLock<GridReadGuard> cell_lock(cell, p);
+            cell_lock->Visit(cell_lock, world_unit_searcher, *(m_creature->GetMap()));
+            cell_lock->Visit(cell_lock, grid_unit_searcher, *(m_creature->GetMap()));
+        }
+
+        std::list<Unit*>::iterator itr;
+        while(tempUnitMap.size() && SpiteTargetGUID.size() < num)
+        {
+            itr = tempUnitMap.begin();
+            advance(itr, rand()%tempUnitMap.size());
+            SpiteTargetGUID.push_back((*itr)->GetGUID());
+            tempUnitMap.erase(itr);
+        }
+
+        for(itr = tempUnitMap.begin(); itr != tempUnitMap.end(); ++itr)
+            (*itr)->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+        m_creature->CastSpell(m_creature, SPELL_SPITE_TARGET, true); // must true
+        for(itr = tempUnitMap.begin(); itr != tempUnitMap.end(); ++itr)
+            (*itr)->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
     }
 
@@ -930,5 +677,5 @@
     {
         //Return since we have no target
-        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+        if (!m_creature->SelectHostilTarget() && !m_creature->getVictim())
             return;
 
@@ -939,20 +686,11 @@
         }
 
-        if(AggroYellTimer)
-            if(AggroYellTimer < diff)
-        {
-            DoYell(ANGER_SAY_FREED2,LANG_UNIVERSAL,NULL);
-            DoPlaySoundToSet(m_creature, ANGER_SOUND_FREED2);
-            AggroYellTimer = 0;
-        }else AggroYellTimer -= diff;
-
         if(CheckTankTimer < diff)
         {
             if(m_creature->getVictim()->GetGUID() != AggroTargetGUID)
-            {
+            {     
                 DoYell(ANGER_SAY_BEFORE,LANG_UNIVERSAL,NULL);
                 DoPlaySoundToSet(m_creature, ANGER_SOUND_BEFORE);
-                DoCast(m_creature, SPELL_SELF_SEETHE);
-                DoCast(m_creature->getVictim(), SPELL_ENEMY_SEETHE, true);
+                DoCast(m_creature, SPELL_SELF_SEETHE, true);
                 AggroTargetGUID = m_creature->getVictim()->GetGUID();
             }
@@ -964,21 +702,33 @@
             DoCast(m_creature->getVictim(), SPELL_SOUL_SCREAM);
             SoulScreamTimer = 10000;
+            if(!(rand()%3))
+            {
+                DoYell(ANGER_SAY_SCREAM,LANG_UNIVERSAL,NULL);
+                DoPlaySoundToSet(m_creature, ANGER_SOUND_SCREAM);
+            }
         }else SoulScreamTimer -= diff;
 
         if(SpiteTimer < diff)
         {
-            for(uint8 i = 0; i < 4; i++)
+            if(!SpiteTargetGUID.empty())
             {
-                Unit* target = NULL;
-                target = SelectUnit(SELECT_TARGET_RANDOM, 0);
-
-                if(target)
-                    DoCast(target, SPELL_SPITE);
-
-            }
-
-            SpiteTimer = 30000;
-            DoYell(ANGER_SAY_SPEC,LANG_UNIVERSAL,NULL);
-            DoPlaySoundToSet(m_creature, ANGER_SOUND_SPEC);
+                for (std::list<uint64>::iterator itr = SpiteTargetGUID.begin(); itr != SpiteTargetGUID.end(); ++itr)
+                {
+                    if(Unit* target = Unit::GetUnit(*m_creature, *itr))
+                    {
+                        target->RemoveAurasDueToSpell(SPELL_SPITE_TARGET);
+                        m_creature->CastSpell(target, SPELL_SPITE_DAMAGE, true);
+                    }
+                }
+                SpiteTargetGUID.clear();
+                SpiteTimer = 24000;
+            }
+            else
+            {
+                SelectSpiteTarget(3);
+                SpiteTimer = 6000;
+                DoYell(ANGER_SAY_SPEC,LANG_UNIVERSAL,NULL);
+                DoPlaySoundToSet(m_creature, ANGER_SOUND_SPEC);
+            }
         }else SpiteTimer -= diff;
 
@@ -995,4 +745,5 @@
             ((boss_reliquary_of_soulsAI*)Reliquary->AI())->SoulDeathCount++;
     }
+    DoCast(m_creature, SPELL_SOUL_RELEASE, true);
 }
 
Index: /trunk/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp (revision 48)
+++ /trunk/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp (revision 57)
@@ -26,5 +26,5 @@
 
 #define SPELL_POUNDING              34162
-#define SPELL_ARCANE_ORB_TRIGGER    34172
+#define SPELL_ARCANE_ORB            34172
 #define SPELL_KNOCK_AWAY            11130
 #define SPELL_BERSERK               27680
@@ -46,6 +46,4 @@
 #define SOUND_POUNDING2         11219
 
-#define CREATURE_ORB_TARGET     19577
-
 struct TRINITY_DLL_DECL boss_void_reaverAI : public ScriptedAI
 {
@@ -65,6 +63,9 @@
     void Reset()
     {
+        m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+        m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
+
         Pounding_Timer = 12000;
-        ArcaneOrb_Timer = 3000;
+        ArcaneOrb_Timer = 6000;
         KnockAway_Timer = 30000;
         Berserk_Timer = 600000;
@@ -144,6 +145,6 @@
             {
                 target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
-                                                            //15 yard radius minimum
-                if(target && target->GetDistance2d(m_creature) > 15)
+                                                            //18 yard radius minimum
+                if(target && target->GetDistance2d(m_creature) > 18)
                     target_list.push_back(target);
                 target = NULL;
@@ -153,12 +154,7 @@
 
             if (target)
-            {
-                Unit* Spawn = NULL;
-                Spawn = m_creature->SummonCreature(CREATURE_ORB_TARGET, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);
-                if (Spawn)
-                    m_creature->CastSpell(Spawn, SPELL_ARCANE_ORB_TRIGGER, true);
-            }
+                m_creature->CastSpell(target, SPELL_ARCANE_ORB, true);
 
-            ArcaneOrb_Timer = 3000;
+            ArcaneOrb_Timer = 6000;
         }else ArcaneOrb_Timer -= diff;
 
Index: /trunk/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp (revision 48)
+++ /trunk/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp (revision 57)
@@ -28,4 +28,5 @@
 #define SPELL_HOLYWRATH         32445
 #define SPELL_HOLYGROUND        29512
+#define SPELL_BERSERK           26662
 
 #define SAY_AGGRO               "Your behavior will not be tolerated!"
@@ -53,4 +54,7 @@
     uint32 Holywrath_Timer;
     uint32 Holyground_Timer;
+    uint32 Enrage_Timer;
+
+    bool Enraged;
 
     void Reset()
@@ -60,4 +64,10 @@
         Holywrath_Timer     = 20000+(rand()%10000);
         Holyground_Timer    = 3000;
+        Enrage_Timer        = 600000;
+
+        Enraged = false;
+
+        m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+        m_creature->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
     }
 
@@ -68,16 +78,16 @@
         switch(rand()%3)
         {
-            case 0:
-                DoYell(SAY_SLAY1,LANG_UNIVERSAL,Victim);
-                DoPlaySoundToSet(m_creature, SOUND_SLAY1);
-                break;
-            case 1:
-                DoYell(SAY_SLAY2,LANG_UNIVERSAL,Victim);
-                DoPlaySoundToSet(m_creature, SOUND_SLAY2);
-                break;
-            case 2:
-                DoYell(SAY_SLAY3,LANG_UNIVERSAL,Victim);
-                DoPlaySoundToSet(m_creature, SOUND_SLAY3);
-                break;
+        case 0:
+            DoYell(SAY_SLAY1,LANG_UNIVERSAL,Victim);
+            DoPlaySoundToSet(m_creature, SOUND_SLAY1);
+            break;
+        case 1:
+            DoYell(SAY_SLAY2,LANG_UNIVERSAL,Victim);
+            DoPlaySoundToSet(m_creature, SOUND_SLAY2);
+            break;
+        case 2:
+            DoYell(SAY_SLAY3,LANG_UNIVERSAL,Victim);
+            DoPlaySoundToSet(m_creature, SOUND_SLAY3);
+            break;
         }
     }
@@ -100,4 +110,10 @@
             return;
 
+        if (Enrage_Timer < diff && !Enraged)
+        {
+            DoCast(m_creature, SPELL_BERSERK,true);
+            Enraged = true;
+        }else Enrage_Timer -=diff;
+
         if (Holyground_Timer < diff)
         {
@@ -112,12 +128,12 @@
             switch(rand()%2)
             {
-                case 0:
-                    DoYell(SAY_REPENTANCE1,LANG_UNIVERSAL,NULL);
-                    DoPlaySoundToSet(m_creature, SOUND_REPENTANCE1);
-                    break;
-                case 1:
-                    DoYell(SAY_REPENTANCE2,LANG_UNIVERSAL,NULL);
-                    DoPlaySoundToSet(m_creature, SOUND_REPENTANCE2);
-                    break;
+            case 0:
+                DoYell(SAY_REPENTANCE1,LANG_UNIVERSAL,NULL);
+                DoPlaySoundToSet(m_creature, SOUND_REPENTANCE1);
+                break;
+            case 1:
+                DoYell(SAY_REPENTANCE2,LANG_UNIVERSAL,NULL);
+                DoPlaySoundToSet(m_creature, SOUND_REPENTANCE2);
+                break;
             }
             Repentance_Timer = 30000 + rand()%15000;        //A little randomness on that spell
@@ -126,21 +142,12 @@
         if (Holyfire_Timer < diff)
         {
-            //Time for an omgwtfpwn code to make maiden cast holy fire only on units outside the holy ground's 18 yard range
             Unit* target = NULL;
-            std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
-            std::vector<Unit *> target_list;
-            for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
+            target = SelectUnit(SELECT_TARGET_RANDOM,0);            
+
+            if(target)
             {
-                target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
-                if(target && target->GetDistance2d(m_creature) > 12 )
-                    target_list.push_back(target);
-                target = NULL;
+                DoCast(target,SPELL_HOLYFIRE);
+                Holyfire_Timer = 8000 + rand()%17000; //Anywhere from 8 to 25 seconds, good luck having several of those in a row!
             }
-            if(target_list.size())
-                target = *(target_list.begin()+rand()%target_list.size());
-
-            DoCast(target,SPELL_HOLYFIRE);
-
-            Holyfire_Timer = 8000 + rand()%17000;           //Anywhere from 8 to 25 seconds, good luck having several of those in a row!
         }else Holyfire_Timer -= diff;
 
