Index: /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp (revision 164)
+++ /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp (revision 182)
@@ -57,8 +57,9 @@
 #define SPELL_SUMMON_WATER_ELEMENT  36459                   //not in use yet(in use ever?)
 #define SPELL_ELEMENTAL_SPAWNIN     25035
-//#define SPELL_BLUE_BEAM             38015                   //channeled Hydross Beam Helper (not in use yet)
+#define SPELL_BLUE_BEAM             /*40227*/38015                   //channeled Hydross Beam Helper (not in use yet)
 
 #define ENTRY_PURE_SPAWN            22035
 #define ENTRY_TAINTED_SPAWN         22036
+#define ENTRY_BEAM_DUMMY            21934
 
 #define HYDROSS_X                   -239.439
@@ -76,12 +77,12 @@
 struct TRINITY_DLL_DECL boss_hydross_the_unstableAI : public ScriptedAI
 {
-    boss_hydross_the_unstableAI(Creature *c) : ScriptedAI(c)
+    boss_hydross_the_unstableAI(Creature *c) : ScriptedAI(c), Summons(m_creature)
     {
         pInstance = ((ScriptedInstance*)c->GetInstanceData());
-        Reset();
+        Reset();		
     }
 
     ScriptedInstance* pInstance;
-
+	uint64 beams[2];
     uint32 PosCheck_Timer;
     uint32 MarkOfHydross_Timer;
@@ -93,7 +94,12 @@
     uint32 EnrageTimer;
     bool CorruptedForm;
+	bool beam;
+	SummonList Summons;
 
     void Reset()
     {
+		DeSummonBeams();
+		beams[0] = 0;
+		beams[1] = 0;
         PosCheck_Timer = 2500;
         MarkOfHydross_Timer = 15000;
@@ -114,6 +120,39 @@
         if (pInstance)
             pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, NOT_STARTED);
-    }
-
+		beam = false;
+		Summons.DespawnAll();
+    }
+
+	void SummonBeams()
+	{		
+		Creature* beamer = m_creature->SummonCreature(ENTRY_BEAM_DUMMY,-258.333,-356.34,22.0499,5.90835,TEMPSUMMON_CORPSE_DESPAWN,0);
+		if(beamer)
+		{
+			beamer->CastSpell(m_creature,SPELL_BLUE_BEAM,true);
+			beamer->SetUInt32Value(UNIT_FIELD_DISPLAYID , 11686);  //invisible
+			beamer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+			beams[0]=beamer->GetGUID();
+		}
+		beamer = beamer = m_creature->SummonCreature(ENTRY_BEAM_DUMMY,-219.918,-371.308,22.0042,2.73072,TEMPSUMMON_CORPSE_DESPAWN,0);		
+		if(beamer)
+		{
+			beamer->CastSpell(m_creature,SPELL_BLUE_BEAM,true);
+			beamer->SetUInt32Value(UNIT_FIELD_DISPLAYID , 11686);  //invisible
+			beamer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+			beams[1]=beamer->GetGUID();
+		}
+	}
+	void DeSummonBeams()
+	{		
+		for(uint8 i=0;i<2;i++)
+		{
+			Creature* mob = (Creature*)Unit::GetUnit(*m_creature,beams[i]);
+			if(mob)
+			{
+				mob->setDeathState(DEAD);
+                mob->RemoveCorpse();
+			}
+		}
+	}
     void Aggro(Unit *who)
     {
@@ -147,9 +186,20 @@
     {
         if (summoned->GetEntry() == ENTRY_PURE_SPAWN)
-            summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
+		{
+			summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
+			summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true);
+			Summons.Summon(summoned);
+		}
         if (summoned->GetEntry() == ENTRY_TAINTED_SPAWN)
-            summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
-
-        summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true);
+		{
+			summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
+			summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true);
+			Summons.Summon(summoned);
+		}
+    }
+
+	void SummonedCreatureDespawn(Creature *summon)
+    {
+        Summons.Despawn(summon);
     }
 
@@ -163,8 +213,14 @@
         if (pInstance)
             pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, NOT_STARTED);
+		Summons.DespawnAll();
     }
 
     void UpdateAI(const uint32 diff)
     {
+		if(!beam)
+		{
+			SummonBeams();
+			beam=true;
+		}
         //Return since we have no target
         if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
@@ -222,10 +278,11 @@
                     DoScriptText(SAY_SWITCH_TO_CLEAN, m_creature);
                     DoResetThreat();
+					SummonBeams();
 
                     // spawn 4 adds
-                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
-                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
-                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
-                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
 
                     m_creature->SetMeleeDamageSchool(SPELL_SCHOOL_FROST);
@@ -288,10 +345,11 @@
                     DoScriptText(SAY_SWITCH_TO_CORRUPT, m_creature);
                     DoResetThreat();
+					DeSummonBeams();
 
                     // spawn 4 adds
-                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
-                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
-                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
-                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
 
                     m_creature->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE);
Index: /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp (revision 164)
+++ /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp (revision 182)
@@ -17,6 +17,6 @@
 /* ScriptData
 SDName: Boss_Leotheras_The_Blind
-SD%Complete: 50
-SDComment: Missing Inner Demons
+SD%Complete: 80
+SDComment: Possesion Support
 SDCategory: Coilfang Resevoir, Serpent Shrine Cavern
 EndScriptData */
@@ -24,4 +24,32 @@
 #include "precompiled.h"
 #include "def_serpent_shrine.h"
+
+// --- Spells used by Leotheras The Blind
+#define SPELL_WHIRLWIND         37640
+#define SPELL_CHAOS_BLAST       37674
+#define SPELL_BERSERK			26662
+#define SPELL_INSIDIOUS_WHISPER 37676
+#define SPELL_DUAL_WIELD		42459
+
+// --- Spells used in banish phase ---
+#define BANISH_BEAM				38909
+#define AURA_BANISH				37833
+
+// --- Spells used by Greyheart Spellbinders
+#define SPELL_EARTHSHOCK		39076
+#define SPELL_MINDBLAST			37531
+
+// --- Spells used by Inner Demons and creature ID
+#define INNER_DEMON_ID			21857 
+#define AURA_DEMONIC_ALIGNMENT	37713
+#define SPELL_SHADOWBOLT		39309
+#define SPELL_SOUL_LINK			38007
+#define SPELL_CONSUMING_MADNESS	37749 //not supported by core yet
+
+//Misc.
+#define MODEL_DEMON				20125
+#define MODEL_NIGHTELF			20514
+#define DEMON_FORM				21875
+#define MOB_SPELLBINDER			21806
 
 #define SAY_AGGRO               -1548009
@@ -38,13 +66,80 @@
 #define SAY_DEATH               -1548020
 
-#define SPELL_WHIRLWIND         40653
-#define SPELL_CHAOS_BLAST       37675
-//#define SPELL_INSIDIOUS_WHISPER 37676                       // useless - dummy effect that can't be implemented
-
-#define MODEL_DEMON             14555
-#define MODEL_NIGHTELF          20514
-
-#define DEMON_FORM              21845
-
+class TRINITY_DLL_DECL InsidiousAura : public Aura {
+public:
+	InsidiousAura(SpellEntry *spell, uint32 eff, int32 *bp, Unit *target, Unit *caster) : Aura(spell, eff, bp, target, caster, NULL)
+	{}
+};
+
+struct TRINITY_DLL_DECL mob_inner_demonAI : public ScriptedAI
+{
+    mob_inner_demonAI(Creature *c) : ScriptedAI(c)
+    {
+		victimGUID = 0;
+        Reset();
+    }
+
+    uint32 ShadowBolt_Timer;
+	
+	uint32 Link_Timer;
+	uint64 victimGUID;
+
+    void Reset()
+    {
+        ShadowBolt_Timer = 10000;		
+		Link_Timer = 1000;
+    }
+	void JustDied(Unit *victim)
+    {
+		Unit* pUnit = Unit::GetUnit((*m_creature),victimGUID);
+		if (pUnit && pUnit->HasAura(SPELL_INSIDIOUS_WHISPER,0))
+			pUnit->RemoveAurasDueToSpell(SPELL_INSIDIOUS_WHISPER);
+	}
+
+	void DamageTaken(Unit *done_by, uint32 &damage)
+	{
+		if(done_by->GetGUID() != victimGUID && done_by->GetGUID() != m_creature->GetGUID())
+		{
+			damage = 0;
+			m_creature->getThreatManager().modifyThreatPercent(done_by, -100);
+		}
+	}
+
+	void Aggro(Unit *who)
+    {
+		if (!victimGUID) return;
+    }
+
+    void UpdateAI(const uint32 diff)
+    {
+        //Return since we have no target
+        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+            return;
+
+		if (m_creature->getVictim()->GetGUID() != victimGUID)
+		{
+			Unit* owner = Unit::GetUnit((*m_creature),victimGUID);
+				if (owner)
+					AttackStart(owner);
+		}
+		if(Link_Timer < diff)
+		{
+			DoCast(m_creature->getVictim(), SPELL_SOUL_LINK, true);
+			Link_Timer = 1000;
+		}else Link_Timer -= diff;
+
+
+		if(!m_creature->HasAura(AURA_DEMONIC_ALIGNMENT, 0))
+			DoCast(m_creature, AURA_DEMONIC_ALIGNMENT,true);
+
+		if(ShadowBolt_Timer < diff)
+		{
+			DoCast(m_creature->getVictim(), SPELL_SHADOWBOLT, false);
+			ShadowBolt_Timer = 10000;
+		}else ShadowBolt_Timer -= diff; 
+
+       DoMeleeAttackIfReady();
+    }
+};
 //Original Leotheras the Blind AI
 struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
@@ -52,42 +147,213 @@
     boss_leotheras_the_blindAI(Creature *c) : ScriptedAI(c)
     {
-        pInstance = ((ScriptedInstance*)c->GetInstanceData());
+		m_creature->GetPosition(x,y,z);
+        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
         Demon = 0;
+		
+		for(uint8 i = 0; i < 3; i++)//clear guids
+			SpellBinderGUID[i] = 0;
         Reset();
-    }
-
+
+	}
     ScriptedInstance *pInstance;
 
     uint32 Whirlwind_Timer;
     uint32 ChaosBlast_Timer;
-    uint32 Switch_Timer;
-
+	uint32 SwitchToDemon_Timer;
+    uint32 SwitchToHuman_Timer;
+	uint32 Berserk_Timer;
+	uint32 InnerDemons_Timer;
+	uint32 BanishTimer;
+	
+	bool DealDamage;
+	bool NeedThreatReset;
     bool DemonForm;
     bool IsFinalForm;
-
+	bool EnrageUsed;
+	float x,y,z;
+	
+	uint64 InnderDemon[5];
+	uint32 InnderDemon_Count;
     uint64 Demon;
+	uint64 SpellBinderGUID[3];
 
     void Reset()
     {
-        Whirlwind_Timer = 20000;
+		CheckChannelers();
+		BanishTimer = 1000;
+        Whirlwind_Timer = 15000;
         ChaosBlast_Timer = 1000;
-        Switch_Timer = 45000;
-
+		SwitchToDemon_Timer = 45000;
+        SwitchToHuman_Timer = 60000;
+		Berserk_Timer = 600000;
+		InnerDemons_Timer = 30000;
+		m_creature->SetCanDualWield(true);
+		DealDamage = true;
         DemonForm = false;
         IsFinalForm = false;
-
-        m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF);
-
-        if (pInstance)
-            pInstance->SetData(DATA_LEOTHERASTHEBLINDEVENT, NOT_STARTED);
-    }
+		NeedThreatReset = false;
+		EnrageUsed = false;
+		InnderDemon_Count = 0;
+		m_creature->SetSpeed( MOVE_RUN, 2.0f, true);
+		m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+		m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
+		m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF);
+		m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY  , 0);
+        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+		m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true);
+		m_creature->SetCorpseDelay(1000*60*60);
+		if(pInstance)
+			pInstance->SetData(DATA_LEOTHERASTHEBLINDEVENT, NOT_STARTED); 
+    }
+
+	void CheckChannelers(bool DoEvade = true)
+	{
+		for(uint8 i = 0; i < 3; i++)
+		{
+			Creature *add = (Creature*)Unit::GetUnit(*m_creature,SpellBinderGUID[i]);
+			if (add && add->isAlive())
+			{
+				add->setDeathState(DEAD);
+                add->RemoveCorpse();
+			}else{
+				if(add && add->isDead())
+					add->RemoveCorpse();
+			}
+			float nx = x;
+			float ny = y;
+			float o = 2.4f;
+			if (i == 0) {nx += 20;o=3.0f;}
+			if (i == 1) ny -= 20;
+			if (i == 2) {nx += 18;ny -= 18;o=2.0f;}
+			Creature* binder = m_creature->SummonCreature(MOB_SPELLBINDER,nx,ny,z,o,TEMPSUMMON_DEAD_DESPAWN,0);
+			if (binder)
+				SpellBinderGUID[i] = binder->GetGUID();
+			
+		}
+	}
+	void MoveInLineOfSight(Unit *who)
+	{
+		if(m_creature->HasAura(AURA_BANISH, 0))
+			return;
+
+		if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) )
+		{
+			if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
+				return;
+
+			float attackRadius = m_creature->GetAttackDistance(who);
+			if(m_creature->IsWithinDistInMap(who, attackRadius))
+			{
+				// Check first that object is in an angle in front of this one before LoS check
+				if( m_creature->HasInArc(M_PI/2.0f, who) && m_creature->IsWithinLOSInMap(who) )
+				{
+					AttackStart(who);
+					who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+					if (!InCombat)
+					{
+						Aggro(who);
+						InCombat = true;
+					}
+				}
+			}
+		}
+	}
 
     void StartEvent()
     {
         DoScriptText(SAY_AGGRO, m_creature);
-
-        if (pInstance)
+        if(pInstance)
             pInstance->SetData(DATA_LEOTHERASTHEBLINDEVENT, IN_PROGRESS);
     }
+
+	void CheckBanish()
+	{
+		uint8 AliveChannelers = 0;
+		for(uint8 i = 0; i < 3; i++)
+		{
+			Unit *add = Unit::GetUnit(*m_creature,SpellBinderGUID[i]);
+			if (add && add->isAlive())
+				AliveChannelers++;
+		}
+
+		// channelers == 0 remove banish aura
+		if(AliveChannelers == 0 && m_creature->HasAura(AURA_BANISH, 0))
+		{	
+			// removing banish aura
+			m_creature->RemoveAurasDueToSpell(AURA_BANISH);
+
+			// Leotheras is getting immune again 
+            m_creature->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);
+
+			// changing model to bloodelf 
+            m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF);
+
+			// and reseting equipment
+			m_creature->LoadEquipment(m_creature->GetEquipmentId());
+
+			if(pInstance && pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
+			{
+				Unit *victim = NULL;
+				victim = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER));
+				if(victim)
+					m_creature->getThreatManager().addThreat(victim, 1);
+				StartEvent();
+			}		
+		}
+		else if(AliveChannelers != 0 && !m_creature->HasAura(AURA_BANISH, 0))
+		{
+			// channelers != 0 apply banish aura
+			// removing Leotheras banish immune to apply AURA_BANISH
+            m_creature->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, MECHANIC_BANISH, false);
+			DoCast(m_creature, AURA_BANISH);
+
+			// changing model
+            m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON);
+			
+			// and removing weapons
+            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY  , 0);
+            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+		}
+	}
+
+	//Despawn all Inner Demon summoned
+	void DespawnDemon()
+	{
+        for(int i=0; i<5; i++)
+		{
+            if(InnderDemon[i])
+			{
+                    //delete creature
+                    Unit* pUnit = Unit::GetUnit((*m_creature), InnderDemon[i]);
+                    if (pUnit && pUnit->isAlive())
+					{
+                        pUnit->DealDamage(pUnit, pUnit->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+					}
+					InnderDemon[i] = 0;
+			}
+		}
+
+		InnderDemon_Count = 0;
+	}
+
+	void CastConsumingMadness()	//remove this once SPELL_INSIDIOUS_WHISPER is supported by core
+	{
+        for(int i=0; i<5; i++)
+		{
+            if(InnderDemon[i] > 0 )
+			{
+                Unit* pUnit = Unit::GetUnit((*m_creature), InnderDemon[i]);
+                if (pUnit && pUnit->isAlive())
+				{
+					Unit* pUnit_target = Unit::GetUnit((*pUnit), ((mob_inner_demonAI *)((Creature *)pUnit)->AI())->victimGUID);
+					if( pUnit_target && pUnit_target->isAlive())
+					{
+						pUnit->CastSpell(pUnit_target, SPELL_CONSUMING_MADNESS, true);
+						m_creature->getThreatManager().modifyThreatPercent(pUnit_target, -100);
+					}
+				}
+			}
+		}
+	}
 
     void KilledUnit(Unit *victim)
@@ -129,5 +395,4 @@
                 pUnit->DealDamage(pUnit, pUnit->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
         }
-
         if (pInstance)
             pInstance->SetData(DATA_LEOTHERASTHEBLINDEVENT, DONE);
@@ -136,5 +401,8 @@
     void Aggro(Unit *who)
     {
-        StartEvent();
+		if(m_creature->HasAura(AURA_BANISH, 0))
+		return;
+
+		m_creature->LoadEquipment(m_creature->GetEquipmentId());
     }
 
@@ -142,29 +410,76 @@
     {
         //Return since we have no target
-        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
-            return;
-
-        if (!DemonForm)
+        if (m_creature->HasAura(AURA_BANISH, 0) || !m_creature->SelectHostilTarget() || !m_creature->getVictim())
+		{
+			if(BanishTimer<diff)
+			{
+				CheckBanish();//no need to check every update tick
+				BanishTimer = 1000;
+			}else BanishTimer -= diff;
+			return;
+		}
+		if(m_creature->HasAura(SPELL_WHIRLWIND, 0))
+			if(Whirlwind_Timer < diff)
+			{
+				Unit *newTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+				if(newTarget)
+				{
+					DoResetThreat();				
+					m_creature->GetMotionMaster()->Clear();
+					m_creature->GetMotionMaster()->MovePoint(0,newTarget->GetPositionX(),newTarget->GetPositionY(),newTarget->GetPositionZ());
+				}
+				Whirlwind_Timer = 2000;
+			}else Whirlwind_Timer -= diff;
+
+		// reseting after changing forms and after ending whirlwind
+		if(NeedThreatReset && !m_creature->HasAura(SPELL_WHIRLWIND, 0))
+		{	
+			// when changing forms seting timers (or when ending whirlwind - to avoid adding new variable i use Whirlwind_Timer to countdown 2s while whirlwinding)
+			if(DemonForm)
+				InnerDemons_Timer = 30000;
+			else
+				Whirlwind_Timer =  15000;
+			
+			NeedThreatReset = false;
+			DoResetThreat();
+			m_creature->GetMotionMaster()->Clear();
+			m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+		}
+
+        //Enrage_Timer ( 10 min )
+        if(Berserk_Timer < diff && !EnrageUsed)
         {
-            //Whirlwind_Timer
-            if (Whirlwind_Timer < diff)
-            {
-                DoCast(m_creature, SPELL_WHIRLWIND);
-                Whirlwind_Timer = 25000;
-            }else Whirlwind_Timer -= diff;
-
+            DoCast(m_creature, SPELL_BERSERK);
+			EnrageUsed = true;
+        }else Berserk_Timer -= diff;
+
+        if(!DemonForm)
+        {
+			//Whirldind Timer
+            if(!m_creature->HasAura(SPELL_WHIRLWIND, 0))
+			{
+				if(Whirlwind_Timer < diff)
+				{
+					DoCast(m_creature, SPELL_WHIRLWIND);
+					// while whirlwinding this variable is used to countdown target's change
+					Whirlwind_Timer = 2000;
+					NeedThreatReset = true;
+				}else Whirlwind_Timer -= diff;
+			}
             //Switch_Timer
-            if (!IsFinalForm)
-            {
-                if (Switch_Timer < diff)
+
+            if(!IsFinalForm)
+                if(SwitchToDemon_Timer < diff)
                 {
                     //switch to demon form
-                    m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON);
-                    DoScriptText(SAY_SWITCH_TO_DEMON, m_creature);
-                    DemonForm = true;
-                    Switch_Timer = 60000;
-                }else Switch_Timer -= diff;
-            }
-
+					m_creature->RemoveAurasDueToSpell(SPELL_WHIRLWIND,0);
+					m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON);
+					DoScriptText(SAY_SWITCH_TO_DEMON, m_creature);
+					m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY  , 0);
+				    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+					DemonForm = true;
+					NeedThreatReset = true;
+                    SwitchToDemon_Timer = 45000;
+                }else SwitchToDemon_Timer -= diff;
             DoMeleeAttackIfReady();
         }
@@ -172,33 +487,90 @@
         {
             //ChaosBlast_Timer
-            if (ChaosBlast_Timer < diff)
-            {
-                DoCast(m_creature->getVictim(), SPELL_CHAOS_BLAST);
-                ChaosBlast_Timer = 1500;
-            }else ChaosBlast_Timer -= diff;
+            if (!m_creature->getVictim())
+				return;
+			if(m_creature->GetDistance(m_creature->getVictim()) < 30)
+				m_creature->StopMoving();
+			if(ChaosBlast_Timer < diff)
+			{
+				// will cast only when in range of spell 
+				if(m_creature->GetDistance(m_creature->getVictim()) < 30)
+				{
+					//m_creature->CastSpell(m_creature->getVictim(), SPELL_CHAOS_BLAST, true);
+					int damage = 100;
+					m_creature->CastCustomSpell(m_creature->getVictim(), SPELL_CHAOS_BLAST, &damage, NULL, NULL, false, NULL, NULL, m_creature->GetGUID());
+				}
+				ChaosBlast_Timer = 3000;
+			}else ChaosBlast_Timer -= diff;
+			//Summon Inner Demon
+			if(InnerDemons_Timer < diff)
+			{
+				std::list<HostilReference *>& ThreatList = m_creature->getThreatManager().getThreatList();
+				std::vector<Unit *> TargetList; 
+				for(std::list<HostilReference *>::iterator itr = ThreatList.begin(); itr != ThreatList.end(); ++itr)
+				{
+					Unit *tempTarget = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
+					if(tempTarget && tempTarget->GetTypeId() == TYPEID_PLAYER && tempTarget->GetGUID() != m_creature->getVictim()->GetGUID() && TargetList.size()<5)
+						TargetList.push_back( tempTarget );
+				}	
+				SpellEntry *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SPELL_INSIDIOUS_WHISPER);
+				for(std::vector<Unit *>::iterator itr = TargetList.begin(); itr != TargetList.end(); ++itr)
+				{
+					if( (*itr) && (*itr)->isAlive() )
+					{
+						Creature * demon = (Creature *)m_creature->SummonCreature(INNER_DEMON_ID, (*itr)->GetPositionX()+10, (*itr)->GetPositionY()+10, (*itr)->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+						if(demon)
+						{
+							((ScriptedAI *)demon->AI())->AttackStart( (*itr) );
+							((mob_inner_demonAI *)demon->AI())->victimGUID = (*itr)->GetGUID();
+														
+							for (int i=0; i<3; i++)
+							{
+								if (!spell->Effect[i])
+									continue;
+								(*itr)->AddAura(new InsidiousAura(spell, i, NULL, (*itr), (*itr)));
+							}
+							if( InnderDemon_Count > 4 ) InnderDemon_Count = 0;
+
+							//Safe storing of creatures
+							InnderDemon[InnderDemon_Count] = demon->GetGUID();
+
+							//Update demon count
+							InnderDemon_Count++;
+						}
+					}
+				}
+				DoScriptText(SAY_INNER_DEMONS, m_creature);
+
+				InnerDemons_Timer = 999999;
+			}else InnerDemons_Timer -= diff;
 
             //Switch_Timer
-            if (Switch_Timer < diff)
+            if(SwitchToHuman_Timer < diff)
             {
                 //switch to nightelf form
                 m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF);
+				m_creature->LoadEquipment(m_creature->GetEquipmentId());
+
+				CastConsumingMadness();
+				DespawnDemon();
+
                 DemonForm = false;
-
-                Switch_Timer = 45000;
-            }else Switch_Timer -= diff;
-        }
+				NeedThreatReset = true;
+
+                SwitchToHuman_Timer = 60000;
+            }else SwitchToHuman_Timer -= diff;
+		}
 
         if (!IsFinalForm && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 15)
         {
             //at this point he divides himself in two parts
-            Creature *Copy = NULL;
-            Copy = DoSpawnCreature(DEMON_FORM, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
-
-            if (Copy)
-            {
-                Demon = Copy->GetGUID();
-                Copy->AI()->AttackStart(m_creature->getVictim());
-            }
-
+			Creature *Copy = NULL;
+            Copy = DoSpawnCreature(DEMON_FORM, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 6000);
+			if(Copy)
+             {
+                 Demon = Copy->GetGUID();
+				if (m_creature->getVictim())
+					Copy->AI()->AttackStart(m_creature->getVictim());
+			}
             //set nightelf final form
             IsFinalForm = true;
@@ -206,5 +578,6 @@
 
             DoScriptText(SAY_FINAL_FORM, m_creature);
-            m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF);
+	        m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF);
+			m_creature->LoadEquipment(m_creature->GetEquipmentId());
         }
     }
@@ -220,8 +593,10 @@
 
     uint32 ChaosBlast_Timer;
+	bool DealDamage;
 
     void Reset()
     {
         ChaosBlast_Timer = 1000;
+		DealDamage = true;
     }
 
@@ -260,16 +635,145 @@
         if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
             return;
-
         //ChaosBlast_Timer
-        if (ChaosBlast_Timer < diff)
-        {
-            DoCast(m_creature->getVictim(), SPELL_CHAOS_BLAST);
-            ChaosBlast_Timer = 1500;
-        }else ChaosBlast_Timer -= diff;
+		if(m_creature->GetDistance(m_creature->getVictim()) < 30)
+			m_creature->StopMoving();
+		
+		if(ChaosBlast_Timer < diff)
+         {
+			// will cast only when in range od spell 
+			if(m_creature->GetDistance(m_creature->getVictim()) < 30)
+			{
+				//m_creature->CastSpell(m_creature->getVictim(),SPELL_CHAOS_BLAST,true);
+				int damage = 100;
+				m_creature->CastCustomSpell(m_creature->getVictim(), SPELL_CHAOS_BLAST, &damage, NULL, NULL, false, NULL, NULL, m_creature->GetGUID());  
+				ChaosBlast_Timer = 3000;
+			}
+         }else ChaosBlast_Timer -= diff;
 
         //Do NOT deal any melee damage to the target.
     }
 };
-
+struct TRINITY_DLL_DECL mob_greyheart_spellbinderAI : public ScriptedAI
+{
+	mob_greyheart_spellbinderAI(Creature *c) : ScriptedAI(c)
+    {
+		pInstance = ((ScriptedInstance *)c->GetInstanceData());;
+		leotherasGUID = 0;
+		AddedBanish = false;
+		Reset();
+	}
+
+	ScriptedInstance *pInstance;
+
+	uint64 leotherasGUID;
+
+	uint32 Mindblast_Timer;
+	uint32 Earthshock_Timer;
+
+	bool AddedBanish;
+
+	void Reset()
+	{
+		Mindblast_Timer  = 3000 + rand()%5000;
+		Earthshock_Timer = 5000 + rand()%5000;
+
+		if(pInstance)
+		{
+			pInstance->SetData64(DATA_LEOTHERAS_EVENT_STARTER, 0);
+			Creature *leotheras = (Creature *)Unit::GetUnit(*m_creature, leotherasGUID);
+			if(leotheras && leotheras->isAlive())
+				((boss_leotheras_the_blindAI*)leotheras->AI())->CheckChannelers(false);
+		}
+	}
+
+	void Aggro(Unit *who)
+	{
+		m_creature->InterruptNonMeleeSpells(false);
+		if(pInstance)
+			pInstance->SetData64(DATA_LEOTHERAS_EVENT_STARTER, who->GetGUID());
+	}
+
+	void JustRespawned()
+	{
+		InCombat = false;
+		AddedBanish = false;
+		Reset();
+	}
+
+	void CastChanneling()
+	{
+		if(!InCombat && !m_creature->m_currentSpells[CURRENT_CHANNELED_SPELL])
+		{
+			if(leotherasGUID)
+			{
+				Creature *leotheras = (Creature *)Unit::GetUnit(*m_creature, leotherasGUID);
+				if(leotheras && leotheras->isAlive())
+					DoCast(leotheras, BANISH_BEAM);
+			}
+		}
+	}	
+
+	void UpdateAI(const uint32 diff)
+	{
+		if(pInstance)
+		{	
+			if(!leotherasGUID)
+				leotherasGUID = pInstance->GetData64(DATA_LEOTHERAS);
+
+			if(!InCombat && pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
+			{
+				Unit *victim = NULL;
+				victim = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER));
+				if(victim)
+					AttackStart(victim);
+			}
+		}
+		
+		if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+		{
+			CastChanneling();
+			return;
+		}
+
+		if(pInstance && !pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
+		{
+			EnterEvadeMode();
+			return;
+		}
+
+		if(Mindblast_Timer < diff)
+		{
+			Unit* target = NULL;
+            target = SelectUnit(SELECT_TARGET_RANDOM,0);
+
+			if ( target )DoCast(target, SPELL_MINDBLAST);
+
+			Mindblast_Timer = 10000 + rand()%5000;
+		}else Mindblast_Timer -= diff;
+
+		if(Earthshock_Timer < diff)
+		{
+			Map *map = m_creature->GetMap();
+			InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers();
+			for(InstanceMap::PlayerList::const_iterator itr = PlayerList.begin();itr != PlayerList.end(); ++itr)
+            {
+				bool isCasting = false;
+				for(uint8 i = 0; i < CURRENT_MAX_SPELL; ++i)
+					if((*itr)->m_currentSpells[i])
+						isCasting = true;
+				
+				if(isCasting)
+				{
+					DoCast((*itr), SPELL_EARTHSHOCK);
+					break;
+				}
+			}
+			Earthshock_Timer = 8000 + rand()%7000;
+		}else Earthshock_Timer -= diff;
+		DoMeleeAttackIfReady();
+	}
+
+	void JustDied(Unit *killer)	{}
+};
 CreatureAI* GetAI_boss_leotheras_the_blind(Creature *_Creature)
 {
@@ -282,4 +786,13 @@
 }
 
+CreatureAI* GetAI_mob_greyheart_spellbinder(Creature *_Creature)
+{
+	return new mob_greyheart_spellbinderAI (_Creature);
+}
+
+CreatureAI* GetAI_mob_inner_demon(Creature *_Creature)
+{
+	return new mob_inner_demonAI (_Creature);
+}
 void AddSC_boss_leotheras_the_blind()
 {
@@ -295,3 +808,13 @@
     newscript->GetAI = GetAI_boss_leotheras_the_blind_demonform;
     m_scripts[nrscripts++] = newscript;
+
+	newscript = new Script;
+    newscript->Name="mob_greyheart_spellbinder";
+    newscript->GetAI = GetAI_mob_greyheart_spellbinder;
+    m_scripts[nrscripts++] = newscript;
+
+	newscript = new Script;
+    newscript->Name="mob_inner_demon";
+    newscript->GetAI = GetAI_mob_inner_demon;
+    m_scripts[nrscripts++] = newscript;
 }
Index: /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp (revision 164)
+++ /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp (revision 182)
@@ -25,5 +25,4 @@
 #include "def_serpent_shrine.h"
 #include "../../../creature/simple_ai.h"
-#include "Item.h"
 #include "Spell.h"
 
@@ -43,4 +42,5 @@
 #define SAY_DEATH                   -1548055
 
+#define SPELL_SURGE				    38044
 #define SPELL_MULTI_SHOT            38310
 #define SPELL_SHOCK_BLAST           38509
@@ -62,10 +62,11 @@
 #define SPOREBAT_O                  5.223932
 
-#define SHIED_GENERATOR_CHANNEL     19870
-#define ENCHANTED_ELEMENTAL         21958
-#define TAINTED_ELEMENTAL           22009
-#define COILFANG_STRIDER            22056
-#define COILFANG_ELITE              22055
-#define TOXIC_SPOREBAT             22140
+#define SHIED_GENERATOR_CHANNEL       19870
+#define ENCHANTED_ELEMENTAL           21958
+#define TAINTED_ELEMENTAL             22009
+#define COILFANG_STRIDER              22056
+#define COILFANG_ELITE                22055
+#define TOXIC_SPOREBAT                22140 
+#define TOXIC_SPORES_TRIGGER          22207 
 
 float ElementPos[8][4] =
@@ -81,4 +82,28 @@
 };
 
+float ElementWPPos[8][3] = 
+{
+    {71.700752, -883.905884, 41.097168},
+    {45.039848, -868.022827, 41.097015},
+    {14.585141, -867.894470, 41.097061},
+    {-25.415508, -906.737732, 41.097061},
+    {-11.801594, -963.405884, 41.097067},
+    {14.556657, -979.051514, 41.097137},
+    {43.466549, -979.406677, 41.097027},
+    {69.945908, -964.663940, 41.097054}
+};
+
+float SporebatWPPos[8][3] = 
+{
+    {31.6,-896.3,59.1},
+    {9.1, -913.9, 56},
+    {5.2, -934.4, 52.4},
+    {20.7, -946.9, 49.7},
+    {41, -941.9, 51},
+    {47.7, -927.3, 55},
+    {42.2, -912.4, 51.7},
+    {27, -905.9, 50}
+};
+
 float CoilfangElitePos[3][4] =
 {
@@ -108,6 +133,9 @@
     boss_lady_vashjAI (Creature *c) : ScriptedAI(c)
     {
-        pInstance = ((ScriptedInstance*)c->GetInstanceData());
-        Reset();
+        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
+		Intro = false;
+		Reset();
+		CanAttack = false;//must be after reset()    
+		m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); //set it only once on creature create (no need do intro if wiped)
     }
 
@@ -115,6 +143,6 @@
 
     uint64 ShieldGeneratorChannel[4];
-	uint64 AggroTargetGUID;
-
+
+	uint32 AggroTimer; 
     uint32 ShockBlast_Timer;
     uint32 Entangle_Timer;
@@ -128,14 +156,15 @@
     uint32 SummonSporebat_Timer;
     uint32 SummonSporebat_StaticTimer;
-	uint32 AggroTimer;
-
     uint8 EnchantedElemental_Pos;
     uint8 Phase;
 
     bool Entangle;
+    bool InCombat;
 	bool Intro;
+	bool CanAttack;
 
     void Reset()
     {
+		AggroTimer = 19000; 
         ShockBlast_Timer = 1+rand()%60000;
         Entangle_Timer = 30000;
@@ -151,21 +180,25 @@
         EnchantedElemental_Pos = 0;
         Phase = 0;
-		AggroTimer = 19000;
-        AggroTargetGUID = 0;
-
-		m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-        // Start off unattackable so that the intro is done properly
-        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
 
         Entangle = false;
-		Intro = false;
+        InCombat = false;
+		CanAttack = true;
+
+		Unit *remo;
+        for(uint8 i = 0; i < 4; i++)
+        {
+            remo = Unit::GetUnit(*m_creature, ShieldGeneratorChannel[i]);
+            if (remo)
+				remo->setDeathState(JUST_DIED);
+        }
 
         if(pInstance)
-            pInstance->SetData(DATA_LADYVASHJEVENT, NOT_STARTED);
-
+			pInstance->SetData(DATA_LADYVASHJEVENT, NOT_STARTED);			
         ShieldGeneratorChannel[0] = 0;
         ShieldGeneratorChannel[1] = 0;
         ShieldGeneratorChannel[2] = 0;
         ShieldGeneratorChannel[3] = 0;
+
+		m_creature->SetCorpseDelay(1000*60*60);
     }
 
@@ -177,36 +210,4 @@
             TaintedElemental_Timer = 50000;
     }
-
-	void MoveInLineOfSight(Unit *who)
-    {
-        if(!who || (!who->isAlive())) return;
-
-        if(who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
-        {
-            float attackRadius = m_creature->GetAttackDistance(who);
-
-            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
-            {
-                if(who->HasStealthAura())
-                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
-
-                m_creature->AddThreat(who, 1.0f);
-            }
-
-            if(!InCombat && !Intro && m_creature->IsWithinDistInMap(who, 40.0f) && (who->GetTypeId() == TYPEID_PLAYER))
-            {
-                if(pInstance)
-                    pInstance->SetData(DATA_LADYVASHJEVENT, IN_PROGRESS);
-
-                m_creature->GetMotionMaster()->Clear(false);
-                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-                DoScriptText(SAY_INTRO, m_creature);
-                m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK);
-                AggroTargetGUID = who->GetGUID();
-                Intro = true;
-            }
-        }
-    }
-
     void KilledUnit(Unit *victim)
     {
@@ -227,5 +228,5 @@
     }
 
-/*    void StartEvent()
+    void StartEvent()
     {
         switch(rand()%4)
@@ -237,11 +238,61 @@
         }
 
+        InCombat = true;
         Phase = 1;
 
         if(pInstance)
             pInstance->SetData(DATA_LADYVASHJEVENT, IN_PROGRESS);
-    }*/
-
-    void Aggro(Unit *who){}
+    }
+
+    void Aggro(Unit *who)
+    {
+		if (pInstance)
+		{
+			//remove old tainted cores to prevent cheating in phase 2
+			Map *map = m_creature->GetMap();
+			InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers();
+			for(InstanceMap::PlayerList::const_iterator i = PlayerList.begin();i != PlayerList.end(); ++i)
+            {
+                if((*i))
+                {
+                    (*i)->DestroyItemCount(31088, 1, true);
+                }
+            }
+		}
+        if(Phase != 2)
+            AttackStart(who);
+
+        if(!InCombat)
+            StartEvent();
+    }
+
+    void MoveInLineOfSight(Unit *who)
+    {
+		if (!Intro)
+		{
+			Intro = true;
+			DoScriptText(SAY_INTRO, m_creature);			
+		}
+		if (!CanAttack)
+			return;
+        if (!who || m_creature->getVictim())
+            return;
+
+        if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
+        {
+            float attackRadius = m_creature->GetAttackDistance(who);
+            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
+            {
+                if(who->HasStealthAura())
+                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+
+                if(Phase != 2)
+                    AttackStart(who);
+
+                if(!InCombat)
+                    StartEvent();
+            }
+        }
+    }
 
     void CastShootOrMultishot()
@@ -260,5 +311,4 @@
                 break;
         }
-
         if(rand()%3)
         {
@@ -273,45 +323,26 @@
     void UpdateAI(const uint32 diff)
     {
+		if(!CanAttack && Intro)
+		{
+			if(AggroTimer < diff)
+			{
+				CanAttack = true;
+				m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
+				AggroTimer=19000;
+			}else 
+			{
+				AggroTimer-=diff;
+				return;
+			}
+		}
         //to prevent abuses during phase 2
         if(Phase == 2 && !m_creature->getVictim() && InCombat)
 		{
-         EnterEvadeMode();
-		 return;
+			EnterEvadeMode();
+			return;
 		}
-
         //Return since we have no target
         if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
             return;
-
-		//Intro
-		if(Intro)
-        {
-            if(AggroTimer < diff)
-            {
-                m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-                m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-				switch(rand()%4)
-				{
-                    case 0: DoScriptText(SAY_AGGRO1, m_creature); break;
-                    case 1: DoScriptText(SAY_AGGRO2, m_creature); break;
-                    case 2: DoScriptText(SAY_AGGRO3, m_creature); break;
-                    case 3: DoScriptText(SAY_AGGRO4, m_creature); break;
-				}
-				Phase = 1;
-                m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
-                Intro = false;
-				//Begin melee attack if we are within range
-                if(AggroTargetGUID && Phase != 2)
-                {
-                    Unit* pUnit = Unit::GetUnit((*m_creature), AggroTargetGUID);
-                    if(pUnit)
-                    {
-                        m_creature->GetMotionMaster()->MoveChase(pUnit);
-                        AttackStart(pUnit);
-                    }
-                    DoZoneInCombat();
-                }else EnterEvadeMode();
-            }else AggroTimer -= diff;
-        }
 
         if(Phase == 1 || Phase == 3)
@@ -371,12 +402,7 @@
                     Phase = 2;
 
-                    m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                     m_creature->GetMotionMaster()->Clear();
                     m_creature->Relocate(MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
                     m_creature->SendMonsterMove(MIDDLE_X, MIDDLE_Y, MIDDLE_Z, 0, 0, 0);
-
-                    m_creature->RemoveAllAuras();
-                                                            // This needs an entry in spell_script_target
-                    DoCast(m_creature, SPELL_MAGIC_BARRIER, true);
 
                     Creature *pCreature;
@@ -387,5 +413,4 @@
                             ShieldGeneratorChannel[i] = pCreature->GetGUID();
                     }
-
                     DoScriptText(SAY_PHASE2, m_creature);
                 }
@@ -398,5 +423,5 @@
                 {
                     Creature *Sporebat = NULL;
-                    Sporebat = m_creature->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+                    Sporebat = m_creature->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_CORPSE_DESPAWN, 0);
 
                     if(Sporebat)
@@ -413,4 +438,8 @@
 
                     SummonSporebat_Timer = SummonSporebat_StaticTimer;
+
+					if(SummonSporebat_Timer < 5000)
+                        SummonSporebat_Timer = 5000;
+
                 }else SummonSporebat_Timer -= diff;
             }
@@ -466,7 +495,5 @@
             {
                 Creature *Elemental;
-                Elemental = m_creature->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElemental_Pos][0], ElementPos[EnchantedElemental_Pos][1], ElementPos[EnchantedElemental_Pos][2], ElementPos[EnchantedElemental_Pos][3], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
-                if(Elemental)
-                    Elemental->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
+                Elemental = m_creature->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElemental_Pos][0], ElementPos[EnchantedElemental_Pos][1], ElementPos[EnchantedElemental_Pos][2], ElementPos[EnchantedElemental_Pos][3], TEMPSUMMON_CORPSE_DESPAWN, 0);
 
                 if(EnchantedElemental_Pos == 7)
@@ -483,10 +510,5 @@
                 Creature *Tain_Elemental;
                 uint32 pos = rand()%8;
-                Tain_Elemental = m_creature->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
-                if(Tain_Elemental)
-                {
-                    Tain_Elemental->GetMotionMaster()->Clear();
-                    Tain_Elemental->GetMotionMaster()->MoveIdle();
-                }
+                Tain_Elemental = m_creature->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN, 0);
 
                 TaintedElemental_Timer = 120000;
@@ -496,8 +518,8 @@
             if(CoilfangElite_Timer < diff)
             {
-                Creature *CoilfangElite;
                 uint32 pos = rand()%3;
-                CoilfangElite = m_creature->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000);
-                if(CoilfangElite)
+                Creature* CoilfangElite = NULL;
+				CoilfangElite = m_creature->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+				if(CoilfangElite)
                 {
                     Unit *target = NULL;
@@ -505,7 +527,8 @@
                     if(target)
                         CoilfangElite->AI()->AttackStart(target);
+					else if(m_creature->getVictim())
+						CoilfangElite->AI()->AttackStart(m_creature->getVictim());
                 }
-
-                CoilfangElite_Timer = 45000+rand()%5000;    //wowwiki says 50 seconds, bosskillers says 45
+                CoilfangElite_Timer = 45000+rand()%5000;
             }else CoilfangElite_Timer -= diff;
 
@@ -513,8 +536,8 @@
             if(CoilfangStrider_Timer < diff)
             {
-                Creature *CoilfangStrider;
                 uint32 pos = rand()%3;
-                CoilfangStrider = m_creature->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000);
-                if(CoilfangStrider)
+				Creature* CoilfangStrider = NULL;
+				CoilfangStrider = m_creature->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+				 if(CoilfangStrider)
                 {
                     Unit *target = NULL;
@@ -522,7 +545,8 @@
                     if(target)
                         CoilfangStrider->AI()->AttackStart(target);
+					else if(m_creature->getVictim())
+						CoilfangStrider->AI()->AttackStart(m_creature->getVictim());
                 }
-
-                CoilfangStrider_Timer = 60000+rand()%10000; //wowwiki says 60 seconds, bosskillers says 60-70
+                CoilfangStrider_Timer = 60000+rand()%10000;
             }else CoilfangStrider_Timer -= diff;
 
@@ -536,5 +560,4 @@
                     m_creature->SetHealth(m_creature->GetMaxHealth()/2);
 
-                    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                     m_creature->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER);
 
@@ -551,5 +574,10 @@
     }
 };
-
+class TRINITY_DLL_DECL VashjSurgeAura : public Aura
+{
+    public:
+        VashjSurgeAura(SpellEntry *spell, uint32 eff, int32 *bp, Unit *target, Unit *caster) : Aura(spell, eff, bp, target, caster, NULL)
+            {}
+};
 //Enchanted Elemental
 //If one of them reaches Vashj he will increase her damage done by 5%.
@@ -558,55 +586,100 @@
     mob_enchanted_elementalAI(Creature *c) : ScriptedAI(c)
     {
-        pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
         Reset();
     }
 
     ScriptedInstance *pInstance;
-
-    uint32 Check_Timer;
-    uint32 Movement_Timer;
+	uint32 move;
+	uint32 phase;
+	float x, y, z;
+	Unit *Vashj;
 
     void Reset()
-    {
-        Check_Timer = 5000;
-        Movement_Timer = 500;
+    {        
+		m_creature->SetSpeed(MOVE_WALK,0.6,true);//walk
+		m_creature->SetSpeed(MOVE_RUN,0.6,true);//run
+		move = 0;
+		phase = 1;
+		Vashj = NULL;
     }
 
     void Aggro(Unit *who) { return; }
 
-    void MoveInLineOfSight(Unit *who) { return; }
-
+    void MoveInLineOfSight(Unit *who){return;}
+	
     void UpdateAI(const uint32 diff)
     {
-        //Check_Timer
-        if(Check_Timer < diff)
-        {
-            if(pInstance)
-            {
-                Unit *Vashj = NULL;
-                Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ));
-                if(Vashj)
+		if(!pInstance)
+			return;
+
+		if (!Vashj){ Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ)); }
+
+		for (int i = 0;i<8;i++)//search for nearest waypoint (up on stairs)
+		{
+			if (!x || !y || !z)
+			{
+				x = ElementWPPos[i][0];
+				y = ElementWPPos[i][1];
+				z = ElementWPPos[i][2];
+			}
+			else
+			{
+				if (m_creature->GetDistance(ElementWPPos[i][0],ElementWPPos[i][1],ElementWPPos[i][2]) < m_creature->GetDistance(x,y,z))
+				{
+					x = ElementWPPos[i][0];
+					y = ElementWPPos[i][1];
+					z = ElementWPPos[i][2];
+				}
+			}
+		}
+
+		if (!Vashj) 
+		{
+			m_creature->Say("Error Vashj not found!", LANG_UNIVERSAL, NULL);
+			return;
+		}
+
+		if(move < diff)
+        {
+			if (phase == 1)
+			{
+				m_creature->GetMotionMaster()->MovePoint(0, x, y, z);
+			}
+			if (phase == 1 && m_creature->GetDistance(x,y,z) < 0.1)
+			{
+				phase = 2;
+			}
+			if (phase == 2)
+			{
+				m_creature->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
+				phase = 3;
+			}
+			if (phase == 3)
+            {
+                m_creature->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
+                if(m_creature->GetDistance(MIDDLE_X, MIDDLE_Y, MIDDLE_Z) < 3)
                 {
-                    if(Vashj->IsWithinDistInMap(m_creature, 5))
+                    SpellEntry *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SPELL_SURGE);
+                    if( spell )
                     {
-                        //increase lady vashj damage (+5%)
-                        const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
-                        Vashj->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 5)));
-                        Vashj->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 5)));
-                        m_creature->UpdateDamagePhysical(BASE_ATTACK);
-
-                        //call Unsummon()
-                        m_creature->setDeathState(JUST_DIED);
+                        for(uint32 i = 0;i<3;i++)
+                        {
+                            if (!spell->Effect[i])
+                                continue;
+
+                            Vashj->AddAura(new VashjSurgeAura(spell, i, NULL, Vashj, Vashj));
+                        }
                     }
-                    else if(((boss_lady_vashjAI*)((Creature*)Vashj)->AI())->InCombat == false)
-                    {
-                        //call Unsummon()
-                        m_creature->setDeathState(JUST_DIED);
-                    }
+                    m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                 }
             }
-            else error_log("ERROR: Instance Data for Serpentshrine Caverns not set");
-            Check_Timer = 1000;
-        }else Check_Timer -= diff;
+			if(((boss_lady_vashjAI*)((Creature*)Vashj)->AI())->InCombat == false || ((boss_lady_vashjAI*)((Creature*)Vashj)->AI())->Phase != 2 || Vashj->isDead())
+            {
+                //call Unsummon()
+				m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+            }	
+			move = 1000;
+		}else move -= diff;      
     }
 };
@@ -618,5 +691,5 @@
     mob_tainted_elementalAI(Creature *c) : ScriptedAI(c)
     {
-        pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
         Reset();
     }
@@ -625,8 +698,10 @@
 
     uint32 PoisonBolt_Timer;
+    uint32 Despawn_Timer;
 
     void Reset()
     {
         PoisonBolt_Timer = 5000+rand()%5000;
+        Despawn_Timer = 30000;
     }
 
@@ -645,4 +720,5 @@
     void Aggro(Unit *who)
     {
+		m_creature->AddThreat(who, 0.1f);
     }
 
@@ -660,4 +736,14 @@
             PoisonBolt_Timer = 5000+rand()%5000;
         }else PoisonBolt_Timer -= diff;
+
+        //Despawn_Timer
+        if(Despawn_Timer < diff)
+        {
+            //call Unsummon()
+            m_creature->setDeathState(DEAD);
+
+            //to prevent crashes
+            Despawn_Timer = 1000;
+        }else Despawn_Timer -= diff;
     }
 };
@@ -669,41 +755,75 @@
     mob_toxic_sporebatAI(Creature *c) : ScriptedAI(c)
     {
-        pInstance = ((ScriptedInstance*)c->GetInstanceData());
-        Reset();
+        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
+        EnterEvadeMode();
     }
 
     ScriptedInstance *pInstance;
 
+	uint32 movement_timer;
     uint32 ToxicSpore_Timer;
+	uint32 bolt_timer;
     uint32 Check_Timer;
 
     void Reset()
     {
-		m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);        
-		m_creature->setFaction(14);
+		m_creature->AddUnitMovementFlag(/*MOVEMENTFLAG_ONTRANSPORT + */MOVEMENTFLAG_LEVITATING);
+        m_creature->setFaction(14);
+		movement_timer = 0;
         ToxicSpore_Timer = 5000;
+		bolt_timer = 5500;
         Check_Timer = 1000;
     }
 
-    void Aggro(Unit *who) {}
+    void Aggro(Unit *who)
+    {
+		
+    }
+
+    void MoveInLineOfSight(Unit *who)
+	{
+		
+    }
+
+	void MovementInform(uint32 type, uint32 id)
+    {
+        if(type != POINT_MOTION_TYPE)
+            return;
+
+        if(id == 1)
+			movement_timer = 0;
+	}
 
     void UpdateAI (const uint32 diff)
     {
-        //Return since we have no target
-        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
-            return;
-
-        //ToxicSpore_Timer
-        if(ToxicSpore_Timer < diff)
-        {
-            Unit *target = NULL;
-            target = SelectUnit(SELECT_TARGET_RANDOM, 0);
-
-            //The Spores will hit you anywhere in the instance: underwater, at the elevator, at the entrance, wherever.
-            if(target)
-                DoCast(target, SPELL_TOXIC_SPORES);
-
-            ToxicSpore_Timer = 20000+rand()%5000;
-        }else ToxicSpore_Timer -= diff;
+
+		/*if(!m_creature->isInCombat())
+			m_creature->SetInCombatState(false);*/
+
+		//Random movement
+        if (movement_timer < diff)
+        {
+			uint32 rndpos = rand()%8;
+			m_creature->GetMotionMaster()->MovePoint(1,SporebatWPPos[rndpos][0], SporebatWPPos[rndpos][1], SporebatWPPos[rndpos][2]);
+			movement_timer = 6000;
+		}else movement_timer -= diff;
+		
+		//toxic spores
+		if(bolt_timer < diff)
+		{
+			Unit *target = NULL;
+			target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+			if(target)
+			{
+				Creature* trig = m_creature->SummonCreature(TOXIC_SPORES_TRIGGER,target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,30000);
+				if(trig)
+				{
+					trig->setFaction(14);
+					trig->CastSpell(trig, SPELL_TOXIC_SPORES,true);
+				}
+			}
+			bolt_timer = 10000+rand()%5000;
+		}
+		else bolt_timer -= diff;
 
         //Check_Timer
@@ -715,5 +835,5 @@
                 Unit *Vashj = NULL;
                 Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ));
-                if(!Vashj || (Vashj && !Vashj->isAlive()))
+                if(!Vashj || (Vashj && !Vashj->isAlive()) || (Vashj && ((boss_lady_vashjAI*)((Creature*)Vashj)->AI())->Phase != 3))
                 {
                     //remove
@@ -726,7 +846,5 @@
             Check_Timer = 1000;
         }else Check_Timer -= diff;
-
-        DoMeleeAttackIfReady();
-    }
+	}
 };
 
@@ -749,5 +867,5 @@
 }
 
-//Coilfang Strifer
+//Coilfang Strider
 //It hits plate for about 8000 damage, has a Mind Blast spell doing about 3000 shadow damage, and a Psychic Scream Aura, which fears everybody in a 8 yard range of it every 2-3 seconds , for 5 seconds and increasing their movement speed by 150% during the fear.
 CreatureAI* GetAI_mob_coilfang_strider(Creature *_Creature)
@@ -773,19 +891,17 @@
     mob_shield_generator_channelAI(Creature *c) : ScriptedAI(c)
     {
-        pInstance = ((ScriptedInstance*)c->GetInstanceData());
+        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
         Reset();
     }
 
     ScriptedInstance *pInstance;
-
     uint32 Check_Timer;
-    bool Channeled;
-
+	bool Casted;
     void Reset()
     {
-        Check_Timer = 1000;
-        Channeled = false;
-                                                            //invisible
-        m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID , 11686);
+        Check_Timer = 0;
+		Casted = false;
+        m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID , 11686);  //invisible
+
         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
     }
@@ -800,5 +916,5 @@
             return;
 
-        if(!Channeled)
+        if(Check_Timer < diff)
         {
             Unit *Vashj = NULL;
@@ -808,9 +924,12 @@
             {
                 //start visual channel
-                m_creature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, Vashj->GetGUID());
-                m_creature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_MAGIC_BARRIER);
-                Channeled = true;
+				if (!Casted || !Vashj->HasAura(SPELL_MAGIC_BARRIER,0))
+				{
+					m_creature->CastSpell(Vashj,SPELL_MAGIC_BARRIER,true);
+					Casted = true;
+				}
             }
-        }
+			Check_Timer = 1000;
+        }else Check_Timer -= diff;
     }
 };
@@ -818,10 +937,9 @@
 bool ItemUse_item_tainted_core(Player *player, Item* _Item, SpellCastTargets const& targets)
 {
-    ScriptedInstance *pInstance = ((ScriptedInstance*)player->GetInstanceData());
+    ScriptedInstance *pInstance = (player->GetInstanceData()) ? ((ScriptedInstance*)player->GetInstanceData()) : NULL;
 
     if(!pInstance)
     {
-        player->GetSession()->SendNotification("ERROR: Instance script not initialized. Notify your administrator.");
-        error_log("ERROR: Lady Vashj Tainted Core: Instance Script Not Initialized");
+        player->GetSession()->SendNotification("Instance script not initialized");
         return true;
     }
@@ -855,5 +973,4 @@
                 default:
                     return true;
-                    break;
             }
 
@@ -870,5 +987,5 @@
             {
                 //call Unsummon()
-                Channel->setDeathState(JUST_DIED);
+                Channel->setDeathState(JUST_DIED);				
             }
 
@@ -950,2 +1067,4 @@
     m_scripts[nrscripts++] = newscript;
 }
+
+
Index: /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/def_serpent_shrine.h
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/def_serpent_shrine.h (revision 90)
+++ /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/def_serpent_shrine.h (revision 182)
@@ -24,3 +24,5 @@
 #define DATA_TIDALVESS 17
 #define DATA_FATHOMLORDKARATHRESSEVENT 18
+#define DATA_LEOTHERAS 19
+#define DATA_LEOTHERAS_EVENT_STARTER 20
 #endif
Index: /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp (revision 90)
+++ /trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp (revision 182)
@@ -17,6 +17,6 @@
 /* ScriptData
 SDName: Instance_Serpent_Shrine
-SD%Complete: 0
-SDComment: VERIFY SCRIPT
+SD%Complete: 100
+SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Serpent Shrine Scripts
 SDCategory: Coilfang Resevoir, Serpent Shrine Cavern
 EndScriptData */
@@ -47,4 +47,7 @@
     uint64 KarathressEvent_Starter;
 
+	uint64 LeotherasTheBlind;
+	uint64 LeotherasEventStarter;
+
     bool ShieldGeneratorDeactivated[4];
 
@@ -60,4 +63,7 @@
         KarathressEvent_Starter = 0;
 
+		LeotherasTheBlind = 0;
+		LeotherasEventStarter = 0;
+
         ShieldGeneratorDeactivated[0] = false;
         ShieldGeneratorDeactivated[1] = false;
@@ -81,10 +87,10 @@
         switch(creature_entry)
         {
-            case 21212: LadyVashj = creature->GetGUID(); break;
-            case 21214: Karathress = creature->GetGUID(); break;
-            case 21966: Sharkkis = creature->GetGUID(); break;
-            case 21965: Tidalvess = creature->GetGUID(); break;
-            case 21964: Caribdis = creature->GetGUID(); break;
-        }
+            case 21212: LadyVashj = creature->GetGUID();			break;
+            case 21214: Karathress = creature->GetGUID();			break;
+            case 21966: Sharkkis = creature->GetGUID();				break;
+            case 21965: Tidalvess = creature->GetGUID();			break;
+            case 21964: Caribdis = creature->GetGUID();				break;
+			case 21215:	LeotherasTheBlind = creature->GetGUID();	break;}
     }
 
@@ -92,5 +98,7 @@
     {
         if(type == DATA_KARATHRESSEVENT_STARTER)
-            KarathressEvent_Starter = data;
+			KarathressEvent_Starter = data;
+		if(type == DATA_LEOTHERAS_EVENT_STARTER)
+			LeotherasEventStarter = data;
     }
 
@@ -99,16 +107,12 @@
         switch(identifier)
         {
-            case DATA_SHARKKIS:
-                return Sharkkis;
-            case DATA_TIDALVESS:
-                return Tidalvess;
-            case DATA_CARIBDIS:
-                return Caribdis;
-            case DATA_LADYVASHJ:
-                return LadyVashj;
-            case DATA_KARATHRESS:
-                return Karathress;
-            case DATA_KARATHRESSEVENT_STARTER:
-                return KarathressEvent_Starter;
+            case DATA_SHARKKIS:					return Sharkkis;
+			case DATA_TIDALVESS:				return Tidalvess;
+            case DATA_CARIBDIS:					return Caribdis;
+            case DATA_LADYVASHJ:				return LadyVashj;
+            case DATA_KARATHRESS:				return Karathress;
+            case DATA_KARATHRESSEVENT_STARTER:	return KarathressEvent_Starter;
+			case DATA_LEOTHERAS:				return LeotherasTheBlind;
+			case DATA_LEOTHERAS_EVENT_STARTER:	return LeotherasEventStarter;
         }
         return 0;
@@ -119,26 +123,12 @@
         switch(type)
         {
-            case DATA_HYDROSSTHEUNSTABLEEVENT:
-                Encounters[0] = (data) ? true : false;
-                break;
-
-            case DATA_LEOTHERASTHEBLINDEVENT:
-                Encounters[1] = (data) ? true : false;
-                break;
-
-            case DATA_THELURKERBELOWEVENT:
-                Encounters[2] = (data) ? true : false;
-                break;
-
-            case DATA_KARATHRESSEVENT:
-                Encounters[3] = (data) ? true : false;
-                break;
-
-            case DATA_MOROGRIMTIDEWALKEREVENT:
-                Encounters[4] = (data) ? true : false;
-                break;
+            case DATA_HYDROSSTHEUNSTABLEEVENT:	Encounters[0] = data;	break;
+            case DATA_LEOTHERASTHEBLINDEVENT:	Encounters[1] = data;	break;
+            case DATA_THELURKERBELOWEVENT:		Encounters[2] = data;	break;
+            case DATA_KARATHRESSEVENT:			Encounters[3] = data;	break;
+            case DATA_MOROGRIMTIDEWALKEREVENT:	Encounters[4] = data;	break;
                 //Lady Vashj
             case DATA_LADYVASHJEVENT:
-                if(data == 0)
+                if(data == NOT_STARTED)
                 {
                     ShieldGeneratorDeactivated[0] = false;
@@ -147,23 +137,12 @@
                     ShieldGeneratorDeactivated[3] = false;
                 }
-                Encounters[5] = (data) ? true : false;
-                break;
-
-            case DATA_SHIELDGENERATOR1:
-                ShieldGeneratorDeactivated[0] = (data) ? true : false;
-                break;
-
-            case DATA_SHIELDGENERATOR2:
-                ShieldGeneratorDeactivated[1] = (data) ? true : false;
-                break;
-
-            case DATA_SHIELDGENERATOR3:
-                ShieldGeneratorDeactivated[2] = (data) ? true : false;
-                break;
-
-            case DATA_SHIELDGENERATOR4:
-                ShieldGeneratorDeactivated[3] = (data) ? true : false;
-                break;
-        }
+                Encounters[5] = data;	break;
+            case DATA_SHIELDGENERATOR1:ShieldGeneratorDeactivated[0] = (data) ? true : false;	break;
+            case DATA_SHIELDGENERATOR2:ShieldGeneratorDeactivated[1] = (data) ? true : false;	break;
+            case DATA_SHIELDGENERATOR3:ShieldGeneratorDeactivated[2] = (data) ? true : false;	break;
+            case DATA_SHIELDGENERATOR4:ShieldGeneratorDeactivated[3] = (data) ? true : false;	break;
+        }
+		if(data = DONE)
+			SaveToDB();
     }
 
@@ -172,42 +151,51 @@
         switch(type)
         {
-            case DATA_HYDROSSTHEUNSTABLEEVENT:
-                return Encounters[0];
-
-            case DATA_LEOTHERASTHEBLINDEVENT:
-                return Encounters[1];
-
-            case DATA_THELURKERBELOWEVENT:
-                return Encounters[2];
-
-            case DATA_KARATHRESSEVENT:
-                return Encounters[3];
-
-            case DATA_MOROGRIMTIDEWALKEREVENT:
-                return Encounters[4];
-
+            case DATA_HYDROSSTHEUNSTABLEEVENT:	return Encounters[0];
+            case DATA_LEOTHERASTHEBLINDEVENT:	return Encounters[1];
+            case DATA_THELURKERBELOWEVENT:		return Encounters[2];
+            case DATA_KARATHRESSEVENT:			return Encounters[3];
+            case DATA_MOROGRIMTIDEWALKEREVENT:	return Encounters[4];
                 //Lady Vashj
-            case DATA_LADYVASHJEVENT:
-                return Encounters[5];
-
-            case DATA_SHIELDGENERATOR1:
-                return ShieldGeneratorDeactivated[0];
-
-            case DATA_SHIELDGENERATOR2:
-                return ShieldGeneratorDeactivated[1];
-
-            case DATA_SHIELDGENERATOR3:
-                return ShieldGeneratorDeactivated[2];
-
-            case DATA_SHIELDGENERATOR4:
-                return ShieldGeneratorDeactivated[3];
-
+            case DATA_LADYVASHJEVENT:			return Encounters[5];
+            case DATA_SHIELDGENERATOR1:			return ShieldGeneratorDeactivated[0];
+            case DATA_SHIELDGENERATOR2:			return ShieldGeneratorDeactivated[1];
+            case DATA_SHIELDGENERATOR3:			return ShieldGeneratorDeactivated[2];
+            case DATA_SHIELDGENERATOR4:			return ShieldGeneratorDeactivated[3];
             case DATA_CANSTARTPHASE3:
-                if(ShieldGeneratorDeactivated[0] && ShieldGeneratorDeactivated[1] && ShieldGeneratorDeactivated[2] && ShieldGeneratorDeactivated[3])
-                    return 1;
-                break;
-        }
-
+				if(ShieldGeneratorDeactivated[0] && ShieldGeneratorDeactivated[1] && ShieldGeneratorDeactivated[2] && ShieldGeneratorDeactivated[3])return 1;break;
+        }
         return 0;
+    }
+	const char* Save()
+	{
+		OUT_SAVE_INST_DATA;
+        std::ostringstream stream;
+        stream << Encounters[0] << " " << Encounters[1] << " " << Encounters[2] << " "
+            << Encounters[3] << " " << Encounters[4] << " " << Encounters[5];
+        char* out = new char[stream.str().length() + 1];
+        strcpy(out, stream.str().c_str());
+        if(out)
+        {
+            OUT_SAVE_INST_DATA_COMPLETE;
+            return out;
+        }
+        return NULL;
+    }
+
+    void Load(const char* in)
+    {
+        if(!in)
+        {
+            OUT_LOAD_INST_DATA_FAIL;
+            return;
+        }
+        OUT_LOAD_INST_DATA(in);
+        std::istringstream stream(in);
+        stream >> Encounters[0] >> Encounters[1] >> Encounters[2] >> Encounters[3]
+		>> Encounters[4] >> Encounters[5];
+		for(uint8 i = 0; i < ENCOUNTERS; ++i)
+			if(Encounters[i] == IN_PROGRESS)                // Do not load an encounter as "In Progress" - reset it instead.
+				Encounters[i] = NOT_STARTED;
+		OUT_LOAD_INST_DATA_COMPLETE;
     }
 };
Index: /trunk/sql/updates/190_world_scripts.sql
===================================================================
--- /trunk/sql/updates/190_world_scripts.sql (revision 182)
+++ /trunk/sql/updates/190_world_scripts.sql (revision 182)
@@ -0,0 +1,7 @@
+UPDATE creature_template SET ScriptName = 'boss_leotheras_the_blind' WHERE entry = '21215';
+UPDATE creature_template SET ScriptName = 'boss_leotheras_the_blind_demonform' WHERE entry = '21875';
+UPDATE creature_template SET ScriptName = 'mob_greyheart_spellbinder' WHERE entry = '21806';
+UPDATE creature_template SET ScriptName = 'mob_inner_demon' WHERE entry = '21857';
+
+UPDATE creature_template SET ScriptName = 'mob_toxic_sporebat', speed = '1' WHERE entry = '22140';
+UPDATE creature_template SET modelid_A = '11686', modelid_H = '11686', flags_extra = '128' WHERE entry = '22207';
