Index: trunk/src/bindings/scripts/scripts/zone/magisters_terrace/def_magisters_terrace.h
===================================================================
--- trunk/src/bindings/scripts/scripts/zone/magisters_terrace/def_magisters_terrace.h (revision 90)
+++ trunk/src/bindings/scripts/scripts/zone/magisters_terrace/def_magisters_terrace.h (revision 137)
@@ -26,4 +26,6 @@
 #define DATA_DELRISSA_DEATH_COUNT   15
 
+#define DATA_KAEL					16
+
 #define ERROR_INST_DATA      "SD2 Error: Instance Data not set properly for Magister's Terrace instance (map 585). Encounters will be buggy."
 #endif
Index: trunk/src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp
===================================================================
--- trunk/src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp (revision 90)
+++ trunk/src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp (revision 137)
@@ -41,4 +41,5 @@
     }
 
+	uint32 DoorState[3];//0seline, 1vexallus, 2derlissa
     uint32 Encounters[NUMBER_OF_ENCOUNTERS];
     uint32 DelrissaDeathCount;
@@ -47,4 +48,5 @@
     std::list<uint64>::iterator CrystalItr;
 
+	uint64 KaelGUID;
     uint64 SelinGUID;
     uint64 DelrissaGUID;
@@ -59,4 +61,7 @@
     void Initialize()
     {
+		for(uint8 i = 0; i < 3; i++)
+			DoorState[i] = 1;//1 closed, 0 opened
+
         for(uint8 i = 0; i < NUMBER_OF_ENCOUNTERS; i++)
             Encounters[i] = NOT_STARTED;
@@ -66,4 +71,5 @@
         DelrissaDeathCount = 0;
 
+		KaelGUID = 0;
         SelinGUID = 0;
         DelrissaGUID = 0;
@@ -104,7 +110,28 @@
         switch(identifier)
         {
-            case DATA_SELIN_EVENT:       Encounters[0] = data;  break;
-            case DATA_VEXALLUS_EVENT:    Encounters[1] = data;  break;
-            case DATA_DELRISSA_EVENT:    Encounters[2] = data;  break;
+            case DATA_SELIN_EVENT:       
+				Encounters[0] = data;  
+				if(data==DONE)
+				{
+					DoorState[0] = 0;
+					SaveToDB();
+				}
+				break;
+            case DATA_VEXALLUS_EVENT:    
+				Encounters[1] = data;  
+				if(data==DONE)
+				{
+					DoorState[1] = 0;
+					SaveToDB();
+				}
+				break;
+            case DATA_DELRISSA_EVENT:    
+				Encounters[2] = data;  
+				if(data==DONE)
+				{
+					DoorState[2] = 0;
+					SaveToDB();
+				}				
+				break;
             case DATA_KAELTHAS_EVENT:    Encounters[3] = data;  break;
 
@@ -115,4 +142,28 @@
     }
 
+	const char* Save()
+    {
+        std::ostringstream ss;
+        ss << "S " << DoorState[0] << " " << DoorState[1] << " " << DoorState[2];
+        char* data = new char[ss.str().length()+1];
+        strcpy(data, ss.str().c_str());
+        return data;
+    }
+
+    void Load(const char* load)
+    {
+        if(!load) return;
+        std::istringstream ss(load);
+        char dataHead; // S
+        uint32 data1, data2, data3;
+        ss >> dataHead >> data1 >> data2 >> data3;
+        if(dataHead == 'S')
+        {
+            DoorState[0] = data1;
+            DoorState[1] = data2;
+            DoorState[2] = data3;
+        }else error_log("SD2: Magister's Terrace: corrupted save data.");
+    }
+
     void OnCreatureCreate(Creature *creature, uint32 entry)
     {
@@ -122,4 +173,5 @@
             case 24560: DelrissaGUID = creature->GetGUID(); break;
             case 24722: FelCrystals.push_back(creature->GetGUID()); break;
+			case 24664:	KaelGUID = creature->GetGUID(); break;
         }
     }
@@ -129,10 +181,19 @@
         switch(go->GetEntry())
         {
-            case 187896:  VexallusDoorGUID = go->GetGUID();       break;
+            case 187896:  
+				VexallusDoorGUID = go->GetGUID();       
+				go->SetGoState(DoorState[1]);
+				break;
             //SunwellRaid Gate 02
-            case 187979:  SelinDoorGUID = go->GetGUID();          break;
+            case 187979:  
+				SelinDoorGUID = go->GetGUID(); 
+				go->SetGoState(DoorState[0]);
+				break;
             //Assembly Chamber Door
             case 188065:  SelinEncounterDoorGUID = go->GetGUID(); break;
-            case 187770:  DelrissaDoorGUID = go->GetGUID();       break;
+            case 187770:  
+				DelrissaDoorGUID = go->GetGUID();  
+				go->SetGoState(DoorState[2]);				
+				break;
             case 188165:  KaelStatue[0] = go->GetGUID();          break;
             case 188166:  KaelStatue[1] = go->GetGUID();          break;
@@ -145,4 +206,5 @@
         {
             case DATA_SELIN:                return SelinGUID;
+			case DATA_KAEL:					return KaelGUID;
             case DATA_DELRISSA:             return DelrissaGUID;
             case DATA_VEXALLUS_DOOR:        return VexallusDoorGUID;
Index: trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp
===================================================================
--- trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp (revision 90)
+++ trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp (revision 137)
@@ -25,4 +25,5 @@
 #include "def_magisters_terrace.h"
 #include "WorldPacket.h"
+#include "ObjectMgr.h"
 
 /*** Spells ***/
@@ -35,4 +36,5 @@
 #define SPELL_PHOENIX                 44194                 // Summons a phoenix (Doesn't work?)
 #define SPELL_PHOENIX_BURN            44198                 // A spell Phoenix uses to damage everything around
+#define SPELL_PHOENIX_FIREBALL		  44202					// Phoenix casts this in phase 2 and stops moving
 
 #define SPELL_FLAMESTRIKE1_NORMAL     44190                 // Damage part
@@ -82,9 +84,12 @@
 
 /** Locations **/
-float KaelLocations[3][2]=
-{
-    {148.744659, 181.377426},
-    {140.823883, 195.403046},
-    {156.574188, 195.650482},
+float KaelLocations[6][2]=
+{
+    {148.744659, 181.377426},//center
+    {140.823883, 195.403046},//phoenixpos1
+    {156.574188, 195.650482},//phoenixpos2
+	{149.813, 160.917},//spherepos1
+	{167.223, 173.594},//spherepos2
+	{130.68, 173.007},//spherepos3
 };
 #define LOCATION_Z      -16.727455
@@ -143,11 +148,32 @@
 
         if(pInstance)
-            pInstance->SetData(DATA_KAELTHAS_EVENT, 0);
-    }
-
+		{
+			if(m_creature->isDead())
+				pInstance->SetData(DATA_KAELTHAS_EVENT, DONE);
+			else
+				pInstance->SetData(DATA_KAELTHAS_EVENT, NOT_STARTED);
+		}
+    }
+	
+	void KilledUnit(Unit* victim)
+    {
+        if(victim && (victim->GetTypeId() == TYPEID_PLAYER))
+        {
+            victim->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
+            victim->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);
+            WorldPacket data(12);
+            data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
+            data.append(victim->GetPackGUID());
+            data << uint32(0);
+            victim->SendMessageToSet(&data, true);
+        }
+	}
     void JustDied(Unit *killer)
     {
+		RemoveGravityLapse();
         DoYell(SAY_DEATH,LANG_UNIVERSAL,NULL);
         DoPlaySoundToSet(m_creature,SOUND_DEATH);
+		if(pInstance)
+			pInstance->SetData(DATA_KAELTHAS_EVENT, DONE);
     }
 
@@ -162,4 +188,6 @@
         DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
         DoPlaySoundToSet(m_creature,SOUND_AGGRO);
+		if(pInstance)
+			pInstance->SetData(DATA_KAELTHAS_EVENT, IN_PROGRESS);
     }
 
@@ -176,21 +204,43 @@
             {
                 float threat = m_creature->getThreatManager().getThreat(pUnit);
-                SummonedUnit->AddThreat(pUnit, threat);
+                SummonedUnit->AddThreat(pUnit, 0.1f);
             }
         }
     }
 
+	void EnterEvadeMode()
+	{
+		RemoveGravityLapse();
+		m_creature->InterruptNonMeleeSpells(true);
+		m_creature->RemoveAllAuras();
+		m_creature->DeleteThreatList();
+		m_creature->CombatStop();
+		m_creature->LoadCreaturesAddon();
+
+		if( m_creature->isAlive() )
+			m_creature->GetMotionMaster()->MoveTargetedHome();
+
+		m_creature->SetLootRecipient(NULL);
+
+		InCombat = false;
+		Reset();
+	}
+
     void TeleportPlayersToSelf()
     {
-        float x = KaelLocations[0][0];
-        float y = KaelLocations[0][1];
-        m_creature->Relocate(x, y, LOCATION_Z, 0);
-        //m_creature->SendMonsterMove(x, y, LOCATION_Z, 0, 0, 0); // causes some issues...
-        std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
-        for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();++i)
-        {
-            Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
-            if(pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER))
-                pUnit->CastSpell(pUnit, SPELL_TELEPORT_CENTER, true);
+		float x,y,z;
+        m_creature->Relocate(KaelLocations[0][0], KaelLocations[0][1], LOCATION_Z, 0);
+		Map *map = m_creature->GetMap();
+        InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers();
+		InstanceMap::PlayerList::const_iterator i;
+		for (i = PlayerList.begin(); i != PlayerList.end(); ++i)
+		{
+			//if(!(*i)->isGameMaster())
+			if((*i) && (*i)->isAlive())
+			{
+				(*i)->CastSpell((*i), SPELL_TELEPORT_CENTER, true);
+				m_creature->GetNearPoint(m_creature,x,y,z,5,5,0);
+				(*i)->TeleportTo(m_creature->GetMapId(),x,y,LOCATION_Z,(*i)->GetOrientation());
+			}
         }
         DoCast(m_creature, SPELL_TELEPORT_CENTER, true);
@@ -199,11 +249,12 @@
     void CastGravityLapseKnockUp()
     {
-        std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
-        for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();++i)
-        {
-            Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
-            if(pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER))
+		Map *map = m_creature->GetMap();
+        InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers();
+		InstanceMap::PlayerList::const_iterator i;
+		for (i = PlayerList.begin(); i != PlayerList.end(); ++i)
+		{            
+			if((*i) && (*i)->isAlive())
                 // Knockback into the air
-                pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE_DOT, true, 0, 0, m_creature->GetGUID());
+                (*i)->CastSpell((*i), SPELL_GRAVITY_LAPSE_DOT, true, 0, 0, m_creature->GetGUID());
         }
     }
@@ -211,18 +262,20 @@
     void CastGravityLapseFly()                              // Use Fly Packet hack for now as players can't cast "fly" spells unless in map 530. Has to be done a while after they get knocked into the air...
     {
-        std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
-        for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();++i)
-        {
-            Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
-            if(pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER))
+		Map *map = m_creature->GetMap();
+		InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers();
+		InstanceMap::PlayerList::const_iterator i;
+		for (i = PlayerList.begin(); i != PlayerList.end(); ++i)
+		{ 
+			if((*i) && (*i)->isAlive())
             {
                 // Also needs an exception in spell system.
-                pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE_FLY, true, 0, 0, m_creature->GetGUID());
+                (*i)->CastSpell((*i), SPELL_GRAVITY_LAPSE_FLY, true, 0, 0, m_creature->GetGUID());
                 // Use packet hack
                 WorldPacket data(12);
                 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
-                data.append(pUnit->GetPackGUID());
+                data.append((*i)->GetPackGUID());
                 data << uint32(0);
-                pUnit->SendMessageToSet(&data, true);
+                (*i)->SendMessageToSet(&data, true);
+				(*i)->SetSpeed(MOVE_FLY, 2.0f);
             }
         }
@@ -231,17 +284,18 @@
     void RemoveGravityLapse()
     {
-        std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
-        for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();++i)
-        {
-            Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
-            if(pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER))
+		Map *map = m_creature->GetMap();
+        InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers();
+		InstanceMap::PlayerList::const_iterator i;
+		for (i = PlayerList.begin(); i != PlayerList.end(); ++i)
+		{ 
+            if((*i))
             {
-                pUnit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
-                pUnit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);
+                (*i)->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
+                (*i)->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);
                 WorldPacket data(12);
                 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
-                data.append(pUnit->GetPackGUID());
+                data.append((*i)->GetPackGUID());
                 data << uint32(0);
-                pUnit->SendMessageToSet(&data, true);
+                (*i)->SendMessageToSet(&data, true);
             }
         }
@@ -279,9 +333,22 @@
                     float x = KaelLocations[random][0];
                     float y = KaelLocations[random][1];
-                    Creature* Phoenix = m_creature->SummonCreature(CREATURE_PHOENIX, x, y, LOCATION_Z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
+                    Creature* Phoenix = m_creature->SummonCreature(CREATURE_PHOENIX, x, y, LOCATION_Z, 0, TEMPSUMMON_CORPSE_DESPAWN, 60000);
                     if(Phoenix)
                     {
                         Phoenix->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
                         SetThreatList(Phoenix);
+						Unit *target = SelectUnit(SELECT_TARGET_RANDOM,1);
+						if(target)
+						{
+							Phoenix->AddThreat(target,1000);
+							Phoenix->Attack(target,true);
+							Phoenix->GetMotionMaster()->MoveChase(target);
+						}
+						else
+						{
+							Phoenix->AddThreat(m_creature->getVictim(),1000);
+							Phoenix->Attack(m_creature->getVictim(),true);
+							Phoenix->GetMotionMaster()->MoveChase(m_creature->getVictim());
+						}
                     }
 
@@ -297,4 +364,5 @@
                     if(target)
                     {
+						m_creature->InterruptNonMeleeSpells(false);
                         DoCast(target, SPELL_FLAMESTRIKE3, true);
                         FlameStrikeTimer = 20000 + rand()%5000;
@@ -322,4 +390,5 @@
             case 1:
             {
+				m_creature->StopMoving();
                 if(GravityLapseTimer < diff)
                 {
@@ -344,4 +413,5 @@
                                 DoPlaySoundToSet(m_creature,SOUND_RECAST_GRAVITY);
                             }
+							m_creature->StopMoving();
                             DoCast(m_creature, SPELL_GRAVITY_LAPSE_INITIAL);
                             GravityLapseTimer = 2000 + diff;// Don't interrupt the visual spell
@@ -366,7 +436,27 @@
                             GravityLapsePhase = 4;
                             for(uint8 i = 0; i < 3; ++i)
-                            {
-                                Creature* Orb = DoSpawnCreature(CREATURE_ARCANE_SPHERE, 5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
-                                if(Orb) SetThreatList(Orb);
+                            {								
+								Creature* Orb = m_creature->SummonCreature(CREATURE_ARCANE_SPHERE,KaelLocations[3+i][0],KaelLocations[3+i][1],LOCATION_Z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,30000);
+								if(Orb) 
+								{			
+									SetThreatList(Orb);
+									Unit *target = SelectUnit(SELECT_TARGET_BOTTOMAGGRO,i);
+									if(target)
+									{
+										Orb->AddThreat(target,1000);
+										Orb->Attack(target,true);
+										Orb->GetMotionMaster()->MoveChase(target);
+									}
+									else
+									{
+										Unit *ntarget = SelectUnit(SELECT_TARGET_RANDOM,0);
+										if(ntarget)
+										{
+											Orb->AddThreat(ntarget,1000);
+											Orb->Attack(ntarget,true);
+											Orb->GetMotionMaster()->MoveChase(ntarget);
+										}
+									}
+								}
                             }
                             DoCast(m_creature, SPELL_GRAVITY_LAPSE_CHANNEL);
@@ -427,12 +517,24 @@
 struct TRINITY_DLL_DECL mob_felkael_phoenixAI : public ScriptedAI
 {
-    mob_felkael_phoenixAI(Creature *c) : ScriptedAI(c) {Reset();}
-
+    mob_felkael_phoenixAI(Creature *c) : ScriptedAI(c)
+	{
+        pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        Reset();
+    }
     uint32 BurnTimer;
+	uint32 CheckTimer;
+	uint8 phase;
+	ScriptedInstance* pInstance;
+	bool end;
 
     void Reset()
     {
+		m_creature->SetSpeed(MOVE_RUN, 0.5f);
+		m_creature->SetSpeed(MOVE_WALK, 0.5f);
         m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
         BurnTimer = 2000;
+		CheckTimer = 1000;
+		phase = 0;
+		end = false;
     }
 
@@ -441,40 +543,83 @@
     void JustDied(Unit* slayer)
     {
-        DoSpawnCreature(CREATURE_PHOENIX_EGG, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
+		if (end)
+			return;
+        DoSpawnCreature(CREATURE_PHOENIX_EGG, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 45000);
     }
 
     void UpdateAI(const uint32 diff)
     {
+		if(CheckTimer < diff)
+        {
+            if (pInstance)
+			{
+				Creature *boss = ((Creature*)Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_KAEL)));
+				if (boss)
+				{
+					phase = ((boss_felblood_kaelthasAI*)boss->AI())->Phase;
+					if(boss->isDead() || !boss->isInCombat())
+					{
+						end = true;
+						m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_FIRE, NULL, false);//temphack, hellfire is not damaging self
+					}
+				}
+			}
+            CheckTimer = 1000;
+        }else CheckTimer -= diff;
+
         if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
             return;
 
-        if (BurnTimer < diff)
-        {
-            DoCast(m_creature->getVictim(), SPELL_PHOENIX_BURN);
-            BurnTimer = 2000;
-        }else BurnTimer -= diff;
-
-        DoMeleeAttackIfReady();
+		if (BurnTimer < diff)
+		{
+			if(!phase)
+			{
+				DoCast(m_creature, SPELL_PHOENIX_BURN);
+				m_creature->DealDamage(m_creature, 1500, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_FIRE, NULL, false);//temphack, hellfire is not damaging self
+			}
+			else
+			{
+				m_creature->StopMoving();
+				DoCast(m_creature->getVictim(), SPELL_PHOENIX_FIREBALL);
+			}
+			BurnTimer = 2000;
+		}else BurnTimer -= diff;		
+
+        //DoMeleeAttackIfReady();
     }
 };
 
-struct TRINITY_DLL_DECL mob_felkael_phoenix_eggAI : public ScriptedAI
-{
-    mob_felkael_phoenix_eggAI(Creature *c) : ScriptedAI(c) {Reset();}
+struct TRINITY_DLL_DECL mob_felkael_phoenix_eggAI : public Scripted_NoMovementAI
+{
+    mob_felkael_phoenix_eggAI(Creature *c) : Scripted_NoMovementAI(c)
+	{
+		pInstance = ((ScriptedInstance*)c->GetInstanceData());
+		Reset();
+	}
 
     uint32 HatchTimer;
-
+	ScriptedInstance* pInstance;
     void Reset() {   HatchTimer = 15000;   }
 
     void Aggro(Unit* who) {}
     void MoveInLineOfSight(Unit* who) {}
-
     void UpdateAI(const uint32 diff)
     {
+		
         if(HatchTimer < diff)
         {
-            DoSpawnCreature(CREATURE_PHOENIX, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
-            m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-        }else HatchTimer -= diff;
+			Creature *bird = DoSpawnCreature(CREATURE_PHOENIX, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 60000);
+			if (bird)
+			{
+				Unit *boss = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_KAEL));
+				if (boss && boss->getVictim())
+				{
+					bird->AddThreat(boss->getVictim(),100);
+					bird->Attack(boss->getVictim(),true);
+					bird->GetMotionMaster()->MoveChase(boss->getVictim());
+				}
+			}
+			m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+		}else HatchTimer -= diff;
     }
 };
@@ -482,17 +627,23 @@
 struct TRINITY_DLL_DECL mob_arcane_sphereAI : public ScriptedAI
 {
-    mob_arcane_sphereAI(Creature *c) : ScriptedAI(c) {Reset();}
-
+    mob_arcane_sphereAI(Creature *c) : ScriptedAI(c)
+	{
+        pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        Reset();
+    }
     uint32 DespawnTimer;
     uint32 ChangeTargetTimer;
-
-    bool TargetLocked;
+	uint32 CheckTimer;
+
+	ScriptedInstance* pInstance;
 
     void Reset()
     {
+		m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
         DespawnTimer = 30000;
         ChangeTargetTimer = 5000;
-        TargetLocked = false;
-
+		CheckTimer = 1000;
+		m_creature->SetSpeed(MOVE_RUN, 0.5f);
+		m_creature->SetSpeed(MOVE_WALK, 0.5f);
         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
         m_creature->setFaction(14);
@@ -500,12 +651,4 @@
     }
 
-    void MoveInLineOfSight(Unit* who)
-    {
-        if(TargetLocked)
-            return;
-        if(who && who->IsHostileTo(m_creature) && (m_creature->IsWithinDistInMap(who, 25)))
-            StalkTarget(who);
-    }
-
     void Aggro(Unit* who) {}
 
@@ -514,7 +657,7 @@
         if(!target)
             return;
-
-        m_creature->GetMotionMaster()->MoveChase(target);
-        TargetLocked = true;
+		m_creature->AddThreat(target,100000);
+		m_creature->GetMotionMaster()->MoveChase(target);
+		m_creature->Attack(target,true);
     }
 
@@ -526,13 +669,60 @@
 
         if(!m_creature->getVictim() || !m_creature->SelectHostilTarget())
-            return;
+			ChangeTargetTimer = 0;
 
         if(ChangeTargetTimer < diff)
         {
-            TargetLocked = false;
+			DoResetThreat();
+            Unit *ntarget = SelectUnit(SELECT_TARGET_RANDOM,0);
+			if (ntarget)
+				StalkTarget(ntarget);
             ChangeTargetTimer = 10000;
         }else ChangeTargetTimer -= diff;
+
+		if(CheckTimer < diff)
+        {
+            if (pInstance)
+			{
+				Creature *boss = (Creature*)Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_KAEL));
+				if(boss)
+				{
+					if(!((boss_felblood_kaelthasAI*)boss->AI())->Phase || boss->isDead())
+						DespawnTimer = 0;
+				}else DespawnTimer = 0;
+			}
+            CheckTimer = 1000;
+        }else CheckTimer -= diff;
     }
 };
+
+bool GOHello_go_kael_orb(Player *player, GameObject* _GO)
+{
+    ScriptedInstance* pInst = (ScriptedInstance*)_GO->GetInstanceData();
+	if (pInst && player)
+	{
+		Unit *kael = Unit::GetUnit((*_GO),pInst->GetData64(DATA_KAEL));
+		if (kael && kael->isDead())
+			player->TeleportTo(530, 12888, -6876, 9, 0.3);
+	}
+    return true;
+}
+
+bool GOHello_go_movie_orb(Player *player, GameObject* _GO)
+{
+	if (player)
+	{
+		WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4);
+        data << (uint32)164;
+        player->GetSession()->SendPacket(&data);
+		
+		if (player->GetQuestStatus(11490) == QUEST_STATUS_INCOMPLETE)
+		{
+			Unit *qUnit = player->SummonCreature(25042,player->GetPositionX(),player->GetPositionY(),player->GetPositionZ()-10,0,TEMPSUMMON_CORPSE_DESPAWN,0);
+			if(qUnit)
+				player->DealDamage(qUnit, qUnit->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+		}
+	}
+    return true;
+}
 
 CreatureAI* GetAI_boss_felblood_kaelthas(Creature* c)
@@ -589,3 +779,13 @@
     newscript->GetAI = GetAI_mob_felkael_flamestrike;
     m_scripts[nrscripts++] = newscript;
+
+	newscript = new Script;
+    newscript->Name="go_kael_orb";
+    newscript->pGOHello = &GOHello_go_kael_orb;
+    m_scripts[nrscripts++] = newscript;
+
+	newscript = new Script;
+    newscript->Name="go_movie_orb";
+    newscript->pGOHello = &GOHello_go_movie_orb;
+    m_scripts[nrscripts++] = newscript;
 }
Index: trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp
===================================================================
--- trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp (revision 105)
+++ trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp (revision 137)
@@ -90,5 +90,5 @@
     uint32 FelExplosionTimer;
     uint32 DrainCrystalTimer;
-    uint32 EmpowerTimer;
+    uint32 CheckTimer;
 
     bool IsDraining;
@@ -109,5 +109,5 @@
                 {
                     if(!pUnit->isAlive())
-                        ((Creature*)pUnit)->Respawn();      // Let TrinIty handle setting death state, etc.
+                        ((Creature*)pUnit)->Respawn();      // Let MaNGOS handle setting death state, etc.
 
                     // Only need to set unselectable flag. You can't attack unselectable units so non_attackable flag is not necessary here.
@@ -115,5 +115,4 @@
                 }
             }
-
             GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR));
             if( Door )
@@ -121,7 +120,9 @@
                                                             // Small door opened after event are expected to be closed by default
             // Set Inst data for encounter
-            pInstance->SetData(DATA_SELIN_EVENT, NOT_STARTED);
+			if (m_creature->isDead())
+				pInstance->SetData(DATA_SELIN_EVENT, DONE);
+			else pInstance->SetData(DATA_SELIN_EVENT, NOT_STARTED);
         }else error_log(ERROR_INST_DATA);
-
+		
         DrainLifeTimer = 3000 + rand()%4000;
         DrainManaTimer = DrainLifeTimer + 5000;
@@ -129,5 +130,5 @@
         DrainCrystalTimer = 10000 + rand()%5000;
         DrainCrystalTimer = 20000 + rand()%5000;
-        EmpowerTimer = 10000;
+        CheckTimer = 1000;
 
         IsDraining = false;
@@ -194,4 +195,5 @@
     void Aggro(Unit* who)
     {
+		m_creature->SetPower(POWER_MANA, 0);
         DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
         DoPlaySoundToSet(m_creature, SOUND_AGGRO);
@@ -263,5 +265,4 @@
             ContinueDoor->SetGoState(0);                    // Open the door leading further in
 
-        ShatterRemainingCrystals();
     }
 
@@ -287,10 +288,6 @@
                     if( DrainManaTimer < diff )
                     {
-                        Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
-                        if( target->getPowerType() == POWER_MANA)
-                        {    
-                            DoCast(target, SPELL_DRAIN_MANA);
-                            DrainManaTimer = 10000;
-                        }
+                        DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DRAIN_MANA);
+                        DrainManaTimer = 10000;
                     }else DrainManaTimer -= diff;
                 }
@@ -322,25 +319,33 @@
             if( IsDraining )
             {
-                if( EmpowerTimer < diff )
-                {
-                    IsDraining = false;
-                    DrainingCrystal = false;
-
-                    DoYell(SAY_EMPOWERED, LANG_UNIVERSAL, NULL);
-                    DoPlaySoundToSet(m_creature, SOUND_EMPOWERED);
-
-                    Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID);
-                    if( CrystalChosen && CrystalChosen->isAlive() )
-                        // Use Deal Damage to kill it, not setDeathState.
-                        CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-
-                    CrystalGUID = 0;
-
-                    m_creature->GetMotionMaster()->Clear();
-                    m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
-                }else EmpowerTimer -= diff;
-            }
-        }
-
+				if (CheckTimer < diff)
+				{
+					Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID);
+					if(CrystalChosen)
+					{
+						if(CrystalChosen->GetUInt32Value(UNIT_CHANNEL_SPELL) == SPELL_MANA_RAGE)
+						{
+							m_creature->StopMoving();
+						}else{
+							IsDraining = false;
+							DrainingCrystal = false;
+
+							DoYell(SAY_EMPOWERED, LANG_UNIVERSAL, NULL);
+							DoPlaySoundToSet(m_creature, SOUND_EMPOWERED);
+
+							Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID);
+							if( CrystalChosen && CrystalChosen->isAlive() )
+								// Use Deal Damage to kill it, not setDeathState.
+								CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+							CrystalGUID = 0;
+
+							m_creature->GetMotionMaster()->Clear();
+							m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+						}
+					}
+					CheckTimer = 1000;
+				}else CheckTimer -= diff;
+			}
+        }
         DoMeleeAttackIfReady();                             // No need to check if we are draining crystal here, as the spell has a stun.
     }
@@ -364,4 +369,5 @@
     void JustDied(Unit* killer)
     {
+		m_creature->RemoveAurasDueToSpell(SPELL_MANA_RAGE);
         if(ScriptedInstance* pInstance = ((ScriptedInstance*)m_creature->GetInstanceData()))
         {
@@ -371,8 +377,8 @@
                 if(((boss_selin_fireheartAI*)Selin->AI())->CrystalGUID == m_creature->GetGUID())
                 {
-                    Selin->RemoveAurasDueToSpell(SPELL_MANA_RAGE);
+                    // Set this to false if we are the creature that Selin is draining so his AI flows properly
                     ((boss_selin_fireheartAI*)Selin->AI())->DrainingCrystal = false;
                     ((boss_selin_fireheartAI*)Selin->AI())->IsDraining = false;
-                    ((boss_selin_fireheartAI*)Selin->AI())->EmpowerTimer = 10000;
+					Selin->RemoveAurasDueToSpell(SPELL_MANA_RAGE);
                     if(Selin->getVictim())
                     {
Index: trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp
===================================================================
--- trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp (revision 90)
+++ trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp (revision 137)
@@ -48,4 +48,5 @@
 #define SPELL_OVERLOAD              44353
 #define SPELL_ARCANE_SHOCK          44319
+#define ASTRAL_FLARE_VISUAL			30237
 
 //Creatures
@@ -82,5 +83,9 @@
 
         if(pInstance)
-            pInstance->SetData(DATA_VEXALLUS_EVENT, NOT_STARTED);
+		{
+			if (m_creature->isDead())
+				pInstance->SetData(DATA_VEXALLUS_EVENT, DONE);
+			else pInstance->SetData(DATA_VEXALLUS_EVENT, NOT_STARTED);
+		}
     }
 
@@ -131,5 +136,5 @@
                 DoPlaySoundToSet(m_creature, SOUND_ENERGY);
                 Creature* PureEnergyCreature = NULL;
-                PureEnergyCreature = DoSpawnCreature(CREATURE_PURE_ENERGY, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+                PureEnergyCreature = DoSpawnCreature(CREATURE_PURE_ENERGY, 10, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                 Unit* target = NULL;
                 target = SelectUnit(SELECT_TARGET_RANDOM, 0);
@@ -139,5 +144,5 @@
                 if(Heroic)                                  // *Heroic mode only - he summons two instead of one.
                 {
-                    PureEnergyCreature = DoSpawnCreature(CREATURE_PURE_ENERGY, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+                    PureEnergyCreature = DoSpawnCreature(CREATURE_PURE_ENERGY, -10, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                     target = SelectUnit(SELECT_TARGET_RANDOM, 0);
                     if (PureEnergyCreature && target)
@@ -187,8 +192,12 @@
 
     uint32 EnergyBoltTimer;
+	uint32 VisualTimer;
 
     void Reset()
     {
         EnergyBoltTimer = 1700;
+		VisualTimer = 1000;
+		m_creature->SetSpeed(MOVE_RUN, 0.5f);
+		m_creature->SetSpeed(MOVE_WALK, 0.5f);
     }
 
@@ -210,4 +219,9 @@
             EnergyBoltTimer = 1700;
         }else   EnergyBoltTimer -= diff;
+		if(VisualTimer < diff)
+        {
+            DoCast(m_creature->getVictim(), ASTRAL_FLARE_VISUAL, true);
+            VisualTimer = 1000;
+        }else   VisualTimer -= diff;
     }
 };
Index: trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp
===================================================================
--- trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp (revision 90)
+++ trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp (revision 137)
@@ -7,10 +7,10 @@
  * 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
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
@@ -103,6 +103,6 @@
         pInstance = ((ScriptedInstance*)c->GetInstanceData());
         Adds.clear();
-        Reset();
-        SummonAdds();
+		//SummonAdds();
+        Reset();        
         Heroic = c->GetMap()->IsHeroic();
     }
@@ -127,4 +127,5 @@
     void Reset()
     {
+		m_creature->SetCorpseDelay(60*60*1000);
         LackeysKilled = 0;
         PlayersKilled = 0;
@@ -140,9 +141,11 @@
         CheckAdds();
 
-        if(pInstance)
-        {
-            pInstance->SetData(DATA_DELRISSA_EVENT, NOT_STARTED);
-            pInstance->SetData(DATA_DELRISSA_DEATH_COUNT, 0);
-        }
+		if(pInstance)
+		{
+			pInstance->SetData(DATA_DELRISSA_DEATH_COUNT, 0);
+			if (m_creature->isDead())
+				pInstance->SetData(DATA_DELRISSA_EVENT, DONE);
+			else pInstance->SetData(DATA_DELRISSA_EVENT, NOT_STARTED);
+		}
         else error_log(ERROR_INST_DATA);
     }
@@ -160,4 +163,6 @@
     void SummonAdds()
     {
+		/*if (m_creature->isDead())
+			return;*/
         std::vector<uint32> AddList;
         for(uint8 i = 0; i < 8; ++i)
@@ -180,23 +185,27 @@
     void CheckAdds()
     {
+		//if (m_creature->isDead())
+		//	return;
         if(Adds.empty())
-            return;
-
+		{
+			SummonAdds();
+            return;
+		}
         for(uint8 i = 0; i < Adds.size(); ++i)
         {
-            bool resummon = true;
             Creature* pAdd = ((Creature*)Unit::GetUnit(*m_creature, Adds[i]->guid));
             if(pAdd && pAdd->isAlive())
             {
-                pAdd->AI()->EnterEvadeMode();               // Force them out of combat and reset if they are in combat.
-                resummon = false;
-            }
-            if(resummon)
-            {
-                pAdd = m_creature->SummonCreature(Adds[i]->entry, LackeyLocations[i][0], LackeyLocations[i][1], POS_Z, ORIENT, TEMPSUMMON_DEAD_DESPAWN, 0);
-                Add* nAdd = new Add(Adds[i]->entry, pAdd->GetGUID());
-                Adds.erase(Adds.begin() + i);
-                Adds.push_back(nAdd);
-            }
+				pAdd->AI()->EnterEvadeMode();
+				pAdd->GetMotionMaster()->MovePoint(0,LackeyLocations[i][0], LackeyLocations[i][1], POS_Z);
+            }	
+			if(!pAdd || (pAdd && pAdd->isDead()))
+            {
+				if(pAdd)
+					pAdd->RemoveCorpse();//looks stupid if mob is alive but has a dead corpse in front of him :)
+				Creature* pAdd = m_creature->SummonCreature(Adds[i]->entry, LackeyLocations[i][0], LackeyLocations[i][1], POS_Z, ORIENT, TEMPSUMMON_DEAD_DESPAWN, 0);
+				if(pAdd)
+					Adds[i]->guid = pAdd->GetGUID();
+			}
         }
     }
@@ -204,5 +213,5 @@
     void KilledUnit(Unit* victim)
     {
-        if(victim->GetTypeId() != TYPEID_PLAYER)
+		if(victim->GetTypeId() != TYPEID_PLAYER || m_creature->isDead())
             return;
 
@@ -215,8 +224,12 @@
     void KilledLackey()
     {
+		if(m_creature->isDead())//no sense to talk if dead..
+			return;
         DoYell(LackeyDeath[LackeysKilled].text, LANG_UNIVERSAL, NULL);
         DoPlaySoundToSet(m_creature, LackeyDeath[LackeysKilled].sound);
         if( LackeysKilled < 3 )
             ++LackeysKilled;
+
+		CheckLootable();
     }
 
@@ -242,5 +255,5 @@
     void CheckLootable()
     {
-        if(LackeysKilled > 4)
+        if(pInstance && pInstance->GetData(DATA_DELRISSA_DEATH_COUNT) >= 4)
             m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
         else
@@ -367,5 +380,10 @@
     {
         UsedPotion = false;
-
+		if(pInstance)
+		{
+			Creature *boss = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_DELRISSA)));
+			if (boss && boss->isDead())
+				boss->Respawn();
+		}
         ResetThreatTimer = 5000 + rand()%15000;             // These guys like to switch targets often, and are not meant to be tanked.
     }
@@ -638,5 +656,7 @@
         }else Fear_Timer -= diff;
 
-        DoMeleeAttackIfReady();
+		if (m_creature->GetDistance(m_creature->getVictim()) <= 10)
+			m_creature->StopMoving();
+        //DoMeleeAttackIfReady();//should not melee, she's a warlock
     }
 };
@@ -741,5 +761,5 @@
             return;
 
-        boss_priestess_guestAI::UpdateAI(diff);
+        boss_priestess_guestAI::UpdateAI(diff);		
 
         if(Polymorph_Timer < diff)
@@ -793,17 +813,27 @@
                     //if in melee range
                     if (target->IsWithinDistInMap(m_creature, 5))
-                {
-                    InMeleeRange = true;
-                    break;
-                }
+					{
+						InMeleeRange = true;
+						break;
+					}
             }
             //if anybody is in melee range than escape by blink
             if(InMeleeRange)
-                DoCast(m_creature, SPELL_BLINK);
-
+			{
+				//DoCast(m_creature, SPELL_BLINK);  //blink does not work on npcs
+				float x,y,z;
+				m_creature->GetPosition(x,y,z);
+				x = rand()%2 ? x+10+rand()%10 : x-10-rand()%10;
+				y = rand()%2 ? y+10+rand()%10 : y-10-rand()%10;
+				m_creature->Relocate(x,y,z);
+				m_creature->SendMonsterMove(x, y, m_creature->GetPositionZ(), 0,0,0); 
+			}
             Blink_Timer = 8000;
         }else Blink_Timer -= diff;
 
-        DoMeleeAttackIfReady();
+		if (m_creature->GetDistance(m_creature->getVictim()) <= 10)
+			m_creature->StopMoving();
+
+        //DoMeleeAttackIfReady(); //mage type, no melee needed
     }
 };
@@ -949,4 +979,6 @@
     uint32 Wing_Clip_Timer;
     uint32 Freezing_Trap_Timer;
+	uint32 StopMoving;
+	bool Stopped;
 
     void Reset()
@@ -961,4 +993,6 @@
         Wing_Clip_Timer = 4000;
         Freezing_Trap_Timer = 15000;
+		StopMoving = 2000;
+		Stopped = false;
 
         boss_priestess_guestAI::Reset();
@@ -1031,4 +1065,14 @@
             }else Shoot_Timer -= diff;
         }
+		if(StopMoving < diff)
+        {
+			if(Stopped)
+				Stopped = false;
+			else
+				Stopped = true;
+            StopMoving = 2000+rand()%5000;
+        }else StopMoving -= diff;
+		if (Stopped)
+			m_creature->StopMoving();
     }
 };
@@ -1179,7 +1223,10 @@
 
         if(Goblin_Dragon_Gun_Timer < diff)
-        {
-            DoCast(m_creature->getVictim(), SPELL_GOBLIN_DRAGON_GUN);
-            Goblin_Dragon_Gun_Timer = 10000;
+        {           
+			if (m_creature->GetDistance(m_creature->getVictim()) <= 5)
+			{
+				Goblin_Dragon_Gun_Timer = 10000;
+				DoCast(m_creature->getVictim(), SPELL_GOBLIN_DRAGON_GUN);
+			}else Goblin_Dragon_Gun_Timer = 2000;
         }else Goblin_Dragon_Gun_Timer -= diff;
 
