All pastes #939645 Raw Edit

coreai

public text v1 · immutable
·published 2008-03-12 13:53 UTC
rendered paste body
Index: src/framework/Platform/Define.h
===================================================================
--- src/framework/Platform/Define.h	(revision 4763)
+++ src/framework/Platform/Define.h	(working copy)
@@ -31,6 +31,7 @@
 #define MANGOS_IMPORT __cdecl
 #define MANGOS_SCRIPT_EXT ".dll"
 #define MANGOS_SCRIPT_NAME "MaNGOSScript"
+#define MANGOS_TIER_SCRIPT_NAME "Script"
 #define SIGQUIT 3
 #else
 #define MANGOS_LIBRARY_HANDLE void*
Index: src/game/AggressorAI.cpp
===================================================================
--- src/game/AggressorAI.cpp	(revision 4763)
+++ src/game/AggressorAI.cpp	(working copy)
@@ -28,129 +28,197 @@
 
 #include <list>
 
-int
-AggressorAI::Permissible(const Creature *creature)
+int AggressorAI::Permissible(const Creature *creature)
 {
     // have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight
-    if( !creature->isCivilian() && !creature->IsNeutralToAll() )
+    if( !creature->isCivilian() && !creature->IsNeutralToAll() && !creature->m_creatureSpellBook )
         return PERMIT_BASE_PROACTIVE;
 
     return PERMIT_BASE_NO;
 }
 
-AggressorAI::AggressorAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
+AggressorAI::AggressorAI(Creature &c) : i_creature(c), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
 {
 }
 
-void
-AggressorAI::MoveInLineOfSight(Unit *u)
+void AggressorAI::MoveInLineOfSight(Unit *who)
 {
-    if( !i_creature.getVictim() && !i_creature.hasUnitState(UNIT_STAT_STUNDED) && u->isTargetableForAttack() &&
-        ( i_creature.IsHostileTo( u ) /*|| u->getVictim() && i_creature.IsFriendlyTo( u->getVictim() )*/ ) &&
-        u->isInAccessablePlaceFor(&i_creature) )
+    //Planning something to get Rid of all Z check like that will be great since it wrong, GS 
+    if( !i_creature.HasPathTo(who) ) 
+        return;
+
+    if( !i_creature.GetUInt64Value(UNIT_FIELD_TARGET) )
     {
-        float attackRadius = i_creature.GetAttackDistance(u);
-        if(i_creature.IsWithinDistInMap(u, attackRadius) && i_creature.GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE)
+        //MoveInLineOfSight Normal
+        if( i_creature.IsHostileTo(who) && who->isInAccessablePlaceFor(&i_creature) )
         {
-            if(!i_creature.IsWithinLOSInMap(u)) return;
-            AttackStart(u);
-            u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+            float _attackRadius = i_creature.GetAttackDistance(who);
+            // Without AggroRate will be much Better and I Sugest we remove
+            if( i_creature.IsWithinDistInMap(who, _attackRadius) )
+            {
+                if(!i_creature.IsWithinLOSInMap(who))
+                    return;
+
+                if( who->HasStealthAura() )
+                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+                selectedAttackRadius = _attackRadius;
+                AttackStart(who);
+                AIMotionTarget(who,FOLLOW_RANGE_MELEE);
+            }
+            //RunAway In Fear, TODO: Check for Attacker List if not empty and we are not in, Stop That and Attack
+            //_attackRadius + RUNAWAY_AGGRO_RANGE, More you put more creature has chance to runaway and from far
+            //_attackRadius <= irand(5,10) , from witch player they runaway... i use same system as aggrorange
+            else if( _attackRadius <= irand(0,10) 
+                     && who->GetTypeId() == TYPEID_PLAYER 
+                     && i_creature.IsWithinDistInMap(who, _attackRadius + RUNAWAY_AGGRO_RANGE) 
+                     && !i_creature.HasAura(CREATURE_SPELL_RUNAWAY,0) )
+            {
+                    float X,Y,Z;
+                    i_creature.GetRespawnCoord(X,Y,Z);
+                    selectedAttackRadius = _attackRadius;
+                    if(who->GetDistance2d(X,Y) < RANGE_MAX_AUTO_FEAR)
+                        i_creature.CastSpell( (Unit*)&i_creature, CREATURE_SPELL_RUNAWAY, false ,NULL,NULL, who->GetGUID());
+            }
+            return;
         }
+        //MoveInLineOfSight Friendly
+        //TODO: hasHealer must be gone away and m_assistance, redesing, GS
+        if( i_creature.IsWithinDistInMap(who,RANGE_AUTO_ASSIST ) && i_creature.IsFriendlyTo(who) && !who->m_hasHealer ) //!irand(0,20) , can be used for Strongnest Adjustement, less Chance more easy
+        {
+            if(!i_creature.IsWithinLOSInMap(who))
+                return;
+
+            //TODO: make it with IsInCombat() + Take target from AttackerList.
+            Unit *victimTarget = who->getVictim();
+            if( who->getVictim() )
+            {   
+                if( i_creature.IsHostileTo(victimTarget) )
+                {
+                    AttackStart( victimTarget );
+                    AIMotionTarget(victimTarget,FOLLOW_RANGE_MELEE);
+                    //That is Ugly, i think i can obtain my status into another check with a Operator Overload
+                    //So temporary i will let it there.
+                    if( who->GetTypeId() == TYPEID_UNIT && ((Creature*)who)->m_AssistenceStatus->requested )
+                        ((Creature*)who)->m_AssistenceStatus->obtained = true;
+                }
+            }
+        }
     }
 }
 
 void AggressorAI::EnterEvadeMode()
 {
-    if( !i_creature.isAlive() )
-    {
-        DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow());
-        i_victimGuid = 0;
-        i_creature.CombatStop(true);
-        i_creature.DeleteThreatList();
+    lastAction = getMSTime()+30000;
+    i_creature.m_AssistenceStatus->reset(); //TODO: fix that scruct, at least make it proctected
+    if( !i_creature.isCharmed() )
+        i_creature.RemoveAllAuras();
+    i_creature.DeleteThreatList();
+    i_creature.CombatStop(true);
+}
+
+void AggressorAI::UpdateAI(const uint32 /*diff*/)
+{
+    if( i_creature.isDead() || i_creature.hasUnitState( UNIT_STAT_FLEEING ) )
         return;
-    }
 
-    Unit* victim = ObjectAccessor::Instance().GetUnit(i_creature, i_victimGuid );
-
-    if( !victim  )
-    {
-        DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
+    //RunAway At friend
+    //Unit::getHpPercent(&i_creature)+irand(10,20), can really change the Strongest.
+    if( !i_creature.hasUnitState( UNIT_STAT_ROOT ) && selectedAttackRadius <= irand(0,40) && i_creature.getVictim() && Unit::getHpPercent(&i_creature)+irand(10,20) < Unit::getHpPercent(i_creature.getVictim()) )
+    {    
+        //i_creature.getVictim()->getAttackers().size() < 3 , can radicaly change the Strongest
+        if( !i_creature.m_AssistenceStatus->requested && i_creature.getVictim()->getAttackers().size() < 2)
+        {
+           i_creature.CastSpell( (Unit*)&i_creature, CREATURE_SPELL_TAP_FRIEND, false );
+           i_creature.m_AssistenceStatus->requested = true;
+           return;
+        }
+        //Check spell http://www.wowhead.com/?spell=32126, who is Flee Combat Much More Better, and keep fear when no combat
+        else if(i_creature.m_AssistenceStatus->obtained = false && Unit::getHpPercent(&i_creature) < irand(7,14) )
+            i_creature.CastSpell( (Unit*)&i_creature, CREATURE_SPELL_RUNAWAY, false ,NULL,NULL, i_creature.GetUInt64Value(UNIT_FIELD_TARGET));    
     }
-    else if( !victim->isAlive() )
+    
+    if( i_creature.SelectHostilTarget() && i_creature.getVictim() && i_creature.isAttackReady() && i_creature.IsWithinDistInMap(i_creature.getVictim(), i_creature.GetFloatValue(UNIT_FIELD_COMBATREACH)) )
     {
-        DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", i_creature.GetGUIDLow());
+        //TODO:Add a Chance To win and Go to Friend.
+        i_creature.AttackerStateUpdate(i_creature.getVictim());
+        i_creature.resetAttackTimer();
+        lastAction = getMSTime();
     }
-    else if( victim->HasStealthAura() )
-    {
-        DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow());
-    }
-    else if( victim->isInFlight() )
-    {
-        DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow());
-    }
-    else
-    {
-        DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", i_creature.GetGUIDLow());
-        //i_state = STATE_LOOK_AT_VICTIM;
-        //i_tracker.Reset(TIME_INTERVAL_LOOK);
-    }
 
-    if(!i_creature.isCharmed())
+    //Wait Time Reset Action Selected, TODO: Change that to put more dynamic action at different timer.
+    //A text Chat can be done there, will be cool.
+    //Do search on wowhead for Gossip before any chat text system.
+    if(lastAction+irand(5000*CREATURE_WAIT_RATE,7000*CREATURE_WAIT_RATE) < getMSTime() )
     {
-        i_creature.RemoveAllAuras();
+        i_creature.m_AssistenceStatus->reset();
 
-        // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
-        if( i_creature.GetMotionMaster()->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE )
-            i_creature.GetMotionMaster()->TargetedHome();
+        i_creature.SelectHostilTarget();
+
+        lastAction = getMSTime();
     }
+}
 
-    i_creature.DeleteThreatList();
-    i_victimGuid = 0;
-    i_creature.CombatStop(true);
-
+bool AggressorAI::IsVisible(Unit *pl) const
+{
+    return i_creature.GetDistanceSq(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
+        && pl->isVisibleForOrDetect(&i_creature,true);
 }
 
-void
-AggressorAI::UpdateAI(const uint32 /*diff*/)
+void AggressorAI::AttackStart(Unit *unit)
 {
-    // update i_victimGuid if i_creature.getVictim() !=0 and changed
-    if(!i_creature.SelectHostilTarget() || !i_creature.getVictim())
+    if( !unit )
         return;
 
-    i_victimGuid = i_creature.getVictim()->GetGUID();
-
-    if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE))
+    if( unit->isTargetableForAttack() /*&& attacker!= m_creature, That should not happen*/ )
     {
-        if( i_creature.isAttackReady() )
+        if ( i_creature.Attack(unit) )
         {
-            i_creature.AttackerStateUpdate(i_creature.getVictim());
+            i_creature.AddThreat(unit, 0.0f);
             i_creature.resetAttackTimer();
+            
+            if (unit->GetTypeId() == TYPEID_PLAYER)
+                i_creature.SetLootRecipient((Player*)unit);
+            selectedAttackRadius = i_creature.GetAttackDistance(unit);
+            AIMotionTarget(unit,FOLLOW_RANGE_MELEE);
+
+            return;
         }
     }
 }
 
-bool
-AggressorAI::IsVisible(Unit *pl) const
+void AggressorAI::AIMotionTarget(Unit* target, float offSet)
 {
-    return i_creature.GetDistanceSq(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
-        && pl->isVisibleForOrDetect(&i_creature,true);
-}
+    bool exist = false;
+    MotionMaster* creatureMM = i_creature.GetMotionMaster();
 
-void
-AggressorAI::AttackStart(Unit *u)
-{
-    if( !u )
-        return;
+    if(!target /*&& creatureMM->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE*/)
+    {
+        //creatureMM->MovementExpired();
+        return;    
+    }
+    //Here is wrong... TODO fix angle... but in fact i wan MV for Follower and One for Attacker.
+    float angle = NULL;
+    if( !i_creature.IsHostileTo(target) )
+    {
+        angle = target->GetOrientation()*2.0f;
+    }
 
-    if(i_creature.Attack(u))
+    if(creatureMM->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE)
     {
-        i_creature.AddThreat(u, 0.0f);
-        //    DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow());
-        i_victimGuid = u->GetGUID();
-
-        i_creature.resetAttackTimer();
-        i_creature.GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*u));
-        if (u->GetTypeId() == TYPEID_PLAYER)
-            i_creature.SetLootRecipient((Player*)u);
+        TargetedMovementGenerator<Creature>* targetMV = static_cast<TargetedMovementGenerator<Creature>*> (creatureMM->top());
+        if( targetMV && targetMV->GetTarget() )
+        {
+            if( targetMV->GetTarget()->GetGUID() != target->GetGUID() )
+            {
+                creatureMM->MovementExpired(false);
+                creatureMM->Mutate(new TargetedMovementGenerator<Creature>(*target,offSet,angle));
+            }
+            else if(targetMV->GetOffSet() != offSet)
+                targetMV->SetOffSet(offSet);
+        }
     }
+    else
+    { 
+        i_creature.GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*target,offSet,angle));
+    }
 }
Index: src/game/AggressorAI.h
===================================================================
--- src/game/AggressorAI.h	(revision 4763)
+++ src/game/AggressorAI.h	(working copy)
@@ -45,8 +45,10 @@
         static int Permissible(const Creature *);
 
     private:
+        void AIMotionTarget(Unit* target, float offSet);
         Creature &i_creature;
-        uint64 i_victimGuid;
+        uint32 lastAction;
+        float selectedAttackRadius;
         AggressorState i_state;
         TimeTracker i_tracker;
 };
Index: src/game/AggressorCasterAI.cpp
===================================================================
--- src/game/AggressorCasterAI.cpp	(revision 0)
+++ src/game/AggressorCasterAI.cpp	(revision 0)
@@ -0,0 +1,792 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "AggressorCasterAI.h"
+#include "Errors.h"
+#include "Creature.h"
+#include "Player.h"
+#include "TargetedMovementGenerator.h"
+#include "ConfusedMovementGenerator.h"
+#include "RandomMovementGenerator.h"
+#include "HomeMovementGenerator.h"
+#include "Database/DBCStores.h"
+#include "ObjectAccessor.h"
+#include "VMapFactory.h"
+#include "World.h"
+
+#include <list>
+
+int AggressorCasterAI::Permissible(const Creature *creature)
+{
+    // have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight
+    if( !creature->isCivilian() && !creature->IsNeutralToAll() && creature->m_creatureSpellBook )
+        return PERMIT_BASE_PROACTIVE;
+
+    return PERMIT_BASE_NO;
+}
+
+AggressorCasterAI::AggressorCasterAI(Creature &c) : spellCasting(new CreatureSpellCasting(c.m_creatureSpellBook)),
+i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK),
+selectedAttackRadius(100.0f),lastAction(0) {}
+
+void AggressorCasterAI::MoveInLineOfSight(Unit *who)
+{
+    //Planning something to get Rid of all Z check like that will be great since it wrong, GS 
+    if( !i_creature.HasPathTo(who) ) 
+        return;
+
+    if( !i_creature.GetUInt64Value(UNIT_FIELD_TARGET) )
+    {
+        //MoveInLineOfSight Normal
+        if( i_creature.IsHostileTo(who) && who->isInAccessablePlaceFor(&i_creature) )
+        {
+            float _attackRadius = i_creature.GetAttackDistance(who);
+            // Without AggroRate will be much Better and I Sugest we remove
+            if( i_creature.IsWithinDistInMap(who, _attackRadius) )
+            {
+                if(!i_creature.IsWithinLOSInMap(who))
+                    return;
+
+                if( who->HasStealthAura() )
+                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+                AttackStart(who);
+                selectedAttackRadius = _attackRadius;
+                if(i_creature.m_creatureSpellBook)
+                    AIMotionTarget(who,FOLLOW_RANGE_CASTER);
+                else
+                    AIMotionTarget(who,FOLLOW_RANGE_MELEE);
+            }
+            //RunAway In Fear, TODO: Check for Attacker List if not empty and we are not in, Stop That and Attack
+            else if( _attackRadius <= irand(0,10) 
+                     && who->GetTypeId() == TYPEID_PLAYER 
+                     && i_creature.IsWithinDistInMap(who, _attackRadius + RUNAWAY_AGGRO_RANGE) 
+                     && !i_creature.HasAura(CREATURE_SPELL_RUNAWAY,0) )
+            {
+                    
+                float X,Y,Z;
+                i_creature.GetRespawnCoord(X,Y,Z);
+                selectedAttackRadius = _attackRadius;
+                if(who->GetDistance2d(X,Y) < RANGE_MAX_AUTO_FEAR)
+                i_creature.CastSpell( (Unit*)&i_creature, CREATURE_SPELL_RUNAWAY, false ,NULL,NULL, who->GetGUID());
+            }
+            return; //Maybe put dynamic Cast on enemy here.
+        }
+        //MoveInLineOfSight Friendly
+        if( i_creature.IsWithinDistInMap(who,RANGE_AUTO_ASSIST ) && i_creature.IsFriendlyTo(who) && ( !who->m_hasHealer || !irand(0,20) ) ) //!irand(0,20) , can be used for Strongnest Adjustement, less Chance more easy
+        {
+            if(!i_creature.IsWithinLOSInMap(who))
+                return;
+
+            //TODO: make it with IsInCombat() + Take target from AttackerList.
+            Unit *victimTarget = who->getVictim();
+            if( who->getVictim() )
+            {   
+                if( i_creature.IsHostileTo(victimTarget) )
+                {
+                    if( spellCasting->spellBook && spellCasting->spellBook->hasHealing() && Unit::getMpPercent(&i_creature) > 10 )
+                    {
+                        i_creature.SetUInt64Value( UNIT_FIELD_TARGET, who->GetGUID() );
+                        who->m_hasHealer = true;
+                        if(i_creature.m_creatureSpellBook)
+                            AIMotionTarget(who,FOLLOW_RANGE_CASTER);
+                        else
+                            AIMotionTarget(who,FOLLOW_RANGE_MELEE);
+                        AISelectSpell( spellCasting );
+                    }
+                    else
+                    {
+                        AttackStart( victimTarget );
+                        if(i_creature.m_creatureSpellBook)
+                            AIMotionTarget(victimTarget,FOLLOW_RANGE_CASTER);
+                        else
+                            AIMotionTarget(victimTarget,FOLLOW_RANGE_MELEE);
+                    }
+                    //That is Ugly, i think i can obtain my status into another check with a Operator Overload
+                    //So temporary i will let it there.
+                    if( who->GetTypeId() == TYPEID_UNIT && ((Creature*)who)->m_AssistenceStatus->requested )
+                        ((Creature*)who)->m_AssistenceStatus->obtained = true;
+                }
+            }
+            else if(spellCasting->spellBook && Unit::getHpPercent(who) < 100 ) //Target is IDLE Around we Heal Of Buff if we can
+                AISelectSpell( spellCasting, who );
+        }
+    }
+
+    //That has fucking too much check, must found the fastes way to dynamic heal... 
+    //We are probaly doing something, event if, we try to do something on a dynamic target
+    if( i_creature.IsWithinDistInMap(who, RANGE_DYNAMIC_ASSIST ) && i_creature.IsFriendlyTo(who) )
+    {
+        if(!i_creature.IsWithinLOSInMap(who))
+            return;
+
+        if( who->getVictim() && i_creature.IsFriendlyTo(who->getVictim()))
+            return;
+        else if( Unit::getHpPercent(who) < 100 && spellCasting->spellBook 
+                 && spellCasting->spellBook->hasHealing() 
+                 && Unit::getMpPercent(&i_creature) > 10 && !irand(0,10))
+        {    
+            if( spellCasting->spellIndex > -1 )
+            {    
+                if( !spellCasting->reached ) //We cancel Current spell Only if not allready into casting Timer
+                    spellCasting->reset();
+                else
+                    return;
+            }
+            AISelectSpell( spellCasting, who );
+            return;
+        }
+    }
+    //TODO:Dynamic cast on Enemy should not be needed ... but will test to see result.
+}
+void AggressorCasterAI::EnterEvadeMode()
+{
+    spellCasting->reset(true);
+    lastAction = getMSTime()+30000;
+    i_creature.m_AssistenceStatus->reset(); //TODO: fix that scruct, at least make it proctected
+    if( !i_creature.isCharmed() )
+        i_creature.RemoveAllAuras();
+    i_creature.DeleteThreatList();
+    i_victimGuid = 0;
+    i_creature.CombatStop(true);
+}
+void AggressorCasterAI::UpdateAI(const uint32 diff)
+{
+    if( i_creature.isDead() || i_creature.hasUnitState( UNIT_STAT_FLEEING ) )
+        return;
+
+    //RunAway At friend
+    if( !i_creature.hasUnitState( UNIT_STAT_ROOT ) && selectedAttackRadius <= irand(0,40) && i_creature.getVictim() && Unit::getHpPercent(&i_creature)+irand(1,20) < Unit::getHpPercent(i_creature.getVictim()) )
+    {    
+        if( !i_creature.m_AssistenceStatus->requested )
+        {
+           i_creature.CastSpell( (Unit*)&i_creature, CREATURE_SPELL_TAP_FRIEND, false );
+           i_creature.m_AssistenceStatus->requested = true;
+           return;
+        }
+        //Check spell http://www.wowhead.com/?spell=32126, who is Flee Combat Much More Better, and keep fear when no combat
+        else if(i_creature.m_AssistenceStatus->obtained = false && Unit::getHpPercent(&i_creature) < irand(7,14) )
+            i_creature.CastSpell( (Unit*)&i_creature, CREATURE_SPELL_RUNAWAY, false ,NULL,NULL, i_creature.GetUInt64Value(UNIT_FIELD_TARGET));    
+    }
+
+    //Spell Casting
+    //Check spell: http://www.wowhead.com/?spell=39258 
+    //root spell should be putted by AICast() and Aura Time Controled with the Spell Timer we gonna cast
+    // so 1 check in less into MV for Spellcasting for Monster, Much more better
+    //All this will go Into Spellcasting Scructure or will become a class with self update at the end.
+    //remember
+    if(spellCasting->spellIndex > -1)
+    {    
+        //Dynamic Target Check, In Fact is too be sure we don't change target or move during action on Dynamic target
+        //Procedure where made fast and will be need to be symplifie for better reading.
+        Unit *target = i_creature.GetUnit( i_creature,i_creature.GetUInt64Value(UNIT_FIELD_TARGET) );
+        Unit *spellTarget = NULL;
+
+        if( spellCasting->targetGUID != i_creature.GetGUID() )
+            spellTarget = i_creature.GetUnit(i_creature,spellCasting->targetGUID );
+        else
+           spellTarget = ((Unit*)&i_creature);
+
+        bool dynamicTarget = false;
+        if(spellCasting->targetGUID != i_creature.GetGUID() && spellCasting->targetGUID != i_creature.GetUInt64Value(UNIT_FIELD_TARGET))
+            dynamicTarget = true;
+
+        if(spellTarget)
+        {
+            if( !spellCasting->reached )
+            {
+                if(dynamicTarget)
+                {
+                    if( i_creature.IsWithinDistInMap(spellTarget, spellCasting->range) )
+                        spellCasting->reached = true;
+                    else
+                    {
+                        spellCasting->reset();
+                        return;
+                    }  
+                }
+                else
+                {
+                    if( spellTarget->GetGUID() == i_creature.GetGUID() || i_creature.IsWithinDistInMap(spellTarget, spellCasting->range) )
+                        spellCasting->reached = true;
+                    else
+                    {
+                        spellCasting->runningTimer += diff;
+                        if(spellCasting->runningTimer > irand(500*CREATURE_WAIT_REACH_RATE,1000*CREATURE_WAIT_REACH_RATE) )
+                        {
+                            //need Speed To reach target, so we cancel Current Spell and try Speed Up.
+                            //DoDoSay("Too Long To Reach Target, IsStopped:%u ",i_creature.IsStopped());
+                            spellCasting->runningTimer = 0;
+                            spellCasting->reset();
+                            
+                            //Not check spellBook since we are here mean she go one for sure... But Maybe i forget something
+                            if( i_creature.m_creatureSpellBook->hasSpeed() && !i_creature.hasUnitState( UNIT_STAT_ROOT ) )
+                            {
+                                spellCasting->reset();
+                                AISelectSpell(spellCasting, spellTarget, SELECTSPELL_SPEED);
+                                return;
+                            }
+                            //TODO:
+                            //Else If CreatureSpeed < TargetSpeed , Chance To Cast Combat OUT Spell.
+                        }
+                        //return;
+                    }
+                }  
+            }
+            if( spellCasting->reached )
+            {
+                if(!spellCasting->started)
+                {
+                    //Aura Control for Root or we can get conflit with spellRoot and unroot before time after casting
+                    if(!i_creature.hasUnitState(UNIT_STAT_ROOT) && spellCasting->spellBook->info[spellCasting->spellIndex].hasCastTime)
+                    {    
+                        //i_creature.SendMonsterMove(i_creature.GetPositionX(),i_creature.GetPositionY(),i_creature.GetPositionZ(),0,true,0);
+                        //i_creature.Relocate(i_creature.GetPositionX(),i_creature.GetPositionY(),i_creature.GetPositionZ());
+                        i_creature.addUnitState(UNIT_STAT_ROOT);
+                        i_creature.StopMoving();
+                    }
+                    AICast(spellCasting);
+                    lastAction = getMSTime();
+                    return;
+                }
+                //Spell Finish
+                else if( i_creature.m_currentSpells[CURRENT_GENERIC_SPELL] ) 
+                {
+                    if( !i_creature.HasSpellChannelActiveTimer() )
+                    {
+                        //TODO: Change Offset after a spell so we look more alive.
+                        //if(!dynamicTarget && target && target->isAlive() && i_creature.hasUnitState(UNIT_STAT_FOLLOW))
+                            //AIMotionTarget(target, rand_norm()*(spellCasting->range));
+                        if(!i_creature.HasAuraType(SPELL_AURA_MOD_ROOT))
+                            i_creature.clearUnitState(UNIT_STAT_ROOT);
+                        spellCasting->reset();
+                    }
+                    return;
+                }
+                else
+                {
+                    i_creature.clearUnitState(UNIT_STAT_ROOT);
+                    spellCasting->reset();
+                    //if(!dynamicTarget && target && target->isAlive() && i_creature.hasUnitState(UNIT_STAT_FOLLOW))
+                        //AIMotionTarget(target);
+                    return;
+                }
+            }
+        }
+        else if(dynamicTarget)      //Bad dynamicTarget Target 
+        {
+            if(!spellCasting->reached)
+                spellCasting->reset();
+        }
+        else                        //Bad Target
+        {
+            if(!spellCasting->reached)
+                spellCasting->reset(true);
+        }
+        //return;
+    }
+
+    //Melee Attack
+    //AICheckFriendTarget(), TODO:remove that from here.... My probleme is the Threath List will remove friend target
+    if( /*!AICheckFriendTarget()*/i_creature.SelectHostilTarget() && i_creature.getVictim() /*&& AICheckVictimTarget()*/ && i_creature.isAttackReady() && i_creature.IsWithinDistInMap(i_creature.getVictim(), i_creature.GetFloatValue(UNIT_FIELD_COMBATREACH)) )
+    {
+        if(i_creature.getVictim()->HasSpellChannelActiveTimer() && i_creature.m_creatureSpellBook && i_creature.m_creatureSpellBook->hasInterrupt())
+        {
+            spellCasting->reset(); //TODO:Check we are casting or not before reset.
+            AISelectSpell( spellCasting,  i_creature.getVictim(), SELECTSPELL_INTERRUPT);
+            return;
+        }
+        //Add a Chance To win and Go to Friend.
+        
+        i_creature.AttackerStateUpdate(i_creature.getVictim());
+        i_creature.resetAttackTimer();
+        lastAction = getMSTime();
+
+    }
+
+    //Choses a Spell To Cast
+    if( spellCasting->spellIndex < 0 && i_creature.GetUInt64Value(UNIT_FIELD_TARGET) )
+        AISelectSpell( spellCasting );
+    
+    //Wait Time Reset Action Selected, TODO: Change that to put more dynamic action at different timer.
+    //A text Chant can be done there, will be cool.
+    if(lastAction+irand(5000*CREATURE_WAIT_RATE,7000*CREATURE_WAIT_RATE) < getMSTime() )
+    {
+        i_creature.m_AssistenceStatus->reset();
+        if( spellCasting->spellIndex > -1 )
+        {
+            if( !spellCasting->reached )
+                spellCasting->reset();
+            else
+                return;
+        }
+
+        if( AICheckFriendTarget() )
+        {
+            Unit* friendTarget = i_creature.GetUnit(i_creature, i_creature.GetUInt64Value(UNIT_FIELD_TARGET));
+            if( friendTarget && friendTarget->getVictim() )
+            {
+                AISelectSpell(spellCasting,friendTarget->getVictim());
+            }
+            else if(friendTarget && Unit::getHpPercent(friendTarget) > irand(90,99))
+            {
+                friendTarget->m_hasHealer = false;
+                i_creature.SelectHostilTarget();         
+            }
+        }
+        else
+            i_creature.SelectHostilTarget();
+
+        lastAction = getMSTime();
+    }
+}
+void AggressorCasterAI::DamageTaken(Unit *done_by, uint32 &damage)
+{
+    // Should be Replaced with better Idea...., GS
+    // Make a helper Attack the Persone is attacking him, so next tick he will be a attacker.
+    if( !i_creature.getVictim() && Unit::getHpPercent(&i_creature) < irand(80,99) )
+    {
+       i_creature.SetUInt64Value(UNIT_FIELD_TARGET,0);
+       MoveInLineOfSight(done_by);
+    }
+}
+void AggressorCasterAI::JustDie()
+{
+    // a healer should never ne target by a healer so, else case should be good
+    // More work needed on Healer selection, must be simple and not flood same target for healing purpose, GS
+    if( AICheckFriendTarget() ) 
+    {    
+        Unit* friendTarget = i_creature.GetUnit(i_creature, i_creature.GetUInt64Value(UNIT_FIELD_TARGET));    
+        friendTarget->m_hasHealer = false;
+    }
+
+}
+bool AggressorCasterAI::IsVisible(Unit *pl) const
+{
+    return i_creature.GetDistanceSq(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
+        && pl->isVisibleForOrDetect(&i_creature,true);
+}
+
+void AggressorCasterAI::AttackStart(Unit *unit)
+{
+    if( !unit )
+        return;
+
+    // AICheckFriendTarget() should not appear here, Must be Checked to be sure she never needed here.
+    if( AICheckFriendTarget() && Unit::getHpPercent(unit) > Unit::getHpPercent(&i_creature)+20 )
+    {
+        i_creature.AddThreat(unit, 0.0f); //target can come from threat, should put at better place
+        return;
+    }
+
+    if( unit->isTargetableForAttack() /*&& attacker!= m_creature, That should not happen*/ )
+    {
+        if ( i_creature.Attack(unit) )
+        {
+            i_creature.AddThreat(unit, 0.0f);
+            i_creature.resetAttackTimer();
+            if (unit->GetTypeId() == TYPEID_PLAYER)
+                i_creature.SetLootRecipient((Player*)unit);
+            selectedAttackRadius = i_creature.GetAttackDistance(unit);
+            if(i_creature.m_creatureSpellBook)
+                AIMotionTarget(unit,FOLLOW_RANGE_CASTER);
+            else
+                AIMotionTarget(unit,FOLLOW_RANGE_MELEE);
+            return;
+        }
+    }
+}
+void AggressorCasterAI::AISelectSpell(CreatureSpellCasting *spellCasting, Unit *dynamicTarget, uint8 specialCase)
+{
+    uint16 chosenSpellId;
+    std::list<uint8> spellIndexFound;
+
+    spellIndexFound.clear();
+
+    if(spellCasting->spellIndex > -1 || !spellCasting->spellBook || i_creature.HasSpellCooldown() )
+        return;
+
+    Unit *enemyTarget = NULL;
+    Unit *friendTarget = NULL;
+    if(dynamicTarget)
+    {
+        if(i_creature.IsHostileTo(dynamicTarget))
+            enemyTarget = dynamicTarget;
+        else
+            friendTarget = dynamicTarget;  
+    }
+    else if(AICheckFriendTarget())
+        friendTarget = i_creature.GetUnit(*&i_creature, i_creature.GetUInt64Value(UNIT_FIELD_TARGET));
+    else if(AICheckVictimTarget())
+        enemyTarget = i_creature.getVictim();
+        
+    switch( specialCase )
+    {
+        case SELECTSPELL_NONE:
+            break;
+        case SELECTSPELL_SPEED:
+        {
+            spellIndexFound.clear();
+            for(uint8 i = CREATURE_SPELL_SPEED_1; i < CREATURE_SPELL_SPEED_MAX; i++)
+            {    
+                CreatureSpellBookInfo *spellInfo = &spellCasting->spellBook->info[i];
+                if( spellInfo->id && !i_creature.HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )
+                    spellIndexFound.push_front(i);
+            }
+            if( spellIndexFound.size() > 0 )
+            {
+                chosenSpellId = 0;
+                std::list<uint8>::iterator itr = spellIndexFound.begin();
+                for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;
+                spellCasting->spellIndex = (*itr);
+                chosenSpellId = spellCasting->spellBook->info[(*itr)].id;
+                
+                //DoDoSay("Speed: %u",chosenSpellId);
+                SetSpellMaxRange(spellCasting);
+                if( !(spellCasting->spellBook->info[(*itr)].targets & (1 << (SELECT_TARGET_ANY_FRIEND-1))) )
+                    spellCasting->targetGUID = i_creature.GetGUID();
+                else
+                    spellCasting->targetGUID = enemyTarget->GetGUID();
+            }
+        }return;
+        case SELECTSPELL_INTERRUPT:
+        {
+            CreatureSpellBookInfo *spellInfo = &spellCasting->spellBook->info[CREATURE_SPELL_INTERRUPT_1];
+            if( spellInfo->id && !i_creature.HasSpellCooldown(spellInfo->id) && AICheckTakePower(CREATURE_SPELL_INTERRUPT_1) )
+            {
+                spellCasting->spellIndex = CREATURE_SPELL_INTERRUPT_1;
+                chosenSpellId = spellInfo->id;
+                SetSpellMaxRange(spellCasting);
+                spellCasting->targetGUID = enemyTarget->GetGUID();
+            }
+        }return;
+    }
+    if( friendTarget )
+    {
+        if( friendTarget->isAlive() )
+        {
+            //heal Friend
+            spellIndexFound.clear();
+            for(uint8 i = CREATURE_SPELL_HEALING_1; i < CREATURE_SPELL_HEALING_MAX; i++)
+            {
+                CreatureSpellBookInfo *spellInfo = &spellCasting->spellBook->info[i];
+                if( spellInfo->id && !i_creature.HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )
+                    spellIndexFound.push_front(i);
+            }
+            if( spellIndexFound.size() > 0 && Unit::getHpPercent(friendTarget) < 70)
+            {
+                chosenSpellId = 0;
+                std::list<uint8>::iterator itr = spellIndexFound.begin();
+                for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;
+                spellCasting->spellIndex = (*itr);
+                chosenSpellId = spellCasting->spellBook->info[(*itr)].id;
+                //DoDoSay("Healing(Friend): %u",chosenSpellId);
+                spellCasting->targetGUID = friendTarget->GetGUID();
+                SetSpellMaxRange(spellCasting);
+                if(!dynamicTarget)
+                    AIMotionTarget(friendTarget,(rand_norm()*spellCasting->range)+1.0f);
+                return;
+
+            }
+
+            //Buff Friend
+            spellIndexFound.clear();
+            for(uint8 i = CREATURE_SPELL_BUFF_1; i < CREATURE_SPELL_BUFF_MAX; i++)
+            {    
+                CreatureSpellBookInfo *spellInfo = &spellCasting->spellBook->info[i];
+                if( spellInfo->id && !i_creature.HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )
+                    spellIndexFound.push_front(i);
+            }
+            if( spellIndexFound.size() > 0 )
+            {
+                srand(getMSTime());
+                chosenSpellId = 0;
+                std::list<uint8>::iterator itr = spellIndexFound.begin();
+                for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;
+                spellCasting->spellIndex = (*itr);
+                chosenSpellId = spellCasting->spellBook->info[(*itr)].id;
+
+                //DoDoSay("Buff Friend: %u",chosenSpellId);
+                spellCasting->targetGUID = friendTarget->GetGUID();
+                SetSpellMaxRange(spellCasting);
+                if(!dynamicTarget)
+                    AIMotionTarget(friendTarget,(rand_norm()*spellCasting->range)+1.0f);
+                return;
+            }
+        }
+    }
+    else if(enemyTarget)
+    {
+        if(!dynamicTarget)
+        {
+            float distance = sqrt(i_creature.GetDistance2dSq(enemyTarget));
+
+            if( !spellCasting->oldTargetRange )
+                spellCasting->oldTargetRange = distance;
+
+            // Target Is Casting a Channeled Spell
+            if( enemyTarget->HasSpellChannelActiveTimer() )
+            {
+                //Cast Intterupted Spell if we have available
+            }
+            // Target Is Running Away, try speed-up to get to her.
+            // Far from what i wan... Need to correct that situation
+
+
+            //Potentiel Charge, but for sure Target is comming to Us
+            // Far from what i wan... Need to correct that situation
+            if( distance < spellCasting->oldTargetRange /*&& !enemyTarget->IsStopped()*/)
+            {
+                spellCasting->oldTargetRange = distance;
+
+                spellIndexFound.clear();
+                for(uint8 i = CREATURE_SPELL_STUNT_1; i < CREATURE_SPELL_STUNT_MAX; i++)
+                {    
+                    CreatureSpellBookInfo *spellInfo = &spellCasting->spellBook->info[i];
+                    if( spellInfo->id && !i_creature.HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )
+                        spellIndexFound.push_front(i);
+                }
+                if( spellIndexFound.size() > 0 )
+                {
+                    srand(getMSTime());
+                    chosenSpellId = 0;
+                    std::list<uint8>::iterator itr = spellIndexFound.begin();
+                    for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;
+                    spellCasting->spellIndex = (*itr);
+                    chosenSpellId = spellCasting->spellBook->info[(*itr)].id;
+                    
+                    //DoDoSay("Stun: %u",chosenSpellId);
+                    SetSpellMaxRange(spellCasting);
+                    if( !(spellCasting->spellBook->info[chosenSpellId].targets & (1 << (SELECT_TARGET_SELF-1))) )
+                        spellCasting->targetGUID = i_creature.GetGUID();
+                    else
+                    {    
+                        AIMotionTarget(enemyTarget,(rand_norm()*spellCasting->range)+1.0f);
+                        spellCasting->targetGUID = enemyTarget->GetGUID();
+                    }
+                    //spellCasting->spellBook->castingTimer = spellCasting->spellBook->info[(*itr)].castingTime;
+                    spellCasting->targetGUID = enemyTarget->GetGUID();
+                    return;
+                }
+            }
+        }
+        //Healing
+        if( Unit::getHpPercent(&i_creature) < irand(40,90) )
+        {
+            spellIndexFound.clear();
+            for(uint8 i = CREATURE_SPELL_HEALING_1; i < CREATURE_SPELL_HEALING_MAX; i++)
+            {    
+                CreatureSpellBookInfo *spellInfo = &spellCasting->spellBook->info[i];
+                if( spellInfo->id && !i_creature.HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )
+                    spellIndexFound.push_front(i);
+            }
+            if( spellIndexFound.size() > 0 )
+            {
+                srand(getMSTime());
+                chosenSpellId = 0;
+                std::list<uint8>::iterator itr = spellIndexFound.begin();
+                for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;
+                spellCasting->spellIndex = (*itr);
+                chosenSpellId = spellCasting->spellBook->info[(*itr)].id;
+                //DoDoSay("Healing: %u",chosenSpellId);
+                //spellCasting->spellBook->castingTimer = spellCasting->spellBook->info[(*itr)].castingTime;
+                spellCasting->targetGUID = i_creature.GetGUID();
+                SetSpellMaxRange(spellCasting);
+                return;
+            }
+
+        }
+        else //Buff
+        {
+            spellIndexFound.clear();
+            for(uint8 i = CREATURE_SPELL_BUFF_1; i < CREATURE_SPELL_BUFF_MAX; i++)
+            {    
+                CreatureSpellBookInfo *spellInfo = &spellCasting->spellBook->info[i];
+                if( spellInfo->id && !i_creature.HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )
+                    spellIndexFound.push_front(i);
+            }
+            if( spellIndexFound.size() > 0 )
+            {
+                srand(getMSTime());
+                chosenSpellId = 0;
+                std::list<uint8>::iterator itr = spellIndexFound.begin();
+                for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;
+                spellCasting->spellIndex = (*itr);
+                chosenSpellId = spellCasting->spellBook->info[(*itr)].id;
+                //DoDoSay("Buff: %u",chosenSpellId);
+                //spellCasting->spellBook->castingTimer = spellCasting->spellBook->info[(*itr)].castingTime;
+                spellCasting->targetGUID = i_creature.GetGUID();
+                SetSpellMaxRange(spellCasting);
+                return;
+            }
+        }
+
+        //Attack Spell
+        spellIndexFound.clear();
+        for(uint8 i = CREATURE_SPELL_ATTACK_1; i < CREATURE_SPELL_ATTACK_MAX; i++)
+        {    
+            CreatureSpellBookInfo *spellInfo = &spellCasting->spellBook->info[i];
+            if( spellInfo->id && !i_creature.HasSpellCooldown(spellInfo->id) && AICheckTakePower(i) )
+                spellIndexFound.push_front(i);
+        }
+        if( spellIndexFound.size() )
+        {
+            srand(getMSTime());
+            chosenSpellId = 0;
+            std::list<uint8>::iterator itr = spellIndexFound.begin();
+            for (uint8 randomIndex = irand(0,spellIndexFound.size()-1); 0 < randomIndex; --randomIndex)++itr;
+            spellCasting->spellIndex = (*itr);
+            chosenSpellId = spellCasting->spellBook->info[(*itr)].id;
+            
+            //DoDoSay("Attack: %u",chosenSpellId);
+            spellCasting->targetGUID = enemyTarget->GetGUID();
+            SetSpellMaxRange(spellCasting);
+            if(!dynamicTarget)
+                AIMotionTarget(enemyTarget,spellCasting->range/1.1f);
+            return;
+        }
+
+        if(!dynamicTarget && i_creature.IsStopped())  //Debug, got to be removed... 
+            AIMotionTarget(enemyTarget,1.5f);
+    }
+}
+
+void AggressorCasterAI::AICast(CreatureSpellCasting *spellCasting)
+{
+    Unit *target = i_creature.GetUnit((i_creature),spellCasting->targetGUID);
+
+    if( !target || !AICheckTakePower(spellCasting->spellIndex, true) )
+    {
+        spellCasting->reset();
+        return;
+    }
+    i_creature.CastSpell(target, spellCasting->spellBook->info[spellCasting->spellIndex].id, false);
+    spellCasting->started = true;
+}
+void AggressorCasterAI::AIMotionTarget(Unit* target, float offSet)
+{
+    bool exist = false;
+    MotionMaster* creatureMM = i_creature.GetMotionMaster();
+
+    if(!target /*&& creatureMM->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE*/)
+    {
+        //creatureMM->MovementExpired();
+        return;    
+    }
+
+    float angle = NULL;
+    if( !i_creature.IsHostileTo(target) )
+    {
+        angle = target->GetOrientation()*2.0f;
+    }
+
+    if(creatureMM->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE)
+    {
+        TargetedMovementGenerator<Creature>* targetMV = static_cast<TargetedMovementGenerator<Creature>*> (creatureMM->top());
+        if( targetMV && targetMV->GetTarget() )
+        {
+            if( targetMV->GetTarget()->GetGUID() != target->GetGUID() )
+            {
+                creatureMM->MovementExpired(false);
+                creatureMM->Mutate(new TargetedMovementGenerator<Creature>(*target,offSet,angle));
+            }
+            else if(targetMV->GetOffSet() != offSet)
+                targetMV->SetOffSet(offSet);
+        }
+    }
+    else
+    { 
+        i_creature.GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*target,offSet,angle));
+    }
+}
+
+bool AggressorCasterAI::AICheckFriendTarget()
+{
+    //Probaly make that function Usable only into Update(), save The status, cause into MoveInLineOfSight(), will be check too much time for nothing.
+    //friend target not found so we reset Status of Friend Follow.
+    if( !i_creature.getVictim() && i_creature.GetUInt64Value(UNIT_FIELD_TARGET) )
+    {
+        Unit* friendTarget = i_creature.GetUnit( i_creature, i_creature.GetUInt64Value(UNIT_FIELD_TARGET) );
+        if( friendTarget && friendTarget->isAlive() && friendTarget->isInCombat() && !i_creature.IsHostileTo(friendTarget) && i_creature.IsWithinDistInMap(friendTarget,35.0f))
+            return true;
+        else
+        {
+            if(friendTarget)
+                friendTarget->m_hasHealer = false;
+            i_creature.SetUInt64Value(UNIT_FIELD_TARGET,0);
+            AIMotionTarget(NULL,NULL);
+        }
+    }
+    return false;
+}
+bool AggressorCasterAI::AICheckVictimTarget()
+{
+    //Check if we have a current target
+    if( i_creature.getVictim() )
+    {
+        //debug Line to help find why sometime MV target is not Creature Target
+        if( i_creature.GetUInt64Value(UNIT_FIELD_TARGET) != i_creature.getVictim()->GetGUID() )
+            i_creature.SetUInt64Value(UNIT_FIELD_TARGET, i_creature.getVictim()->GetGUID());
+
+        if( i_creature.getVictim()->isTargetableForAttack() && i_creature.isAlive())
+            return true;
+    }
+    return false;
+}
+bool AggressorCasterAI::AICheckTakePower(uint8 spellIndex, bool take)
+{
+    uint32 currentPowerValue;
+    // Don't take SpellAddon PowerType, Because can be missing, so is up to us
+    // to not put spell for mage on a warrior.
+    Powers creaturePowerType = i_creature.getPowerType();
+    switch( creaturePowerType )
+    {
+        case POWER_RAGE: currentPowerValue = i_creature.GetPower(POWER_RAGE)/10; break;
+        case POWER_MANA: currentPowerValue = i_creature.GetPower(POWER_MANA); break;
+        case POWER_FOCUS: currentPowerValue = i_creature.GetPower(POWER_FOCUS); break;
+        case POWER_ENERGY: currentPowerValue = i_creature.GetPower(POWER_ENERGY); break;
+        case POWER_HAPPINESS: currentPowerValue = i_creature.GetPower(POWER_HAPPINESS); break;
+    }
+    if( i_creature.m_creatureSpellBook->info[spellIndex].cost > currentPowerValue )
+        return false;
+
+    if( take && !i_creature.m_creatureSpellBook->info[spellIndex].usingDBC )
+        switch(POWER_MANA) //We Only use this one for The Moment
+        {
+            case POWER_RAGE:
+                i_creature.SetPower(creaturePowerType, (currentPowerValue - i_creature.m_creatureSpellBook->info[spellIndex].cost)*10 );break;
+            case POWER_MANA:
+                i_creature.SetPower(creaturePowerType, (currentPowerValue - i_creature.m_creatureSpellBook->info[spellIndex].cost) );break;
+            case POWER_FOCUS: 
+                i_creature.SetPower(creaturePowerType, (currentPowerValue - i_creature.m_creatureSpellBook->info[spellIndex].cost) );break;
+            case POWER_ENERGY:
+                i_creature.SetPower(creaturePowerType, (currentPowerValue - i_creature.m_creatureSpellBook->info[spellIndex].cost) );break;
+            case POWER_HAPPINESS:
+                i_creature.SetPower(creaturePowerType, (currentPowerValue - i_creature.m_creatureSpellBook->info[spellIndex].cost) );break;
+        }
+
+    return true;
+}
+
+
+float AggressorCasterAI::SetSpellMaxRange(CreatureSpellCasting *spellCasting)
+{
+    // Not OK ... 
+    float _rangeMax = spellCasting->spellBook->info[spellCasting->spellIndex].range[1] - 2.0f;
+    spellCasting->range  = _rangeMax < 5.5f ? 5.5f : _rangeMax;
+    return spellCasting->range;
+}
Index: src/game/AggressorCasterAI.h
===================================================================
--- src/game/AggressorCasterAI.h	(revision 0)
+++ src/game/AggressorCasterAI.h	(revision 0)
@@ -0,0 +1,104 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef MANGOS_AGGRESSORCASTERAI_H
+#define MANGOS_AGGRESSORCASTERAI_H
+
+#include "Creature.h"
+#include "CreatureAI.h"
+#include "Timer.h"
+
+enum SelectSpellType
+{
+    SELECTSPELL_NONE,
+    SELECTSPELL_SPEED,
+    SELECTSPELL_INTERRUPT
+};
+
+//Will be used like this: CREATURE_GLOBAL_COOLDOWN-(Level*1000)
+#define CREATURE_SPELL_GLOBAL_COOLDOWN  1500
+#define CREATURE_WAIT_REACH_RATE        1
+
+class Creature;
+
+struct CreatureSpellCasting
+{
+    CreatureSpellCasting(CreatureSpellBook *_spellBook) : 
+    spellIndex(-1), targetGUID(0), runningTimer(0), oldTargetRange(0.0f),range(0.0f),
+    started(false),reached(false),dynamicTarget(false),spellBook(_spellBook) {}
+
+    int8 spellIndex;
+    uint64 targetGUID;
+    uint32 runningTimer;
+    float oldTargetRange, range;
+    bool started, reached, dynamicTarget;
+    CreatureSpellBook* spellBook;
+    
+    void reset(bool resetRange = false)
+    {
+        spellIndex = -1;
+        targetGUID = 0;
+        runningTimer = 0;
+        range = 0.0f;
+        started = false;
+        reached = false;
+        dynamicTarget = false;
+        if(resetRange)
+            oldTargetRange = 0.0f;
+    }
+};
+class MANGOS_DLL_DECL AggressorCasterAI : public CreatureAI
+{
+    enum AggressorState
+    {
+        STATE_NORMAL = 1,
+        STATE_LOOK_AT_VICTIM = 2
+    };
+
+    public:
+
+        AggressorCasterAI(Creature &c);
+
+        void MoveInLineOfSight(Unit *);
+        void AttackStart(Unit *);
+        void EnterEvadeMode();
+        bool IsVisible(Unit *) const;
+        void DamageTaken(Unit *done_by, uint32 &damage);
+        void JustDie();
+        void UpdateAI(const uint32);
+        static int Permissible(const Creature *);
+
+    private:
+        void AISelectAction(Unit* who);
+        void AISelectSpell(CreatureSpellCasting *spellCasting, Unit *target = NULL, uint8 specialCase = 0);
+        void AICast(CreatureSpellCasting *spellCasting);
+        void AIMotionTarget(Unit *target, float offSet = 0.0f);
+        bool AICheckFriendTarget();
+        bool AICheckVictimTarget();
+        bool AICheckTakePower(uint8 spellIndex, bool take = false);
+        float SetSpellMaxRange(CreatureSpellCasting *spellCasting);
+
+        CreatureSpellCasting *spellCasting;
+        Creature &i_creature;
+        uint32 lastAction;
+        uint64 i_victimGuid;
+        float selectedAttackRadius;
+        AggressorState i_state;
+        TimeTracker i_tracker;
+};
+#endif
Index: src/game/ConfusedMovementGenerator.cpp
===================================================================
--- src/game/ConfusedMovementGenerator.cpp	(revision 4763)
+++ src/game/ConfusedMovementGenerator.cpp	(working copy)
@@ -22,9 +22,7 @@
 #include "ConfusedMovementGenerator.h"
 #include "DestinationHolderImp.h"
 
-template<class T>
-void
-ConfusedMovementGenerator<T>::Initialize(T &unit)
+template<class T> void ConfusedMovementGenerator<T>::Initialize(T &unit)
 {
     const float wander_distance=11;
     float x,y,z;
@@ -62,30 +60,22 @@
         unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z);
         i_waypoints[idx][2] =  z;
     }
-
-    unit.StopMoving();
     unit.setMoveRunFlag(true);
 }
 
-template<>
-void
-ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
+template<> void ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
 {
     is_water_ok = creature.isCanSwimOrFly();
     is_land_ok  = creature.isCanWalkOrFly();
 }
 
-template<>
-void
-ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
+template<> void ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
 {
     is_water_ok = true;
     is_land_ok  = true;
 }
 
-template<class T>
-void
-ConfusedMovementGenerator<T>::Reset(T &unit)
+template<class T> void ConfusedMovementGenerator<T>::Reset(T &unit)
 {
     i_nextMove = 1;
     i_nextMoveTime.Reset(0);
@@ -93,15 +83,17 @@
     unit.StopMoving();
 }
 
-template<class T>
-bool
-ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
+template<class T> bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
 {
     if(!&unit)
-        return true;
-    if(unit.hasUnitState(UNIT_STAT_ROOT) || unit.hasUnitState(UNIT_STAT_STUNDED))
-        return true;
-
+        return false;
+    //if(unit.hasUnitState(UNIT_STAT_ROOT) || unit.hasUnitState(UNIT_STAT_STUNDED))
+        //return true;
+    if(!unit.HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED))
+    {
+        unit.clearUnitState(UNIT_STAT_CONFUSED);
+        return false;
+    }
     if( i_nextMoveTime.Passed() )
     {
         // currently moving, update location
@@ -110,9 +102,7 @@
         {
             if( i_destinationHolder.HasArrived())
             {
-                // arrived, stop and wait a bit
-                unit.StopMoving();
-
+                unit.clearUnitState(UNIT_STAT_CONFUSED);
                 i_nextMove = urand(1,MAX_CONF_WAYPOINTS);
                 i_nextMoveTime.Reset(urand(0, 1500-1));         // TODO: check the minimum reset time, should be probably higher
             }
@@ -129,6 +119,7 @@
             const float x = i_waypoints[i_nextMove][0];
             const float y = i_waypoints[i_nextMove][1];
             const float z = i_waypoints[i_nextMove][2];
+            unit.addUnitState(UNIT_STAT_CONFUSED);
             Traveller<T> traveller(unit);
             i_destinationHolder.SetDestination(traveller, x, y, z);
         }
Index: src/game/ConfusedMovementGenerator.h
===================================================================
--- src/game/ConfusedMovementGenerator.h	(revision 4763)
+++ src/game/ConfusedMovementGenerator.h	(working copy)
@@ -16,8 +16,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef MANGOS_RANDOMMOTIONGENERATOR_H
-#define MANGOS_RANDOMMOTIONGENERATOR_H
+#ifndef MANGOS_CONFUSEDMOTIONGENERATOR_H
+#define MANGOS_CONFUSEDMOTIONGENERATOR_H
 
 #include "MovementGenerator.h"
 #include "DestinationHolder.h"
@@ -35,7 +35,10 @@
         void Initialize(T &);
         void Reset(T &);
         bool Update(T &, const uint32 &);
-
+        void UpdateMapPosition(float &x ,float &y, float &z)
+        {
+            i_destinationHolder.GetLocationNow(x,y,z);
+        }
         MovementGeneratorType GetMovementGeneratorType() { return CONFUSED_MOTION_TYPE; }
     private:
         void _InitSpecific(T &, bool &, bool &);
Index: src/game/Creature.cpp
===================================================================
--- src/game/Creature.cpp	(revision 4763)
+++ src/game/Creature.cpp	(working copy)
@@ -37,6 +37,7 @@
 #include "WaypointMovementGenerator.h"
 #include "InstanceData.h"
 #include "BattleGround.h"
+#include "spell.h"
 
 // apply implementation of the singletons
 #include "Policies/SingletonImp.h"
@@ -56,11 +57,10 @@
     for(int i =0; i<4; ++i)
         m_spells[i] = 0;
 
-    m_CreatureSpellCooldowns.clear();
     m_CreatureCategoryCooldowns.clear();
     m_GlobalCooldown = 0;
-
-    m_AlreadyCallAssistence = false;
+    m_creatureSpellBook = NULL;
+    m_AssistenceStatus = new AssistenceStatus();
 }
 
 Creature::~Creature()
@@ -174,6 +174,7 @@
     {
         case JUST_DIED:
             // Dont must be called, see Creature::setDeathState JUST_DIED -> CORPSE promoting.
+            getHostilRefManager().deleteReferences();
             sLog.outError("Creature (GUIDLow: %u Entry: %u ) in wrong state: JUST_DEAD (1)",GetGUIDLow(),GetEntry());
             break;
         case DEAD:
@@ -204,6 +205,9 @@
             if( m_deathTimer <= diff )
             {
                 RemoveCorpse();
+                float x,y,z;
+                GetRespawnCoord(x, y, z);
+                Relocate(x,y,z); //Check this out Use World Relocation if still cool, or GridRelocation and here is probaly Grid needed so..., GS
                 DEBUG_LOG("Removing corpse... %u ", GetUInt32Value(OBJECT_FIELD_ENTRY));
             }
             else
@@ -1244,7 +1248,7 @@
 
     // checked at loading
     m_defaultMovementType = MovementGeneratorType(cinfo->MovementType);
-
+    m_creatureSpellBook = objmgr.GetCreatureSpellBook(Entry);
     //Notify the map's instance data.
     //Only works if you create the object in it, not if it is moves to that map.
     //Normally non-players do not teleport to other maps.
@@ -1694,14 +1698,13 @@
     return false;
 }
 
-void Creature::CallAssistence()
+/*void Creature::CallAssistence()
 {
     if( !m_AlreadyCallAssistence && getVictim() )
     {
-        CastSpell(this,SPELL_ID_AGGRO, true, NULL, NULL, getVictim()->GetGUID());
+        //CastSpell(this,SPELL_ID_AGGRO, true, NULL, NULL, getVictim()->GetGUID());
     }
-}
-
+}*/
 void Creature::SaveRespawnTime()
 {
     if(isPet())
@@ -1732,7 +1735,10 @@
         return false;
 
     float rx,ry,rz;
-    GetRespawnCoord(rx, ry, rz);
+    if(isPet() && GetOwner() )
+        GetOwner()->GetPosition(rx,ry,rz);
+    else
+       GetRespawnCoord(rx, ry, rz); 
 
     float length = pVictim->GetDistanceSq(rx,ry,rz);
     return ( length > 10000.0f);                            // real value unknown
@@ -1813,14 +1819,39 @@
     if(!spellInfo)
         return;
 
-    uint32 cooldown = spellInfo->CategoryRecoveryTime > spellInfo->RecoveryTime ? spellInfo->CategoryRecoveryTime : spellInfo->RecoveryTime;
+    uint32 cooldown = 0;
+
+    if(m_creatureSpellBook)
+    {
+        //When Struct SpellCasting Is available into Core, Use Index comming from there
+        //So no use to search the spell we are casting ;), GS
+        CreatureSpellBookInfoMap::const_iterator _info = m_creatureSpellBook->info.begin();
+        for(;_info != m_creatureSpellBook->info.end(); ++_info)
+        {
+            if( _info->second.id == spellid )
+            {
+                cooldown = _info->second.recoveryTime;
+                break;
+            }
+        }
+    }
+
+    if(!cooldown)
+    {
+        SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid);
+        if(!spellInfo)
+            return;
+
+        cooldown = spellInfo->CategoryRecoveryTime > spellInfo->RecoveryTime ? spellInfo->CategoryRecoveryTime : spellInfo->RecoveryTime; 
+    }
+    
     if(cooldown)
         _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown/1000);
 
     if(spellInfo->Category)
         _AddCreatureCategoryCooldown(spellInfo->Category, time(NULL));
 
-    m_GlobalCooldown = 1500;
+    m_GlobalCooldown = 1500; // We Should Add A Rate, so we Control a little, Strenght Of Spell Casting
 }
 
 bool Creature::HasCategoryCooldown(uint32 spell_id) const
@@ -1833,10 +1864,13 @@
     return(itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / 1000)) > time(NULL));
 }
 
-bool Creature::HasSpellCooldown(uint32 spell_id) const
+bool Creature::HasSpellCooldown(uint32 spell_id,uint32 addTime) const
 {
+    if(!spell_id)
+        return m_GlobalCooldown > 0;
+
     CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spell_id);
-    return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)) || m_GlobalCooldown > 0 || HasCategoryCooldown(spell_id);
+    return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)+addTime) || m_GlobalCooldown > 0 || HasCategoryCooldown(spell_id);
 }
 
 bool Creature::IsInEvadeMode() const
@@ -1852,3 +1886,159 @@
             break;
     return i < CREATURE_MAX_SPELLS;                     //broke before end of iteration of known spells
 }
+
+/*void Creature::LoadSpellInfo()
+{
+    if(m_creatureSpellBook)
+        delete m_creatureSpellBook;
+
+    QueryResult* _result = sDatabase.PQuery("SELECT * FROM creature_spellbook WHERE entry=%u",GetEntry());
+    if(_result)
+    {
+        Field *_spellInfo = _result->Fetch();
+        char* _spellId = NULL;
+
+        m_creatureSpellBook = new CreatureSpellBook();
+        //spellId, recoveryTime, unknow1, buffDuration, cost, rangeMin, rangeMax
+        for(uint8 itr = CREATURE_SPELL_MIN; itr < CREATURE_SPELL_MAX; ++itr)
+        {
+            const char*  rawSpellInfo = _spellInfo[itr+1].GetString();
+            _spellId = strtok((char*)rawSpellInfo, " "); 
+            if( _spellId )
+            {
+                uint32 spellId = m_creatureSpellBook->info[itr].id = atoi(_spellId);
+
+                char* _recoveryTime = strtok(NULL, " ");
+                if(_recoveryTime)
+                    m_creatureSpellBook->info[itr].recoveryTime = atoi(_recoveryTime);
+                char* _castingTime = strtok(NULL, " ");
+                if(_castingTime)
+                     m_creatureSpellBook->info[itr].unknow1 = atoi(_castingTime);
+                char* _buffDuration = strtok(NULL, " ");
+                if(_buffDuration)
+                     m_creatureSpellBook->info[itr].buffDuration = atoi(_buffDuration);
+                char* _cost = strtok(NULL, " ");
+                if(_cost)
+                     m_creatureSpellBook->info[itr].cost = atoi(_cost);
+                char* _rangeMin = strtok(NULL, " ");
+                if(_rangeMin)
+                     m_creatureSpellBook->info[itr].range[0] = atof(_rangeMin);
+                char* _rangeMax = strtok(NULL, " ");
+                if(_rangeMax)
+                     m_creatureSpellBook->info[itr].range[1] = atof(_rangeMax);
+            }
+        }
+        delete _result;
+
+        SpellEntry const* dbcSpell;
+        SpellRangeEntry const *dbcRange;
+        SpellDurationEntry const * dbcDuration;
+        SpellCastTimesEntry const *dbcCastTime;
+
+        CreatureSpellInfoMap::iterator itr = m_creatureSpellBook->info.begin();
+        if(itr == m_creatureSpellBook->info.end())
+            return;
+        
+        for(; itr != m_creatureSpellBook->info.end(); ++itr)
+        {
+            dbcSpell = GetSpellStore()->LookupEntry(itr->second.id);
+            if( !dbcSpell )
+                continue;
+            dbcRange = GetSpellRangeStore()->LookupEntry(dbcSpell->rangeIndex);
+            dbcDuration = GetSpellDurationStore()->LookupEntry(dbcSpell->DurationIndex);
+            dbcCastTime = GetCastTimesStore()->LookupEntry(dbcSpell->CastingTimeIndex);
+
+            for (int j=0; j<3; j++)
+            {
+                //Spell targets self
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF )
+                    itr->second.targets |= 1 << (SELECT_TARGET_SELF-1);
+
+                //Spell targets a single enemy
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_SELECTED_ENEMY )
+                    itr->second.targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1);
+
+                //Spell targets AoE at enemy
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )
+                    itr->second.targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);
+
+                //Spell targets an enemy
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_SELECTED_ENEMY ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )
+                    itr->second.targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);
+
+                //Spell targets a single friend(or self)
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY )
+                    itr->second.targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1);
+
+                //Spell targets aoe friends
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY )
+                    itr->second.targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);
+
+                //Spell targets any friend(or self)
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY )
+                    itr->second.targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);
+
+                //Make sure that this spell includes a damage effect
+                if ( dbcSpell->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE || 
+                     dbcSpell->Effect[j] == SPELL_EFFECT_INSTAKILL || 
+                     dbcSpell->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE || 
+                     dbcSpell->Effect[j] == SPELL_EFFECT_HEALTH_LEECH )
+                    itr->second.effects |= 1 << (SELECT_EFFECT_DAMAGE-1);
+
+                //Make sure that this spell includes a healing effect
+                if ( dbcSpell->Effect[j] == SPELL_EFFECT_HEAL || 
+                     dbcSpell->Effect[j] == SPELL_EFFECT_HEAL_MAX_HEALTH || 
+                     dbcSpell->Effect[j] == SPELL_EFFECT_HEAL_MECHANICAL )
+                    itr->second.effects |= 1 << (SELECT_EFFECT_HEALING-1);
+
+                //Make sure that this spell applies an aura
+                if( dbcSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA )
+                    itr->second.effects |= 1 << (SELECT_EFFECT_AURA-1);
+                
+                // Buff Duration
+                if( dbcDuration && itr->second.buffDuration < dbcDuration->Duration[j] )//DBC Info Not Good
+                    itr->second.buffDuration = dbcDuration->Duration[j];
+            }
+            
+            //We use powerCost from SQL on missing DBC value
+            if( dbcSpell->manaCost )
+            {
+                itr->second.usingDBC = true;
+                itr->second.cost = dbcSpell->manaCost;
+            }
+
+            //CoolDown
+            if( !itr->second.recoveryTime && dbcSpell->RecoveryTime )
+                itr->second.recoveryTime = dbcSpell->RecoveryTime;
+
+            if(dbcRange)
+            {
+                //Range Min
+                if( !itr->second.range[0] )
+                    itr->second.range[0] = dbcRange->minRange;
+                //Range Max
+                if( !itr->second.range[1] )//DBC Info Not Good
+                    itr->second.range[1] = dbcRange->maxRange;
+            }
+            
+            //Casttime
+            if(dbcCastTime && dbcCastTime->CastTime)
+                itr->second.isDelayed = true;
+        }
+    }
+}
+*/
Index: src/game/Creature.h
===================================================================
--- src/game/Creature.h	(revision 4763)
+++ src/game/Creature.h	(working copy)
@@ -269,6 +269,124 @@
     uint32 modelid_other_gender;
 };
 
+enum CreatureSpellSelectTarget
+{
+    SELECT_TARGET_DONTCARE = 0,         //All target types allowed
+
+    SELECT_TARGET_SELF,                 //Only Self casting
+
+    SELECT_TARGET_SINGLE_ENEMY,         //Only Single Enemy
+    SELECT_TARGET_AOE_ENEMY,            //Only AoE Enemy
+    SELECT_TARGET_ANY_ENEMY,            //AoE or Single Enemy
+
+    SELECT_TARGET_SINGLE_FRIEND,        //Only Single Friend
+    SELECT_TARGET_AOE_FRIEND,           //Only AoE Friend
+    SELECT_TARGET_ANY_FRIEND,           //AoE or Single Friend
+};
+
+enum CreatureSpellSelectEffect
+{
+    SELECT_EFFECT_DONTCARE = 0,         //All spell effects allowed
+    SELECT_EFFECT_DAMAGE,               //Spell does damage
+    SELECT_EFFECT_HEALING,              //Spell does healing
+    SELECT_EFFECT_AURA,                 //Spell applies an aura
+};
+enum CreatureSpellIndex
+{
+    CREATURE_SPELL_MIN,
+    CREATURE_SPELL_ATTACK_1 = 0,            //Normal Attack
+    CREATURE_SPELL_ATTACK_2,
+    CREATURE_SPELL_ATTACK_3,
+    CREATURE_SPELL_ATTACK_4,
+    CREATURE_SPELL_ATTACK_5,
+    CREATURE_SPELL_ATTACK_MAX,
+    CREATURE_SPELL_SPEED_1 = 5,         //When target Run Away
+    CREATURE_SPELL_SPEED_2,
+    CREATURE_SPELL_SPEED_MAX,
+    CREATURE_SPELL_STUNT_1 = 7,
+    CREATURE_SPELL_STUNT_2,             //When target Run Closer
+    CREATURE_SPELL_STUNT_MAX,
+    CREATURE_SPELL_HEALING_1 = 9,       //When Less Life Or Friend Target
+    CREATURE_SPELL_HEALING_2,
+    CREATURE_SPELL_HEALING_MAX,
+    CREATURE_SPELL_BUFF_1 = 11,         //When Begin of the fight Or Friend Target
+    CREATURE_SPELL_BUFF_2,
+    CREATURE_SPELL_BUFF_MAX,
+    CREATURE_SPELL_INTERRUPT_1 = 13,    //Select When Target is Casting Channeling Spell
+    CREATURE_SPELL_INTERRUPT_MAX,
+    CREATURE_SPELL_MAX = 14
+};
+struct CreatureSpellBookInfo
+{
+    CreatureSpellBookInfo() : id(NULL), recoveryTime(0), 
+    unknow1(0),buffDuration(0),cost(0),
+    targets(0),effects(0),usingDBC(false),hasCastTime(false)
+    {
+        range[0] = 0.0f;
+        range[1] = 0.0f;
+    }
+
+    uint8 targets,effects;
+    uint32 id,recoveryTime,unknow1,buffDuration,cost;
+    float range[2];
+    bool usingDBC,hasCastTime;
+};
+typedef std::map<uint8,CreatureSpellBookInfo> CreatureSpellBookInfoMap;
+struct CreatureSpellBook
+{ 
+    CreatureSpellBook() { info.clear(); }
+    CreatureSpellBookInfoMap info;
+
+    bool hasHealing()
+    {
+        CreatureSpellBookInfoMap::iterator spellItr;
+        for(uint8 i = CREATURE_SPELL_HEALING_1; i < CREATURE_SPELL_HEALING_MAX; ++i)
+        {
+            spellItr = info.find(i);
+            if( spellItr != info.end() && spellItr->second.id)
+                return true;
+        }
+        return false;
+    }
+    bool hasSpeed()
+    {
+        CreatureSpellBookInfoMap::iterator spellItr;
+        for(uint8 i = CREATURE_SPELL_SPEED_1; i < CREATURE_SPELL_SPEED_MAX; ++i)
+        {
+            spellItr = info.find(i);
+            if( spellItr != info.end() && spellItr->second.id)
+                return true;
+        }
+        return false;
+    }
+    bool hasInterrupt()
+    {
+        CreatureSpellBookInfoMap::iterator spellItr;
+        for(uint8 i = CREATURE_SPELL_INTERRUPT_1; i < CREATURE_SPELL_INTERRUPT_MAX; ++i)
+        {
+            spellItr = info.find(i);
+            if( spellItr != info.end() && spellItr->second.id)
+                return true;
+        }
+        return false;
+    }
+};
+
+
+
+
+struct AssistenceStatus
+{
+    AssistenceStatus() : requested(false), obtained(false) {}
+    bool requested;
+    bool obtained;
+
+    void reset()
+    {
+        obtained = false;
+        requested = false;
+    }
+};
 enum InhabitTypeValues
 {
     INHAVIT_GROUND = 1,
@@ -364,7 +482,7 @@
         void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time);
         void _AddCreatureCategoryCooldown(uint32 category, time_t apply_time);
         void AddCreatureSpellCooldown(uint32 spellid);
-        bool HasSpellCooldown(uint32 spell_id) const;
+        bool HasSpellCooldown(uint32 spell_id = 0, uint32 addTime = 0) const;
         bool HasCategoryCooldown(uint32 spell_id) const;
 
         bool HasSpell(uint32 spellID) const;
@@ -465,15 +583,16 @@
         SpellEntry const *reachWithSpellCure(Unit *pVictim);
 
         uint32 m_spells[CREATURE_MAX_SPELLS];
+        uint32 m_GlobalCooldown;
         CreatureSpellCooldowns m_CreatureSpellCooldowns;
         CreatureSpellCooldowns m_CreatureCategoryCooldowns;
-        uint32 m_GlobalCooldown;
 
         float GetAttackDistance(Unit *pl) const;
 
-        void CallAssistence();
-        void SetNoCallAssistence(bool val) { m_AlreadyCallAssistence = val; }
-
+        //void CallAssistence();
+        //void SetCallAssistence( bool value ) { m_AlreadyCallAssistence = value; }
+        //bool GetCallAssistence() const { return m_AlreadyCallAssistence; }
+        AssistenceStatus* m_AssistenceStatus;
         MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; }
         void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; }
 
@@ -507,6 +626,7 @@
             else
                 return m_charmInfo->GetCharmSpell(pos)->spellId;
         }
+        CreatureSpellBook *m_creatureSpellBook;
 
     protected:
         // vendor items
@@ -548,7 +668,7 @@
         uint32 m_regenTimer;
         MovementGeneratorType m_defaultMovementType;
         Cell m_currentCell;                                 // store current cell where creature listed
-        bool m_AlreadyCallAssistence;
+        //bool m_AlreadyCallAssistence;
 
         uint32 m_DBTableGuid;
         bool m_regenHealth;
Index: src/game/CreatureAI.h
===================================================================
--- src/game/CreatureAI.h	(revision 4763)
+++ src/game/CreatureAI.h	(working copy)
@@ -32,6 +32,21 @@
 #define TIME_INTERVAL_LOOK   5000
 #define VISIBILITY_RANGE    10000
 
+//Creature Follow Range on aggro
+#define AI_MANGOS                       1     //To add Featured or Normal Version
+#define FOLLOW_RANGE_CASTER             9.0f
+#define FOLLOW_RANGE_MELEE              0.0f
+#define RUNAWAY_AGGRO_RANGE             3.3f  // +Aggro == start RunAway at that range
+#define RANGE_AUTO_ASSIST               2.0f
+#define RANGE_AUTO_ASSIST_PET           20.0f
+#define RANGE_AUTO_ASSIST_PLAYER        15.0f
+#define RANGE_AUTO_ASSIST_NPC           0.5f
+#define RANGE_DYNAMIC_ASSIST            15.0f
+#define RANGE_MAX_AUTO_FEAR             15.0f   //If player distance from SpawnPoint > RANGE_MAX_AUTO_FEAR, AUTO fear Off.
+#define CREATURE_SPELL_RUNAWAY          8225
+#define CREATURE_SPELL_TAP_FRIEND       38192
+#define CREATURE_WAIT_RATE              15
+
 class MANGOS_DLL_SPEC CreatureAI
 {
     public:
Index: src/game/CreatureAIRegistry.cpp
===================================================================
--- src/game/CreatureAIRegistry.cpp	(revision 4763)
+++ src/game/CreatureAIRegistry.cpp	(working copy)
@@ -20,6 +20,7 @@
 #include "NullCreatureAI.h"
 #include "ReactorAI.h"
 #include "AggressorAI.h"
+#include "AggressorCasterAI.h"
 #include "GuardAI.h"
 #include "PetAI.h"
 #include "TotemAI.h"
@@ -37,6 +38,7 @@
     {
         (new CreatureAIFactory<NullCreatureAI>("NullAI"))->RegisterSelf();
         (new CreatureAIFactory<AggressorAI>("AggressorAI"))->RegisterSelf();
+        (new CreatureAIFactory<AggressorCasterAI>("AggressorCasterAI"))->RegisterSelf();
         (new CreatureAIFactory<ReactorAI>("ReactorAI"))->RegisterSelf();
         (new CreatureAIFactory<GuardAI>("GuardAI"))->RegisterSelf();
         (new CreatureAIFactory<PetAI>("PetAI"))->RegisterSelf();
Index: src/game/DestinationHolder.h
===================================================================
--- src/game/DestinationHolder.h	(revision 4763)
+++ src/game/DestinationHolder.h	(working copy)
@@ -35,11 +35,12 @@
     uint32 i_timeElapsed;
     bool i_destSet;
     float i_fromX, i_fromY, i_fromZ;
+    uint32 i_fromMapId;
     float i_destX, i_destY, i_destZ;
 
     public:
         DestinationHolder() : i_tracker(TRAVELLER_UPDATE_INTERVAL), i_totalTravelTime(0), i_timeStarted(0), i_timeElapsed(0),
-            i_destSet(false), i_fromX(0), i_fromY(0), i_fromZ(0), i_destX(0), i_destY(0), i_destZ(0) {}
+            i_destSet(false), i_fromX(0), i_fromY(0), i_fromZ(0),i_fromMapId(0), i_destX(0), i_destY(0), i_destZ(0) {}
 
         uint32 SetDestination(TRAVELLER &traveller, float dest_x, float dest_y, float dest_z, bool sendMove = true);
         void GetDestination(float &x, float &y, float &z) { x = i_destX; y = i_destY; z = i_destZ; }
@@ -48,13 +49,15 @@
         uint32 GetTotalTravelTime(void) const { return i_totalTravelTime; }
         uint32 GetStartTravelTime(void) const { return i_timeStarted; }
         bool HasDestination(void) const { return i_destSet; }
+        float GetDestinationDiff2d(float x, float y, float z) const;
         float GetDestinationDiff(float x, float y, float z) const;
         bool HasArrived(void) const { return (i_totalTravelTime == 0 || i_timeElapsed >= i_totalTravelTime); }
+        uint32 GetTimeToDest(void) const { return i_totalTravelTime - i_timeElapsed; }
         bool UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool force_update);
         uint32 StartTravel(TRAVELLER &traveller, bool sendMove = true);
-        void GetLocationNow(float &x, float &y, float &z) const;
+        void GetLocationNow(float &x, float &y, float &z, bool is3D = false) const;
+        float GetDistanceFromDest2dSq(const WorldObject &obj) const;
         float GetDistanceFromDestSq(const WorldObject &obj) const;
-
     private:
         void _findOffSetPoint(float x1, float y1, float x2, float y2, float offset, float &x, float &y);
 
Index: src/game/DestinationHolderImp.h
===================================================================
--- src/game/DestinationHolderImp.h	(revision 4763)
+++ src/game/DestinationHolderImp.h	(working copy)
@@ -25,9 +25,7 @@
 
 #include <cmath>
 
-template<typename TRAVELLER>
-void
-DestinationHolder<TRAVELLER>::_findOffSetPoint(float x1, float y1, float x2, float y2, float offset, float &x, float &y)
+template<typename TRAVELLER> void DestinationHolder<TRAVELLER>::_findOffSetPoint(float x1, float y1, float x2, float y2, float offset, float &x, float &y)
 {
     /* given the point (x1, y1) and (x2, y2).. need to find the point (x,y) on the same line
      * such that the distance from (x, y) to (x2, y2) is offset.
@@ -61,12 +59,10 @@
     }
 }
 
-template<typename TRAVELLER>
-uint32
-DestinationHolder<TRAVELLER>::SetDestination(TRAVELLER &traveller, float dest_x, float dest_y, float dest_z, bool sendMove)
+template<typename TRAVELLER> uint32 DestinationHolder<TRAVELLER>::SetDestination(TRAVELLER &traveller, float dest_x, float dest_y, float dest_z, bool sendMove)
 {
-    if (i_destSet && i_destX == dest_x && i_destY == dest_y && i_destZ == dest_z)
-        return 0;
+    //if (i_destSet && i_destX == dest_x && i_destY == dest_y && i_destZ == dest_z)
+        //return 0;
 
     i_destSet = true;
     i_destX = dest_x;
@@ -76,34 +72,39 @@
     return StartTravel(traveller, sendMove);
 }
 
-template<typename TRAVELLER>
-uint32
-DestinationHolder<TRAVELLER>::StartTravel(TRAVELLER &traveller, bool sendMove)
+template<typename TRAVELLER> uint32 DestinationHolder<TRAVELLER>::StartTravel(TRAVELLER &traveller, bool sendMove)
 {
     if(!i_destSet) return 0;
 
     i_fromX = traveller.GetPositionX();
     i_fromY = traveller.GetPositionY();
     i_fromZ = traveller.GetPositionZ();
+    i_fromMapId = traveller.GetTraveller().GetMapId();
 
     float dx = i_destX - i_fromX;
     float dy = i_destY - i_fromY;
     float dz = i_destZ - i_fromZ;
-    double dist = ::sqrt((dx*dx) + (dy*dy) + (dz*dz));
-    double speed = traveller.Speed();
-    if(speed<=0)
+
+    float dist;
+    //Should be for Creature Flying too and Swimming.
+    if(traveller.GetTraveller().hasUnitState(UNIT_STAT_IN_FLIGHT))
+        dist = sqrt((dx*dx) + (dy*dy) + (dz*dz)); 
+    else    //Walking on the ground
+        dist = sqrt((dx*dx) + (dy*dy)); 
+    float speed = traveller.Speed();
+    if(speed<=0.0f)                                     // -0 will be reverse ??? for me at lease, GS
         speed = 2.5f;
     speed *=  0.001f;                                       // speed is in seconds so convert from second to millisecond
-    i_totalTravelTime = static_cast<uint32>( dist/speed + 0.5 );
+    i_totalTravelTime = static_cast<uint32>( dist/speed);
     i_timeStarted = getMSTime();
     i_timeElapsed = 0;
-    if(sendMove) traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime);
+    if(sendMove) 
+        traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime);
+
     return i_totalTravelTime;
 }
 
-template<typename TRAVELLER>
-bool
-DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool force_update)
+template<typename TRAVELLER> bool DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool force_update)
 {
     i_tracker.Update(diff);
     i_timeElapsed += diff;
@@ -112,9 +113,14 @@
         ResetUpdate();
         if(!i_destSet) return true;
         float x,y,z;
-        GetLocationNow(x, y, z);
+        
+        if(traveller.GetTraveller().hasUnitState(UNIT_STAT_IN_FLIGHT))
+            GetLocationNow(x, y, z,true);    //Should repositione Object with right Coord, so i can bypass some Grid Relocation, GS
+        else
+            GetLocationNow(x, y, z);
         if( x == -431602080 )
             return false;
+            
         if( traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y )
         {
             float ori = traveller.GetTraveller().GetAngle(x, y);
@@ -125,9 +131,7 @@
     return false;
 }
 
-template<typename TRAVELLER>
-void
-DestinationHolder<TRAVELLER>::GetLocationNow(float &x, float &y, float &z) const
+template<typename TRAVELLER> void DestinationHolder<TRAVELLER>::GetLocationNow(float &x, float &y, float &z, bool is3D) const
 {
     if( HasArrived() )
     {
@@ -135,28 +139,49 @@
         y = i_destY;
         z = i_destZ;
     }
-    else
+    else if(HasDestination())
     {
         double percent_passed = (double)i_timeElapsed / (double)i_totalTravelTime;
-        x = i_fromX + ((i_destX - i_fromX) * percent_passed);
-        y = i_fromY + ((i_destY - i_fromY) * percent_passed);
-        z = i_fromZ + ((i_destZ - i_fromZ) * percent_passed);
+        const float distanceX = ((i_destX - i_fromX) * percent_passed);
+        const float distanceY = ((i_destY - i_fromY) * percent_passed);
+        const float distanceZ = ((i_destZ - i_fromZ) * percent_passed);
+        x = i_fromX + distanceX;
+        y = i_fromY + distanceY;
+        //All that is wrong... Probleme is traveller need to fly or swimg... bad way to make it..., GS
+        if(is3D)
+            z = i_fromZ + distanceZ;
+        else
+        {
+            //That part is good... for mob Walking on the floor... But the floor is not allways what we thought :(...
+            z = MapManager::Instance().GetBaseMap(i_fromMapId)->GetHeight(x,y,i_fromZ);
+            const float groundDist = sqrt(distanceX*distanceX + distanceY*distanceY);
+            const float zDist = fabs(i_fromZ - z) + 0.000001f; //FineTune with that value..., GS
+            const float slope = groundDist / zDist;
+            if(fabs(slope) < 1.0f) // Or i set the Z to -10000 and ExpireMG when Z == -10000 so at that precise place the SetLocation will see something is wrong.
+                z = i_destZ;
+        }
     }
 }
 
-template<typename TRAVELLER>
-float
-DestinationHolder<TRAVELLER>::GetDistanceFromDestSq(const WorldObject &obj) const
+template<typename TRAVELLER> float DestinationHolder<TRAVELLER>::GetDistanceFromDest2dSq(const WorldObject &obj) const
 {
     float x,y,z;
     obj.GetPosition(x,y,z);
-    return (i_destX-x)*(i_destX-x)+(i_destY-y)*(i_destY-y)+(i_destZ-z)*(i_destZ-z);
+    return (i_destX-x)*(i_destX-x) + (i_destY-y)*(i_destY-y);
 }
 
-template<typename TRAVELLER>
-float
-DestinationHolder<TRAVELLER>::GetDestinationDiff(float x, float y, float z) const
+template<typename TRAVELLER> float DestinationHolder<TRAVELLER>::GetDistanceFromDestSq(const WorldObject &obj) const
 {
-    return sqrt(((x-i_destX)*(x-i_destX)) + ((y-i_destY)*(y-i_destY)) + ((z-i_destZ)*(z-i_destZ)));
+    float x,y,z;
+    obj.GetPosition(x,y,z);
+    return (i_destX-x)*(i_destX-x) + (i_destY-y)*(i_destY-y) + (i_destZ-z)*(i_destZ-z);
 }
+template<typename TRAVELLER> float DestinationHolder<TRAVELLER>::GetDestinationDiff2d(float x, float y, float z) const
+{
+    return sqrt( ((x-i_destX)*(x-i_destX)) + ((y-i_destY)*(y-i_destY)) );
+}
+template<typename TRAVELLER> float DestinationHolder<TRAVELLER>::GetDestinationDiff(float x, float y, float z) const
+{
+    return sqrt( ((x-i_destX)*(x-i_destX)) + ((y-i_destY)*(y-i_destY)) + ((z-i_destZ)*(z-i_destZ)));
+}
 #endif
Index: src/game/FleeingMovementGenerator.cpp
===================================================================
--- src/game/FleeingMovementGenerator.cpp	(revision 0)
+++ src/game/FleeingMovementGenerator.cpp	(revision 0)
@@ -0,0 +1,164 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "Creature.h"
+#include "MapManager.h"
+#include "FleeingMovementGenerator.h"
+#include "DestinationHolderImp.h"
+#include "ObjectAccessor.h"
+
+template<class T> void FleeingMovementGenerator<T>::_setNextLocation(T &unit)
+{
+    //no grid search since, i just need a angle... and badly need one if i fear something, GS
+    Unit* fearWho = ObjectAccessor::Instance().GetUnit(unit, fearWhoGuid);
+    if(!fearWho)
+        return;
+
+    float fearMoveAngle = unit.GetAngle(fearWho)+M_PI;
+    float fearWhoAngle = fearWho->GetOrientation();
+    float speed = unit.GetSpeed(MOVE_RUN);
+    float X = unit.GetPositionX();
+    float Y = unit.GetPositionY();
+    float Z = unit.GetPositionZ();
+    uint32 mapid = unit.GetMapId();
+    
+    //TODO: Play with max range, GS
+    if(unit.IsWithinDistInMap(fearWho, 28))
+    {
+        float x = X + speed * cos(fearMoveAngle);
+        float y = Y + speed * sin(fearMoveAngle);
+        float z;
+
+        if(unit.HasPathTo(x,y))
+        {
+            z = MapManager::Instance().GetBaseMap(mapid)->GetHeight(x,y,Z);
+            Traveller<T> traveller(unit);
+            unit.SetOrientation(fearMoveAngle);
+            i_destinationHolder.SetDestination(traveller, x, y, z);
+            unit.addUnitState(UNIT_STAT_FLEEING);
+        }
+        else
+        {
+            Traveller<T> traveller(unit);
+            unit.SetOrientation(fearMoveAngle);
+            i_destinationHolder.SetDestination(traveller, X, Y, Z);
+            unit.clearUnitState(UNIT_STAT_FLEEING);
+        }
+        
+        /*uint8 interlevingSide = 0;
+        float leftAngle, rightAngle;
+        leftAngle = rightAngle = 0.0f;
+        
+        //That is a path like searching with LOS.... I have another one without LOS... need fine tune and add that, GS.
+        while( (!unit.IsWithinLOS(x,y,z) ) && interlevingSide < 76 ) //interlevingSide 63 gave me about 90 Degree each Side
+        {
+            fearMoveAngle = fearWhoAngle+M_PI;
+            if ( !(interlevingSide & 1))        //Pair Number
+            { 
+                leftAngle += 0.05;
+                if(fearMoveAngle + leftAngle > (M_PI*2))
+                    fearMoveAngle = fearMoveAngle + leftAngle - (M_PI*2);
+                else
+                   fearMoveAngle += leftAngle; 
+                ++interlevingSide;       
+            }
+            else                                //Impair Number
+            {
+                rightAngle -= 0.05;
+                if( fearMoveAngle + rightAngle < 0)
+                    fearMoveAngle = fearMoveAngle + rightAngle + (M_PI*2);
+                else
+                    fearMoveAngle += rightAngle; 
+                ++interlevingSide; 
+            }
+            x = X + (speed*3+unit.GetObjectSize()) * cos(fearMoveAngle);
+            y = Y + (speed*3+unit.GetObjectSize()) * sin(fearMoveAngle);
+            z = MapManager::Instance().GetBaseMap(mapid)->GetHeight(x,y,Z);
+        }
+
+        if( interlevingSide < 76 )
+        {
+            x = X + (speed*3) * cos(fearMoveAngle);
+            y = Y + (speed*3) * sin(fearMoveAngle);
+            //z = Z; //Doing Test... Probaly not needed...
+            z = MapManager::Instance().GetBaseMap(mapid)->GetHeight(x,y,Z);
+
+
+        }
+        else                //At this point i think is better UnFear the MV owner or at max Range.. , GS
+        {
+            Traveller<T> traveller(unit);
+            unit.SetOrientation(fearMoveAngle);
+            i_destinationHolder.SetDestination(traveller, X, Y, Z);
+            unit.clearUnitState(UNIT_STAT_FLEEING);
+        }*/
+    }
+}
+
+template<class T> void FleeingMovementGenerator<T>::Initialize(T &unit)
+{
+    if(!&unit || !unit.isAlive())
+        return;
+
+    unit.setMoveRunFlag(true);
+    _setNextLocation(unit);
+}
+template<class T> void FleeingMovementGenerator<T>::Reset(T &unit)
+{
+
+}
+
+template<class T> bool FleeingMovementGenerator<T>::Update(T &unit, const uint32 &diff)
+{
+    if(!&unit || !unit.isAlive())
+        return false;
+
+    if(!i_destinationHolder.HasArrived() && unit.IsStopped())
+        unit.addUnitState(UNIT_STAT_FLEEING);
+
+    if( i_destinationHolder.GetTimeToDest() < diff )
+    {
+        float x,y,z;
+        i_destinationHolder.GetLocationNow(x,y,z);
+        unit.Relocate(x,y,z);
+        _setNextLocation(unit);
+    }
+    Traveller<T> traveller(unit);
+    i_destinationHolder.UpdateTraveller(traveller, diff, false);
+    
+    if( !unit.HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_FLEEING) )
+    {
+        /*if(i_destinationHolder.GetTimeToDest())
+        {
+            float x,y,z;
+            i_destinationHolder.GetLocationNow(x,y,z);
+            unit.Relocate(x,y,z);
+        }*/
+        return false;
+    }
+    return true;
+}
+
+template void FleeingMovementGenerator<Player>::_setNextLocation(Player &);
+template void FleeingMovementGenerator<Creature>::_setNextLocation(Creature &);
+template void FleeingMovementGenerator<Player>::Initialize(Player &player);
+template void FleeingMovementGenerator<Creature>::Initialize(Creature &creature);
+template void FleeingMovementGenerator<Player>::Reset(Player &player);
+template void FleeingMovementGenerator<Creature>::Reset(Creature &creature);
+template bool FleeingMovementGenerator<Player>::Update(Player &player, const uint32 &diff);
+template bool FleeingMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff);
Index: src/game/FleeingMovementGenerator.h
===================================================================
--- src/game/FleeingMovementGenerator.h	(revision 0)
+++ src/game/FleeingMovementGenerator.h	(revision 0)
@@ -0,0 +1,46 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef MANGOS_FLEEINGMOTIONGENERATOR_H
+#define MANGOS_FLEEINGMOTIONGENERATOR_H
+
+#include "MovementGenerator.h"
+#include "DestinationHolder.h"
+#include "Traveller.h"
+
+template<class T>
+class MANGOS_DLL_DECL FleeingMovementGenerator 
+    : public MovementGeneratorMedium< T, FleeingMovementGenerator<T> >
+{
+    public:
+        FleeingMovementGenerator(const Unit &, const uint64 _fearWhoGuid) : fearWhoGuid(_fearWhoGuid) {}
+
+        void Initialize(T &);
+        void Reset(T &);
+        bool Update(T &, const uint32 &);
+        void UpdateMapPosition(float &x ,float &y, float &z)
+        {
+            i_destinationHolder.GetLocationNow(x,y,z);
+        }
+        MovementGeneratorType GetMovementGeneratorType() { return FLEEING_MOTION_TYPE; }
+    private:
+        void _setNextLocation(T &);
+        DestinationHolder< Traveller<T> > i_destinationHolder;
+        uint64 fearWhoGuid;
+};
+#endif
Index: src/game/GridDefines.h
===================================================================
--- src/game/GridDefines.h	(revision 4763)
+++ src/game/GridDefines.h	(working copy)
@@ -33,7 +33,7 @@
 
 #define MAX_NUMBER_OF_GRIDS      64
 
-#define SIZE_OF_GRIDS            533.33333f
+#define SIZE_OF_GRIDS            533.333333f
 #define CENTER_GRID_ID           (MAX_NUMBER_OF_GRIDS/2)
 
 #define CENTER_GRID_OFFSET      (SIZE_OF_GRIDS/2)
Index: src/game/GridNotifiers.h
===================================================================
--- src/game/GridNotifiers.h	(revision 4763)
+++ src/game/GridNotifiers.h	(working copy)
@@ -623,10 +623,10 @@
                     return false;
 
                 // only from same creature faction
-                if(u->getFaction() != i_funit->getFaction() )
+                if( u->getFaction() != i_funit->getFaction() )
                     return false;
 
-                if(!u->IsWithinLOSInMap(i_enemy) )
+                if( !u->IsWithinLOSInMap(i_enemy) )
                     return false;
 
                 return true;
Index: src/game/GridNotifiersImpl.h
===================================================================
--- src/game/GridNotifiersImpl.h	(revision 4763)
+++ src/game/GridNotifiersImpl.h	(working copy)
@@ -70,24 +70,26 @@
     pl->UpdateVisibilityOf(c);
 
     // Creature AI reaction
-    if(!c->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING))
+    if( !c->hasUnitState( UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING ) )
     {
-        if( c->AI() && c->AI()->IsVisible(pl) && !c->IsInEvadeMode() )
+        if( c->AI() && c->AI()->IsVisible(pl) /*&& !c->IsInEvadeMode()*/ )
             c->AI()->MoveInLineOfSight(pl);
     }
 }
 
 inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2)
 {
-    if(!c1->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING))
+    //C2 is the Mover
+    if( !c1->hasUnitState( UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING) )
     {
-        if( c1->AI() && c1->AI()->IsVisible(c2) && !c1->IsInEvadeMode() )
+        if( c1->AI() && c1->AI()->IsVisible(c2)  )
             c1->AI()->MoveInLineOfSight(c2);
     }
-
-    if(!c2->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING))
+    
+    //To make Pet See everyone they call MILOS on... 
+    if( c2->isPet() && !c2->hasUnitState( (UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING )) )
     {
-        if( c2->AI() && c2->AI()->IsVisible(c1) && !c2->IsInEvadeMode() )
+        if( c2->AI() && c2->AI()->IsVisible(c1) )
             c2->AI()->MoveInLineOfSight(c1);
     }
 }
@@ -107,6 +109,15 @@
 inline void
 MaNGOS::CreatureRelocationNotifier::Visit(PlayerMapType &m)
 {
+    //Here should be when a creature move with RandomMV as example
+    //So she be sure to make all player around call for MILOS, is Player move with have double MILOS and before my change we had 4x MILOS
+    //So now we have MILOS comming from player only when Player move...
+    //All that maybe sound like a probleme... but not if grid notifier.
+    //Grid notifier should get update at all 100MS and checked for changed XY and Z
+    //So we have maximun 1 MILOS by target for a total 100MS.
+    //Why i think is better, not used that needed case here for the moment.
+    //Not good way to solve this situation... Is taking too much CPU, GS.
+    //return;
     if(!i_creature.isAlive())
         return;
 
@@ -119,7 +130,7 @@
 inline void
 MaNGOS::CreatureRelocationNotifier::Visit(CreatureMapType &m)
 {
-    if(!i_creature.isAlive())
+    if(!i_creature.isAlive() || (!i_creature.hasUnitState(UNIT_STAT_CHASE) && !i_creature.isPet() ) )
         return;
 
     for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
Index: src/game/GuardAI.cpp
===================================================================
--- src/game/GuardAI.cpp	(revision 4763)
+++ src/game/GuardAI.cpp	(working copy)
@@ -44,7 +44,7 @@
         u->isInAccessablePlaceFor(&i_creature))
     {
         float attackRadius = i_creature.GetAttackDistance(u);
-        if(i_creature.IsWithinDistInMap(u,attackRadius) && i_creature.GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE)
+        if(i_creature.IsWithinDistInMap(u,attackRadius) && !i_creature.HasPathTo(u))
         {
             //Need add code to let guard suport player
             AttackStart(u);
@@ -58,8 +58,6 @@
     if( !i_creature.isAlive() )
     {
         DEBUG_LOG("Creature stopped attacking because he's dead [guid=%u]", i_creature.GetGUIDLow());
-        i_creature.StopMoving();
-        i_creature.GetMotionMaster()->Idle();
 
         i_state = STATE_NORMAL;
 
@@ -97,10 +95,6 @@
     i_victimGuid = 0;
     i_creature.CombatStop(true);
     i_state = STATE_NORMAL;
-
-    // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
-    if( i_creature.GetMotionMaster()->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE )
-        i_creature.GetMotionMaster()->TargetedHome();
 }
 
 void GuardAI::UpdateAI(const uint32 diff)
Index: src/game/HomeMovementGenerator.cpp
===================================================================
--- src/game/HomeMovementGenerator.cpp	(revision 4763)
+++ src/game/HomeMovementGenerator.cpp	(working copy)
@@ -23,50 +23,58 @@
 #include "ObjectAccessor.h"
 #include "DestinationHolderImp.h"
 
-void
-HomeMovementGenerator<Creature>::Initialize(Creature & owner)
+#define WALKING_CHANCE_HOMEMV 20    //Chance will be " 1 / WALKING_CHANCE_HOMEMV"
+
+void HomeMovementGenerator<Creature>::_setHomeLocation(Creature & creature)
 {
-    owner.setMoveRunFlag(true);
-    _setTargetLocation(owner);
+    //I don't think set destination should start traveller.... so we are little more flexible, GS
+    if( !&creature || !creature.isAlive() )
+        return;
+
+    float x, y, z;
+    creature.GetRespawnCoord(x, y, z);
+    
+    Traveller<Creature> traveller(creature);
+    creature.SetOrientation(creature.GetAngle(x,y));//Need Badly Orientation of Spawn, GS
+    i_destinationHolder.SetDestination(traveller, x, y, z);
+    creature.addUnitState(UNIT_STAT_SEARCHING);
 }
-
-void
-HomeMovementGenerator<Creature>::Reset(Creature &)
+void HomeMovementGenerator<Creature>::Initialize(Creature & creature)
 {
+    creature.setMoveRunFlag(irand(0,WALKING_CHANCE_HOMEMV));
+    _setHomeLocation(creature);
 }
-
-void
-HomeMovementGenerator<Creature>::_setTargetLocation(Creature & owner)
+void HomeMovementGenerator<Creature>::Reset(Creature &)
 {
-    if( !&owner )
-        return;
 
-    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED) )
-        return;
-
-    float x, y, z;
-    owner.GetRespawnCoord(x, y, z);
-
-    CreatureTraveller traveller(owner);
-
-    uint32 travel_time = i_destinationHolder.SetDestination(traveller, x, y, z);
-    modifyTravelTime(travel_time);
-    owner.clearUnitState(UNIT_STAT_ALL_STATE);
 }
-
-bool
-HomeMovementGenerator<Creature>::Update(Creature &owner, const uint32& time_diff)
+bool HomeMovementGenerator<Creature>::Update(Creature &creature, const uint32& diff)
 {
-    CreatureTraveller traveller( owner);
-    i_destinationHolder.UpdateTraveller(traveller, time_diff, false);
+    //TODO: Complete UNIT_STAT_SEARCHING, when creature has this status she won't accept any MILOS...
+    //So a creature going home won't change mind into the first 50% of mv... other MV will herite too.
+    //Juts have to think really with is the best UNIT STAT to use... and Do automation with checking unit field flag, as the client do is best.
+    if(!&creature || !creature.isAlive())
+        return false;
 
-    if (time_diff > i_travel_timer)
+    CreatureTraveller traveller(creature);
+    
+    if(!i_destinationHolder.HasDestination())
     {
-        owner.setMoveRunFlag(false);
+       Initialize(creature);
+       return true; 
+    }
+    else if( i_destinationHolder.HasArrived() )
+    {
+        if(!creature.IsStopped())
+            creature.clearUnitState(UNIT_STAT_SEARCHING);
         return false;
     }
+    else if(  i_destinationHolder.GetTimeToDest() < i_destinationHolder.GetTotalTravelTime()/2.0f)
+         creature.clearUnitState(UNIT_STAT_SEARCHING);
+    else if ( creature.IsStopped() )
+        creature.addUnitState((UNIT_STAT_SEARCHING | UNIT_STAT_ROAMING));
 
-    i_travel_timer -= time_diff;
+    i_destinationHolder.UpdateTraveller(traveller, diff, false);
 
     return true;
 }
Index: src/game/HomeMovementGenerator.h
===================================================================
--- src/game/HomeMovementGenerator.h	(revision 4763)
+++ src/game/HomeMovementGenerator.h	(working copy)
@@ -40,14 +40,15 @@
         void Initialize(Creature &);
         void Reset(Creature &);
         bool Update(Creature &, const uint32 &);
-        void modifyTravelTime(uint32 travel_time) { i_travel_timer = travel_time; }
+        void UpdateMapPosition(float &x ,float &y, float &z)
+        {
+            i_destinationHolder.GetLocationNow(x,y,z);
+        }
         MovementGeneratorType GetMovementGeneratorType() { return HOME_MOTION_TYPE; }
 
     private:
-        void _setTargetLocation(Creature &);
+        void _setHomeLocation(Creature &);
         DestinationHolder< Traveller<Creature> > i_destinationHolder;
-
-        uint32 i_travel_timer;
 };
 
 #endif
Index: src/game/IdleMovementGenerator.cpp
===================================================================
--- src/game/IdleMovementGenerator.cpp	(revision 4763)
+++ src/game/IdleMovementGenerator.cpp	(working copy)
@@ -17,11 +17,28 @@
  */
 
 #include "IdleMovementGenerator.h"
-#include "Creature.h"
+#include "Unit.h"
+//IdleMovementGenerator si_idleMovement;
 
-IdleMovementGenerator si_idleMovement;
-
-void
-IdleMovementGenerator::Reset(Unit &owner)
+void IdleMovementGenerator::Reset(Unit &owner)
 {
+    //Maybe reset lastTimer if not infinite
 }
+void IdleMovementGenerator::Initialize(Unit &owner)
+{
+}
+bool IdleMovementGenerator::Update(Unit &owner, const uint32 &diff)
+{
+    if(!owner.IsStopped())
+        owner.clearUnitState(UNIT_STAT_MOVING);
+
+    if(!i_infinite)
+    {
+        if( i_lastTimer < diff )
+            return false;
+        else
+            i_lastTimer -= diff;
+    }
+
+    return true;
+}
Index: src/game/IdleMovementGenerator.h
===================================================================
--- src/game/IdleMovementGenerator.h	(revision 4763)
+++ src/game/IdleMovementGenerator.h	(working copy)
@@ -24,12 +24,20 @@
 class MANGOS_DLL_SPEC IdleMovementGenerator : public MovementGenerator
 {
     public:
+        IdleMovementGenerator(Unit &, bool infinite = true, uint32 lastTimer = 0) : 
+        i_infinite(infinite), i_lastTimer(lastTimer) {}
+        ~IdleMovementGenerator() {}
 
-        void Initialize(Unit &) {  }
+        void Initialize(Unit &);
         void Reset(Unit &);
-        bool Update(Unit &, const uint32 &) { return true; }
+        bool Update(Unit &, const uint32 &);
         MovementGeneratorType GetMovementGeneratorType() { return IDLE_MOTION_TYPE; }
+
+    private:
+        uint32 i_lastTimer;
+        bool i_infinite;
+    
 };
 
-extern IdleMovementGenerator si_idleMovement;
+//extern IdleMovementGenerator si_idleMovement;
 #endif
Index: src/game/Map.cpp
===================================================================
--- src/game/Map.cpp	(revision 4763)
+++ src/game/Map.cpp	(working copy)
@@ -1448,7 +1448,7 @@
 {
     CellLock<ReadGuard> cell_lock(cell, cellpair);
     MaNGOS::CreatureRelocationNotifier relocationNotifier(*creature);
-    cell.data.Part.reserved = ALL_DISTRICT;
+    cell.data.Part.reserved = CENTER_DISTRICT;
     cell.SetNoCreate();                                     // not trigger load unloaded grids at notifier call
 
     TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, WorldTypeMapContainer > c2world_relocation(relocationNotifier);
Index: src/game/MotionMaster.cpp
===================================================================
--- src/game/MotionMaster.cpp	(revision 4763)
+++ src/game/MotionMaster.cpp	(working copy)
@@ -20,123 +20,106 @@
 #include "CreatureAISelector.h"
 #include "Creature.h"
 #include "Traveller.h"
+#include "TargetedMovementGenerator.h"
 #include "HomeMovementGenerator.h"
 #include "IdleMovementGenerator.h"
+#include "RandomMovementGenerator.h"
 #include <cassert>
 
-inline bool isStatic(MovementGenerator *mv)
+MotionMaster::~MotionMaster()
 {
-    return (mv == &si_idleMovement);
-}
-
-void
-MotionMaster::Initialize()
-{
-    // clear ALL movement generators (including default)
-    while(!empty())
+    // clear ALL movement generators
+    while( !empty() )
     {
         MovementGenerator *curr = top();
         pop();
-        if( !isStatic( curr ) )
-            delete curr;
+        delete curr;
     }
+}
+void MotionMaster::Initialize()
+{
+    i_owner->StopMoving();
 
-    // set new default movement generator
-    if(i_owner->GetTypeId() == TYPEID_UNIT)
+    if(!empty())
+        top()->Initialize(*i_owner);
+    else if(i_owner->GetTypeId() == TYPEID_UNIT && !((Creature*)i_owner)->isPet())
     {
         MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner);
-        push(  movement == NULL ? &si_idleMovement : movement );
+        push(  movement == NULL ? new IdleMovementGenerator(*i_owner) : movement );
         top()->Initialize(*i_owner);
     }
+    else if(i_owner->GetTypeId() == TYPEID_UNIT && ((Creature*)i_owner)->isPet())
+    {
+        push(new RandomMovementGenerator<Creature>(*i_owner)); 
+    }    
     else
-        push(&si_idleMovement);
-}
-
-MotionMaster::~MotionMaster()
-{
-    // clear ALL movement generators (including default)
-    while(!empty())
     {
-        MovementGenerator *curr = top();
-        pop();
-        if( !isStatic( curr ) )
-            delete curr;
+        push(new IdleMovementGenerator(*i_owner));
+        //top()->Initialize(*i_owner);
     }
 }
-
-void
-MotionMaster::UpdateMotion(const uint32 &diff)
+void MotionMaster::UpdateMotion(const uint32 &diff)
 {
-    if(i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
+    //TODO: Remove Both with the Use of Idle MV , GS
+    if(i_owner->hasUnitState((UNIT_STAT_ROOT | UNIT_STAT_STUNDED )) )
         return;
-    assert( !empty() );
+
     if (!top()->Update(*i_owner, diff))
         MovementExpired();
 }
-
-void
-MotionMaster::Clear(bool reset)
+void MotionMaster::Clear(bool reset)
 {
-    while( !empty() && size() > 1 )
+    while( size() > 1 )
     {
         MovementGenerator *curr = top();
         pop();
-        if( !isStatic( curr ) )
-            delete curr;
+        delete curr;
     }
 
-    assert( !empty() );
-    if (reset) top()->Reset(*i_owner);
+    if(reset)
+        top()->Initialize(*i_owner);
 }
-
-void
-MotionMaster::MovementExpired(bool reset)
+void MotionMaster::MovementExpired(bool reset)
 {
-    if( empty() || size() == 1 )
+    if( size() < 2 )                //Never Delete the Index 0, and if we are at 0... something is wrong, GS
         return;
 
-    MovementGenerator *curr = top();
-    pop();
+    i_owner->StopMoving();                          // In Fact No need to STOP, but need to update the Current Map Location before expiration, GS
+    MovementGenerator *curr = top();                // Save pointer to object into the list as Current One
+    pop();                                          // delete from List current one and put the next one on top.
+    delete curr;                                    // Delete object at pointer, old current one
 
-    if( !isStatic(curr) )
-        delete curr;
+    curr = top();
 
-    assert( !empty() );
-    while( !empty() && top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE )
-    {
-        // Should check if target is still valid? If not valid it will crash.
-        curr = top();
-        pop();
-        delete curr;
-    }
-    if( empty() )
-        Initialize();
-    if (reset) top()->Reset(*i_owner);
+    if( reset )
+        curr->Initialize(*i_owner);
 }
 
-void
-MotionMaster::TargetedHome()
+void MotionMaster::TargetedHome()
 {
-    if(i_owner->hasUnitState(UNIT_STAT_FLEEING))
-        return;
-
-    DEBUG_LOG("Target home location %u", i_owner->GetGUIDLow());
-
-    Clear(false);
     Mutate(new HomeMovementGenerator<Creature>());
 }
 
-void MotionMaster::Idle(void)
+void MotionMaster::Idle(bool infinite, uint32 lastTimer)
 {
-    if( empty() || !isStatic( top() ) )
-        push( &si_idleMovement );
+    Mutate(new IdleMovementGenerator(*i_owner,infinite,lastTimer) );
 }
 
 void MotionMaster::Mutate(MovementGenerator *m)
 {
-    // HomeMovement is not that important, delete it if meanwhile a new comes
-    if (!empty() && top()->GetMovementGeneratorType() == HOME_MOTION_TYPE)
-        MovementExpired(false);
+    i_owner->StopMoving();
+
+    if(size() == 1 && i_owner->GetTypeId() == TYPEID_UNIT && !((Creature*)i_owner)->isPet()&& (m->GetMovementGeneratorType() & (TARGETED_MOTION_TYPE | FLEEING_MOTION_TYPE)) )
+    {
+        //Buggy case, but for moment ok doki... 
+        switch(top()->GetMovementGeneratorType())
+        {
+            case IDLE_MOTION_TYPE:
+            {
+                push(new HomeMovementGenerator<Creature>());
+            }
+        }
+    }
     m->Initialize(*i_owner);
     push(m);
 }
Index: src/game/MotionMaster.h
===================================================================
--- src/game/MotionMaster.h	(revision 4763)
+++ src/game/MotionMaster.h	(working copy)
@@ -38,7 +38,8 @@
     CONFUSED_MOTION_TYPE  = 4,                              // ConfusedMovementGenerator.h
     TARGETED_MOTION_TYPE  = 5,                              // TargetedMovementGenerator.h
     HOME_MOTION_TYPE      = 6,                              // HomeMovementGenerator.h
-    FLIGHT_MOTION_TYPE    = 7                               // WaypointMovementGenerator.h
+    FLIGHT_MOTION_TYPE    = 7,                              // WaypointMovementGenerator.h
+    FLEEING_MOTION_TYPE   = 8                               // FleeingMovementGenerator.h
 };
 
 class MANGOS_DLL_SPEC MotionMaster : private std::stack<MovementGenerator *>
@@ -67,7 +68,7 @@
 
         void MovementExpired(bool reset = true);
 
-        void Idle(void);
+        void Idle(bool infinite = true, uint32 lastTimer = 0);
 
         void TargetedHome();
 
Index: src/game/MovementHandler.cpp
===================================================================
--- src/game/MovementHandler.cpp	(revision 4763)
+++ src/game/MovementHandler.cpp	(working copy)
@@ -111,7 +111,7 @@
 {
     CHECK_PACKET_SIZE(recv_data, 4+4+4+4+4+4);
 
-    if(GetPlayer()->GetDontMove())
+    if( GetPlayer()->GetDontMove() )
         return;
 
     /* extract packet */
@@ -239,15 +239,19 @@
         GetPlayer()->SetInWater( !GetPlayer()->IsInWater() );
     /*----------------------*/
 
-    /* process position-change */
-    recv_data.put<uint32>(4, getMSTime());
-    WorldPacket data(recv_data.GetOpcode(), (GetPlayer()->GetPackGUID().size()+recv_data.size()));
-    data.append(GetPlayer()->GetPackGUID());
-    data.append(recv_data.contents(), recv_data.size());
-    GetPlayer()->SendMessageToSet(&data, false);
 
-    GetPlayer()->SetPosition(x, y, z, orientation);
-    GetPlayer()->SetMovementFlags(flags);
+
+    if(!GetPlayer()->HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_FLEEING))
+    {
+        /* process position-change */
+        recv_data.put<uint32>(4, getMSTime());
+        WorldPacket data(recv_data.GetOpcode(), (GetPlayer()->GetPackGUID().size()+recv_data.size()));
+        data.append(GetPlayer()->GetPackGUID());
+        data.append(recv_data.contents(), recv_data.size());
+        GetPlayer()->SendMessageToSet(&data, false);
+        GetPlayer()->SetPosition(x, y, z, orientation);
+        GetPlayer()->SetMovementFlags(flags);
+    }
 }
 
 void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
Index: src/game/NPCHandler.cpp
===================================================================
--- src/game/NPCHandler.cpp	(revision 4763)
+++ src/game/NPCHandler.cpp	(working copy)
@@ -35,6 +35,7 @@
 #include "MapManager.h"
 #include "Pet.h"
 #include "WaypointMovementGenerator.h"
+#include "IdleMovementGenerator.h"
 #include "BattleGroundMgr.h"
 #include "BattleGround.h"
 
@@ -250,7 +251,8 @@
 
     if( unit->isArmorer() || unit->isCivilian() || unit->isQuestGiver() || unit->isServiceProvider())
     {
-        unit->StopMoving();
+        //TODO: Add static until all Gossip are closed.
+        unit->GetMotionMaster()->Mutate(new IdleMovementGenerator(*unit,false,30000));
         //npcIsStopped[unit->GetGUID()] = true;
     }
 
Index: src/game/Object.cpp
===================================================================
--- src/game/Object.cpp	(revision 4763)
+++ src/game/Object.cpp	(working copy)
@@ -864,18 +864,19 @@
     return ( dist > 0 ? dist : 0);
 }
 
-bool WorldObject::IsWithinDistInMap(const WorldObject* obj, const float dist2compare) const
+//TODO: Rename to: IsWithinDistInMap2D and create 3D, GS
+bool WorldObject::IsWithinDistInMap(const WorldObject* obj, const float withInDist) const
 {
+    //I wan faster, faster, faster Code here :) , GS  
     if (!obj || !IsInMap(obj)) return false;
 
     float dx = GetPositionX() - obj->GetPositionX();
     float dy = GetPositionY() - obj->GetPositionY();
     float dz = GetPositionZ() - obj->GetPositionZ();
-    float distsq = dx*dx + dy*dy + dz*dz;
-    float sizefactor = GetObjectSize() + obj->GetObjectSize();
-    float maxdist = dist2compare + sizefactor;
+    float dist2D = sqrt(dx*dx + dy*dy) - GetObjectSize() - obj->GetObjectSize();
+    float distZ = sqrt(dz*dz) - 4.0f; //Each Moving Object is in size 2.0f Tall, event maybe a little more, GS.
 
-    return distsq < maxdist * maxdist;
+    return withInDist >= dist2D && withInDist >= distZ;
 }
 
 bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const
@@ -891,7 +892,7 @@
     float x,y,z;
     GetPosition(x,y,z);
     VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
-    return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f);
+    return vMapManager->isInLineOfSight(GetMapId(), x, y, z+1.4f, ox, oy, oz+1.4f);
 }
 
 float WorldObject::GetAngle(const WorldObject* obj) const
@@ -946,7 +947,9 @@
     }
 
     // angle to face `obj` to `this`
-    float angle = rand_norm()*2*M_PI;
+    srand(getMSTime());
+    float angle = rand_norm()*(M_PI*2);
+    srand(getMSTime());
     float new_dist = rand_norm()*distance;
 
     rand_x = x + new_dist * cos(angle);
@@ -962,7 +965,7 @@
     {
         float new_z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(x,y,z);
         if(new_z > VMAP_INVALID_HEIGHT)
-            z = new_z+ 0.2f;                                // just to be sure that we are not a few pixel under the surface
+            z = new_z/*+ 0.1f*/;                                // just to be sure that we are not a few pixel under the surface
     }
 }
 
@@ -1203,20 +1206,82 @@
 } // namespace MaNGOS
 
 //===================================================================================================
+//HasPathTo is to test not complete and doing really not good job... so...TESTING, GS
+bool WorldObject::HasPathTo(WorldObject const* who)
+{
+    const float angleToWho = GetAngle(who);
+    const float distanceToWho = GetDistance2d(who);
+    float distanceToCheck = 0.5;
+    float X,Y,Z,x,y,z, checkX,checkY,checkZ;
+    who->GetPosition(x,y,z);
+    GetPosition(X,Y,Z);
+    const Map* map = MapManager::Instance().GetBaseMap(GetMapId());
+    
+    //if( fabs(z - Z) + 0.000001f > 3.0f)
+       // return false;
 
+    for(;distanceToWho > distanceToCheck; distanceToCheck += 0.5)
+    {
+        checkX = X + (distanceToCheck * cos(angleToWho));
+        checkY = Y + (distanceToCheck * sin(angleToWho));
+        checkZ = map->GetHeight(checkX,checkY,Z);     //Disable LOS when a creature is the target... For saving cpu... but is needed in fact, GS.
+        const float zDist = fabs(checkZ - Z) + 0.000001f; //FineTune with that value..., GS
+        const float slope = distanceToCheck / zDist;
+        if(fabs(slope) < 1.00 || (map->GetTerrainType(checkX,checkY) & 0x01))
+            return false;
+    }
+    return true;
+}
+bool WorldObject::HasPathTo(float x, float y)
+{
+    
+    const float angleToWho = GetAngle(x,y);
+    const float distanceToWho = GetDistance2d(x,y);
+    float distanceToCheck = 0.5;
+    float X,Y,Z, checkX,checkY,checkZ;
+    GetPosition(X,Y,Z);
+    const Map* map = MapManager::Instance().GetBaseMap(GetMapId());
+    for(;distanceToWho > distanceToCheck; distanceToCheck += 0.5)
+    {
+        checkX = X + (distanceToCheck * cos(angleToWho));
+        checkY = Y + (distanceToCheck * sin(angleToWho));
+        checkZ = map->GetHeight(checkX,checkY,Z);
+        const float zDist = fabs(checkZ - Z) + 0.000001f; //FineTune with that value..., GS
+        const float slope = distanceToCheck / zDist;
+        if(fabs(slope) < 1.00 || (map->GetTerrainType(checkX,checkY) & 0x01) )
+            return false;
+    }
+    return true;
+}
 void WorldObject::GetNearPoint2D(float &x, float &y, float distance2d, float absAngle ) const
 {
-    x = GetPositionX() + (GetObjectSize() + distance2d) * cos(absAngle);
-    y = GetPositionY() + (GetObjectSize() + distance2d) * sin(absAngle);
+    x = GetPositionX() + ((distance2d+GetObjectSize()) * cos(absAngle));
+    y = GetPositionY() + ((distance2d+GetObjectSize()) * sin(absAngle));
 }
-
-void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y, float &z, float distance2d, float absAngle ) const
+//Pet Follow Will be wrong there, i think best way will be to specifie if Combat Targeted or Following Targeted, GS
+void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y, float &z, float distance2d, float absAngle) const
 {
-    float size = searcher ? searcher->GetObjectSize() : 0;
-
-    GetNearPoint2D(x,y,distance2d+size,absAngle);
+    //Need to fix that so Pet are not using that distance check, should be since searcher is NULL on pet Follow... But... GS
+    float minReachRadius = searcher ? searcher->GetObjectSize() + (searcher->GetFloatValue(UNIT_FIELD_COMBATREACH)/1.75) : 0;
+    distance2d = distance2d < minReachRadius ? minReachRadius : distance2d;
+    GetNearPoint2D(x,y,distance2d,absAngle);
     z = GetPositionZ();
+    const float nz = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(x,y,z);
+    
+    //2D-MG
+    const float zDist = fabs(z - nz) + 0.000001f; //FineTune with that value..., GS
+    const float slope = distance2d / zDist;
+    if(fabs(slope) < 1.00 || (MapManager::Instance().GetBaseMap(GetMapId())->GetTerrainType(x,y) & 0x01)) // Doing Loop To find good One is better and Put Next Update time very High if can find any.
+    {
+        if(searcher)
+        {
+            searcher->GetPosition(x,y,z); // all wrong but for testing... as i say ofent into comment Targeted MV need replacement so.., GS
+        }  
+    }
+    return;
 
+    //All below are such complicated for what we really need for poscollision.
+    //TODO: Update that... will be done in fact from MovementGenerator
     // if detection disabled, return first point
     if(!sWorld.getConfig(CONFIG_DETECT_POS_COLLISION))
     {
@@ -1230,7 +1295,7 @@
     bool first_los_conflict = false;                                  // first point LOS problems
 
     // prepare selector for for work
-    ObjectPosSelector selector(GetPositionX(),GetPositionY(),GetObjectSize(),distance2d+size);
+    ObjectPosSelector selector(GetPositionX(),GetPositionY(),GetObjectSize(),distance2d+minReachRadius);
 
     // adding used positions around object
     {
Index: src/game/Object.h
===================================================================
--- src/game/Object.h	(revision 4763)
+++ src/game/Object.h	(working copy)
@@ -24,13 +24,14 @@
 #include "UpdateFields.h"
 #include "UpdateData.h"
 #include "GameSystem/GridReference.h"
+#include "../shared/Util.h"
 
 #include <set>
 #include <string>
 
 #define CONTACT_DISTANCE            0.5
 #define INTERACTION_DISTANCE        5
-#define ATTACK_DISTANCE                 5
+#define ATTACK_DISTANCE             5
 #define DETECT_DISTANCE             20                      // max distance to successful detect stealthed unit
 #define MAX_VISIBILITY_DISTANCE     (5*SIZE_OF_GRID_CELL/2) // max distance for visible object show, limited by active zone for player based at cell size (active zone = 5x5 cells)
 #define DEFAULT_VISIBILITY_DISTANCE (SIZE_OF_GRID_CELL)     // default visible distance
@@ -278,17 +279,23 @@
         void GetPosition( float &x, float &y, float &z ) const
             { x = m_positionX; y = m_positionY; z = m_positionZ; }
         float GetOrientation( ) const { return m_orientation; }
+        bool HasPathTo(WorldObject const* who);
+        bool HasPathTo(float x, float y);
         void GetNearPoint2D( float &x, float &y, float distance, float absAngle) const;
-        void GetNearPoint( WorldObject const* searcher, float &x, float &y, float &z, float distance2d,float absAngle) const;
+        void GetNearPoint( WorldObject const* follower, float &x, float &y, float &z, float distance2d,float absAngle) const;
         void GetClosePoint(float &x, float &y, float &z, float distance2d = 0, float angle = 0) const
         {
             // angle calculated from current orientation
             GetNearPoint(NULL,x,y,z,distance2d,GetOrientation() + angle);
+            
         }
         void GetContactPoint( const WorldObject* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const
         {
-            // angle to face `obj` to `this` using distance includes size of `obj`
-            GetNearPoint(obj,x,y,z,distance2d,GetAngle( obj ));
+            //angle to face `obj` to `this` using distance includes size of `obj`
+            //Will be much more better make a MASK 32 Bits on each Unit... and we make 32 possible solution
+            //16 Front 16 Back... i think will be enought, or 64Bits mask... so 32/32
+            //To replace PosCollision, PosCollision is good system but will better, for a global collision system, GS
+            GetNearPoint(obj,x,y,z,distance2d, /*GetAngle(obj)*/rand_norm()*(M_PI*2));
         }
         const float GetObjectSize() const
         {
Index: src/game/ObjectAccessor.cpp
===================================================================
--- src/game/ObjectAccessor.cpp	(revision 4763)
+++ src/game/ObjectAccessor.cpp	(working copy)
@@ -604,6 +604,9 @@
             update_cell << 1;
             update_cell -= 1;
 
+            //Here is Creating Loop under some Circonstance, GS...
+            // >> / << Update X and +/- Update Y
+            //Seem to happen when we are very near Bondary... of a Grid....
             for( ; abs(int32(standing_cell.x_coord) - int32(update_cell.x_coord)) < 2; update_cell >> 1 )
             {
                 for(CellPair cell_iter=update_cell; abs(int32(standing_cell.y_coord) - int32(cell_iter.y_coord)) < 2; cell_iter += 1 )
Index: src/game/ObjectMgr.cpp
===================================================================
--- src/game/ObjectMgr.cpp	(revision 4763)
+++ src/game/ObjectMgr.cpp	(working copy)
@@ -693,7 +693,11 @@
         data.movementType   = fields[19].GetUInt8();
         data.auras          = fields[20].GetCppString();
         int16 gameEvent     = fields[21].GetInt16();
-
+        if(data.movementType == 1 && data.spawndist <= 0.0f)
+        {
+            sLog.outErrorDb("table creature, GUID:%u , table creature_template, ENTRY:%u , Has RandomMovement but SpawnDist==%f",guid,data.id,data.spawndist);
+            data.movementType = 0;
+        }
         if (gameEvent==0)                                   // if not this is to be managed by GameEvent System
             AddCreatureToGrid(guid, &data);
         count++;
@@ -706,6 +710,191 @@
     sLog.outString( ">> Loaded %u creatures", mCreatureDataMap.size() );
 }
 
+void ObjectMgr::LoadCreatureSpellBook()
+{
+    
+    QueryResult* _result = WorldDatabase.Query("SELECT * FROM creature_spellbook");
+
+    if(!_result)
+    {
+        barGoLink bar(1);
+
+        bar.step();
+
+        sLog.outString("");
+        sLog.outErrorDb(">> Loaded 0 creature_spellBook definition. DB table `creature_spellBook` is empty.");
+        return;
+    }
+
+    barGoLink bar(_result->GetRowCount());
+
+    do
+    {
+        bar.step();
+        Field *_spellInfo = _result->Fetch();
+        uint32 creatureEntry = _spellInfo[0].GetUInt32();
+        if(!creatureEntry)
+            continue;
+
+        char* _spellId = NULL;
+
+        //spellId, recoveryTime, unknow1, buffDuration, cost, rangeMin, rangeMax
+        for(uint8 itr = CREATURE_SPELL_MIN; itr < CREATURE_SPELL_MAX; ++itr)
+        {
+            const char*  rawSpellInfo = _spellInfo[itr+1].GetString();
+            _spellId = strtok((char*)rawSpellInfo, " "); 
+            if( _spellId )
+            {
+                uint32 spellId = mCreatureSpellBookMap[creatureEntry].info[itr].id = atoi(_spellId);
+
+                char* _recoveryTime = strtok(NULL, " ");
+                if(_recoveryTime)
+                    mCreatureSpellBookMap[creatureEntry].info[itr].recoveryTime = atoi(_recoveryTime);
+
+                char* _castingTime = strtok(NULL, " ");
+                if(_castingTime)
+                    mCreatureSpellBookMap[creatureEntry].info[itr].unknow1 = atoi(_castingTime);
+
+                char* _buffDuration = strtok(NULL, " ");
+                if(_buffDuration)
+                    mCreatureSpellBookMap[creatureEntry].info[itr].buffDuration = atoi(_buffDuration);
+
+                char* _cost = strtok(NULL, " ");
+                if(_cost)
+                    mCreatureSpellBookMap[creatureEntry].info[itr].cost = atoi(_cost);
+
+                char* _rangeMin = strtok(NULL, " ");
+                if(_rangeMin)
+                    mCreatureSpellBookMap[creatureEntry].info[itr].range[0] = atof(_rangeMin);
+
+                char* _rangeMax = strtok(NULL, " ");
+                if(_rangeMax)
+                    mCreatureSpellBookMap[creatureEntry].info[itr].range[1] = atof(_rangeMax);
+            }
+        }
+
+        SpellEntry const* dbcSpell;
+        SpellRangeEntry const *dbcRange;
+        SpellDurationEntry const *dbcDuration;
+        SpellCastTimesEntry const *dbcCastTime;
+
+        CreatureSpellBookInfoMap::iterator itr = mCreatureSpellBookMap[creatureEntry].info.begin();
+        
+        for(; itr != mCreatureSpellBookMap[creatureEntry].info.end(); ++itr)
+        {
+            dbcSpell = GetSpellStore()->LookupEntry(itr->second.id);
+            if( !dbcSpell )
+                continue;
+            dbcRange = GetSpellRangeStore()->LookupEntry(dbcSpell->rangeIndex);
+            dbcDuration = GetSpellDurationStore()->LookupEntry(dbcSpell->DurationIndex);
+            dbcCastTime = GetCastTimesStore()->LookupEntry(dbcSpell->CastingTimeIndex);
+
+            for (int j=0; j<3; j++)
+            {
+                //Spell targets self
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF )
+                    itr->second.targets |= 1 << (SELECT_TARGET_SELF-1);
+
+                //Spell targets a single enemy
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_SELECTED_ENEMY )
+                    itr->second.targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1);
+
+                //Spell targets AoE at enemy
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )
+                    itr->second.targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);
+
+                //Spell targets an enemy
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_SELECTED_ENEMY ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )
+                    itr->second.targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);
+
+                //Spell targets a single friend(or self)
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY )
+                    itr->second.targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1);
+
+                //Spell targets aoe friends
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY )
+                    itr->second.targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);
+
+                //Spell targets any friend(or self)
+                if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
+                     dbcSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY )
+                    itr->second.targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);
+
+                //Make sure that this spell includes a damage effect
+                if ( dbcSpell->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE || 
+                     dbcSpell->Effect[j] == SPELL_EFFECT_INSTAKILL || 
+                     dbcSpell->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE || 
+                     dbcSpell->Effect[j] == SPELL_EFFECT_HEALTH_LEECH )
+                    itr->second.effects |= 1 << (SELECT_EFFECT_DAMAGE-1);
+
+                //Make sure that this spell includes a healing effect
+                if ( dbcSpell->Effect[j] == SPELL_EFFECT_HEAL || 
+                     dbcSpell->Effect[j] == SPELL_EFFECT_HEAL_MAX_HEALTH || 
+                     dbcSpell->Effect[j] == SPELL_EFFECT_HEAL_MECHANICAL )
+                    itr->second.effects |= 1 << (SELECT_EFFECT_HEALING-1);
+
+                //Make sure that this spell applies an aura
+                if( dbcSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA )
+                    itr->second.effects |= 1 << (SELECT_EFFECT_AURA-1);
+                
+                // Buff Duration
+                if( dbcDuration && itr->second.buffDuration < dbcDuration->Duration[j] )//DBC Info Not Good
+                    itr->second.buffDuration = dbcDuration->Duration[j];
+            }
+            
+            //We use powerCost from SQL on missing DBC value
+            if( dbcSpell->manaCost )
+            {
+                itr->second.usingDBC = true;
+                itr->second.cost = dbcSpell->manaCost;
+            }
+
+            //CoolDown
+            if( !itr->second.recoveryTime && dbcSpell->RecoveryTime )
+                itr->second.recoveryTime = dbcSpell->RecoveryTime;
+
+            if(dbcRange)
+            {
+                //Range Min
+                if( !itr->second.range[0] )
+                    itr->second.range[0] = dbcRange->minRange;
+                //Range Max
+                if( !itr->second.range[1] )//DBC Info Not Good
+                    itr->second.range[1] = dbcRange->maxRange;
+            }
+            
+            //Casttime
+            if(dbcCastTime && dbcCastTime->CastTime)
+                itr->second.hasCastTime = true;
+        }
+    }while( _result->NextRow() );
+
+    delete _result;
+
+    sLog.outString();
+    sLog.outString( ">> Loaded %u creatures", mCreatureSpellBookMap.size() );
+}
+CreatureSpellBook* ObjectMgr::GetCreatureSpellBook(uint32 entry)
+{
+   CreatureSpellBookMap::iterator itr = mCreatureSpellBookMap.find(entry);
+   if( itr != mCreatureSpellBookMap.end() )
+    return &itr->second;
+   else
+    return NULL;
+}
 void ObjectMgr::AddCreatureToGrid(uint32 guid, CreatureData const* data)
 {
     CellPair cell_pair = MaNGOS::ComputeCellPair(data->posX, data->posY);
Index: src/game/ObjectMgr.h
===================================================================
--- src/game/ObjectMgr.h	(revision 4763)
+++ src/game/ObjectMgr.h	(working copy)
@@ -45,6 +45,7 @@
 
 extern SQLStorage sCreatureStorage;
 extern SQLStorage sCreatureDataAddonStorage;
+//extern SQLStorage sCreatureRawSpellBookStorage;
 extern SQLStorage sCreatureInfoAddonStorage;
 extern SQLStorage sCreatureModelStorage;
 extern SQLStorage sEquipmentStorage;
@@ -74,7 +75,6 @@
     float z;
     float o;
 };
-
 typedef std::multimap<uint32, ScriptInfo> ScriptMap;
 typedef std::map<uint32, ScriptMap > ScriptMapMap;
 extern ScriptMapMap sQuestEndScripts;
@@ -115,6 +115,7 @@
 
 typedef HM_NAMESPACE::hash_map<uint64/*(instance,guid) pair*/,time_t> RespawnTimes;
 
+typedef HM_NAMESPACE::hash_map<uint32,CreatureSpellBook> CreatureSpellBookMap;
 typedef HM_NAMESPACE::hash_map<uint32,CreatureData> CreatureDataMap;
 typedef HM_NAMESPACE::hash_map<uint32,GameObjectData> GameObjectDataMap;
 typedef HM_NAMESPACE::hash_map<uint32,CreatureLocale> CreatureLocaleMap;
@@ -267,15 +268,16 @@
         void RemoveArenaTeam(ArenaTeam* arenateam) { mArenaTeamSet.erase( arenateam ); }
 
         CreatureInfo const *GetCreatureTemplate( uint32 id );
+        
         CreatureModelInfo const *GetCreatureModelInfo( uint32 modelid );
         CreatureModelInfo const* GetCreatureModelRandomGender(uint32 display_id);
         uint32 ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data);
         EquipmentInfo const *GetEquipmentInfo( uint32 entry );
+        
         static CreatureDataAddon const *GetCreatureAddon( uint32 lowguid )
         {
             return sCreatureDataAddonStorage.LookupEntry<CreatureDataAddon>(lowguid);
         }
-
         static CreatureDataAddon const *GetCreatureTemplateAddon( uint32 entry )
         {
             return sCreatureInfoAddonStorage.LookupEntry<CreatureDataAddon>(entry);
@@ -464,6 +466,8 @@
         void LoadCreatureRespawnTimes();
         void LoadCreatureAddons();
         void LoadCreatureModelInfo();
+        void LoadCreatureSpellBook();
+        CreatureSpellBook* GetCreatureSpellBook(uint32 entry);
         void LoadEquipmentTemplates();
         void LoadGameObjectLocales();
         void LoadGameobjects();
@@ -821,6 +825,7 @@
         MapObjectGuids mMapObjectGuids;
         CreatureDataMap mCreatureDataMap;
         CreatureLocaleMap mCreatureLocaleMap;
+        CreatureSpellBookMap mCreatureSpellBookMap;
         GameObjectDataMap mGameObjectDataMap;
         GameObjectLocaleMap mGameObjectLocaleMap;
         ItemLocaleMap mItemLocaleMap;
@@ -836,6 +841,6 @@
         typedef HM_NAMESPACE::hash_map<uint32, SpellProcEventEntry> SpellProcEventMap;
         SpellProcEventMap mSpellProcEventMap;
 };
-
+//SQLStorage const* GetCreaturesSpellsBooks() {return &sCreatureSpellBookStorage;}
 #define objmgr MaNGOS::Singleton<ObjectMgr>::Instance()
 #endif
Index: src/game/Pet.h
===================================================================
--- src/game/Pet.h	(revision 4763)
+++ src/game/Pet.h	(working copy)
@@ -100,11 +100,12 @@
 
 #define ACTIVE_SPELLS_MAX           4
 
-#define OWNER_MAX_DISTANCE 100
+#define OWNER_MAX_DISTANCE 100.0f
 
-#define PET_FOLLOW_DIST  1
-#define PET_FOLLOW_ANGLE (M_PI/2)
+#define PET_FOLLOW_DIST  2.0f
 
+#define PET_FOLLOW_ANGLE (M_PI/2.0f)
+
 class Pet : public Creature
 {
     public:
Index: src/game/PetAI.cpp
===================================================================
--- src/game/PetAI.cpp	(revision 4763)
+++ src/game/PetAI.cpp	(working copy)
@@ -42,41 +42,80 @@
     UpdateAllies();
 }
 
-void PetAI::MoveInLineOfSight(Unit *u)
+void PetAI::MoveInLineOfSight(Unit *who)
 {
-    if( !i_pet.getVictim() && (i_pet.isPet() || i_pet.isCharmed()) && i_pet.GetCharmInfo()->HasReactState(REACT_AGGRESSIVE) &&
-        u->isTargetableForAttack() && i_pet.IsHostileTo( u )  &&
-        u->isInAccessablePlaceFor(&i_pet))
+    if( i_pet.GetCharmInfo() )
     {
-        float attackRadius = i_pet.GetAttackDistance(u);
-        if(i_pet.IsWithinDistInMap(u, attackRadius) && i_pet.GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE)
+        //Planning something to get Rid of all Z check like that will be great since it wrong, GS 
+        if( !i_pet.HasPathTo(who) ) 
+            return;
+
+        if( !i_pet.GetUInt64Value(UNIT_FIELD_TARGET) )
         {
-            if(!i_pet.IsWithinLOSInMap(u)) return;
-            AttackStart(u);
-            u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+            if( i_pet.GetCharmInfo()->HasReactState(REACT_AGGRESSIVE))
+            {
+                if( i_pet.IsWithinDistInMap(who,RANGE_AUTO_ASSIST_PET ) && i_pet.IsFriendlyTo(who) )
+                {
+                    if(!i_pet.IsWithinLOSInMap(who))
+                        return;
+
+                    //TODO: make it with IsInCombat() + Take target from AttackerList.
+                    if(!who->getAttackers().empty())
+                    {   
+                        Unit* victimTarget = *(who->getAttackers().begin());
+                        if( i_pet.IsHostileTo(victimTarget) && (Unit::getHpPercent(victimTarget) < 100 || Unit::getHpPercent(who) < 100) 
+                            && i_pet.IsWithinDistInMap(victimTarget, 46.0f) ) //Just a safe distance.
+                            AttackStart( victimTarget );
+                    }
+                }
+                return;
+            }
+
+            if((i_pet.GetCharmInfo()->HasReactState(REACT_DEFENSIVE) && Unit::getHpPercent(who) < 100))
+            {
+                if( i_pet.IsWithinDistInMap(who,RANGE_AUTO_ASSIST_PET ) && i_pet.IsFriendlyTo(who) )
+                {
+                    if(!i_pet.IsWithinLOSInMap(who))
+                        return;
+
+                    //TODO: make it with IsInCombat() + Take target from AttackerList.
+                    if(!who->getAttackers().empty())
+                    {   
+                        Unit* victimTarget = *(who->getAttackers().begin());
+                        if( i_pet.IsHostileTo(victimTarget) && i_pet.IsWithinDistInMap(victimTarget, 46.0f)) //Just a safe distance.
+                            AttackStart( victimTarget );
+                    }
+                }
+            }
         }
     }
 }
 
-void PetAI::AttackStart(Unit *u)
+void PetAI::AttackStart(Unit *unit)
 {
-    if( i_pet.getVictim() || !u || i_pet.isPet() && ((Pet&)i_pet).getPetType()==MINI_PET )
+    if( !unit || i_pet.isPet() && ((Pet&)i_pet).getPetType()==MINI_PET )
         return;
 
-    if(i_pet.Attack(u))
+    if( unit->isTargetableForAttack() && i_pet.HasPathTo(unit))
     {
-        i_pet.clearUnitState(UNIT_STAT_FOLLOW);
-        // TMGs call CreatureRelocation which via MoveInLineOfSight can call this function
-        // thus with the following clear the original TMG gets invalidated and crash, doh
-        // hope it doesn't start to leak memory without this :-/
-        //i_pet->Clear();
-        i_victimGuid = u->GetGUID();
-        i_pet.GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*u));
+        if ( i_pet.Attack(unit) )
+        {
+            i_pet.AddThreat(unit, 0.0f);
+            i_pet.resetAttackTimer();
+            if(i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
+                AIMotionTarget(unit,FOLLOW_RANGE_MELEE);
+
+            return;
+        }else if( i_pet.getVictim() == unit && i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW) ) //HackWay... Cause Attack() will return false if same attacker.
+            AIMotionTarget(unit,FOLLOW_RANGE_MELEE);    
     }
 }
 
 void PetAI::EnterEvadeMode()
 {
+    i_pet.DeleteThreatList();
+    i_pet.AttackStop();
+    i_pet.ClearInCombat(false);
 }
 
 bool PetAI::IsVisible(Unit *pl) const
@@ -98,136 +137,50 @@
 
 void PetAI::_stopAttack()
 {
-    if( !i_victimGuid )
-        return;
+    EnterEvadeMode();
+}
 
-    Unit* victim = ObjectAccessor::Instance().GetUnit(i_pet, i_victimGuid );
-
-    if ( !victim )
+void PetAI::UpdateAI(const uint32 diff)
+{
+    Unit* owner = i_pet.GetCharmerOrOwner();
+    if(!owner)
         return;
 
-    assert(!i_pet.getVictim() || i_pet.getVictim() == victim);
-
-    if( !i_pet.isAlive() )
+	// update i_victimGuid if i_pet.getVictim() !=0 and changed
+    if(!i_pet.getVictim() && !i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE))
     {
-        DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_pet.GetGUIDLow());
-        i_pet.StopMoving();
-        i_pet.GetMotionMaster()->Clear();
-        i_pet.GetMotionMaster()->Idle();
-        i_victimGuid = 0;
-        i_pet.CombatStop(true);
-        i_pet.getHostilRefManager().deleteReferences();
+        
+        Unit* ownerAttacker = owner->getAttackerForHelper();
+        if(ownerAttacker)
+        {
 
-        return;
+            if(i_pet.GetCharmInfo()->HasReactState(REACT_AGGRESSIVE) && (Unit::getHpPercent(ownerAttacker) < 100 || Unit::getHpPercent(owner) < 100))
+                AttackStart(ownerAttacker);
+            else if(Unit::getHpPercent(owner) < 100)
+                AttackStart(ownerAttacker);
+        }
     }
-    else if( !victim  )
-    {
-        DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_pet.GetGUIDLow());
-    }
-    else if( !victim->isAlive() )
-    {
-        DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", i_pet.GetGUIDLow());
-    }
-    else if( victim->HasStealthAura() )
-    {
-        DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_pet.GetGUIDLow());
-    }
-    else if( victim->isInFlight() )
-    {
-        DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_pet.GetGUIDLow());
-    }
-    else
-    {
-        DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", i_pet.GetGUIDLow());
-    }
 
-    Unit* owner = i_pet.GetCharmerOrOwner();
-
-    if(owner && i_pet.GetCharmInfo() && i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
-    {
-        i_pet.addUnitState(UNIT_STAT_FOLLOW);
-        i_pet.GetMotionMaster()->Clear();
-        i_pet.GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE));
-    }
-    else
-    {
-        i_pet.clearUnitState(UNIT_STAT_FOLLOW);
-        i_pet.addUnitState(UNIT_STAT_STOPPED);
-        i_pet.GetMotionMaster()->Clear();
-        i_pet.GetMotionMaster()->Idle();
-    }
-    i_victimGuid = 0;
-    i_pet.AttackStop();
-}
-
-void PetAI::UpdateAI(const uint32 diff)
-{
-    // update i_victimGuid if i_pet.getVictim() !=0 and changed
-    if(i_pet.getVictim())
-        i_victimGuid = i_pet.getVictim()->GetGUID();
-
-    Unit* owner = i_pet.GetCharmerOrOwner();
-
     if(m_updateAlliesTimer <= diff)
         // UpdateAllies self set update timer
         UpdateAllies();
     else
         m_updateAlliesTimer -= diff;
-
-    // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
-    if( i_victimGuid )
+    
+    if( !i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) && !_needToStop() )
     {
-        if( _needToStop() )
+        if( i_pet.isAttackReady() && i_pet.IsWithinDistInMap(i_pet.getVictim(), i_pet.GetFloatValue(UNIT_FIELD_COMBATREACH)) )
         {
-            DEBUG_LOG("Pet AI stoped attacking [guid=%u]", i_pet.GetGUIDLow());
-            _stopAttack();                                  // i_victimGuid == 0 && i_pet.getVictim() == NULL now
-            return;
+            i_pet.AttackerStateUpdate(i_pet.getVictim());
+            i_pet.resetAttackTimer();
+            i_pet.SelectHostilTarget();
         }
-        else if( i_pet.IsStopped() || i_pet.IsWithinDistInMap(i_pet.getVictim(), ATTACK_DISTANCE))
-        {
-            // required to be stopped cases
-            if ( i_pet.IsStopped() && i_pet.IsNonMeleeSpellCasted(false) )
-            {
-                if( i_pet.hasUnitState(UNIT_STAT_FOLLOW) )
-                    i_pet.InterruptNonMeleeSpells(false);
-                else
-                    return;
-            }
-            // not required to be stopped case
-            else if( i_pet.isAttackReady() && i_pet.canReachWithAttack(i_pet.getVictim()) )
-            {
-                i_pet.AttackerStateUpdate(i_pet.getVictim());
-
-                i_pet.resetAttackTimer();
-
-                if ( !i_pet.getVictim() )
-                    return;
-
-                //if pet misses its target, it will also be the first in threat list
-                i_pet.getVictim()->AddThreat(&i_pet,0.0f);
-
-                if( _needToStop() )
-                    _stopAttack();
-            }
-        }
     }
-    else if(owner && i_pet.GetCharmInfo())
+    if( i_pet.isInCombat() && _needToStop() )
     {
-        if(owner->isInCombat() && !(i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) || i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY)))
-        {
-            AttackStart(owner->getAttackerForHelper());
-        }
-        else if(i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
-        {
-            if (!i_pet.hasUnitState(UNIT_STAT_FOLLOW) )
-            {
-                i_pet.addUnitState(UNIT_STAT_FOLLOW);
-                i_pet.GetMotionMaster()->Clear();
-                i_pet.GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE));
-            }
-        }
+        _stopAttack();
+        return;
     }
-
     //Autocast
     HM_NAMESPACE::hash_map<uint32, Unit*> targetMap;
     targetMap.clear();
@@ -242,7 +195,7 @@
 
         Spell *spell = new Spell(&i_pet, spellInfo, false, 0);
 
-        if(!IsPositiveSpell(spellInfo->Id) && i_pet.getVictim() && !_needToStop() && !i_pet.hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(i_pet.getVictim()))
+        if(!IsPositiveSpell(spellInfo->Id) && i_pet.getVictim() && !_needToStop() /*&& !i_pet.hasUnitState(UNIT_STAT_FOLLOW)*/ && spell->CanAutoCast(i_pet.getVictim()))
             targetMap[spellID] = i_pet.getVictim();
         else
         {
@@ -294,6 +247,8 @@
         spell->prepare(&targets);
     }
     targetMap.clear();
+    
+    //if(i_pet.getVictim())
 }
 
 bool PetAI::_isVisible(Unit *u) const
@@ -342,10 +297,48 @@
         m_AllySet.insert(owner->GetGUID());
 }
 
-void PetAI::AttackedBy(Unit *attacker)
+void PetAI::AIMotionTarget(Unit* target, float offSet)
 {
+    bool exist = false;
+    MotionMaster* creatureMM = i_pet.GetMotionMaster();
+
+    if(!target /*&& creatureMM->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE*/)
+    {
+        //creatureMM->MovementExpired();
+        return;    
+    }
+    //Here is wrong... TODO fix angle... but in fact i wan MV for Follower and One for Attacker.
+    float angle = NULL;
+    if( !i_pet.IsHostileTo(target) )
+    {
+        angle = target->GetOrientation()*2.0f;
+    }
+
+    if(creatureMM->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE)
+    {
+        TargetedMovementGenerator<Creature>* targetMV = static_cast<TargetedMovementGenerator<Creature>*> (creatureMM->top());
+        if( targetMV && targetMV->GetTarget() )
+        {
+            if( targetMV->GetTarget()->GetGUID() != target->GetGUID() )
+            {
+                creatureMM->MovementExpired(false);
+                creatureMM->Mutate(new TargetedMovementGenerator<Creature>(*target,offSet,angle));
+            }
+            else if(targetMV->GetOffSet() != offSet)
+                targetMV->SetOffSet(offSet);
+        }
+    }
+    else
+    { 
+        i_pet.GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*target,offSet,angle));
+    }
+}
+
+/*void PetAI::AttackedBy(Unit *attacker)
+{
     //when attacked, fight back in case 1)no victim already AND 2)not set to passive AND 3)not set to stay, unless can it can reach attacker with melee attack anyway
     if(!i_pet.getVictim() && i_pet.GetCharmInfo() && !i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
         (!i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY) || i_pet.canReachWithAttack(attacker)))
         AttackStart(attacker);
 }
+*/
Index: src/game/PetAI.h
===================================================================
--- src/game/PetAI.h	(revision 4763)
+++ src/game/PetAI.h	(working copy)
@@ -34,7 +34,7 @@
         void AttackStart(Unit *);
         void EnterEvadeMode();
         void DamageTaken(Unit *done_by, uint32 &damage) { AttackedBy(done_by); }
-        void AttackedBy(Unit *attacker);
+        void AttackedBy(Unit *attacker) {}
         bool IsVisible(Unit *) const;
 
         void UpdateAI(const uint32);
@@ -45,6 +45,7 @@
         bool _isVisible(Unit *) const;
         bool _needToStop(void) const;
         void _stopAttack(void);
+        void AIMotionTarget(Unit *, float);
 
         Creature &i_pet;
         uint64 i_victimGuid;
Index: src/game/PetHandler.cpp
===================================================================
--- src/game/PetHandler.cpp	(revision 4763)
+++ src/game/PetHandler.cpp	(working copy)
@@ -26,6 +26,7 @@
 #include "Spell.h"
 #include "ObjectAccessor.h"
 #include "MapManager.h"
+#include "IdleMovementGenerator.h"
 #include "TargetedMovementGenerator.h"
 #include "CreatureAI.h"
 #include "Util.h"
@@ -71,46 +72,51 @@
         sLog.outError("WorldSession::HandlePetAction: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID());
         return;
     }
-
+    //All here was wrong... i just tryed to make my own version, until i got real data from official, GS
+    // I have the good data from official and will have some probleme doing the defencive Status.. all other will be much more sample 
+    // then the actual one :) , GS
     switch(flag)
     {
         case ACT_COMMAND:                                   //0x0700
             switch(spellid)
             {
                 case COMMAND_STAY:                          //flat=1792  //STAY
-                    pet->StopMoving();
-                    pet->GetMotionMaster()->Clear();
-                    pet->GetMotionMaster()->Idle();
+                    if(!pet->hasUnitState(UNIT_STAT_FOLLOW))
+                        break;
+                    if(pet->GetMotionMaster()->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE)
+                        pet->GetMotionMaster()->MovementExpired(); 
+
+                    //Will be possible to him to overide Fleeing MV, Check this out, GS
+                    //In fact FleeingMV should not accept to be Overide so the fix should be very great that way.
+                    //I must be able to add a new MG but at index (top() - 1)
+                    pet->GetMotionMaster()->Mutate(new IdleMovementGenerator(*pet));
+                    pet->clearUnitState(UNIT_STAT_FOLLOW);
                     charmInfo->SetCommandState( COMMAND_STAY );
                     break;
                 case COMMAND_FOLLOW:                        //spellid=1792  //FOLLOW
-                    pet->AttackStop();
-                    pet->addUnitState(UNIT_STAT_FOLLOW);
+                    //Here i use clear() to return to originalMG, but fear must not be overide here.. so same as STAY.. solution will come later, GS
                     pet->GetMotionMaster()->Clear();
-                    pet->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*_player,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE));
+                    pet->addUnitState(UNIT_STAT_FOLLOW);
+                    ((Creature*)pet)->AI()->EnterEvadeMode();
                     charmInfo->SetCommandState( COMMAND_FOLLOW );
                     break;
                 case COMMAND_ATTACK:                        //spellid=1792  //ATTACK
                 {
-                    // only place where pet can be player
-                    pet->clearUnitState(UNIT_STAT_FOLLOW);
                     uint64 selguid = _player->GetSelection();
                     Unit *TargetUnit = ObjectAccessor::Instance().GetUnit(*_player, selguid);
-                    if(TargetUnit == NULL) return;
+                    if(TargetUnit == NULL) 
+                        return;
 
-                    // not let attack friendly units.
                     if( GetPlayer()->IsFriendlyTo(TargetUnit))
                         return;
 
-                    if(pet->getVictim() && TargetUnit!=pet->getVictim())
-                        pet->AttackStop();
+                    if(((Creature*)pet)->AI())
+                        ((Creature*)pet)->AI()->AttackStart(TargetUnit);
 
-                    if(pet->GetTypeId() != TYPEID_PLAYER)
+                    break;
+                    //TODO: check this out and add it correctely
+                    /*if(pet->GetTypeId() != TYPEID_PLAYER)
                     {
-                        pet->GetMotionMaster()->Clear();
-                        if (((Creature*)pet)->AI())
-                            ((Creature*)pet)->AI()->AttackStart(TargetUnit);
-
                         //10% chance to play special pet attack talk, else growl
                         if(((Creature*)pet)->isPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
                             pet->SendPetTalk((uint32)PET_TALK_ATTACK);
@@ -119,13 +125,8 @@
                             // 90% chance for pet and 100% chance for charmed creature
                             pet->SendPetAIReaction(guid1);
                         }
-                    }
-                    else                                    // charmed player
-                    {
-                        pet->Attack(TargetUnit);
-                        pet->SendPetAIReaction(guid1);
-                    }
-                    break;
+                        break;
+                    }*/
                 }
                 case COMMAND_ABANDON:                       // abandon (hunter pet) or dismiss (summoned pet)
                     if(((Creature*)pet)->isPet())
@@ -151,7 +152,6 @@
                 case REACT_DEFENSIVE:                       //recovery
                 case REACT_AGGRESSIVE:                      //activete
                     charmInfo->SetReactState( ReactStates(spellid) );
-                    break;
             }
             break;
         case ACT_DISABLED:                                  //0x8100    spell (disabled), ignore
@@ -182,8 +182,6 @@
             if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
                 return;
 
-            pet->clearUnitState(UNIT_STAT_FOLLOW);
-
             Spell *spell = new Spell(pet, spellInfo, false, 0);
 
             int16 result = spell->PetCanCast(unit_target);
@@ -218,10 +216,6 @@
 
                 if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
                 {
-                    pet->clearUnitState(UNIT_STAT_FOLLOW);
-                    if(unit_target!=pet->getVictim())
-                        pet->AttackStop();
-                    pet->GetMotionMaster()->Clear();
                     if (((Creature*)pet)->AI())
                         ((Creature*)pet)->AI()->AttackStart(unit_target);
                 }
@@ -569,8 +563,6 @@
     if(!targets.read(&recvPacket,pet))
         return;
 
-    pet->clearUnitState(UNIT_STAT_FOLLOW);
-
     Spell *spell = new Spell(pet, spellInfo, false, 0);
     spell->m_targets = targets;
 
Index: src/game/RandomMovementGenerator.cpp
===================================================================
--- src/game/RandomMovementGenerator.cpp	(revision 4763)
+++ src/game/RandomMovementGenerator.cpp	(working copy)
@@ -22,124 +22,105 @@
 #include "RandomMovementGenerator.h"
 #include "DestinationHolderImp.h"
 
-/*
-Here interpolation is disabled by default due to it causing crashing
-in some compile environments.
-If your server can handle the small amount of lag this may cause
-and you can build without experiencing a significant increase in crashes
-then you may uncomment the following line to have correct random motion.
-*/
-// uncomment now for wide testing purpose
-#define USE_INTERPOLATION
+#define RUNNING_CHANCE_RANDOMMV 20                                  //will be "1 / RUNNING_CHANCE_RANDOMMV"
 
-template<>
-void
-RandomMovementGenerator<Creature>::Initialize(Creature &creature)
+template<> void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
 {
-    float x,y,z,z2, wander_distance;
-    creature.GetRespawnCoord(x, y, z);
-    creature.GetRespawnDist(wander_distance);
-    uint32 mapid=creature.GetMapId();
+    //Doing temporay Use of this Generator for Pet.... But still need it Own.. with Life Feature ;), GS
+    float X,Y,Z,z,nx,ny,nz,wander_distance;
 
-    Map const* map = MapManager::Instance().GetBaseMap(mapid);
-    // Initialization is done in bulk. Don’t use vamps for that (4. parameter = false). It is too costly when entering a new map grid
-    z2 = map->GetHeight(x,y,z, false);
-    if( fabs( z2 - z ) < 5 )
-        z = z2;
-
-    i_nextMove = 1;
-    i_waypoints[0][0] = x;
-    i_waypoints[0][1] = y;
-    i_waypoints[0][2] = z;
-
-    bool is_water_ok = creature.isCanSwimOrFly();
-    bool is_land_ok  = creature.isCanWalkOrFly();
-
-    for(unsigned int idx=1; idx < MAX_RAND_WAYPOINTS+1; ++idx)
+    if( creature.isPet() )
     {
-        const float angle = 2*M_PI*rand_norm();
-        const float range = wander_distance*rand_norm();
+        if( !creature.GetOwner() )
+            return;
+        creature.GetOwner()->GetPosition(X, Y, Z);
+        wander_distance = (rand_norm()*PET_FOLLOW_DIST)+2.5f;
+    }
+    else
+    {   
+        creature.GetRespawnCoord(X, Y, Z);
+        creature.GetRespawnDist(wander_distance);
+    }
 
-        i_waypoints[idx][0] = x+ range * cos(angle);
-        i_waypoints[idx][1] = y+ range * sin(angle);
+    z = creature.GetPositionZ();
+    uint32 mapid=creature.GetMapId();
+    Map const* map = MapManager::Instance().GetBaseMap(mapid);
 
-        // prevent invalid coordinates generation
-        MaNGOS::NormalizeMapCoord(i_waypoints[idx][0]);
-        MaNGOS::NormalizeMapCoord(i_waypoints[idx][1]);
+    //Both water and fly , will do later... since will be cool to select random Z and will need to check dist into 3d
+    //bool is_water_ok = creature.isCanSwimOrFly();
+    //bool is_land_ok  = creature.isCanWalkOrFly();
+    const float angle = rand_norm()*(M_PI*2);
+    srand(getMSTime());
+    const float range = rand_norm()*wander_distance;
+    const float distanceX = range * cos(angle);
+    const float distanceY = range * sin(angle);
+    const float distanceZ = range * tan(angle);
+    nx = X + distanceX;
+    ny = Y + distanceY;
+    //nz = Z + distanceZ; //3D-MG
+    nz = map->GetHeight(nx,ny,Z);
+    
+    //2D-MG
+    const float groundDist = sqrt(distanceX*distanceX + distanceY*distanceY);
+    const float zDist = fabs(z - nz) + 0.000001f; //FineTune with that value..., GS
+    const float slope = groundDist / zDist;
+    if(fabs(slope) < 1.0f || (map->GetTerrainType(nx,ny) & 0x01))
+        nz = Z;
 
-        bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z);
-        // if generated wrong path just ignore
-        if( is_water && !is_water_ok || !is_water && !is_land_ok )
-        {
-            i_waypoints[idx][0] = i_waypoints[idx-1][0];
-            i_waypoints[idx][1] = i_waypoints[idx-1][1];
-            i_waypoints[idx][2] = i_waypoints[idx-1][2];
-            continue;
-        }
+    Traveller<Creature> traveller(creature);
+    creature.SetOrientation(creature.GetAngle(nx,ny));
+    i_destinationHolder.SetDestination(traveller, nx, ny, nz);
+    i_nextMoveTime.Reset(rand32(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime()));
+    creature.addUnitState(UNIT_STAT_ROAMING);
+}
 
-        // Initialization is done in bulk. Don’t use vamps for that (4. parameter = false). It is too costly when entering a new map grid
-        z2 = map->GetHeight(i_waypoints[idx][0],i_waypoints[idx][1],z, false);
-        if( fabs( z2 - z ) < 5 )
-            z = z2;
-        i_waypoints[idx][2] =  z;
-    }
-    i_nextMoveTime.Reset(urand(0, 10000-1));                // TODO: check the lower bound (it is probably too small)
-    creature.StopMoving();
+template<> void RandomMovementGenerator<Creature>::Initialize(Creature &creature)
+{
+    if(!&creature || !creature.isAlive())
+        return;
+
+    creature.setMoveRunFlag(irand(0,RUNNING_CHANCE_RANDOMMV) ? false : true);
+    _setRandomLocation(creature);
 }
 
-template<>
-void
-RandomMovementGenerator<Creature>::Reset(Creature &creature)
+template<> void RandomMovementGenerator<Creature>::Reset(Creature &creature)
 {
-    i_nextMove = 1;
-    i_nextMoveTime.Reset(urand(0,10000-1));                 // TODO: check the lower bound (it is probably too small)
-    creature.StopMoving();
+    Initialize(creature);
 }
 
-template<>
-bool
-RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
+template<> bool RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
 {
+    //During a creature death... we will request at each 300Ms the delete of tha Motion... But he can be the index 0
+    //Not creating any probleme... but suck cpu for absolute nothing
     if(!&creature)
+        return false;
+
+    if(!creature.isAlive())
+    {
+        i_nextMoveTime.Reset(3000);
         return true;
-    if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
-        return true;
+    }
+
     i_nextMoveTime.Update(diff);
-    #ifdef USE_INTERPOLATION
+
+    if(i_destinationHolder.HasArrived() && !creature.IsStopped())
+        creature.clearUnitState(UNIT_STAT_ROAMING);
+        
+    if(!i_destinationHolder.HasArrived() && creature.IsStopped())
+        creature.addUnitState(UNIT_STAT_ROAMING);
+
     CreatureTraveller traveller(creature);
-    i_destinationHolder.UpdateTraveller(traveller, diff, false);
-    #endif
-    if( i_nextMoveTime.Passed() )
+    if( i_destinationHolder.UpdateTraveller(traveller, diff, false) )
     {
-        if( creature.IsStopped() )
+        if(i_nextMoveTime.Passed())
         {
-            assert( i_nextMove <= MAX_RAND_WAYPOINTS );
-            const float x = i_waypoints[i_nextMove][0];
-            const float y = i_waypoints[i_nextMove][1];
-            const float z = i_waypoints[i_nextMove][2];
-            creature.addUnitState(UNIT_STAT_ROAMING);
-            CreatureTraveller traveller(creature);
-            i_destinationHolder.SetDestination(traveller, x, y, z);
-            #ifndef USE_INTERPOLATION
-            traveller.Relocation(x,y,z);
-            #endif
-            i_nextMoveTime.Reset( i_destinationHolder.GetTotalTravelTime() );
+            creature.setMoveRunFlag(irand(0,20) ? false : true);
+            _setRandomLocation(creature);
         }
-        else
+        else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f)
         {
-            creature.StopMoving();
-            creature.setMoveRunFlag(!urand(0,10));
-
-            ++i_nextMove;
-            if( i_nextMove == MAX_RAND_WAYPOINTS )
-            {
-                i_nextMove = 0;
-                i_nextMoveTime.Reset(urand(0, 3000-1));     // TODO: check the lower bound (it is probably too small)
-            }
-            else
-            {
-                i_nextMoveTime.Reset(urand(0, 7000-1));     // TODO: check the lower bound (it is probably too small)
-            }
+           creature.setMoveRunFlag(true);
+           _setRandomLocation(creature);
         }
     }
     return true;
Index: src/game/RandomMovementGenerator.h
===================================================================
--- src/game/RandomMovementGenerator.h	(revision 4763)
+++ src/game/RandomMovementGenerator.h	(working copy)
@@ -23,7 +23,6 @@
 #include "DestinationHolder.h"
 #include "Traveller.h"
 
-#define MAX_RAND_WAYPOINTS 8
 
 template<class T>
 class MANGOS_DLL_DECL RandomMovementGenerator
@@ -32,14 +31,18 @@
     public:
         RandomMovementGenerator(const Unit &) : i_nextMoveTime(0) {}
 
+        void _setRandomLocation(T &);
         void Initialize(T &);
         void Reset(T &);
         bool Update(T &, const uint32 &);
-
+        void UpdateMapPosition(float &x ,float &y, float &z)
+        {
+            i_destinationHolder.GetLocationNow(x,y,z);
+        }
         MovementGeneratorType GetMovementGeneratorType() { return RANDOM_MOTION_TYPE; }
     private:
-        TimeTracker i_nextMoveTime;
-        float i_waypoints[MAX_RAND_WAYPOINTS+1][3];
+        TimeTracker2 i_nextMoveTime;
+        //float i_waypoints[MAX_RAND_WAYPOINTS+1][3];
         DestinationHolder< Traveller<T> > i_destinationHolder;
         uint32 i_nextMove;
 };
Index: src/game/ReactorAI.cpp
===================================================================
--- src/game/ReactorAI.cpp	(revision 4763)
+++ src/game/ReactorAI.cpp	(working copy)
@@ -41,19 +41,26 @@
 }
 
 void
-ReactorAI::AttackStart(Unit *p)
+ReactorAI::AttackStart(Unit *unit)
 {
-    if(!p)
+    if( !unit )
         return;
 
-    if(i_creature.Attack(p))
+    if( unit->isTargetableForAttack() /*&& attacker!= m_creature, That should not happen*/ )
     {
-        DEBUG_LOG("Tag unit GUID: %u (TypeId: %u) as a victim", p->GetGUIDLow(), p->GetTypeId());
-        i_creature.AddThreat(p, 0.0f);
-        i_victimGuid = p->GetGUID();
-        i_creature.GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*p));
-        if (p->GetTypeId() == TYPEID_PLAYER)
-            i_creature.SetLootRecipient((Player*)p);
+        if ( i_creature.Attack(unit) )
+        {
+            i_creature.AddThreat(unit, 0.0f);
+            selectedAttackRadius = i_creature.GetAttackDistance(unit);
+            i_creature.resetAttackTimer();
+            
+            if (unit->GetTypeId() == TYPEID_PLAYER)
+                i_creature.SetLootRecipient((Player*)unit);
+
+            AIMotionTarget(unit,FOLLOW_RANGE_MELEE);
+
+            return;
+        }
     }
 }
 
@@ -66,61 +73,86 @@
 void
 ReactorAI::UpdateAI(const uint32 time_diff)
 {
-    // update i_victimGuid if i_creature.getVictim() !=0 and changed
-    if(!i_creature.SelectHostilTarget() || !i_creature.getVictim())
+    if( i_creature.isDead() || i_creature.hasUnitState( UNIT_STAT_FLEEING ) )
         return;
 
-    i_victimGuid = i_creature.getVictim()->GetGUID();
-
-    if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE))
-    {
-        if( i_creature.isAttackReady() )
+    //RunAway At friend
+    if( !i_creature.hasUnitState( UNIT_STAT_ROOT ) && selectedAttackRadius <= irand(0,40) && i_creature.getVictim() && Unit::getHpPercent(&i_creature)+irand(1,20) < Unit::getHpPercent(i_creature.getVictim()) )
+    {    
+        if( !i_creature.m_AssistenceStatus->requested )
         {
-            i_creature.AttackerStateUpdate(i_creature.getVictim());
-            i_creature.resetAttackTimer();
+           i_creature.CastSpell( (Unit*)&i_creature, CREATURE_SPELL_TAP_FRIEND, false );
+           i_creature.m_AssistenceStatus->requested = true;
+           return;
         }
+        //Check spell http://www.wowhead.com/?spell=32126, who is Flee Combat Much More Better, and keep fear when no combat
+        else if(i_creature.m_AssistenceStatus->obtained = false && Unit::getHpPercent(&i_creature) < irand(7,14) )
+            i_creature.CastSpell( (Unit*)&i_creature, CREATURE_SPELL_RUNAWAY, false ,NULL,NULL, i_creature.GetUInt64Value(UNIT_FIELD_TARGET));    
     }
-}
+    
+    if( i_creature.SelectHostilTarget() && i_creature.getVictim() && i_creature.isAttackReady() && i_creature.IsWithinDistInMap(i_creature.getVictim(), i_creature.GetFloatValue(UNIT_FIELD_COMBATREACH)) )
+    {
+        //TODO:Add a Chance To win and Go to Friend.
+        i_creature.AttackerStateUpdate(i_creature.getVictim());
+        i_creature.resetAttackTimer();
+        lastAction = getMSTime();
+    }
 
-void
-ReactorAI::EnterEvadeMode()
-{
-    if( !i_creature.isAlive() )
+    //Wait Time Reset Action Selected, TODO: Change that to put more dynamic action at different timer.
+    //A text Chat can be done there, will be cool.
+    //Do search on wowhead for Gossip before any chat text system.
+    if(lastAction+irand(5000*CREATURE_WAIT_RATE,7000*CREATURE_WAIT_RATE) < getMSTime() )
     {
-        DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow());
-        i_creature.GetMotionMaster()->MovementExpired();
-        i_creature.GetMotionMaster()->Idle();
-        i_victimGuid = 0;
-        i_creature.CombatStop(true);
-        i_creature.DeleteThreatList();
-        return;
+        i_creature.m_AssistenceStatus->reset();
+
+        i_creature.SelectHostilTarget();
+
+        lastAction = getMSTime();
     }
+}
 
-    Unit* victim = ObjectAccessor::Instance().GetUnit(i_creature, i_victimGuid );
+void ReactorAI::EnterEvadeMode()
+{
+    lastAction = getMSTime()+30000;
+    i_creature.m_AssistenceStatus->reset(); //TODO: fix that scruct, at least make it proctected
+    if( !i_creature.isCharmed() )
+        i_creature.RemoveAllAuras();
+    i_creature.DeleteThreatList();
+    i_creature.CombatStop(true);
+}
+void ReactorAI::AIMotionTarget(Unit* target, float offSet)
+{
+    bool exist = false;
+    MotionMaster* creatureMM = i_creature.GetMotionMaster();
 
-    if( !victim  )
+    if(!target /*&& creatureMM->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE*/)
     {
-        DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
+        //creatureMM->MovementExpired();
+        return;    
     }
-    else if( victim->HasStealthAura() )
+    //Here is wrong... TODO fix angle... but in fact i wan MV for Follower and One for Attacker.
+    float angle = NULL;
+    if( !i_creature.IsHostileTo(target) )
     {
-        DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow());
+        angle = target->GetOrientation()*2.0f;
     }
-    else if( victim->isInFlight() )
+
+    if(creatureMM->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE)
     {
-        DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow());
+        TargetedMovementGenerator<Creature>* targetMV = static_cast<TargetedMovementGenerator<Creature>*> (creatureMM->top());
+        if( targetMV && targetMV->GetTarget() )
+        {
+            if( targetMV->GetTarget()->GetGUID() != target->GetGUID() )
+            {
+                creatureMM->MovementExpired(false);
+                creatureMM->Mutate(new TargetedMovementGenerator<Creature>(*target,offSet,angle));
+            }
+            else if(targetMV->GetOffSet() != offSet)
+                targetMV->SetOffSet(offSet);
+        }
     }
     else
-    {
-        DEBUG_LOG("Creature stopped attacking due to target %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", i_creature.GetGUIDLow());
+    { 
+        i_creature.GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*target,offSet,angle));
     }
-
-    i_creature.RemoveAllAuras();
-    i_creature.DeleteThreatList();
-    i_victimGuid = 0;
-    i_creature.CombatStop(true);
-
-    // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
-    if( i_creature.GetMotionMaster()->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE )
-        i_creature.GetMotionMaster()->TargetedHome();
 }
Index: src/game/ReactorAI.h
===================================================================
--- src/game/ReactorAI.h	(revision 4763)
+++ src/game/ReactorAI.h	(working copy)
@@ -27,7 +27,7 @@
 {
     public:
 
-        ReactorAI(Creature &c) : i_creature(c), i_victimGuid(0) {}
+        ReactorAI(Creature &c) : i_creature(c) {}
 
         void MoveInLineOfSight(Unit *);
         void AttackStart(Unit *);
@@ -38,7 +38,9 @@
         static int Permissible(const Creature *);
 
     private:
+        void AIMotionTarget(Unit* target, float offSet);
+        uint32 lastAction;
+        float selectedAttackRadius;
         Creature &i_creature;
-        uint64 i_victimGuid;
 };
 #endif
Index: src/game/ScriptCalls.cpp
===================================================================
--- src/game/ScriptCalls.cpp	(revision 4763)
+++ src/game/ScriptCalls.cpp	(working copy)
@@ -41,8 +41,18 @@
 {
     ScriptsSet testScript=new _ScriptSet;
 
-    std::string name = strlen(libName) ? libName : MANGOS_SCRIPT_NAME;
+    std::string name;
+    name = strlen(libName) ? libName : MANGOS_TIER_SCRIPT_NAME;
     name += MANGOS_SCRIPT_EXT;
+    
+    const char* TierScriptName = name.c_str();
+    
+    if( !fopen( TierScriptName, "r") ) //Tier Script Not Present Taking Default MaNGOSScript.dll
+    {
+        printf("Error loading TIER Scripts Library %s !\n",name.c_str());
+        name = strlen(libName) ? libName : MANGOS_SCRIPT_NAME;
+        name += MANGOS_SCRIPT_EXT;
+    }
 
     testScript->hScriptsLib=MANGOS_LOAD_LIBRARY(name.c_str());
 
Index: src/game/Spell.cpp
===================================================================
--- src/game/Spell.cpp	(revision 4763)
+++ src/game/Spell.cpp	(working copy)
@@ -1480,6 +1480,8 @@
 
 void Spell::SendSpellCooldown()
 {
+    if( m_caster->GetTypeId() == TYPEID_UNIT && !((Creature*)m_caster)->isPet() )
+        ((Creature*)m_caster)->AddCreatureSpellCooldown(m_spellInfo->Id);
     if(m_caster->GetTypeId() != TYPEID_PLAYER)
         return;
 
@@ -1639,9 +1641,11 @@
     }
 
     // check if the player caster has moved before the spell finished
-    if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
-        (m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) &&
-        (m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK || !((Player*)m_caster)->HasMovementFlags(MOVEMENTFLAG_FALLING)) )
+    if( m_timer != 0 
+        && ( m_castPositionX != m_caster->GetPositionX() 
+             || m_castPositionY != m_caster->GetPositionY() 
+             || m_castPositionZ != m_caster->GetPositionZ() ) 
+        && ( m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK || ( m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->HasMovementFlags(MOVEMENTFLAG_FALLING))) )
     {
         // always cancel for channeled spells
         if( m_spellState == SPELL_STATE_CASTING )
@@ -1686,6 +1690,12 @@
                     if( m_spellInfo->ChannelInterruptFlags & CHANNEL_FLAG_TURNING && m_castOrientation != m_caster->GetOrientation() )
                         cancel();
                 }
+                else
+                {
+                    // check for incapacitating NPC states
+                    if( m_caster->hasUnitState( UNIT_STAT_STUNDED | UNIT_STAT_CONFUSED ) )
+                        cancel();
+                }
 
                 // check if there are alive targets left
                 for(int i=0;i<3;i++)
@@ -2073,6 +2083,7 @@
 {
     if(time == 0)
     {
+        m_timer = 0; //reset Channeling Timer, Should not be there, in place Must Check with State , but have to Be sure Deleyed and CASTING are never together.
         m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,0);
         m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL,0);
     }
@@ -3117,7 +3128,7 @@
 
     if(target && target != m_caster)
     {
-        float dist = m_caster->GetDistanceSq(target);
+        float dist = m_caster->GetDistance2dSq(target);
         if(dist > max_range * max_range)
             return SPELL_FAILED_OUT_OF_RANGE;               //0x5A;
         if(dist < min_range * min_range)
@@ -3129,7 +3140,7 @@
 
     if(m_targets.m_targetMask == TARGET_FLAG_DEST_LOCATION && m_targets.m_destX != 0 && m_targets.m_destY != 0 && m_targets.m_destZ != 0)
     {
-        float dist = m_caster->GetDistanceSq(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ);
+        float dist = m_caster->GetDistance2d(m_targets.m_destX, m_targets.m_destY) * m_caster->GetDistance2d(m_targets.m_destX, m_targets.m_destY);
         if(dist > max_range * max_range)
             return SPELL_FAILED_OUT_OF_RANGE;
         if(dist < min_range * min_range)
Index: src/game/Spell.h
===================================================================
--- src/game/Spell.h	(revision 4763)
+++ src/game/Spell.h	(working copy)
@@ -577,6 +577,7 @@
 
         CurrentSpellTypes GetCurrentContainer();
 
+        uint32 GetTimer() { return m_timer; }
         Unit* GetCaster() { return m_caster; }
         Unit* GetOriginalCaster() { return m_originalCaster; }
 
Index: src/game/SpellAuras.cpp
===================================================================
--- src/game/SpellAuras.cpp	(revision 4763)
+++ src/game/SpellAuras.cpp	(working copy)
@@ -39,6 +39,8 @@
 #include "Creature.h"
 #include "ConfusedMovementGenerator.h"
 #include "TargetedMovementGenerator.h"
+#include "FleeingMovementGenerator.h"
+#include "HomeMovementGenerator.h"
 #include "Formulas.h"
 #include "BattleGround.h"
 #include "BattleGroundAV.h"
@@ -297,7 +299,7 @@
 m_procCharges(0), m_spellmod(NULL), m_spellId(spellproto->Id), m_effIndex(eff), m_caster_guid(0), m_target(target),
 m_timeCla(1000), m_castItemGuid(castItem?castItem->GetGUID():0), m_auraSlot(MAX_AURAS),
 m_positive(false), m_permanent(false), m_isPeriodic(false), m_isTrigger(false), m_isAreaAura(false), m_isPersistent(false),
-m_periodicTimer(0), m_PeriodicEventId(0), m_updated(false), m_removeOnDeath(false),m_fearMoveAngle(0)
+m_periodicTimer(0), m_PeriodicEventId(0), m_updated(false), m_removeOnDeath(false),m_fearMoveAngle(0),m_fearMovementTimer(0)
 {
     assert(target);
 
@@ -452,52 +454,7 @@
             caster->ModifyPower(powertype,-manaPerSecond);
             caster->ModifyPower(powertype,-manaPerSecondPerLevel);
         }
-        if(caster && m_target->isAlive() && m_target->HasFlag(UNIT_FIELD_FLAGS,(UNIT_STAT_FLEEING<<16)))
-        {
-            int q = rand() % 80;
-            if(q == 8) m_fearMoveAngle += (float)(urand(45, 90));
-            else if(q == 23) m_fearMoveAngle -= (float)(urand(45, 90));
-
-            // If the m_target is player,and if the speed is too slow,change it :P
-            float speed = m_target->GetSpeed(MOVE_RUN);
-            // Speed modifier, may need to find correct one
-            float mod = m_target->GetTypeId() != TYPEID_PLAYER ? 10 : 6;
-            float pos_x = m_target->GetPositionX();
-            float pos_y = m_target->GetPositionY();
-            uint32 mapid = m_target->GetMapId();
-            float pos_z = MapManager::Instance().GetBaseMap(mapid)->GetHeight(pos_x,pos_y, m_target->GetPositionZ());
-            // Control the max Distance; 28 for temp.
-            if(m_target->IsWithinDistInMap(caster, 28))
-            {
-                float x = m_target->GetPositionX() - (speed*cosf(m_fearMoveAngle))/mod;
-                float y = m_target->GetPositionY() - (speed*sinf(m_fearMoveAngle))/mod;
-                float z = MapManager::Instance().GetBaseMap(mapid)->GetHeight(x,y, m_target->GetPositionZ());
-                // Control the target to not climb or drop when dz > |x|,x = 1.3 for temp.
-                // fixed me if it needs checking when the position will be in water?
-                                                            //+vmaps
-                if((z<=pos_z+1.3 && z>=pos_z-1.3) && m_target->IsWithinLOS(x,y,z))
-                {
-                    m_target->SendMonsterMove(x,y,z,0,true,(diff*2));
-                    if(m_target->GetTypeId() != TYPEID_PLAYER)
-                        MapManager::Instance().GetMap(m_target->GetMapId(), m_target)->CreatureRelocation((Creature*)m_target,x,y,z,m_target->GetOrientation());
-                }
-                else
-                {
-                    //Complete the move only if z coord is now correct
-                    m_fearMoveAngle += 120;
-                    x = m_target->GetPositionX() + (speed*sinf(m_fearMoveAngle))/mod;
-                    y = m_target->GetPositionY() + (speed*cosf(m_fearMoveAngle))/mod;
-                    z = MapManager::Instance().GetBaseMap(mapid)->GetHeight(x,y, m_target->GetPositionZ());
-                                                            //+vmaps
-                    if((z<=pos_z+1.3 && z>=pos_z-1.3) && m_target->IsWithinLOS(x,y,z))
-                    {
-                        m_target->SendMonsterMove(x,y,z,0,true,(diff*2));
-                        if(m_target->GetTypeId() != TYPEID_PLAYER)
-                            MapManager::Instance().GetMap(m_target->GetMapId(), m_target)->CreatureRelocation((Creature*)m_target,x,y,z,m_target->GetOrientation());
-                    }
-                }
-            }
-        }
+        //Better remove all this and create a runaway MV, and we simpli stack one over the other, GS
     }
 
     if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent))
@@ -1761,8 +1718,7 @@
             m_target->DeleteThreatList();
             if(m_target->GetTypeId() == TYPEID_UNIT)
             {
-                m_target->StopMoving();
-                m_target->GetMotionMaster()->Clear();
+                m_target->GetMotionMaster()->Clear(false);
                 m_target->GetMotionMaster()->Idle();
                 CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
                 charmInfo->InitPossessCreateSpells();
@@ -1969,7 +1925,6 @@
 
     if( apply )
     {
-        m_target->addUnitState(UNIT_STAT_CONFUSED);
         m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
 
         if(m_target->GetTypeId() == TYPEID_PLAYER)
@@ -2004,7 +1959,6 @@
     }
     else
     {
-        m_target->clearUnitState(UNIT_STAT_CONFUSED);
         m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
 
         if(m_target->GetTypeId() == TYPEID_PLAYER)
@@ -2019,15 +1973,7 @@
         // only at real remove aura
         if(Real)
         {
-            m_target->GetMotionMaster()->MovementExpired(false);
 
-            if (m_target->GetTypeId() == TYPEID_UNIT)
-            {
-                Creature* c = (Creature*)m_target;
-                // if in combat restore movement generator
-                if(c->getVictim())
-                    c->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*c->getVictim()));
-            }
         }
     }
 }
@@ -2036,53 +1982,23 @@
 {
     if( Apply )
     {
-        m_target->addUnitState(UNIT_STAT_FLEEING);
         m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
-
-        // only at real add aura
+        
+        //only at real add aura
         if(Real)
         {
-            //FIX ME: we need Mutate to now not existed FleeMovementGenerator (see Aura::Update hack code)
-            // at this moment Idle instead
-            m_target->GetMotionMaster()->MovementExpired(false);
-            m_target->GetMotionMaster()->Idle();
-
-            // what is this for ? (doesn't work anyway)
-            /*WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 9);
-            data.append(m_target->GetPackGUID());
-            data << uint8(0x00);
-            m_target->SendMessageToSet(&data,true);*/
+           if (m_target->GetTypeId() == TYPEID_UNIT)
+                m_target->GetMotionMaster()->Mutate(new FleeingMovementGenerator<Creature>(*m_target,m_caster_guid) );
+           else
+                m_target->GetMotionMaster()->Mutate(new FleeingMovementGenerator<Player>(*m_target,m_caster_guid) );
         }
     }
     else
     {
-        m_target->clearUnitState(UNIT_STAT_FLEEING);
         m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
-
         // only at real remove aura
         if(Real)
         {
-            m_target->GetMotionMaster()->MovementExpired(false);
-
-            if(m_target->GetTypeId() != TYPEID_PLAYER)
-            {
-                // restore appropriate movement generator
-                if(m_target->getVictim())
-                    m_target->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_target->getVictim()));
-                else
-                    m_target->GetMotionMaster()->Initialize();
-
-                // attack caster if can
-                Unit* caster = GetCaster();
-                if(caster && caster != m_target->getVictim())
-                    ((Creature*)m_target)->AI()->AttackStart(caster);
-            }
-
-            // what is this for ? (doesn't work anyway)
-            /*WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 9);
-            data.append(m_target->GetPackGUID());
-            data << uint8(0x01);
-            m_target->SendMessageToSet(&data,true);*/
         }
     }
 }
@@ -2156,7 +2072,7 @@
     if (apply)
     {
         m_target->addUnitState(UNIT_STAT_STUNDED);
-        m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
+        //m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
         m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
 
         if (caster)
@@ -2174,14 +2090,16 @@
         // Creature specific
         if(m_target->GetTypeId() != TYPEID_PLAYER)
         {
+            WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
+
+            data.append(m_target->GetPackGUID());
+            data << uint32(0);
+            m_target->SendMessageToSet(&data,true);
+        }
+        else
+        {
             ((Creature *)m_target)->StopMoving();
         }
-
-        WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
-
-        data.append(m_target->GetPackGUID());
-        data << uint32(0);
-        m_target->SendMessageToSet(&data,true);
     }
     else
     {
@@ -2194,11 +2112,16 @@
 
         if(m_target->getVictim() && m_target->isAlive())
             m_target->SetUInt64Value (UNIT_FIELD_TARGET,m_target->getVictim()->GetGUID() );
+        //if(caster && m_target->isAlive())
+            //m_target->SetUInt64Value (UNIT_FIELD_TARGET,GetCasterGUID());
 
-        WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4);
-        data.append(m_target->GetPackGUID());
-        data << uint32(0);
-        m_target->SendMessageToSet(&data,true);
+        if(m_target->GetTypeId() == TYPEID_PLAYER)
+        {
+            WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4);
+            data.append(m_target->GetPackGUID());
+            data << uint32(0);
+            m_target->SendMessageToSet(&data,true);
+        }
         if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->SpellIconID == 1721)
         {
             if( !caster || caster->GetTypeId()!=TYPEID_PLAYER )
@@ -2386,14 +2309,16 @@
     if (apply)
     {
         m_target->addUnitState(UNIT_STAT_ROOT);
-        m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
+        //m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
                                                             // probably wrong
-        m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
+        //m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
 
         //Save last orientation
         if( m_target->getVictim() )
             m_target->SetOrientation(m_target->GetAngle(m_target->getVictim()));
 
+        //if (caster)
+           // m_target->SetOrientation(m_target->GetAngle(caster));
         if(m_target->GetTypeId() == TYPEID_PLAYER)
         {
             WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
@@ -2402,7 +2327,9 @@
             m_target->SendMessageToSet(&data,true);
         }
         else
+        {
             ((Creature *)m_target)->StopMoving();
+        }
     }
     else
     {
@@ -2414,6 +2341,9 @@
                                                             // probably wrong
         m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
 
+        //m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
+        //if(caster && m_target->isAlive())                   // set creature facing on root effect if alive
+            //m_target->SetUInt64Value (UNIT_FIELD_TARGET,GetCasterGUID());
         if(m_target->getVictim() && m_target->isAlive())
             m_target->SetUInt64Value (UNIT_FIELD_TARGET,m_target->getVictim()->GetGUID() );
 
Index: src/game/SpellAuras.h
===================================================================
--- src/game/SpellAuras.h	(revision 4763)
+++ src/game/SpellAuras.h	(working copy)
@@ -264,6 +264,7 @@
         uint64 m_caster_guid;
         Unit* m_target;
         int32 m_maxduration;
+        uint16 m_fearMovementTimer;
         int32 m_duration;
         int32 m_timeCla;
         // it is NOT safe to keep a pointer to the item because it may get deleted
Index: src/game/SpellEffects.cpp
===================================================================
--- src/game/SpellEffects.cpp	(revision 4763)
+++ src/game/SpellEffects.cpp	(working copy)
@@ -53,6 +53,8 @@
 #include "BattleGroundWS.h"
 #include "VMapFactory.h"
 #include "Language.h"
+#include "TargetedMovementGenerator.h"
+#include "IdleMovementGenerator.h"
 
 pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
 {
@@ -1233,7 +1235,11 @@
 
     sLog.outDebug("Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[i]);
 
-    Aura* Aur = new Aura(m_spellInfo, i, &m_currentBasePoints[i], unitTarget,m_caster, m_CastItem);
+    Aura* Aur;
+    if( m_originalCaster )
+        Aur = new Aura(m_spellInfo, i, &m_currentBasePoints[i], unitTarget, m_originalCaster, m_CastItem);
+    else
+        Aur = new Aura(m_spellInfo, i, &m_currentBasePoints[i], unitTarget, m_caster, m_CastItem);
 
     if (!Aur->IsPositive() && Aur->GetCasterGUID() != Aur->GetTarget()->GetGUID())
     {
@@ -3073,11 +3079,14 @@
     switch(m_spellInfo->Id)
     {
         // Keep in top, because core use it for npc aggro other npc
-        case SPELL_ID_AGGRO:
+        case CREATURE_SPELL_TAP_FRIEND:
         {
             if( !m_caster || m_caster->GetTypeId() != TYPEID_UNIT || !m_caster->getVictim() )
                 return;
 
+            // Should be == to diff from Home Location to Location, with a maximun of 50 like, GS
+            //So we can bring her too far away from original location, GS
+            // Need to readjuste, AnyAssistCreatureInRangeCheck to be more smart, Like select Strong First, GS
             float radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTEMCE_RADIUS);
             if(radius > 0)
             {
@@ -3097,16 +3106,14 @@
                     CellLock<GridReadGuard> cell_lock(cell, p);
                     cell_lock->Visit(cell_lock, grid_creature_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster));
                 }
-
-                for(std::list<Creature*>::iterator iter = assistList.begin(); iter != assistList.end(); ++iter)
+                std::list<Creature*>::iterator firstTarget = assistList.begin();
+                if( firstTarget != assistList.end() )
                 {
-                    ((Creature*)m_caster)->SetNoCallAssistence(true);
-                    (*iter)->SetNoCallAssistence(true);
-                    if((*iter)->AI())
-                        (*iter)->AI()->AttackStart(m_caster->getVictim());
+                    //TODO:Create Bondary Range Check into Object..., GS
+                    m_caster->GetMotionMaster()->Mutate(new IdleMovementGenerator(*m_caster,false,1000));
+                    m_caster->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>( *(*firstTarget),(*firstTarget)->GetObjectSize()+m_caster->GetObjectSize(),(rand_norm()*(M_PI*2)),true ));
                 }
             }
-
             return;
         }
 
@@ -3764,15 +3771,17 @@
         return;
 
     float x, y, z;
-    unitTarget->GetContactPoint(m_caster, x, y, z);
-    if(unitTarget->GetTypeId() != TYPEID_PLAYER)
-        ((Creature *)unitTarget)->StopMoving();
-
+    unitTarget->GetPosition( x, y, z);
     m_caster->SendMonsterMove(x, y, z, 0, true,1);
-    if(m_caster->GetTypeId() != TYPEID_PLAYER)
+    if(m_caster->GetMotionMaster()->top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE)
+    {
+        m_caster->Relocate(x, y, z);
+        m_caster->GetMotionMaster()->top()->Initialize(*m_caster);
+    }
+    else if(m_caster->GetTypeId() == TYPEID_UNIT)
         MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)->CreatureRelocation((Creature*)m_caster,x,y,z,m_caster->GetOrientation());
+    m_caster->Attack(unitTarget,true);
 
-    m_caster->Attack(unitTarget,true);
 }
 
 void Spell::EffectSummonCritter(uint32 i)
Index: src/game/TargetedMovementGenerator.cpp
===================================================================
--- src/game/TargetedMovementGenerator.cpp	(revision 4763)
+++ src/game/TargetedMovementGenerator.cpp	(working copy)
@@ -22,6 +22,7 @@
 #include "Creature.h"
 #include "MapManager.h"
 #include "DestinationHolderImp.h"
+#include "Spell.h"
 
 #define SMALL_ALPHA 0.05f
 
@@ -39,129 +40,122 @@
 };
 */
 
-template<class T>
-void
-TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
+template<class T> void TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
 {
-    if( !&i_target || !&owner )
+    if( !&i_target || !&owner || !i_target.isValid())               //Added To make Script.dll don't crash into DEBUG Mode
         return;
 
-    if( owner.hasUnitState(UNIT_STAT_ROOT) || owner.hasUnitState(UNIT_STAT_STUNDED) )
-        return;
-
-    // prevent redundant micro-movement for pets, other followers.
-    if(i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
-        return;
-
     float x, y, z;
-    if(!i_offset)
-    {
-        // to nearest contact position
-        i_target->GetContactPoint( &owner, x, y, z );
-    }
-    else
-    {
-        // to at i_offset distance from target and i_angle from target facing
-        i_target->GetClosePoint(x,y,z,owner.GetObjectSize() + i_offset,i_angle);
-    }
+    
+    const float minReachRadius = owner.GetObjectSize() + (owner.GetFloatValue(UNIT_FIELD_COMBATREACH)/1.75);
+    i_offset = i_offset < minReachRadius ? minReachRadius : i_offset;
 
-    //We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize
-    float  bothObjectSize = i_target->GetObjectSize() + owner.GetObjectSize() + CONTACT_DISTANCE;
-    if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize )
-        return;
+    //absAngle should herite PositionCollision
+    float const absAngle = owner.GetAngle(i_target.getTarget());
+    x = i_target.getTarget()->GetPositionX() + ((i_offset+i_target.getTarget()->GetObjectSize()) * cos(absAngle));
+    y = i_target.getTarget()->GetPositionY() + ((i_offset+i_target.getTarget()->GetObjectSize()) * sin(absAngle));
+    z = i_target.getTarget()->GetPositionZ();
+
     Traveller<T> traveller(owner);
+    owner.SetOrientation(owner.GetAngle(x,y));
     i_destinationHolder.SetDestination(traveller, x, y, z);
     owner.addUnitState(UNIT_STAT_CHASE);
 }
 
-template<class T>
-void
-TargetedMovementGenerator<T>::Initialize(T &owner)
+template<class T> void TargetedMovementGenerator<T>::Initialize(T &owner)
 {
     if(!&owner)
         return;
+
+    //Will have to change that..., so we can dynamic check for Best walk or run, GS
+    //TODO: AIMotionMaster after spell Casting Walk.... and Lower range, GS
     owner.setMoveRunFlag(true);
     _setTargetLocation(owner);
 }
-
-template<class T>
-void
-TargetedMovementGenerator<T>::Reset(T &owner)
+template<class T> void TargetedMovementGenerator<T>::Reset(T &owner)
 {
     Initialize(owner);
 }
 
-template<class T>
-bool
-TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
+template<class T> bool TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
 {
-    if(!i_target.isValid())
-    {
+    //Hum that is cause ReferenceFollower... Not sure yet again if we really need that... since we should search allways for XYZ
+    // and fuck the target.... so target should never never appear here... only XYZ
+    //TODO: Change the way Targeted Work and make it: FollowerMovementGenerator(), ChasingMovementGenerator()
+    //For the moment is working much better then actual but ... is more like little finetune here and there.
+    //We doo at the end with Path Searching...., GS
+    
+    //ReferenceFollower are no more needed i think so, if we keep that Generator only for Victim... :)
+    //if( owner.getVictim() != i_target.getTarget() )
+       // return false;
+
+    if(!i_target.isValid() || !&owner || !owner.isAlive() )
         return false;
-    }
-    if( !&owner || !owner.isAlive() || !&i_target )
-        return true;
-    if( owner.hasUnitState(UNIT_STAT_ROOT) || owner.hasUnitState(UNIT_STAT_STUNDED) || owner.hasUnitState(UNIT_STAT_FLEEING))
-        return true;
-    if( !owner.isInCombat() && !owner.hasUnitState(UNIT_STAT_FOLLOW) )
-    {
-        //owner.AIM_Initialize();   This case must be the one, when a creature aggroed you. By Initalized a new AI, we prevented to Ai::_stopAttack() to be executed properly.
-        return true;
-    }
 
-    // prevent crash after creature killed pet
-    if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget())
-        return true;
+    if( !owner.GetUInt32Value(UNIT_FIELD_TARGET))
+        return false;
 
+    //To Debug why sometime Mangos screw: UNIT_FIELD_TARGET, GS
+    if( owner.getVictim() && i_target.getTarget() && owner.GetUInt64Value(UNIT_FIELD_TARGET) != i_target.getTarget()->GetGUID() )
+        owner.GetUInt64Value(UNIT_FIELD_TARGET);
+        
+    // prevent crash after creature killed pet //HEIN??? , GS
+    //if( !owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget())
+        //return true;
+
     Traveller<T> traveller(owner);
 
     if( !i_destinationHolder.HasDestination() )
         _setTargetLocation(owner);
+
     if( owner.IsStopped() && !i_destinationHolder.HasArrived() )
-    {
         owner.addUnitState(UNIT_STAT_CHASE);
-        i_destinationHolder.StartTravel(traveller);
-        return true;
-    }
 
     if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
     {
-        // put targeted movement generators on a higher priority
-        if (owner.GetObjectSize())
-            i_destinationHolder.ResetUpdate(50);
+        // put targeted movement generators on a higher priority, No way Man, GS
+        i_destinationHolder.ResetUpdate(100);
+        //DEBUG value, GS
+        float _asdf = sqrt(i_destinationHolder.GetDistanceFromDest2dSq(*i_target.getTarget()));
+        float _asdf2 = owner.GetFloatValue(UNIT_FIELD_COMBATREACH);
+        float _asdf3 = i_target->GetObjectSize() + owner.GetFloatValue(UNIT_FIELD_COMBATREACH) + owner.GetObjectSize() + i_offset;
 
-        float dist = i_target->GetObjectSize() + owner.GetObjectSize() + CONTACT_DISTANCE;
-
-        // try to counter precision differences
-        if( i_destinationHolder.GetDistanceFromDestSq(*i_target.getTarget()) > dist * dist + 0.8)
-        {
-            owner.SetInFront(i_target.getTarget());         // Set new Angle For Map::
-            _setTargetLocation(owner);                      //Calculate New Dest and Send data To Player
+        // try to counter precision differences,
+        float targetDistToDest = sqrt(i_destinationHolder.GetDistanceFromDest2dSq(*i_target.getTarget())) - (i_target->GetObjectSize() + owner.GetFloatValue(UNIT_FIELD_COMBATREACH) + owner.GetObjectSize() + i_offset);
+        // -0.5 should be Bounding radius of this.... but for test use that one... be sure NPC move if your too close.
+        if( targetDistToDest > -0.5f &&  (i_destinationHolder.HasArrived() || i_destinationHolder.GetTimeToDest() > TRAVELLER_UPDATE_INTERVAL) )
+        {    
+            float x,y,z;
+            i_destinationHolder.GetLocationNow(x,y,z);
+            traveller.Relocation(x,y,z);
+            _setTargetLocation(owner);
         }
-        // Update the Angle of the target only for Map::, no need to send packet for player
-        else if ( !i_angle && !owner.HasInArc( 0.01f, i_target.getTarget() ) )
-            owner.SetInFront(i_target.getTarget());
 
+        //Angle update will be made with Operator Overload into GetOrientation()
+        //For fast Angle Update during fight, MeanMachine Rocking idea :), GS
         if( !owner.IsStopped() && i_destinationHolder.HasArrived())
         {
-            //Angle update will take place into owner.StopMoving()
+            owner.clearUnitState(UNIT_STAT_MOVING);
             owner.SetInFront(i_target.getTarget());
-
-            owner.StopMoving();
-            if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
-                owner.Attack(i_target.getTarget());
+            if(i_forceExpireAtDest)
+                return false;
         }
     }
     return true;
 }
 
-template<class T>
-Unit* 
-TargetedMovementGenerator<T>::GetTarget() const
+template<class T> Unit* TargetedMovementGenerator<T>::GetTarget() const
 {
     return i_target.getTarget();
 }
-
+template<class T> float TargetedMovementGenerator<T>::GetOffSet() const
+{
+    return i_offset;
+}
+template<class T> void TargetedMovementGenerator<T>::SetOffSet(float newOffSet)
+{
+    i_offset = *new float(newOffSet);
+}
 template void TargetedMovementGenerator<Player>::_setTargetLocation(Player &);
 template void TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &);
 template void TargetedMovementGenerator<Player>::Initialize(Player &);
@@ -172,3 +166,7 @@
 template bool TargetedMovementGenerator<Creature>::Update(Creature &, const uint32 &);
 template Unit* TargetedMovementGenerator<Player>::GetTarget() const;
 template Unit* TargetedMovementGenerator<Creature>::GetTarget() const;
+template float TargetedMovementGenerator<Player>::GetOffSet() const;
+template float TargetedMovementGenerator<Creature>::GetOffSet() const;
+template void TargetedMovementGenerator<Player>::SetOffSet(float newOffSet);
+template void TargetedMovementGenerator<Creature>::SetOffSet(float newOffSet);
Index: src/game/TargetedMovementGenerator.h
===================================================================
--- src/game/TargetedMovementGenerator.h	(revision 4763)
+++ src/game/TargetedMovementGenerator.h	(working copy)
@@ -39,10 +39,10 @@
 {
     public:
 
-        TargetedMovementGenerator(Unit &target)
-            : TargetedMovementGeneratorBase(target), i_offset(0), i_angle(0) {}
-        TargetedMovementGenerator(Unit &target, float offset, float angle)
-            : TargetedMovementGeneratorBase(target), i_offset(offset), i_angle(angle) {}
+        TargetedMovementGenerator(Unit &target, bool forceExpireAtDest = false)
+            : TargetedMovementGeneratorBase(target), i_offset(0), i_angle(0),i_forceExpireAtDest(forceExpireAtDest) {}
+        TargetedMovementGenerator(Unit &target, float offset, float angle, bool forceExpireAtDest = false)
+            : TargetedMovementGeneratorBase(target), i_offset(offset), i_angle(angle),i_forceExpireAtDest(forceExpireAtDest) {}
         ~TargetedMovementGenerator() {}
 
         void Initialize(T &);
@@ -51,7 +51,12 @@
         MovementGeneratorType GetMovementGeneratorType() { return TARGETED_MOTION_TYPE; }
 
         Unit* GetTarget() const;
-
+        float GetOffSet() const;
+        void SetOffSet(float newOffSet);
+        void UpdateMapPosition(float &x ,float &y, float &z)
+        {
+            i_destinationHolder.GetLocationNow(x,y,z);
+        }
         bool GetDestination(float &x, float &y, float &z)
         {
             if(!i_destinationHolder.HasDestination()) return false;
@@ -61,9 +66,10 @@
     private:
 
         void _setTargetLocation(T &);
-
+        
         float i_offset;
         float i_angle;
+        bool i_forceExpireAtDest;
         DestinationHolder< Traveller<T> > i_destinationHolder;
 };
 #endif
Index: src/game/Traveller.h
===================================================================
--- src/game/Traveller.h	(revision 4763)
+++ src/game/Traveller.h	(working copy)
@@ -47,6 +47,7 @@
     inline float GetPositionX() const { return i_traveller.GetPositionX(); }
     inline float GetPositionY() const { return i_traveller.GetPositionY(); }
     inline float GetPositionZ() const { return i_traveller.GetPositionZ(); }
+    inline float GetOrientation() const { return i_traveller.GetOrientation(); }
     inline T& GetTraveller(void) { return i_traveller; }
 
     float Speed(void) { assert(false); return 0.0f; }
@@ -71,7 +72,7 @@
 template<>
 inline void Traveller<Creature>::MoveTo(float x, float y, float z, uint32 t)
 {
-    i_traveller.AI_SendMoveToPacket(x, y, z, t, i_traveller.getMoveRunFlag(), 0);
+    i_traveller.AI_SendMoveToPacket(x, y, z, t, Speed(), 0);
 }
 
 // specialization for players
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp	(revision 4763)
+++ src/game/Unit.cpp	(working copy)
@@ -39,6 +39,12 @@
 #include "Totem.h"
 #include "BattleGround.h"
 #include "MovementGenerator.h"
+#include "TargetedMovementGenerator.h"
+#include "ConfusedMovementGenerator.h"
+#include "RandomMovementGenerator.h"
+#include "WaypointMovementGenerator.h"
+#include "HomeMovementGenerator.h"
+#include "FleeingMovementGenerator.h"
 
 #include <math.h>
 
@@ -132,6 +138,7 @@
 
     for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++)
         m_currentSpells[i] = NULL;
+    m_hasHealer = false;    
     m_addDmgOnce = 0;
     m_TotemSlot[0] = m_TotemSlot[1] = m_TotemSlot[2] = m_TotemSlot[3]  = 0;
     m_ObjectSlot[0] = m_ObjectSlot[1] = m_ObjectSlot[2] = m_ObjectSlot[3] = 0;
@@ -302,17 +309,16 @@
     SendMonsterMove(x,y,z,0,run,transitTime);
 }
 
-void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, bool Run, uint32 Time)
+void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, bool Run, uint32 Time, bool tryFlag512)
 {
     WorldPacket data( SMSG_MONSTER_MOVE, (41 + GetPackGUID().size()) );
     data.append(GetPackGUID());
-
     // Point A, starting location
     data << GetPositionX() << GetPositionY() << GetPositionZ();
     // unknown field - unrelated to orientation
     // seems to increment about 1000 for every 1.7 seconds
     // for now, we'll just use mstime
-    data << getMSTime();
+    data << getMSTime()/* + ((Time / 1000) * 140)*/; //Simulate 140 allways Ping
 
     data << uint8(type);                                    // unknown
     switch(type)
@@ -323,14 +329,17 @@
             SendMessageToSet( &data, true );
             return;
         case 3:                                             // not used currently
-            data << uint64(0);                              // probably target guid
+            data << uint64(GetUInt64Value(UNIT_FIELD_TARGET));                              // probably target guid
             break;
         case 4:                                             // not used currently
             data << float(0);                               // probably orientation
             break;
     }
 
-    data << uint32(Run ? 0x00000100 : 0x00000000);          // flags (0x100 - running, 0x200 - taxi)
+    if(tryFlag512)
+        data <<  uint32(0x11111111);
+    else
+        data << uint32(Run ? 0x00000100 : 0x00000000);          // flags (0x100 - running, 0x200 - taxi)
     /* Flags:
     512: Floating, moving without walking/running
     */
@@ -383,6 +392,10 @@
     return (!m_modAuras[auraType].empty());
 }
 
+bool Unit::HasSpellChannelActiveTimer()
+{
+    return m_currentSpells[CURRENT_GENERIC_SPELL] ? m_currentSpells[CURRENT_GENERIC_SPELL]->GetTimer() > 0 : false;
+}
 /* Called by DealDamage for auras that have a chance to be dispelled on damage taken. */
 void Unit::RemoveSpellbyDamageTaken(uint32 auraType, uint32 damage)
 {
@@ -643,6 +656,9 @@
                 ((Creature*)pVictim)->AI()->JustDied(this);
         }
 
+
+        m_hasHealer = false;
+
         //judge if GainXP, Pet kill like player kill,kill pet not like PvP
         bool PvP = false;
         Player *player = NULL;
@@ -877,7 +893,7 @@
 
         if (damagetype != NODAMAGE)
         {
-            if(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL] && pVictim->GetTypeId() == TYPEID_PLAYER && damage)
+            if(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL] /*&& pVictim->GetTypeId() == TYPEID_PLAYER*/ && damage)
             {
                 if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_CASTING)
                 {
@@ -2077,7 +2093,7 @@
         }
     }
 
-    if (pVictim->GetTypeId() == TYPEID_PLAYER && *damage)
+    if (/*pVictim->GetTypeId() == TYPEID_PLAYER &&*/ *damage)
     {
         for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
         {
@@ -4724,19 +4740,21 @@
 
     //Set our target
     SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID());
+    SetInFront(victim);
 
     addUnitState(UNIT_STAT_ATTACKING);
     SetInCombat();
     m_attacking = victim;
     m_attacking->_addAttacker(this);
 
-    if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->AI())
-        ((Creature*)m_attacking)->AI()->AttackedBy(this);
+    //if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->AI())
+        //((Creature*)m_attacking)->AI()->AttackedBy(this); //Heu.. don't understand why we need that???
 
-    if( GetTypeId()==TYPEID_UNIT && !(((Creature*)this)->isPet() || isCharmed()) )
+    /*if( GetTypeId()==TYPEID_UNIT && !(((Creature*)this)->isPet() || isCharmed()) )
     {
         ((Creature*)this)->CallAssistence();
-    }
+    }*/
+
     //if(!isAttackReady(BASE_ATTACK))
     //resetAttackTimer(BASE_ATTACK);
 
@@ -4766,11 +4784,12 @@
     clearUnitState(UNIT_STAT_ATTACKING);
 
     InterruptSpell(CURRENT_MELEE_SPELL);
-
+    m_hasHealer = false; // I don't wan that, I must get rid at the end.. system should be smooth enought so no need at all, GS
+    
     if( GetTypeId()==TYPEID_UNIT )
     {
-        // reset call assistance
-        ((Creature*)this)->SetNoCallAssistence(false);
+        // reset assistance
+        ((Creature*)this)->m_AssistenceStatus->reset();
     }
 
     SendAttackStop(victim);
@@ -6338,13 +6357,12 @@
     }
 
     // no target but something prevent go to evade mode
+    // !isInCombat(), Do EnterEvade Only if inCombat(), no need after
+    // HasAuraType(SPELL_AURA_MOD_TAUNT), Cause EnterEvadeTake Place here : Unit::TauntFadeOut(Unit *taunter)
     if( !isInCombat() || HasAuraType(SPELL_AURA_MOD_TAUNT) || !CanFreeMove() )
         return false;
 
-    // last case when creature don't must go to evade mode:
-    // it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list
-    // for example at owner command to pet attack some far away creature
-    // Note: creature not have targeted movement generator but have attacker in this case 
+    // this, is waiting the Attacker to come to aggro range, no yet Threat Created from Attacker, GS
     if( GetMotionMaster()->empty() || GetMotionMaster()->top()->GetMovementGeneratorType() != TARGETED_MOTION_TYPE )
     {
         for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
@@ -7392,14 +7410,69 @@
 
 void Unit::StopMoving()
 {
+    //Should Add other Moving MV and prepare for Compatibility
+    if( !hasUnitState(UNIT_STAT_MOVING))
+       return;
+
+    //Was for testing in begin but since is pretty good, must be updated, GS
+    //TODO: make that much more simple, and Support Player as Creature.
+    if( GetTypeId() == TYPEID_UNIT )
+    {
+        MotionMaster* currentMotion = GetMotionMaster();
+        float x,y,z;                            //Dummy Usage into that case but needed since we carry pointer.
+        switch( currentMotion->top()->GetMovementGeneratorType() )
+        {
+            case IDLE_MOTION_TYPE:
+            {
+                break;
+            }
+            case TARGETED_MOTION_TYPE:
+            {
+                TargetedMovementGenerator<Creature>* currentMV = static_cast<TargetedMovementGenerator<Creature>*> (currentMotion->top());
+                currentMV->UpdateMapPosition(x,y,z);
+                MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation((Creature*)this, x, y, z, this->GetOrientation());
+                break;
+            }
+            case CONFUSED_MOTION_TYPE:
+            {
+                ConfusedMovementGenerator<Creature>* currentMV = static_cast<ConfusedMovementGenerator<Creature>*> (currentMotion->top());
+                currentMV->UpdateMapPosition(x,y,z);
+                MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation((Creature*)this, x, y, z, this->GetOrientation());
+                break;
+            }
+            case FLEEING_MOTION_TYPE:
+            {
+                FleeingMovementGenerator<Creature>* currentMV = static_cast<FleeingMovementGenerator<Creature>*> (currentMotion->top());
+                currentMV->UpdateMapPosition(x,y,z);
+                MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation((Creature*)this, x, y, z, this->GetOrientation());
+                break;
+            }
+            case HOME_MOTION_TYPE:
+            {
+                HomeMovementGenerator<Creature>* currentMV = static_cast<HomeMovementGenerator<Creature>*> (currentMotion->top());
+                currentMV->UpdateMapPosition(x,y,z);
+                MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation((Creature*)this, x, y, z, this->GetOrientation());
+                break;
+            }
+            case RANDOM_MOTION_TYPE:
+            {
+                RandomMovementGenerator<Creature>* currentMV = static_cast<RandomMovementGenerator<Creature>*> (currentMotion->top());
+                currentMV->UpdateMapPosition(x,y,z);
+                MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation((Creature*)this, x, y, z, this->GetOrientation());
+                break;
+            }
+            case WAYPOINT_MOTION_TYPE:
+            {
+                WaypointMovementGenerator<Creature>* currentMV = static_cast<WaypointMovementGenerator<Creature>*> (currentMotion->top());
+                currentMV->UpdateMapPosition(x,y,z);
+                MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation((Creature*)this, x, y, z, this->GetOrientation());
+                break;
+            }
+        }
+    }
     clearUnitState(UNIT_STAT_MOVING);
     // send explicit stop packet
-    SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(),0,true,0);
-
-    // update position and orientation;
-    WorldPacket data;
-    BuildHeartBeatMsg(&data);
-    SendMessageToSet(&data,false);
+    SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(),1,true,0);
 }
 
 bool Unit::IsStandState() const
@@ -7409,4 +7482,4 @@
         s != PLAYER_STATE_SIT_MEDIUM_CHAIR && s != PLAYER_STATE_SIT_HIGH_CHAIR && 
         s != PLAYER_STATE_SIT && s != PLAYER_STATE_SLEEP &&
         s != PLAYER_STATE_KNEEL;
-}
\ No newline at end of file
+}
Index: src/game/Unit.h
===================================================================
--- src/game/Unit.h	(revision 4763)
+++ src/game/Unit.h	(working copy)
@@ -314,9 +314,9 @@
     UNIT_STAT_STUNDED       = 8,
     UNIT_STAT_ROAMING       = 16,
     UNIT_STAT_CHASE         = 32,
-    UNIT_STAT_SEARCHING     = 64,
+    UNIT_STAT_SEARCHING     = 64,           //Creature is Moving but no MILOS called to Her... example: She go Home first 25% distance reached creature has SEARCHING, the rest will have normal ROAMING
     UNIT_STAT_FLEEING       = 128,
-    UNIT_STAT_MOVING        = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING),
+    UNIT_STAT_MOVING        = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING | 2048 | 256 | 512),
     UNIT_STAT_IN_FLIGHT     = 256,                          // player is in flight mode
     UNIT_STAT_FOLLOW        = 512,
     UNIT_STAT_ROOT          = 1024,
@@ -326,6 +326,9 @@
 
 enum UnitMoveType
 {
+    //All that is very important for prediction im gonna do...
+    //I will allways call for bigger Motion and will check if i can stop from there, we do reverse.
+    //Angle will be very important... since a creature will target right in front a player + 5 yard is player is MOVE WALK or RUN, so creature will allways act as intercept and not chasing retared..
     MOVE_WALK       = 0,
     MOVE_RUN        = 1,
     MOVE_WALKBACK   = 2,
@@ -907,6 +910,7 @@
             { return m_Auras.find(spellEffectPair(spellId, effIndex)) != m_Auras.end(); }
         
         bool virtual HasSpell(uint32 /*spellID*/) const { return false; }
+        bool HasSpellChannelActiveTimer();
 
         bool HasStealthAura()      const { return HasAuraType(SPELL_AURA_MOD_STEALTH); }
         bool HasInvisibilityAura() const { return HasAuraType(SPELL_AURA_MOD_INVISIBILITY); }
@@ -937,7 +941,7 @@
         void SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchools DamageType, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount);
         void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchools DamageType,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false);
 
-        void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, bool Run, uint32 Time);
+        void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, bool Run, uint32 Time, bool tryFlag512 = false);
 
         virtual void MoveOutOfRange(Player &) {  };
 
@@ -1022,6 +1026,7 @@
         void InterruptNonMeleeSpells(bool withDelayed);
 
         Spell* m_currentSpells[CURRENT_MAX_SPELL];
+        bool m_hasHealer;
         uint32 m_addDmgOnce;
         uint64 m_TotemSlot[4];
         uint64 m_ObjectSlot[4];
@@ -1152,7 +1157,27 @@
 
         bool IsStopped() const { return !(hasUnitState(UNIT_STAT_MOVING)); }
         void StopMoving();
-
+        
+        //AI Improuved Function
+        const bool hasFriendTarget()
+        {
+            return ( !getVictim() && GetUInt64Value(UNIT_FIELD_TARGET) );
+        }
+        const bool hasVictim()
+        {
+            return getVictim() ? true : false;
+        }
+        static const uint8 getHpPercent(Unit* unit)
+        { 
+            return unit->GetMaxHealth() ? uint8( (float)unit->GetHealth() / (float)unit->GetMaxHealth() * 100 )  : 0;
+        }
+        static const uint8 getMpPercent(Unit* unit) 
+        { 
+            return unit->GetMaxPower( POWER_MANA) ? uint8((float)unit->GetPower(POWER_MANA) / (float)unit->GetMaxPower(POWER_MANA) * 100 ) : 0; 
+        }
+        void DoDoSay(const char *text, ...); //Debug Function Should get Removed, GS
+        // END AI Improuved Feature
+        
         void setMoveRunFlag(bool f) { m_moveRun = f; }
         bool getMoveRunFlag() const { return m_moveRun; }
 
Index: src/game/WaypointMovementGenerator.cpp
===================================================================
--- src/game/WaypointMovementGenerator.cpp	(revision 4763)
+++ src/game/WaypointMovementGenerator.cpp	(working copy)
@@ -159,6 +159,8 @@
 {
     QueryResult *result = WorldDatabase.Query("SELECT distinct(`id`) as uniqueid FROM `creature_movement`");
 
+    //Need to redone everything here... MeanMachine has created a patch for this.... , GS
+    //Badly need MeanMachine Patch + add my change to it.
     if( result )
     {
         do
@@ -181,8 +183,8 @@
     // Waypoint movement can be switched on/off
     // This is quite handy for escort quests and other stuff
 
-    if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
-        return true;
+    //if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
+        //return true;
 
     // prevent crash at empty waypoint path.
     if(i_path.Empty())
@@ -373,34 +375,39 @@
 bool
 FlightPathMovementGenerator::Update(Player &player, const uint32 &diff)
 {
-    if( MovementInProgress() )
-    {
+    //if( MovementInProgress() )
+    //{
         Traveller<Player> traveller(player);
-        if( i_destinationHolder.UpdateTraveller(traveller, diff, false) )
-        {
-            i_destinationHolder.ResetUpdate(FLIGHT_TRAVEL_UPDATE);
+        i_destinationHolder.UpdateTraveller(traveller, diff, false);
+        //if( i_destinationHolder.UpdateTraveller(traveller, diff, false) )
+        //{
+            //i_destinationHolder.ResetUpdate(FLIGHT_TRAVEL_UPDATE);
             if( i_destinationHolder.HasArrived() )
             {
+                if(i_path.Size() <= i_currentNode+1)
+                {
+                    EndFlight(player);
+                    return false;
+                }
                 ++i_currentNode;
-                if( MovementInProgress() )
-                {
-                    DEBUG_LOG("loading node %u for player %s", i_currentNode, player.GetName());
+                //if( MovementInProgress() )
+                //{
+                    //DEBUG_LOG("loading node %u for player %s", i_currentNode, player.GetName());
                     // do not send movement, it was sent already
                     i_destinationHolder.SetDestination(traveller, i_path[i_currentNode].x, i_path[i_currentNode].y, i_path[i_currentNode].z, false);
-                    return true;
-                }
+                //}
                 //else HasArrived()
             }
-            else
-                return true;
-        }
-        else
-            return true;
-    }
-
+            //else
+                //return true;
+        //}
+        //else
+           // return true;
+    //}
+    return true;
     // we have arrived at the end of the path
-    EndFlight(player);
-    return false;
+    //EndFlight(player);
+    //return false;
 }
 
 void
Index: src/game/WaypointMovementGenerator.h
===================================================================
--- src/game/WaypointMovementGenerator.h	(revision 4763)
+++ src/game/WaypointMovementGenerator.h	(working copy)
@@ -67,7 +67,10 @@
         {
             return i_currentNode;
         }
-
+        void UpdateMapPosition(float &x ,float &y, float &z)
+        {
+            i_destinationHolder.GetLocationNow(x,y,z);
+        }
     protected:
         uint32 i_currentNode;
         DestinationHolder< Traveller<T> > i_destinationHolder;
Index: src/game/World.cpp
===================================================================
--- src/game/World.cpp	(revision 4763)
+++ src/game/World.cpp	(working copy)
@@ -380,7 +380,7 @@
     m_configs[CONFIG_GROUP_XP_DISTANCE] = m_configs[CONFIG_GROUP_XP_DISTANCE]*m_configs[CONFIG_GROUP_XP_DISTANCE];
     /// \todo Add MonsterSight and GuarderSight (with meaning) in mangosd.conf or put them as define
     m_configs[CONFIG_SIGHT_MONSTER] = sConfig.GetIntDefault("MonsterSight", 400);
-    m_configs[CONFIG_SIGHT_GUARDER] = sConfig.GetIntDefault("GuarderSight", 500);
+    m_configs[CONFIG_SIGHT_GUARDER] = sConfig.GetIntDefault("GuarderSight", 800);
     m_configs[CONFIG_GAME_TYPE] = sConfig.GetIntDefault("GameType", 0);
     m_configs[CONFIG_ALLOW_TWO_SIDE_ACCOUNTS] = sConfig.GetIntDefault("AllowTwoSide.Accounts", 0);
     m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT]    = sConfig.GetIntDefault("AllowTwoSide.Interaction.Chat",0);
@@ -633,6 +633,9 @@
     sLog.outString( "Loading Creature Respawn Data..." );   // must be after PackInstances()
     objmgr.LoadCreatureRespawnTimes();
 
+    sLog.outString( "Loading Creature SpellBook Data..." );
+    objmgr.LoadCreatureSpellBook();
+
     sLog.outString( "Loading Gameobject Data..." );
     objmgr.LoadGameobjects();
 
Index: src/shared/Database/DBCStores.cpp
===================================================================
--- src/shared/Database/DBCStores.cpp	(revision 4763)
+++ src/shared/Database/DBCStores.cpp	(working copy)
@@ -819,3 +819,5 @@
 // script support functions
 MANGOS_DLL_SPEC DBCStorage <SpellEntry>      const* GetSpellStore()      { return &sSpellStore;      }
 MANGOS_DLL_SPEC DBCStorage <SpellRangeEntry> const* GetSpellRangeStore() { return &sSpellRangeStore; }
+MANGOS_DLL_SPEC DBCStorage <SpellDurationEntry> const* GetSpellDurationStore() { return &sSpellDurationStore; }
+MANGOS_DLL_SPEC DBCStorage <SpellCastTimesEntry> const* GetCastTimesStore() { return &sCastTimesStore; }
Index: src/shared/Database/DBCStores.h
===================================================================
--- src/shared/Database/DBCStores.h	(revision 4763)
+++ src/shared/Database/DBCStores.h	(working copy)
@@ -202,6 +202,8 @@
 void LoadDBCStores(std::string dataPath);
 
 // script support functions
-MANGOS_DLL_SPEC DBCStorage <SpellEntry>      const* GetSpellStore()     ;
-MANGOS_DLL_SPEC DBCStorage <SpellRangeEntry> const* GetSpellRangeStore() ;
+MANGOS_DLL_SPEC DBCStorage <SpellEntry>      const* GetSpellStore();
+MANGOS_DLL_SPEC DBCStorage <SpellRangeEntry> const* GetSpellRangeStore();
+MANGOS_DLL_SPEC DBCStorage <SpellDurationEntry> const* GetSpellDurationStore();
+MANGOS_DLL_SPEC DBCStorage <SpellCastTimesEntry> const* GetCastTimesStore();
 #endif
Index: src/shared/Timer.h
===================================================================
--- src/shared/Timer.h	(revision 4763)
+++ src/shared/Timer.h	(working copy)
@@ -74,4 +74,13 @@
     time_t GetExpiry(void) const { return i_expiryTime; }
     time_t i_expiryTime;
 };
+
+struct TimeTracker2
+{
+    TimeTracker2(int32 expiry) : i_expiryTime(expiry) {}
+    void Update(int32 diff) { i_expiryTime -= diff; }
+    bool Passed(void) const { return (i_expiryTime <= 0); }
+    void Reset(int32 interval) { i_expiryTime = interval; }
+    int32 i_expiryTime;
+};
 #endif
Index: src/shared/Util.h
===================================================================
--- src/shared/Util.h	(revision 4763)
+++ src/shared/Util.h	(working copy)
@@ -36,6 +36,7 @@
 /* Return a random number in the range min..max; (max-min) must be smaller than 32768.
  * Note: Not reentrant - if two threads call this simultaneously, they will likely
  * get the same random number. */
+MANGOS_DLL_SPEC
 extern int32 irand(int32 min, int32 max);
 
 /* Return a random number in the range min..max; (max-min) must be smaller than 32768.
@@ -52,11 +53,13 @@
 /* Return a random number in the range 0 .. RAND32_MAX.
  * Note: Not reentrant - if two threads call this simultaneously, they will likely
  * get the same random number. */
+MANGOS_DLL_SPEC
 extern int32 rand32(void);
 
 /* Return a random double from 0.0 to 1.0 (exclusive). Floats support only 7 valid decimal digits.
  * A double supports up to 15 valid decimal digits and is used internaly (RAND32_MAX has 10 digits).
  * With an FPU, there is usually no difference in performance between float and double. */
+MANGOS_DLL_SPEC
 inline double rand_norm(void)
 {
     return double(rand32()) / double(RAND32_MAX+1);
Index: src/shared/vmap/VMapManager.cpp
===================================================================
--- src/shared/vmap/VMapManager.cpp	(revision 4763)
+++ src/shared/vmap/VMapManager.cpp	(working copy)
@@ -431,9 +431,9 @@
             {
                 height = VMAP_INVALID_HEIGHT;               //no height
             }
-            Command c = Command();
-            c.fillTestHeightCmd(pMapId,Vector3(x,y,z),height);
-            iCommandLogger.appendCmd(c);
+            //Command c = Command();
+            //c.fillTestHeightCmd(pMapId,Vector3(x,y,z),height);
+            //iCommandLogger.appendCmd(c);
         }
         return(height);
     }
Index: win/mangosdVC80.sln
===================================================================
--- win/mangosdVC80.sln	(revision 4763)
+++ win/mangosdVC80.sln	(working copy)
@@ -7,10 +7,10 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared", "VC80\shared.vcproj", "{90297C34-F231-4DF4-848E-A74BCC0E40ED}"
 	ProjectSection(ProjectDependencies) = postProject
+		{BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E} = {BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E}
+		{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} = {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}
+		{8072769E-CF10-48BF-B9E1-12752A5DAC6E} = {8072769E-CF10-48BF-B9E1-12752A5DAC6E}
 		{262199E8-EEDF-4700-A1D1-E9CC901CF480} = {262199E8-EEDF-4700-A1D1-E9CC901CF480}
-		{8072769E-CF10-48BF-B9E1-12752A5DAC6E} = {8072769E-CF10-48BF-B9E1-12752A5DAC6E}
-		{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} = {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}
-		{BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E} = {BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mangosd", "VC80\mangosd.vcproj", "{A3A04E47-43A2-4C08-90B3-029CEF558594}"
Index: win/VC80/game.vcproj
===================================================================
--- win/VC80/game.vcproj	(revision 4763)
+++ win/VC80/game.vcproj	(working copy)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8,00"
+	Version="8.00"
 	Name="game"
 	ProjectGUID="{1DC6C4DA-A028-41F3-877D-D5400C594F88}"
 	RootNamespace="game"
@@ -598,6 +598,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\game\AggressorCasterAI.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\game\AggressorCasterAI.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\game\AnimalRandomMovementGenerator.h"
 				>
 			</File>
@@ -694,6 +702,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\game\FleeingMovementGenerator.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\game\FleeingMovementGenerator.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\game\Formulas.h"
 				>
 			</File>
Index: win/VC80/mangosd.vcproj
===================================================================
--- win/VC80/mangosd.vcproj	(revision 4763)
+++ win/VC80/mangosd.vcproj	(working copy)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8,00"
+	Version="8.00"
 	Name="mangosd"
 	ProjectGUID="{A3A04E47-43A2-4C08-90B3-029CEF558594}"
 	RootNamespace="mangosd"
Index: win/VC80/shared.vcproj
===================================================================
--- win/VC80/shared.vcproj	(revision 4763)
+++ win/VC80/shared.vcproj	(working copy)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8,00"
+	Version="8.00"
 	Name="shared"
 	ProjectGUID="{90297C34-F231-4DF4-848E-A74BCC0E40ED}"
 	>