Index: /trunk/src/game/Unit.cpp
===================================================================
--- /trunk/src/game/Unit.cpp (revision 236)
+++ /trunk/src/game/Unit.cpp (revision 239)
@@ -498,5 +498,5 @@
     // interrupt channeled spell
     if(Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
-        if(spell->getState() == SPELL_STATE_CASTING && (spell->m_spellInfo->AuraInterruptFlags & flag))
+        if(spell->getState() == SPELL_STATE_CASTING && (spell->m_spellInfo->ChannelInterruptFlags & flag))
             InterruptNonMeleeSpells(false);
 }
@@ -512,5 +512,5 @@
     if(Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
         if(spell->getState() == SPELL_STATE_CASTING)
-            m_interruptMask |= spell->m_spellInfo->AuraInterruptFlags;
+            m_interruptMask |= spell->m_spellInfo->ChannelInterruptFlags;
 }
 
Index: /trunk/src/game/Spell.cpp
===================================================================
--- /trunk/src/game/Spell.cpp (revision 236)
+++ /trunk/src/game/Spell.cpp (revision 239)
@@ -4929,8 +4929,8 @@
         // unselectable targets skipped in all cases except TARGET_SCRIPT targeting
         // in case TARGET_SCRIPT target selected by server always and can't be cheated
-        if( target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) &&
+        /*if( target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) &&
             m_spellInfo->EffectImplicitTargetA[eff] != TARGET_SCRIPT &&
             m_spellInfo->EffectImplicitTargetB[eff] != TARGET_SCRIPT )
-            return false;
+            return false;*/
     }
 
Index: /trunk/src/bindings/scripts/scripts/go/go_scripts.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/go/go_scripts.cpp (revision 90)
+++ /trunk/src/bindings/scripts/scripts/go/go_scripts.cpp (revision 239)
@@ -195,15 +195,15 @@
     newscript = new Script;
     newscript->Name="go_tablet_of_madness";
-    newscript->pGOHello =           GOHello_go_tablet_of_madness;
+    newscript->pGOHello =           &GOHello_go_tablet_of_madness;
     m_scripts[nrscripts++] = newscript;
 
     newscript = new Script;
     newscript->Name="go_tablet_of_the_seven";
-    newscript->pGOHello =           GOHello_go_tablet_of_the_seven;
+    newscript->pGOHello =           &GOHello_go_tablet_of_the_seven;
     m_scripts[nrscripts++] = newscript;
 
     newscript = new Script;
     newscript->Name="go_teleporter";
-    newscript->pGOHello =           GOHello_go_teleporter;
-    m_scripts[nrscripts++] = newscript;
-}
+    newscript->pGOHello =           &GOHello_go_teleporter;
+    m_scripts[nrscripts++] = newscript;
+}
Index: /trunk/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/creature/mob_event_ai.cpp (revision 229)
+++ /trunk/src/bindings/scripts/scripts/creature/mob_event_ai.cpp (revision 239)
@@ -1371,5 +1371,8 @@
 
                 if (EAI_ErrorLevel > 1)
-                    error_db_log("SD2: Creature %u Event %u. Creature are in instance but neither EFLAG_NORMAL or EFLAG_HEROIC are set. Event Disabled.", _Creature->GetEntry(), (*i).event_id);
+                {
+                    error_db_log("SD2: Creature %u Event %u. Creature are in instance but neither EFLAG_NORMAL or EFLAG_HEROIC are set.", _Creature->GetEntry(), (*i).event_id);
+                    EventList.push_back(EventHolder(*i));
+                }
 
                 continue;
Index: /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp (revision 203)
+++ /trunk/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp (revision 239)
@@ -2279,5 +2279,5 @@
     newscript = new Script;
     newscript->Name="mob_cage_trap_trigger";
-    newscript->GetAI = GetAI_cage_trap_trigger;
+    newscript->GetAI = &GetAI_cage_trap_trigger;
     m_scripts[nrscripts++] = newscript;
 
Index: /trunk/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp (revision 90)
+++ /trunk/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp (revision 239)
@@ -1,17 +1,17 @@
-/* Copyright ? 2006,2007 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
- */
+/* Copyright ?2006,2007 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
+*/
 
 /* ScriptData
@@ -19,137 +19,100 @@
 SD%Complete: 0
 SDComment: VERIFY SCRIPT
-SDCategory: Sunwell Plateau
 EndScriptData */
 
 #include "precompiled.h"
-#include "WorldPacket.h"
 #include "def_sunwell_plateau.h"
 
-#define SAY_KALECGOS_AGGRO         "Aggh! No longer will I be a slave to Malygos! Challenge me and you will be destroyed!"
-#define SOUND_KALECGOS_AGGRO       12422
-#define SAY_KALECGOS_SPELL1        "I will purge you!"
-#define SOUND_KALECGOS_SPELL1      12423
-#define SAY_KALECGOS_SPELL2        "Your pain has only begun!"
-#define SOUND_KALECGOS_SPELL2      12424
-#define SAY_KALECGOS_SLAY1         "In the name of Kil'jaeden!"
-#define SOUND_KALECGOS_SLAY1       12425
-#define SAY_KALECGOS_SLAY2         "You were warned!"
-#define SOUND_KALECGOS_SLAY2       12426
-#define SAY_KALECGOS_ENRAGE        "My awakening is complete! You shall all perish!"
-#define SOUND_KALECGOS_ENRAGE      12427
-
-#define SAY_SATH_AGGRO             "There will be no reprieve. My work here is nearly finished."
-#define SOUND_SATH_AGGRO           12451
-#define SAY_SATH_DEATH             "I'm... never on... the losing... side..."
-#define SOUND_SATH_DEATH           12452
-#define SAY_SATH_SPELL1            "Your misery is my delight!"
-#define SOUND_SATH_SPELL1          12453
-#define SAY_SATH_SPELL2            "I will watch you bleed!"
-#define SOUND_SATH_SPELL2          12454
-#define SAY_SATH_SLAY1             "Pitious mortal!"
-#define SOUND_SATH_SLAY1           12455
-#define SAY_SATH_SLAY2             "Haven't you heard? I always win!"
-#define SOUND_SATH_SLAY2           12456
-#define SAY_SATH_ENRAGE            "I have toyed with you long enough!"
-#define SOUND_SATH_ENRAGE          12457
-
-#define SAY_KALEC_AGGRO            "I need... your help... Cannot... resist him... much longer..."
-#define SOUND_KALEC_AGGRO          12428
-#define SAY_KALEC_NEAR_DEATH       "Aaahhh! Help me, before I lose my mind!"
-#define SOUND_KALEC_NEAR_DEATH     12429
-                                                            //???
-#define SAY_KALEC_NEAR_DEATH2      "Hurry! There is not much of me left!"
-#define SOUND_KALEC_NEAR_DEATH2    12430
-#define SAY_KALEC_PLRWIN           "I am forever in your debt. Once we have triumphed over Kil'jaeden, this entire world will be in your debt as well."
-#define SOUND_KALEC_PLRWIN         12431
-
-#define SPELL_SPECTRAL_EXHAUSTION           44867
-#define SPELL_TELEPORT_SPECTRAL_REALM       46019
-#define SPELL_SPECTRAL_REALM                46021
-
-#define NOTIFY_SPECTRALLY_EXHAUSTED     "Your body is too exhausted to travel to the Spectral Realm."
-#define ERROR_INST_DATA                 "SD2: Instance Data not set properly for Sunwell Plateau. Kalecgos Encounter will be buggy."
-#define ERROR_INST_DATA_PLR             "SD2 ERROR: Instance Data not set properly for Sunwell Plateau. Please report this to your administrator."
-#define ERROR_UNABLE_TO_TELEPORT        "SD2: Unable to select target for Spectral Blast. Threatlist has too few players."
-#define ERROR_MISSING_TELEPORT_GUID     "SD2: [Kalecgos] Invalid TeleportTargetGUID. Unable to teleport player."
-#define ERROR_KALECGOS_NOT_FOUND        "SD2: Unable to create pointer to Kalecgos from Sathrovarr."
-
-#define KALECGOS_ARENA_X        1704.34
-#define KALECGOS_ARENA_Y        928.17
-#define KALECGOS_ARENA_Z        53.08
-
-/*** Kalecgos ****/
-#define SPELL_SPECTRAL_BLAST            44866
+#define KALECGOS_SAY_AGGRO             "No longer will I be a slave to Malygos! Challenge me and you will be destroyed!"
+#define KALECGOS_SOUND_AGGRO           12422
+#define KALECGOS_SAY_SPELL_1           "I will purge you!"
+#define KALECGOS_SOUND_SPELL_1         12423
+#define KALECGOS_SAY_SPELL_2           "Your pain has only begun!"
+#define KALECGOS_SOUND_SPELL_2         12424
+#define KALECGOS_SAY_KILL_1            "In the name of Kil'jaeden!"
+#define KALECGOS_SOUND_KILL_1          12425
+#define KALECGOS_SAY_KILL_2            "You were warned!"
+#define KALECGOS_SOUND_KILL_2          12426
+#define KALECGOS_SAY_FLY_AWAY          "My awakening is complete! You shall all perish!"
+#define KALECGOS_SOUND_FLY_AWAY        12427
+#define KALECGOS_SAY_WIN               "I am forever in your debt. Once we have triumphed over Kil'jaeden, this entire world will be in your debt as well."
+#define KALECGOS_SOUND_WIN             12431
+
+#define SATH_SAY_AGGRO           "Gyahaha... There will be no reprieve. My work here is nearly finished."
+#define SATH_SOUND_AGGRO         12451
+#define SATH_SAY_DIE             "I'm... never on... the losing... side..."
+#define SATH_SOUND_DIE           12452
+#define SATH_SAY_SPELL_1         "Your misery is my delight!"
+#define SATH_SOUND_SPELL_1       12453
+#define SATH_SAY_SPELL_2         "I will watch you bleed!"
+#define SATH_SOUND_SPELL_2       12454
+#define SATH_SAY_KILL_1          "Pitious mortal!"
+#define SATH_SOUND_KILL_1        12455
+#define SATH_SAY_KILL_2          "Haven't you heard? I always win!"
+#define SATH_SOUND_KILL_2        12456
+#define SATH_SAY_ENRAGE          "I have toyed with you long enough!"
+#define SATH_SOUND_ENRAGE        12457
+
+#define KALEC_SAY_AGGRO         "I need... your help... Cannot... resist him... much longer..."
+#define KALEC_SOUND_AGGRO       12428
+#define KALEC_SAY_LOSING1       "Aaahhh! Help me, before I lose my mind!"
+#define KALEC_SOUND_LOSING1     12429
+#define KALEC_SAY_LOSING2       "Hurry! There is not much of me left!" //???
+#define KALEC_SOUND_LOSING2     12430
+
+#define GO_FAILED               "You are unable to use this currently."
+
+#define FLY_X       1679
+#define FLY_Y       900
+#define FLY_Z       82
+
+#define CENTER_X    1705
+#define CENTER_Y    930
+#define RADIUS      30
+
+#define AURA_SUNWELL_RADIANCE           45769
+#define AURA_SPECTRAL_EXHAUSTION        44867
+#define AURA_SPECTRAL_REALM             46021
+#define AURA_SPECTRAL_INVISIBILITY      44801
+#define AURA_DEMONIC_VISUAL             44800
+
+#define SPELL_SPECTRAL_BLAST            44869
+#define SPELL_TELEPORT_SPECTRAL         46019
 #define SPELL_ARCANE_BUFFET             45018
 #define SPELL_FROST_BREATH              44799
+#define SPELL_TAIL_LASH                 45122
+
+#define SPELL_BANISH                    44836
+#define SPELL_TRANSFORM_KALEC           44670
+#define SPELL_ENRAGE                    44807
+
+#define SPELL_CORRUPTION_STRIKE         45029
+#define SPELL_AGONY_CURSE               45032
+#define SPELL_SHADOW_BOLT               45031
+
 #define SPELL_HEROIC_STRIKE             45026
 #define SPELL_REVITALIZE                45027
-#define SPELL_TAIL_LASH                 45122
-#define SPELL_TRANSFORM_KALEC           45027
-#define SPELL_CRAZED_RAGE               44806
+
+#define MOB_KALECGOS    24850
+#define MOB_KALEC       24891
+#define MOB_SATHROVARR  24892
+
+#define DRAGON_REALM_Z  53.079
+#define DEMON_REALM_Z   -74.558
+
 uint32 WildMagic[]= { 44978, 45001, 45002, 45004, 45006, 45010 };
 
-/*** Sathrovarr ***/
-#define SPELL_CORRUPTING_STRIKE         45029
-#define SPELL_CURSE_OF_BOUNDLESS_AGONY  45032
-#define SPELL_SHADOW_BOLT_VOLLEY        45031
-
-/*** Misc ***/
-#define SPELL_BANISH                    44836
-
-void TeleportToInnerVeil(Player* plr)
-{
-    if(plr->HasAura(SPELL_SPECTRAL_EXHAUSTION, 0))
-    {
-        plr->GetSession()->SendNotification(NOTIFY_SPECTRALLY_EXHAUSTED);
-        return;
-    }
-
-    ScriptedInstance* pInstance = ((ScriptedInstance*)plr->GetInstanceData());
-    if(!pInstance)
-    {
-        error_log(ERROR_INST_DATA);
-        plr->GetSession()->SendNotification(ERROR_INST_DATA_PLR);
-        return;
-    }
-
-    pInstance->SetData64(DATA_PLAYER_SPECTRAL_REALM, plr->GetGUID());
-    // Remove the player from Kalecgos' Threat List
-    Creature* Kalecgos = ((Creature*)Unit::GetUnit(*plr, pInstance->GetData64(DATA_KALECGOS_DRAGON)));
-    if(Kalecgos)
-    {
-        HostilReference* ref = Kalecgos->getThreatManager().getOnlineContainer().getReferenceByTarget(plr);
-        if(ref)
-            ref->removeReference();
-    }
-
-    // Add the player to Sathrovarr's Threat List
-    Creature* Sathrovarr = ((Creature*)Unit::GetUnit(*plr, pInstance->GetData64(DATA_SATHROVARR)));
-    if(Sathrovarr)
-        Sathrovarr->AddThreat(plr, 1.0f);
-
-    // Make them able to see Sathrovarr (he's invisible for some reason). Also, when this buff wears off, they get teleported back to Normal Realm (this is handled by Instance Script)
-    plr->CastSpell(plr, SPELL_SPECTRAL_REALM, true);
-    plr->CastSpell(plr, SPELL_TELEPORT_SPECTRAL_REALM, true);
-}
-
-bool GOHello_GO_Spectral_Portal(Player* plr, GameObject* go)
-{
-    TeleportToInnerVeil(plr);
-
-    return true;
-}
 
 struct TRINITY_DLL_DECL boss_kalecgosAI : public ScriptedAI
 {
-    boss_kalecgosAI(Creature* c) : ScriptedAI(c)
+    boss_kalecgosAI(Creature *c) : ScriptedAI(c) 
     {
         pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        SathGUID = 0;
+        DoorGUID = 0;
         Reset();
     }
 
-    ScriptedInstance* pInstance;
-
-    uint64 TeleportTargetGUID;
+    ScriptedInstance *pInstance;
 
     uint32 ArcaneBuffetTimer;
@@ -157,501 +120,581 @@
     uint32 WildMagicTimer;
     uint32 SpectralBlastTimer;
-    uint32 SpectralTeleportTimer;
-    uint32 ForceFieldTimer;
-    uint32 ExitTimer;
-
-    bool LockedArena;
-    bool Uncorrupted;
-    bool Banished;
-    bool Checked;
-    bool Enraged;
+    uint32 TailLashTimer;
+    uint32 CheckTimer;
+    uint32 TalkTimer;
+    uint32 TalkSequence;
+
+    bool isFriendly;
+    bool isEnraged;
+    bool isBanished;
+
+    uint64 SathGUID;
+    uint64 DoorGUID;
 
     void Reset()
     {
-        TeleportTargetGUID = 0;
-
-        // TODO: Fix timers
-        ArcaneBuffetTimer       = 8000;
-        FrostBreathTimer        = 24000;
-        WildMagicTimer          = 18000;
-        SpectralBlastTimer      = 30000;
-        SpectralTeleportTimer   = SpectralBlastTimer + 2000;
-
-        ForceFieldTimer = 20000;
-        ExitTimer = 0;
-
-        LockedArena = false;
-        Uncorrupted = false;
-        Banished    = false;
-        Checked     = false;
-        Enraged     = false;
-
-        // Reset Sathrovarr too
         if(pInstance)
-            if(Creature* Sath = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_SATHROVARR))))
-                Sath->AI()->EnterEvadeMode();
+        {
+            uint64 SathGUID = pInstance->GetData64(DATA_SATHROVARR);
+            uint64 DoorGUID = pInstance->GetData64(DATA_GO_FORCEFIELD);
+        }
+
+        Unit *Sath = Unit::GetUnit(*m_creature,SathGUID);
+        if(Sath) ((Creature*)Sath)->AI()->EnterEvadeMode();
+
+        GameObject *Door = GameObject::GetGameObject(*m_creature, DoorGUID);
+        if(Door) Door->SetLootState(GO_JUST_DEACTIVATED);
+
+        m_creature->setFaction(14);
+        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
+        m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+        m_creature->SetVisibility(VISIBILITY_ON);
+        m_creature->SetStandState(PLAYER_STATE_SLEEP);
+
+        ArcaneBuffetTimer = 8000;
+        FrostBreathTimer = 15000;
+        WildMagicTimer = 10000;
+        TailLashTimer = 25000;
+        SpectralBlastTimer = 20000+(rand()%5000);
+        CheckTimer = SpectralBlastTimer+20000; //after spectral blast
+
+        TalkTimer = 0;
+        TalkSequence = 0;
+        isFriendly = false;
+        isEnraged = false;
+        isBanished = false;
+        //m_creature->CastSpell(m_creature, AURA_SUNWELL_RADIANCE, true);
+    }
+
+    void DamageTaken(Unit *done_by, uint32 &damage)
+    {
+        if(damage >= m_creature->GetHealth() && done_by != m_creature)
+            damage = 0;
     }
 
     void Aggro(Unit* who)
     {
-        DoYell(SAY_KALECGOS_AGGRO, LANG_UNIVERSAL, NULL);
-        DoPlaySoundToSet(m_creature, SOUND_KALECGOS_AGGRO);
-
+        m_creature->SetStandState(PLAYER_STATE_NONE);
+        DoYell(KALECGOS_SAY_AGGRO, LANG_UNIVERSAL,NULL);
+        DoPlaySoundToSet(m_creature, KALECGOS_SOUND_AGGRO);
+        GameObject *Door = GameObject::GetGameObject(*m_creature, DoorGUID);
+        if(Door) Door->SetLootState(GO_ACTIVATED);
+        DoZoneInCombat();
+    }
+
+    void KilledUnit(Unit *victim)
+    {
+        switch(rand()%2)
+        {
+        case 0:
+            DoYell(KALECGOS_SAY_KILL_1,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature,KALECGOS_SOUND_KILL_1);
+            break;
+        case 1:
+            DoYell(KALECGOS_SAY_KILL_2,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature,KALECGOS_SOUND_KILL_2);
+            break;
+        }
+    }
+
+    void MovementInform(uint32 type,uint32 id)
+    {
+        m_creature->SetVisibility(VISIBILITY_OFF);
+        if(isFriendly)
+            m_creature->setDeathState(JUST_DIED);
+        else
+        {
+            m_creature->GetMotionMaster()->MoveTargetedHome();
+            TalkTimer = 30000;
+        }
+    }
+
+    void GoodEnding()
+    {
+        switch(TalkSequence)
+        {
+        case 1:
+            m_creature->setFaction(35);
+            DoCast(m_creature, SPELL_TRANSFORM_KALEC);
+            TalkTimer = 1000;
+            break;
+        case 2:
+            DoSay(KALECGOS_SAY_WIN, LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature, KALECGOS_SOUND_WIN);
+            TalkTimer = 10000;
+            break;
+        case 3:
+            m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+            m_creature->GetMotionMaster()->Clear();
+            m_creature->GetMotionMaster()->MovePoint(0,FLY_X,FLY_Y,FLY_Z);
+            TalkTimer = 600000;
+            break;
+        default:
+            break;
+        }
+    }
+
+    void BadEnding()
+    {
+        switch(TalkSequence)
+        {
+        case 1:
+            DoYell(KALECGOS_SAY_FLY_AWAY,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature,KALECGOS_SOUND_FLY_AWAY);
+            TalkTimer = 3000;
+            break;
+        case 2:
+            m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+            m_creature->GetMotionMaster()->Clear();
+            m_creature->GetMotionMaster()->MovePoint(0,FLY_X,FLY_Y,FLY_Z);
+            TalkTimer = 600000;
+            break;
+        case 3:
+            EnterEvadeMode();
+            break;
+        default:
+            break;
+        }
+    }
+
+    void UpdateAI(const uint32 diff);
+};
+
+struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI
+{
+    boss_sathrovarrAI(Creature *c) : ScriptedAI(c) 
+    {
+        pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        KalecGUID = 0;
+        KalecgosGUID = 0;
+        Reset();
+    }
+
+    ScriptedInstance *pInstance;
+
+    uint32 CorruptionStrikeTimer;
+    uint32 AgonyCurseTimer;
+    uint32 ShadowBoltTimer;
+    uint32 CheckTimer;
+
+    uint64 KalecGUID;
+    uint64 KalecgosGUID;
+
+    bool isEnraged;
+    bool isBanished;
+
+    void Reset()
+    {
         if(pInstance)
-            pInstance->SetData(DATA_KALECGOS_EVENT, IN_PROGRESS);
-    }
-
-    void DamageTaken(Unit* done_by, uint32 &damage)
-    {
-        if(damage > m_creature->GetHealth() && done_by != m_creature)
-        {
-            if(!Uncorrupted)
+            KalecgosGUID = pInstance->GetData64(DATA_KALECGOS_DRAGON);
+
+        if(KalecGUID)
+        {
+            if(Unit* Kalec = Unit::GetUnit(*m_creature, KalecGUID))
+                Kalec->setDeathState(JUST_DIED);
+            KalecGUID = 0;
+        }
+
+        ShadowBoltTimer = 7000 + rand()%3 * 1000;
+        AgonyCurseTimer = 20000;
+        CorruptionStrikeTimer = 13000;
+        CheckTimer = 1000;
+        isEnraged = false;
+        isBanished = false;
+        //m_creature->CastSpell(m_creature, AURA_SPECTRAL_INVISIBILITY, true);
+        //m_creature->CastSpell(m_creature, AURA_SUNWELL_RADIANCE, true);
+        //m_creature->CastSpell(m_creature, AURA_DEMONIC_VISUAL, true);
+    }
+
+    void Aggro(Unit* who)
+    {
+        Creature *Kalec = m_creature->SummonCreature(MOB_KALEC, m_creature->GetPositionX() + 10, m_creature->GetPositionY() + 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+        if(Kalec)
+        {
+            KalecGUID = Kalec->GetGUID();
+            m_creature->CombatStart(Kalec);
+            m_creature->AddThreat(Kalec, 100.0f);
+        }
+        DoYell(SATH_SAY_AGGRO, LANG_UNIVERSAL, NULL);
+        DoPlaySoundToSet(m_creature, SATH_SOUND_AGGRO);
+    }
+
+    void DamageTaken(Unit *done_by, uint32 &damage)
+    {
+        if(damage >= m_creature->GetHealth() && done_by != m_creature)
+            damage = 0;
+    }
+
+    void KilledUnit(Unit *target)
+    {
+        if(target->GetGUID() == KalecGUID)
+        {
+            TeleportAllPlayersBack();
+            if(Unit *Kalecgos = Unit::GetUnit(*m_creature, KalecgosGUID))
             {
-                damage = 0;
-                Banished = true;
-                DoCast(m_creature, SPELL_BANISH, true);
-                m_creature->GetMotionMaster()->MoveIdle();
+                ((boss_kalecgosAI*)((Creature*)Kalecgos)->AI())->TalkTimer = 1;
+                ((boss_kalecgosAI*)((Creature*)Kalecgos)->AI())->isFriendly = false;
             }
-            else
+            EnterEvadeMode();
+            return;
+        }
+        switch(rand()%2)
+        {
+        case 0:
+            DoYell(SATH_SAY_KILL_1,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature,SATH_SOUND_KILL_1);
+            break;
+        case 1:
+            DoYell(SATH_SAY_KILL_2,LANG_UNIVERSAL,NULL);
+            DoPlaySoundToSet(m_creature,SATH_SOUND_KILL_2);
+            break;
+        }
+    }
+
+    void JustDied(Unit *victim)
+    {
+        DoYell(SATH_SAY_DIE, LANG_UNIVERSAL, NULL);
+        DoPlaySoundToSet(m_creature, SATH_SOUND_DIE);
+        m_creature->Relocate(m_creature->GetPositionX(), m_creature->GetPositionY(), DRAGON_REALM_Z, m_creature->GetOrientation());
+        TeleportAllPlayersBack();
+        if(Unit *Kalecgos = Unit::GetUnit(*m_creature, KalecgosGUID))
+        {
+            ((boss_kalecgosAI*)((Creature*)Kalecgos)->AI())->TalkTimer = 1;
+            ((boss_kalecgosAI*)((Creature*)Kalecgos)->AI())->isFriendly = true;
+        }
+    }
+
+    void TeleportAllPlayersBack()
+    {
+        Map *map = m_creature->GetMap();
+        if(!map->IsDungeon()) return;
+        InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers();
+        InstanceMap::PlayerList::const_iterator i;
+        for (i = PlayerList.begin(); i != PlayerList.end(); ++i)
+        {
+            if((*i)->HasAura(AURA_SPECTRAL_REALM,0))
+                (*i)->RemoveAurasDueToSpell(AURA_SPECTRAL_REALM);
+        }
+    }
+
+    void Enrage(); // demon and dragon should enrage at the same time
+
+    void UpdateAI(const uint32 diff)
+    {
+        if (!m_creature->SelectHostilTarget() && !m_creature->getVictim())
+            return;	
+
+        if(CheckTimer < diff)
+        {
+            if(!isEnraged && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 10)
+                Enrage();
+
+            if(!isBanished && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 1)
             {
-                damage = 0;
-                BeginOutro();
+                if(Unit *Kalecgos = Unit::GetUnit(*m_creature, KalecgosGUID))
+                {
+                    if(((boss_kalecgosAI*)((Creature*)Kalecgos)->AI())->isBanished)
+                    {
+                        m_creature->setDeathState(JUST_DIED);
+                        return;
+                    }
+                    else
+                    {
+                        m_creature->CastSpell(m_creature, SPELL_BANISH, true);
+                        isBanished = true;
+                    }
+                }
+                else
+                {
+                    DoTextEmote("is unable to find Kalecgos", NULL);
+                    EnterEvadeMode();
+                }
             }
-        }
-    }
-
-    void KilledUnit(Unit* victim)
-    {
-        switch(rand()%2)
-        {
+            CheckTimer = 1000;
+        }else CheckTimer -= diff;
+
+        if(ShadowBoltTimer < diff)
+        {
+            DoCast(m_creature, SPELL_SHADOW_BOLT);
+            ShadowBoltTimer = 7000+(rand()%3000);
+        }else ShadowBoltTimer -= diff;
+
+        if(AgonyCurseTimer < diff)
+        {
+            Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+            if(!target) target = m_creature->getVictim();
+            DoCast(target, SPELL_AGONY_CURSE);
+            AgonyCurseTimer = 20000;
+        }else AgonyCurseTimer -= diff;
+
+        if(CorruptionStrikeTimer < diff)
+        {
+            DoCast(m_creature->getVictim(), SPELL_CORRUPTION_STRIKE);
+            CorruptionStrikeTimer = 13000;
+        }else CorruptionStrikeTimer -= diff;
+
+        DoMeleeAttackIfReady();	
+    }
+};
+
+struct TRINITY_DLL_DECL boss_kalecAI : public ScriptedAI
+{
+    ScriptedInstance *pInstance;
+
+    uint32 RevitalizeTimer;
+    uint32 HeroicStrikeTimer;
+    uint32 YellTimer;
+    uint32 YellSequence;
+
+    uint64 SathGUID;
+
+    bool isEnraged; // if demon is enraged
+
+    boss_kalecAI(Creature *c) : ScriptedAI(c)
+    {
+        pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        Reset();
+    }
+
+    void Reset()
+    {		
+        if(pInstance)
+            SathGUID = pInstance->GetData64(DATA_SATHROVARR);
+
+        RevitalizeTimer = 5000;
+        HeroicStrikeTimer = 3000;
+        YellTimer = 5000;
+        YellSequence = 0;
+
+        isEnraged = false;
+
+        //m_creature->CastSpell(m_creature, AURA_SPECTRAL_INVISIBILITY, true);
+        //m_creature->CastSpell(m_creature, AURA_SUNWELL_RADIANCE, true);
+    }
+
+    void Aggro(Unit* who) {}
+
+    void DamageTaken(Unit *done_by, uint32 &damage)
+    {
+        if(done_by->GetGUID() != SathGUID)
+            damage = 0;
+        else if(isEnraged)
+            damage *= 3;
+    }
+
+    void UpdateAI(const uint32 diff)
+    {
+        if(!m_creature->getVictim()) // only victim is Sath
+        {
+            EnterEvadeMode();
+            return;
+        }
+
+        if(YellTimer < diff)
+        {
+            switch(YellSequence)
+            {
             case 0:
-                DoYell(SAY_KALECGOS_SLAY1,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature,SOUND_KALECGOS_SLAY1);
+                DoYell(KALEC_SAY_AGGRO, LANG_UNIVERSAL, NULL);
+                DoPlaySoundToSet(m_creature, KALEC_SOUND_AGGRO);
+                YellSequence++;
                 break;
             case 1:
-                DoYell(SAY_KALECGOS_SLAY2,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature,SOUND_KALECGOS_SLAY2);
+                if((m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 50)
+                {
+                    DoYell(KALEC_SAY_LOSING1, LANG_UNIVERSAL, NULL);
+                    DoPlaySoundToSet(m_creature, KALEC_SOUND_LOSING1);
+                    YellSequence++;
+                }
                 break;
-        }
-    }
-
-    void BeginOutro()
-    {
-        debug_log("SD2: KALEC: Beginning Outro");
-
-        if(!pInstance)
-        {
-            error_log(ERROR_INST_DATA);
+            case 2:
+                if((m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 10)
+                {
+                    DoYell(KALEC_SAY_LOSING2, LANG_UNIVERSAL, NULL);
+                    DoPlaySoundToSet(m_creature, KALEC_SOUND_LOSING2);
+                    YellSequence++;
+                }
+                break;
+            default:
+                break;
+            }
+            YellTimer = 5000;
+        }
+
+        if(RevitalizeTimer < diff)
+        {
+            DoCast(m_creature, SPELL_REVITALIZE);
+            RevitalizeTimer = 5000;
+        }else RevitalizeTimer -= diff;
+
+        if(HeroicStrikeTimer < diff)
+        {
+            DoCast(m_creature->getVictim(), SPELL_HEROIC_STRIKE);
+            HeroicStrikeTimer = 2000;
+        }else HeroicStrikeTimer -= diff;
+
+        DoMeleeAttackIfReady();
+    }
+};
+
+void boss_kalecgosAI::UpdateAI(const uint32 diff)
+{
+    if(TalkTimer)
+    {
+        if(!TalkSequence)
+        {
+            m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
+            m_creature->InterruptNonMeleeSpells(true);
+            m_creature->RemoveAllAuras();
+            m_creature->DeleteThreatList();
+            m_creature->CombatStop();
+            GameObject *Door = GameObject::GetGameObject(*m_creature, DoorGUID);
+            if(Door) Door->SetLootState(GO_JUST_DEACTIVATED);
+            TalkSequence++;
+        }
+        if(TalkTimer <= diff)
+        {
+            if(isFriendly)
+                GoodEnding();
+            else
+                BadEnding();
+            TalkSequence++;
+        }else TalkTimer -= diff;
+    }
+    else
+    {
+        if (!m_creature->SelectHostilTarget() && !m_creature->getVictim())
             return;
-        }
-
-        Unit* Sathrovarr = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_SATHROVARR));
-        if(Sathrovarr)
-        {
-            Sathrovarr->DealDamage(Sathrovarr, Sathrovarr->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-
-            Sathrovarr->Relocate(KALECGOS_ARENA_X, KALECGOS_ARENA_Y, KALECGOS_ARENA_Z);
-            Sathrovarr->SendMonsterMove(KALECGOS_ARENA_X, KALECGOS_ARENA_Y, KALECGOS_ARENA_Z, 0, 0, 0);
-        }
-
-        Creature* Kalec = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_KALECGOS_HUMAN)));
-        if(Kalec)
-        {
-            Kalec->DeleteThreatList();
-            Kalec->SetVisibility(VISIBILITY_OFF);
-        }
-
-        m_creature->GetMotionMaster()->MoveIdle();
-        m_creature->setFaction(35);
-    }
-
-    void MovementInform(uint32 type, uint32 id)
-    {
-        if(type != POINT_MOTION_TYPE)
-            return;
-
-        if(id)
-        {
-            if(pInstance)
+
+        if(CheckTimer < diff)
+        {
+            if(!isEnraged && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 10)
             {
-                GameObject* ForceField = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_GO_FORCEFIELD));
-                if(ForceField)
-                    ForceField->SetGoState(1);
-
-                pInstance->SetData(DATA_KALECGOS_EVENT, DONE);
+                if(Unit *Sath = Unit::GetUnit(*m_creature, SathGUID))
+                    ((boss_sathrovarrAI*)((Creature*)Sath)->AI())->Enrage();
             }
-            else error_log(ERROR_INST_DATA);
-
-            m_creature->SetVisibility(VISIBILITY_OFF);
-            m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-        }
-    }
-
-    void UpdateAI(const uint32 diff)
-    {
-        if(!m_creature->getVictim() || !m_creature->SelectHostilTarget() || Banished)
-            return;
-
-        if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !Enraged)
-        {
-            Unit* Sathrovarr = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_SATHROVARR));
-            if(Sathrovarr)
-                Sathrovarr->CastSpell(Sathrovarr, SPELL_CRAZED_RAGE, true);
-            DoCast(m_creature, SPELL_CRAZED_RAGE, true);
-            Enraged = true;
-        }
-
-        if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 1) && !Checked)
-        {
-            Checked = true;
-
-            if(!Uncorrupted)
+
+            if(!isBanished && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 1)
             {
-                Banished = true;
-                DoCast(m_creature, SPELL_BANISH, true);
-                m_creature->GetMotionMaster()->MoveIdle();
+                if(Unit *Sath = Unit::GetUnit(*m_creature, SathGUID))
+                {
+                    if(((boss_sathrovarrAI*)((Creature*)Sath)->AI())->isBanished)
+                        Sath->setDeathState(JUST_DIED);
+                    else
+                    {
+                        m_creature->CastSpell(m_creature, SPELL_BANISH, true);
+                        isBanished = true;
+                    }
+                }
+                else 
+                {
+                    DoTextEmote("is unable to find Sath", NULL);
+                    EnterEvadeMode();
+                }
             }
-            else
-                BeginOutro();
-        }
-
-        if(ExitTimer)
-            if(ExitTimer <= diff)
-        {
-            debug_log("SD2: KALEC: Exiting the arena");
-            DoYell(SAY_KALEC_PLRWIN, LANG_UNIVERSAL, NULL);
-            DoPlaySoundToSet(m_creature, SOUND_KALEC_PLRWIN);
-            m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
-            float x, y, z;
-            float iniX, iniY, iniZ;
-            m_creature->GetPosition(iniX, iniY, iniZ);
-            m_creature->GetRandomPoint(iniX, iniY, iniZ, 30, x, y, z);
-            z = 70;
-            m_creature->GetMotionMaster()->MovePoint(1, x, y, z);
-        }else ExitTimer -= diff;
-
-        if(!LockedArena)
-            if(ForceFieldTimer < diff)
-        {
-            if(pInstance)
-            {
-                GameObject* ForceField = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GO_FORCEFIELD));
-                if(ForceField)
-                    ForceField->SetUInt32Value(GAMEOBJECT_STATE, 0);
-
-                LockedArena = true;
-            }else error_log(ERROR_INST_DATA);
-        }else ForceFieldTimer -= diff;
+            CheckTimer = 1000; //every 1 sec we check this
+        }else CheckTimer -= diff;
 
         if(ArcaneBuffetTimer < diff)
         {
-            if(rand()%3 == 0)
-            {
-                DoYell(SAY_KALECGOS_SPELL1, LANG_UNIVERSAL, NULL);
-                DoPlaySoundToSet(m_creature, SOUND_KALECGOS_SPELL1);
-            }
             DoCast(m_creature->getVictim(), SPELL_ARCANE_BUFFET);
-            ArcaneBuffetTimer = 20000;
+            ArcaneBuffetTimer = 8000;
         }else ArcaneBuffetTimer -= diff;
 
         if(FrostBreathTimer < diff)
         {
-            if(rand()%2 == 0)
-            {
-                DoYell(SAY_KALECGOS_SPELL2, LANG_UNIVERSAL, NULL);
-                DoPlaySoundToSet(m_creature, SOUND_KALECGOS_SPELL2);
-            }
             DoCast(m_creature->getVictim(), SPELL_FROST_BREATH);
-            FrostBreathTimer = 25000;
+            FrostBreathTimer = 15000;
         }else FrostBreathTimer -= diff;
 
+        if(TailLashTimer < diff)
+        {
+            DoCast(m_creature->getVictim(), SPELL_TAIL_LASH);
+            TailLashTimer = 15000;
+        }else TailLashTimer -= diff;
+
         if(WildMagicTimer < diff)
         {
-            DoCast(m_creature->getVictim(), WildMagic[rand()%6]);
-            WildMagicTimer = 19000;
+            DoCast(m_creature, WildMagic[rand()%6]);
+            WildMagicTimer = 20000;
         }else WildMagicTimer -= diff;
 
         if(SpectralBlastTimer < diff)
         {
-            if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1))
-            {
-                TeleportTargetGUID = target->GetGUID();
-                m_creature->SetUInt64Value(UNIT_FIELD_TARGET, TeleportTargetGUID);
-                SpectralBlastTimer = 30000;
-                SpectralTeleportTimer = 2000;
-            }
+            m_creature->CastSpell(m_creature, SPELL_SPECTRAL_BLAST, true);
+            SpectralBlastTimer = 20000+(rand()%5000);
         }else SpectralBlastTimer -= diff;
 
-        if(SpectralTeleportTimer < diff)
-        {
-            if(TeleportTargetGUID)
-            {
-                Unit* pUnit = Unit::GetUnit((*m_creature), TeleportTargetGUID);
-                if(pUnit)
-                {
-                    pUnit->CastSpell(pUnit, SPELL_SPECTRAL_BLAST, true);
-                    TeleportToInnerVeil((Player*)pUnit);
-                }
-                else error_log(ERROR_MISSING_TELEPORT_GUID);
-            }
-            else error_log(ERROR_MISSING_TELEPORT_GUID);
-
-            m_creature->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->getVictim()->GetGUID());
-            TeleportTargetGUID = 0;
-            SpectralTeleportTimer = SpectralBlastTimer + 2000;
-
-        }else SpectralTeleportTimer -= diff;
-
-        if(!Banished) DoMeleeAttackIfReady();
-    }
-};
-
-struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI
-{
-    boss_sathrovarrAI(Creature* c) : ScriptedAI(c)
-    {
-        pInstance = ((ScriptedInstance*)c->GetInstanceData());
-        Reset();
-    }
-
-    ScriptedInstance* pInstance;
-
-    uint32 CorruptingStrikeTimer;
-    uint32 CurseOfBoundlessAgonyTimer;
-    uint32 ShadowBoltVolleyTimer;
-    bool Banished;
-    bool Enraged;
-
-    void Reset()
-    {
-        // FIXME: Timers
-        CorruptingStrikeTimer = 5000;
-        CurseOfBoundlessAgonyTimer = 15000;
-        ShadowBoltVolleyTimer = 10000;
-
-        Banished = false;
-        Enraged  = false;
-
-        DoCast(m_creature, SPELL_SPECTRAL_REALM, true);
-    }
-
-    void Aggro(Unit* who)
-    {
-        DoYell(SAY_SATH_AGGRO, LANG_UNIVERSAL, NULL);
-        DoPlaySoundToSet(m_creature, SOUND_SATH_AGGRO);
-
-        Creature* Kalec = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_KALECGOS_HUMAN)));
-        if(Kalec)
-        {
-            m_creature->AddThreat(Kalec, 10000000.0f);
-            Kalec->AddThreat(m_creature, 10000000.0f);
-        }
-    }
-
-    void DamageTaken(Unit* done_by, uint32 &damage)
-    {
-        if(damage > m_creature->GetHealth())
-        {
-            damage = 0;
-            DoCast(m_creature, SPELL_BANISH, true);
-            Banished = true;
-
-            DoYell(SAY_SATH_DEATH, LANG_UNIVERSAL, NULL);
-            DoPlaySoundToSet(m_creature, SOUND_SATH_DEATH);
-
-            if(!pInstance)
-            {
-                error_log(ERROR_INST_DATA);
-                return;
-            }
-
-            pInstance->SetData(DATA_SET_SPECTRAL_CHECK, 5000);
-
-            Creature* Kalecgos = ((Creature*)Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KALECGOS_DRAGON)));
-            if(Kalecgos)
-            {
-                ((boss_kalecgosAI*)Kalecgos->AI())->Checked = false;
-                ((boss_kalecgosAI*)Kalecgos->AI())->Uncorrupted = true;
-            }
-            else error_log(ERROR_KALECGOS_NOT_FOUND);
-        }
-    }
-
-    void KilledUnit(Unit* victim)
-    {
-        switch(rand()%2)
-        {
-            case 0:
-                DoYell(SAY_SATH_SLAY1,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature,SOUND_SATH_SLAY1);
-                break;
-            case 1:
-                DoYell(SAY_SATH_SLAY2,LANG_UNIVERSAL,NULL);
-                DoPlaySoundToSet(m_creature,SOUND_SATH_SLAY2);
-                break;
-        }
-    }
-
-    void UpdateAI(const uint32 diff)
-    {
-        if(!m_creature->getVictim() || !m_creature->SelectHostilTarget() || Banished)
-            return;
-
-        if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !Enraged)
-        {
-            Unit* Kalecgos = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_KALECGOS_DRAGON));
-            if(Kalecgos)
-                Kalecgos->CastSpell(Kalecgos, SPELL_CRAZED_RAGE, true);
-            DoCast(m_creature, SPELL_CRAZED_RAGE, true);
-            Enraged = true;
-        }
-
-        if(CorruptingStrikeTimer < diff)
-        {
-            if(rand()%2 == 0)
-            {
-                DoYell(SAY_SATH_SPELL2, LANG_UNIVERSAL, NULL);
-                DoPlaySoundToSet(m_creature, SOUND_SATH_SPELL2);
-            }
-            DoCast(m_creature->getVictim(), SPELL_CORRUPTING_STRIKE);
-            CorruptingStrikeTimer = 13000;
-        }else CorruptingStrikeTimer -= diff;
-
-        if(CurseOfBoundlessAgonyTimer < diff)
-        {
-            DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_CURSE_OF_BOUNDLESS_AGONY);
-            CurseOfBoundlessAgonyTimer = 35000;
-            DoCast(m_creature, SPELL_SPECTRAL_REALM, true);
-        }else CurseOfBoundlessAgonyTimer -= diff;
-
-        if(ShadowBoltVolleyTimer < diff)
-        {
-            if(rand()%2 == 0)
-            {
-                DoYell(SAY_SATH_SPELL1, LANG_UNIVERSAL, NULL);
-                DoPlaySoundToSet(m_creature, SOUND_SATH_SPELL1);
-            }
-            DoCast(m_creature->getVictim(), SPELL_SHADOW_BOLT_VOLLEY);
-            ShadowBoltVolleyTimer = 15000;
-        }else ShadowBoltVolleyTimer -= diff;
-
         DoMeleeAttackIfReady();
     }
-};
-
-struct TRINITY_DLL_DECL boss_kalecAI : public ScriptedAI
-{
-    boss_kalecAI(Creature* c) : ScriptedAI(c)
-    {
-        pInstance = ((ScriptedInstance*)c->GetInstanceData());
-        Reset();
-    }
-
-    ScriptedInstance *pInstance;
-
-    uint32 RevitalizeTimer;
-    uint32 HeroicStrikeTimer;
-
-    bool HasYelled10Percent;
-    bool HasYelled20Percent;
-
-    void Reset()
-    {
-        //TODO: Times!
-        RevitalizeTimer = 30000;
-        HeroicStrikeTimer = 8000;
-
-        HasYelled10Percent = false;
-        HasYelled20Percent = false;
-
-        DoCast(m_creature, SPELL_SPECTRAL_REALM, true);
-    }
-
-    void Aggro(Unit* who)
-    {
-        DoYell(SAY_KALEC_AGGRO, LANG_UNIVERSAL, NULL);
-        DoPlaySoundToSet(m_creature, SOUND_KALEC_AGGRO);
-    }
-
-    void JustDied(Unit* killer)
-    {
-        // Whatever happens when Kalec (Half-elf) dies
-    }
-
-    void UpdateAI(const uint32 diff)
-    {
-        if(!m_creature->getVictim() || !m_creature->SelectHostilTarget())
-            return;
-
-        if(RevitalizeTimer < diff)
-        {
-            if(pInstance)
-            {
-                Unit* pUnit = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_RANDOM_SPECTRAL_PLAYER));
-                if(pUnit)
-                    DoCast(pUnit, SPELL_REVITALIZE);
-                RevitalizeTimer = 30000;
-            }
-        }else RevitalizeTimer -= diff;
-
-        if(HeroicStrikeTimer < diff)
-        {
-            DoCast(m_creature->getVictim(), SPELL_HEROIC_STRIKE);
-            HeroicStrikeTimer = 30000;
-        }else HeroicStrikeTimer -= diff;
-
-        if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 20) && !HasYelled20Percent)
-        {
-            DoYell(SAY_KALEC_NEAR_DEATH, LANG_UNIVERSAL, NULL);
-            DoPlaySoundToSet(m_creature, SOUND_KALEC_NEAR_DEATH);
-            HasYelled20Percent = true;
-        }
-
-        if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !HasYelled10Percent)
-        {
-            DoYell(SAY_KALEC_NEAR_DEATH2, LANG_UNIVERSAL, NULL);
-            DoPlaySoundToSet(m_creature, SOUND_KALEC_NEAR_DEATH2);
-            HasYelled10Percent = true;
-        }
-    }
-};
-
-CreatureAI* GetAI_boss_kalecgos(Creature* c)
-{
-    return new boss_kalecgosAI(c);
 }
 
-CreatureAI* GetAI_boss_sathrovarr(Creature* c)
-{
-    return new boss_sathrovarrAI(c);
+void boss_sathrovarrAI::Enrage()
+{
+    Unit *Kalecgos = Unit::GetUnit(*m_creature, KalecgosGUID);
+    Unit *Kalec = Unit::GetUnit(*m_creature, KalecGUID);
+    if(!Kalecgos)
+    {
+        error_log("SD2 ERROR: unable to find Kalecgos");
+        return;
+    }
+    if(!Kalec)
+    {
+        error_log("SD2 ERROR: unable to find Kalec");
+        return;
+    }
+    DoYell(SATH_SAY_ENRAGE,LANG_UNIVERSAL,NULL);
+    m_creature->CastSpell(m_creature, SPELL_ENRAGE, true);
+    Kalecgos->CastSpell(Kalecgos, SPELL_ENRAGE, true);
+    isEnraged = true;
+    ((boss_kalecgosAI*)((Creature*)Kalecgos)->AI())->isEnraged = true;
+    ((boss_kalecAI*)((Creature*)Kalec)->AI())->isEnraged = true;
 }
 
-CreatureAI* GetAI_boss_kalec(Creature* c)
-{
-    return new boss_kalecAI(c);
+bool GOkalocegos_teleporter(Player *player, GameObject* _GO)
+{
+    if(player->HasAura(AURA_SPECTRAL_EXHAUSTION, 0))
+        player->GetSession()->SendNotification(GO_FAILED);
+    else
+        player->CastSpell(player, SPELL_TELEPORT_SPECTRAL, true);
+    return true;
 }
 
+CreatureAI* GetAI_boss_kalecgos(Creature *_Creature)
+{
+    return new boss_kalecgosAI (_Creature);
+}
+
+CreatureAI* GetAI_boss_Sathrovarr(Creature *_Creature)
+{
+    return new boss_sathrovarrAI (_Creature);
+}
+
+CreatureAI* GetAI_boss_kalec(Creature *_Creature)
+{
+    return new boss_kalecAI (_Creature);
+}
+
 void AddSC_boss_kalecgos()
 {
-    Script* newscript;
-
+    Script *newscript;
     newscript = new Script;
+    newscript->Name="boss_kalecgos";
     newscript->GetAI = GetAI_boss_kalecgos;
-    newscript->Name = "boss_kalecgos";
     m_scripts[nrscripts++] = newscript;
 
     newscript = new Script;
-    newscript->GetAI = GetAI_boss_sathrovarr;
-    newscript->Name = "boss_sathrovarr";
+    newscript->Name="boss_sathrovarr";
+    newscript->GetAI = GetAI_boss_Sathrovarr;
     m_scripts[nrscripts++] = newscript;
 
     newscript = new Script;
+    newscript->Name="boss_kalec";
     newscript->GetAI = GetAI_boss_kalec;
-    newscript->Name = "boss_kalec";
     m_scripts[nrscripts++] = newscript;
 
     newscript = new Script;
-    newscript->pGOHello = GOHello_GO_Spectral_Portal;
-    newscript->Name = "go_spectral_portal";
+    newscript->Name="kalocegos_teleporter";
+    newscript->pGOHello = &GOkalocegos_teleporter;
     m_scripts[nrscripts++] = newscript;
 }
Index: /trunk/src/bindings/scripts/scripts/zone/sunwell_plateau/def_sunwell_plateau.h
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/sunwell_plateau/def_sunwell_plateau.h (revision 90)
+++ /trunk/src/bindings/scripts/scripts/zone/sunwell_plateau/def_sunwell_plateau.h (revision 239)
@@ -37,7 +37,3 @@
 
 /*** Misc ***/
-#define DATA_PLAYER_SPECTRAL_REALM  24
-#define DATA_SET_SPECTRAL_CHECK     25
-#define DATA_RANDOM_SPECTRAL_PLAYER 26
-#define DATA_INST_EJECT_PLAYERS     27
 #endif
Index: /trunk/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp (revision 90)
+++ /trunk/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp (revision 239)
@@ -14,8 +14,4 @@
 
 #define ENCOUNTERS 6
-
-#define SPELL_SPECTRAL_REALM        46021
-#define SPELL_TELEPORT_NORMAL_REALM 46020
-#define SPELL_SPECTRAL_EXHAUSTION   44867
 
 /* Sunwell Plateau:
@@ -159,9 +155,6 @@
             case DATA_KILJAEDEN_CONTROLLER: return KilJaedenController; break;
             case DATA_ANVEENA:              return Anveena;             break;
+        }
 
-            case DATA_RANDOM_SPECTRAL_PLAYER:
-                return *(SpectralRealmList.begin() + rand()%SpectralRealmList.size());
-                break;
-        }
         return 0;
     }
@@ -177,7 +170,4 @@
             case DATA_MURU_EVENT:          Encounters[4] = data; break;
             case DATA_KILJAEDEN_EVENT:     Encounters[5] = data; break;
-
-            case DATA_SET_SPECTRAL_CHECK:  SpectralRealmTimer = data; break;
-            case DATA_INST_EJECT_PLAYERS:  EjectPlayers(); break;
         }
     }
@@ -185,77 +175,8 @@
     void SetData64(uint32 id, uint64 guid)
     {
-        switch(id)
-        {
-            case DATA_PLAYER_SPECTRAL_REALM:
-                SpectralRealmList.push_back(guid);
-                break;
-        }
-    }
-
-    // Dirty Hack as we can't use Unit::GetUnit in instance scripts due to lack of a WorldObject.
-    Player* DirtyHackToGetPlayerFromSpectralList(uint64 guid)
-    {
-        Player* first = ((InstanceMap*)instance)->GetPlayers().front();
-        if(!first)
-            return NULL;
-
-        Player* plr = ((Player*)Unit::GetUnit(*first, guid));
-        if(plr)
-            return plr;
-
-        return NULL;
-    }
-
-    void EjectPlayer(Player* plr)
-    {
-        debug_log("SD2: INST: Ejecting Player %s from Spectral Realm", plr->GetName());
-        // Remove player from Sathrovarr's threat list
-        Creature* Sath = ((Creature*)Unit::GetUnit(*plr, Sathrovarr));
-        if(Sath && Sath->isAlive())
-        {
-            HostilReference* ref = Sath->getThreatManager().getOnlineContainer().getReferenceByTarget(plr);
-            if(ref)
-            {
-                ref->removeReference();
-                debug_log("SD2: INST: Deleting %s from Sathrovarr's threatlist", plr->GetName());
-            }
-        }
-
-        // Put player back in Kalecgos(Dragon)'s threat list
-        Creature* Kalecgos = ((Creature*)Unit::GetUnit(*plr, Kalecgos_Dragon));
-        if(Kalecgos && Kalecgos->isAlive())
-        {
-            debug_log("SD2: INST: Putting %s in Kalecgos' threatlist", plr->GetName());
-            Kalecgos->AddThreat(plr, 1.0f);
-        }
-
-        plr->CastSpell(plr, SPELL_TELEPORT_NORMAL_REALM, true);
-        plr->CastSpell(plr, SPELL_SPECTRAL_EXHAUSTION, true);
-    }
-
-    void EjectPlayers()
-    {
-        for(uint8 i = 0; i < SpectralRealmList.size(); ++i)
-        {
-            Player* plr = DirtyHackToGetPlayerFromSpectralList(SpectralRealmList[i]);
-            if(plr && !plr->HasAura(SPELL_SPECTRAL_REALM, 0))
-            {
-                EjectPlayer(plr);
-                SpectralRealmList.erase(SpectralRealmList.begin() + i);
-            }
-        }
-
-        SpectralRealmList.clear();
     }
 
     void Update(uint32 diff)
     {
-        // Only check for Spectral Realm if Kalecgos Encounter is running
-        if(Encounters[0] == IN_PROGRESS)
-            if(SpectralRealmTimer < diff)
-        {
-            EjectPlayers();
-            SpectralRealmTimer = 5000;
-        }else SpectralRealmTimer -= diff;
     }
 };
Index: /trunk/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp (revision 125)
+++ /trunk/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp (revision 239)
@@ -194,5 +194,5 @@
     newscript = new Script;
     newscript->Name="go_barrel_old_hillsbrad";
-    newscript->pGOHello = GOHello_go_barrel_old_hillsbrad;
+    newscript->pGOHello = &GOHello_go_barrel_old_hillsbrad;
     m_scripts[nrscripts++] = newscript;
 
Index: /trunk/sql/updates/146_world.sql
===================================================================
--- /trunk/sql/updates/146_world.sql (revision 178)
+++ /trunk/sql/updates/146_world.sql (revision 239)
@@ -17,9 +17,4 @@
 VALUES
    (-30410, 44032, 0, 'Manticron Cube Mind Exhaustion');
-
-INSERT INTO spell_linked_spell
-   (`spell_trigger`, `spell_effect`, `type`, `comment`)
-VALUES
-   (-45934, 7, 0, 'Dark Fiend Suicide');
 
 INSERT INTO spell_linked_spell
Index: /trunk/sql/updates/147_world.sql
===================================================================
--- /trunk/sql/updates/147_world.sql (revision 223)
+++ /trunk/sql/updates/147_world.sql (revision 239)
@@ -1,13 +1,2 @@
-DELETE FROM spell_linked_spell WHERE `spell_trigger` IN (46648, 46019, 46021, -46021, 46020);
-INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (46648, 44866, 1, 'Spectral Blast');
-INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (46019, 46021, 1, 'Teleport: Spectral Realm');
-INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (46021, 44852, 1, 'Spectral Realm Aura');
-INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (-46021, 46020, 0, 'Teleport: Normal Realm');
-INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (46020, 44867, 1, 'Spectral Exhaustion');
-
-DELETE FROM spell_target_position WHERE `id` IN (46019, 46020);
-INSERT INTO spell_target_position () VALUES (46019, 580, 1704.34, 928.17, -74.558, 0);
-INSERT INTO spell_target_position () VALUES (46020, 580, 1704.34, 928.17, 53.079, 0);
-
 -- Magtheridon Earthquake
 DELETE FROM spell_script_target WHERE `entry` IN (30657);
Index: /trunk/sql/updates/247_world.sql
===================================================================
--- /trunk/sql/updates/247_world.sql (revision 239)
+++ /trunk/sql/updates/247_world.sql (revision 239)
@@ -0,0 +1,29 @@
+ALTER TABLE `spell_linked_spell` DROP PRIMARY KEY;
+
+UPDATE creature_template SET scriptname = 'boss_kalecgos' WHERE entry = 24850;
+UPDATE creature_template SET scriptname = 'boss_sathrovarr' WHERE entry = 24892;
+UPDATE creature_template SET scriptname = 'boss_kalec' WHERE entry = 24891;
+UPDATE creature_template SET minhealth = 2018275, maxhealth = minhealth = 2018275 WHERE entry = 24892;
+UPDATE creature_template SET minlevel = 73, maxlevel = 73, minhealth = 828555, maxhealth = 828555, armor = 5000, mindmg = 1000, maxdmg = 2000 WHERE entry = 24891;
+UPDATE gameobject_template SET scriptname = 'kalocegos_teleporter' WHERE entry = 187055;
+
+INSERT INTO creature_template_addon (entry) SELECT 24891 FROM creature_template_addon WHERE NOT EXISTS(SELECT * FROM creature_template_addon WHERE entry = 24891) LIMIT 1; 
+INSERT INTO creature_template_addon (entry) SELECT 24892 FROM creature_template_addon WHERE NOT EXISTS(SELECT * FROM creature_template_addon WHERE entry = 24892) LIMIT 1; 
+UPDATE creature_template_addon SET auras = '45769 0 45769 1' WHERE entry = 24850;
+UPDATE creature_template_addon SET auras = '45769 0 45769 1 44801 0 44801 1 44801 2' WHERE entry = 24891;
+UPDATE creature_template_addon SET auras = '45769 0 45769 1 44801 0 44801 1 44801 2 44800 0' WHERE entry = 24892;
+
+DELETE FROM spell_linked_spell WHERE `spell_trigger` IN (44869, 46648, 46019, 46021, -46021, 46020);
+INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (44869, 44866, 1, 'Spectral Blast Portal');
+-- 46648 will cause severe lag if your video card is not good enough
+-- INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (44869, 46648, 1, 'Spectral Blast Visual');
+INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (44869, 46019, 1, 'Spectral Blast Teleport');
+INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (46019, 46021, 1, 'Spectral Realm Aura');
+-- 44852 makes boss friendly to you, weird
+-- INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (46021, 44852, 1, 'Spectral Realm Aura');
+INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (-46021, 46020, 0, 'Teleport: Normal Realm');
+INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (46020, 44867, 1, 'Spectral Exhaustion');
+
+DELETE FROM spell_target_position WHERE `id` IN (46019, 46020);
+INSERT INTO spell_target_position () VALUES (46019, 580, 1704.34, 928.17, -74.558, 0);
+INSERT INTO spell_target_position () VALUES (46020, 580, 1704.34, 928.17, 53.079, 0);
