Index: /trunk/src/game/SpellEffects.cpp
===================================================================
--- /trunk/src/game/SpellEffects.cpp (revision 168)
+++ /trunk/src/game/SpellEffects.cpp (revision 174)
@@ -133,5 +133,5 @@
     &Spell::EffectPickPocket,                               // 71 SPELL_EFFECT_PICKPOCKET
     &Spell::EffectAddFarsight,                              // 72 SPELL_EFFECT_ADD_FARSIGHT
-    &Spell::EffectSummonGuardian,                           // 73 SPELL_EFFECT_SUMMON_POSSESSED
+    &Spell::EffectSummonPossessed,                          // 73 SPELL_EFFECT_SUMMON_POSSESSED
     &Spell::EffectSummonTotem,                              // 74 SPELL_EFFECT_SUMMON_TOTEM
     &Spell::EffectHealMechanical,                           // 75 SPELL_EFFECT_HEAL_MECHANICAL          one spell: Mechanical Patch Kit
@@ -3128,7 +3128,9 @@
     {
         case SUMMON_TYPE_GUARDIAN:
+            EffectSummonGuardian(i);
+            break;
         case SUMMON_TYPE_POSESSED:
         case SUMMON_TYPE_POSESSED2:
-            EffectSummonGuardian(i);
+            EffectSummonPossessed(i);
             break;
         case SUMMON_TYPE_WILD:
@@ -3676,4 +3678,26 @@
         map->Add((Creature*)spawnCreature);
     }
+}
+
+void Spell::EffectSummonPossessed(uint32 i)
+{
+    uint32 creatureEntry = m_spellInfo->EffectMiscValue[i];
+    if(!creatureEntry)
+        return;
+
+    if(m_caster->GetTypeId() != TYPEID_PLAYER)
+        return;
+
+    uint32 level = m_caster->getLevel();
+
+    float px, py, pz;
+    m_caster->GetClosePoint(px, py, pz, DEFAULT_WORLD_OBJECT_SIZE);
+
+    int32 duration = GetSpellDuration(m_spellInfo);
+
+    TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OR_DEAD_DESPAWN;
+
+    Creature* c = m_caster->SummonCreature(creatureEntry, px, py, pz, m_caster->GetOrientation(), summonType, duration);
+    ((Player*)m_caster)->Possess(c);
 }
 
Index: /trunk/src/game/PetHandler.cpp
===================================================================
--- /trunk/src/game/PetHandler.cpp (revision 152)
+++ /trunk/src/game/PetHandler.cpp (revision 174)
@@ -110,5 +110,4 @@
                     if(pet->GetTypeId() != TYPEID_PLAYER)
                     {
-                        pet->GetMotionMaster()->Clear();
                         if (((Creature*)pet)->AI())
                             ((Creature*)pet)->AI()->AttackStart(TargetUnit);
@@ -140,6 +139,11 @@
                             p->setDeathState(CORPSE);
                     }
-                    else                                    // charmed
-                        _player->Uncharm();
+                    else                                    // charmed or possessed
+                    {
+                        if (_player->isPossessing())
+                            _player->RemovePossess(true);
+                        else
+                            _player->Uncharm();
+                    }
                     break;
                 default:
@@ -195,5 +199,5 @@
 
                                                             //auto turn to target unless possessed
-            if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
+            if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed())
             {
                 pet->SetInFront(unit_target);
@@ -223,5 +227,5 @@
                 }
 
-                if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
+                if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed())
                 {
                     pet->clearUnitState(UNIT_STAT_FOLLOW);
@@ -237,5 +241,5 @@
             else
             {
-                if(pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
+                if(pet->isPossessed())
                 {
                     WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
@@ -479,5 +483,8 @@
         else if(pet->GetGUID() == _player->GetCharmGUID())
         {
-            _player->Uncharm();
+            if (_player->isPossessing())
+                _player->RemovePossess(true);
+            else
+                _player->Uncharm();
         }
     }
@@ -602,13 +609,11 @@
     recvPacket >> guid >> spellid;
 
+    // This opcode is also sent from charmed and possessed units (players and creatures)
     if(!_player->GetPet() && !_player->GetCharm())
         return;
 
-    if(ObjectAccessor::FindPlayer(guid))
-        return;
-
-    Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid);
-
-    if(!pet || (pet != _player->GetPet() && pet!= _player->GetCharm()))
+    Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
+
+    if(!caster || (caster != _player->GetPet() && caster != _player->GetCharm()))
     {
         sLog.outError( "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
@@ -616,5 +621,5 @@
     }
 
-    if (pet->GetGlobalCooldown() > 0)
+    if (caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->GetGlobalCooldown() > 0)
         return;
 
@@ -627,14 +632,14 @@
 
     // do not cast not learned spells
-    if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
+    if(!caster->HasSpell(spellid) || IsPassiveSpell(spellid))
         return;
 
     SpellCastTargets targets;
-    if(!targets.read(&recvPacket,pet))
-        return;
-
-    pet->clearUnitState(UNIT_STAT_FOLLOW);
-
-    Spell *spell = new Spell(pet, spellInfo, false);
+    if(!targets.read(&recvPacket,caster))
+        return;
+
+    caster->clearUnitState(UNIT_STAT_FOLLOW);
+
+    Spell *spell = new Spell(caster, spellInfo, false);
     spell->m_targets = targets;
 
@@ -642,15 +647,19 @@
     if(result == -1)
     {
-        pet->AddCreatureSpellCooldown(spellid);
-        if(pet->isPet())
-        {
-            Pet* p = (Pet*)pet;
-            p->CheckLearning(spellid);
-            //10% chance to play special pet attack talk, else growl
-            //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
-            if(p->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
-                pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
-            else
-                pet->SendPetAIReaction(guid);
+        if(caster->GetTypeId() == TYPEID_UNIT)
+        {
+            Creature* pet = (Creature*)caster;
+            pet->AddCreatureSpellCooldown(spellid);
+            if(pet->isPet())
+            {
+                Pet* p = (Pet*)pet;
+                p->CheckLearning(spellid);
+                // 10% chance to play special pet attack talk, else growl
+                // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
+                if(p->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
+                    pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
+                else
+                    pet->SendPetAIReaction(guid);
+            }
         }
 
@@ -659,7 +668,15 @@
     else
     {
-        pet->SendPetCastFail(spellid, result);
-        if(!pet->HasSpellCooldown(spellid))
-            pet->SendPetClearCooldown(spellid);
+        caster->SendPetCastFail(spellid, result);
+        if(caster->GetTypeId() == TYPEID_PLAYER)
+        {
+            if(!((Player*)caster)->HasSpellCooldown(spellid))
+                caster->SendPetClearCooldown(spellid);
+        }
+        else
+        {
+            if(!((Creature*)caster)->HasSpellCooldown(spellid))
+                caster->SendPetClearCooldown(spellid);
+        }
 
         spell->finish(false);
Index: /trunk/src/game/Level3.cpp
===================================================================
--- /trunk/src/game/Level3.cpp (revision 173)
+++ /trunk/src/game/Level3.cpp (revision 174)
@@ -6545,2 +6545,28 @@
     return true;
 }
+
+bool ChatHandler::HandlePossessCommand(const char* args)
+{
+    Unit* pUnit = getSelectedUnit();
+    if(!pUnit)
+        return false;
+
+    // Don't allow unlimited possession of players
+    if (pUnit->GetTypeId() == TYPEID_PLAYER)
+        return false;
+
+    m_session->GetPlayer()->Possess(pUnit);
+
+    return true;
+}
+
+bool ChatHandler::HandleUnPossessCommand(const char* args)
+{
+    // Use this command to also unpossess ourselves
+    if (m_session->GetPlayer()->isPossessed())
+        m_session->GetPlayer()->UnpossessSelf(false);
+    else
+        m_session->GetPlayer()->RemovePossess(false);
+
+    return true;
+}
Index: /trunk/src/game/Object.h
===================================================================
--- /trunk/src/game/Object.h (revision 141)
+++ /trunk/src/game/Object.h (revision 174)
@@ -414,6 +414,6 @@
         bool HasInArc( const float arcangle, const WorldObject* obj ) const;
 
-        virtual void SendMessageToSet(WorldPacket *data, bool self);
-        virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self);
+        virtual void SendMessageToSet(WorldPacket *data, bool self, bool to_possessor = true);
+        virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool to_possessor = true);
         void BuildHeartBeatMsg( WorldPacket *data ) const;
         void BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, float ang) const;
Index: /trunk/src/game/SpellHandler.cpp
===================================================================
--- /trunk/src/game/SpellHandler.cpp (revision 102)
+++ /trunk/src/game/SpellHandler.cpp (revision 174)
@@ -303,4 +303,8 @@
     }
 
+    // can't use our own spells when we're in possession of another unit,
+    if(_player->isPossessing())
+        return;
+
     // client provided targets
     SpellCastTargets targets;
@@ -348,4 +352,19 @@
     if (!spellInfo)
         return;
+
+    // Remove possess aura from the possessed as well
+    if(_player->isPossessing())
+    {
+        for (int i = 0; i < 3; ++i)
+        {
+            if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_POSSESS ||
+                spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_POSSESS_PET)
+            {
+                _player->RemoveAurasDueToSpellByCancel(spellId);
+                _player->GetCharm()->RemoveAurasDueToSpellByCancel(spellId);
+                return;
+            }
+        }
+    }
 
     // not allow remove non positive spells and spells with attr SPELL_ATTR_CANT_CANCEL
Index: /trunk/src/game/Chat.cpp
===================================================================
--- /trunk/src/game/Chat.cpp (revision 169)
+++ /trunk/src/game/Chat.cpp (revision 174)
@@ -561,4 +561,6 @@
 		{ "listfreeze",     SEC_ADMINISTRATOR,  false, &ChatHandler::HandleListFreezeCommand,          "", NULL }, 
 		{ "flusharenapoints", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand,   "", NULL }, 
+        { "possess",        SEC_ADMINISTRATOR,  false, &ChatHandler::HandlePossessCommand,             "", NULL },
+        { "unpossess",      SEC_ADMINISTRATOR,  false, &ChatHandler::HandleUnPossessCommand,           "", NULL },
 
 		{ NULL,             0,                  false, NULL,                                           "", NULL }
Index: /trunk/src/game/TemporarySummon.cpp
===================================================================
--- /trunk/src/game/TemporarySummon.cpp (revision 107)
+++ /trunk/src/game/TemporarySummon.cpp (revision 174)
@@ -175,4 +175,6 @@
     CombatStop();
 
+    UnpossessSelf(false);
+
     CleanupsBeforeDelete();
     AddObjectToRemoveList();
Index: /trunk/src/game/Map.h
===================================================================
--- /trunk/src/game/Map.h (revision 102)
+++ /trunk/src/game/Map.h (revision 174)
@@ -141,8 +141,8 @@
         virtual void Update(const uint32&);
 
-        void MessageBroadcast(Player *, WorldPacket *, bool to_self);
-        void MessageBroadcast(WorldObject *, WorldPacket *);
-        void MessageDistBroadcast(Player *, WorldPacket *, float dist, bool to_self, bool own_team_only = false);
-        void MessageDistBroadcast(WorldObject *, WorldPacket *, float dist);
+        void MessageBroadcast(Player *, WorldPacket *, bool to_self, bool to_possessor);
+        void MessageBroadcast(WorldObject *, WorldPacket *, bool to_possessor);
+        void MessageDistBroadcast(Player *, WorldPacket *, float dist, bool to_self, bool to_possessor, bool own_team_only = false);
+        void MessageDistBroadcast(WorldObject *, WorldPacket *, float dist, bool to_possessor);
 
         void PlayerRelocation(Player *, float x, float y, float z, float angl);
@@ -237,4 +237,6 @@
         Creature* GetCreatureInMap(uint64 guid);
         GameObject* GetGameObjectInMap(uint64 guid);
+
+        template<class T> void SwitchGridContainers(T* obj, bool active);
     private:
         void LoadVMap(int pX, int pY);
Index: /trunk/src/game/ObjectAccessor.h
===================================================================
--- /trunk/src/game/ObjectAccessor.h (revision 120)
+++ /trunk/src/game/ObjectAccessor.h (revision 174)
@@ -209,6 +209,9 @@
             UpdateDataMapType &i_updateDatas;
             WorldObject &i_object;
+            std::set<uint64> plr_list;
             WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {}
             void Visit(PlayerMapType &);
+            void Visit(CreatureMapType &);
+            void BuildPacket(Player* plr);
             template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
         };
Index: /trunk/src/game/GridNotifiers.h
===================================================================
--- /trunk/src/game/GridNotifiers.h (revision 102)
+++ /trunk/src/game/GridNotifiers.h (revision 174)
@@ -90,42 +90,44 @@
     };
 
-    struct TRINITY_DLL_DECL MessageDeliverer
-    {
-        Player &i_player;
+    struct TRINITY_DLL_DECL Deliverer
+    {
+        WorldObject &i_source;
         WorldPacket *i_message;
+        std::set<uint64> plr_list;
+        bool i_toPossessor;
+        float i_dist;
+        Deliverer(WorldObject &src, WorldPacket *msg, bool to_possessor, float dist = 0.0f) : i_source(src), i_message(msg), i_toPossessor(to_possessor), i_dist(dist) {}
+        void Visit(PlayerMapType &m);
+        void Visit(CreatureMapType &m);
+        virtual void VisitObject(Player* plr) = 0;
+        void SendPacket(Player* plr);
+        template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
+    };
+        
+    struct TRINITY_DLL_DECL MessageDeliverer : public Deliverer
+    {
         bool i_toSelf;
-        MessageDeliverer(Player &pl, WorldPacket *msg, bool to_self) : i_player(pl), i_message(msg), i_toSelf(to_self) {}
-        void Visit(PlayerMapType &m);
-        template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
-    };
-
-    struct TRINITY_DLL_DECL ObjectMessageDeliverer
-    {
-        WorldPacket *i_message;
-        explicit ObjectMessageDeliverer(WorldPacket *msg) : i_message(msg) {}
-        void Visit(PlayerMapType &m);
-        template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
-    };
-
-    struct TRINITY_DLL_DECL MessageDistDeliverer
-    {
-        Player &i_player;
-        WorldPacket *i_message;
+        MessageDeliverer(Player &pl, WorldPacket *msg, bool to_possessor, bool to_self) : Deliverer(pl, msg, to_possessor), i_toSelf(to_self) {}
+        void VisitObject(Player* plr);
+    };
+
+    struct TRINITY_DLL_DECL ObjectMessageDeliverer : public Deliverer
+    {
+        explicit ObjectMessageDeliverer(WorldObject &src, WorldPacket *msg, bool to_possessor) : Deliverer(src, msg, to_possessor) {}
+        void VisitObject(Player* plr) { SendPacket(plr); }
+    };
+
+    struct TRINITY_DLL_DECL MessageDistDeliverer : public Deliverer
+    {
         bool i_toSelf;
         bool i_ownTeamOnly;
-        float i_dist;
-        MessageDistDeliverer(Player &pl, WorldPacket *msg, float dist, bool to_self, bool ownTeamOnly) : i_player(pl), i_message(msg), i_dist(dist), i_toSelf(to_self), i_ownTeamOnly(ownTeamOnly) {}
-        void Visit(PlayerMapType &m);
-        template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
-    };
-
-    struct TRINITY_DLL_DECL ObjectMessageDistDeliverer
-    {
-        WorldObject &i_object;
-        WorldPacket *i_message;
-        float i_dist;
-        ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, float dist) : i_object(obj), i_message(msg), i_dist(dist) {}
-        void Visit(PlayerMapType &m);
-        template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
+        MessageDistDeliverer(Player &pl, WorldPacket *msg, bool to_possessor, float dist, bool to_self, bool ownTeamOnly) : Deliverer(pl, msg, to_possessor, dist), i_toSelf(to_self), i_ownTeamOnly(ownTeamOnly) {}
+        void VisitObject(Player* plr);
+    };
+
+    struct TRINITY_DLL_DECL ObjectMessageDistDeliverer : public Deliverer
+    {
+        ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, bool to_possessor, float dist) : Deliverer(obj, msg, to_possessor, dist) {}
+        void VisitObject(Player* plr) { SendPacket(plr); }
     };
 
Index: /trunk/src/game/Unit.h
===================================================================
--- /trunk/src/game/Unit.h (revision 161)
+++ /trunk/src/game/Unit.h (revision 174)
@@ -990,8 +990,30 @@
         void SetPet(Pet* pet);
         void SetCharm(Unit* pet);
+        void SetPossessedTarget(Unit* target)
+        {
+            if (!target) return;
+            SetCharm(target);
+            target->SetCharmerGUID(GetGUID());
+            target->m_isPossessed = true;
+        }
+        void RemovePossessedTarget()
+        {
+            if (!GetCharm()) return;
+            GetCharm()->SetCharmerGUID(0);
+            GetCharm()->m_isPossessed = false;
+            SetCharm(0);
+        }
+
         bool isCharmed() const { return GetCharmerGUID() != 0; }
+        bool isPossessed() const { return m_isPossessed; }
+        bool isPossessedByPlayer() const { return m_isPossessed && IS_PLAYER_GUID(GetCharmerGUID()); }
+        bool isPossessing() const { return GetCharm() && GetCharm()->isPossessed(); }
+        bool isPossessing(Unit* u) const { return u->isPossessed() && GetCharmGUID() == u->GetGUID(); }
+        bool isPossessingCreature() const { return isPossessing() && IS_CREATURE_GUID(GetCharmGUID()); }
 
         CharmInfo* GetCharmInfo() { return m_charmInfo; }
         CharmInfo* InitCharmInfo(Unit* charm);
+        void UncharmSelf();
+        void UnpossessSelf(bool attack);
 
         Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0);
@@ -1317,4 +1339,5 @@
 
         CharmInfo *m_charmInfo;
+        bool m_isPossessed;
 
         virtual SpellSchoolMask GetMeleeDamageSchoolMask() const;
Index: /trunk/src/game/CreatureAISelector.cpp
===================================================================
--- /trunk/src/game/CreatureAISelector.cpp (revision 102)
+++ /trunk/src/game/CreatureAISelector.cpp (revision 174)
@@ -57,5 +57,5 @@
             if( creature->isGuard() )
                 ai_factory = ai_registry.GetRegistryItem("GuardAI"); 
-            else if(creature->isPet() || creature->isCharmed())
+            else if(creature->isPet() || (creature->isCharmed() && !creature->isPossessed()))
                 ai_factory = ai_registry.GetRegistryItem("PetAI");
             else if(creature->isTotem())
@@ -63,4 +63,6 @@
             else if(creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
                 ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
+            else if(creature->isPossessed())
+                creature->InitPossessedAI();
         }
 
Index: /trunk/src/game/Makefile.am
===================================================================
--- /trunk/src/game/Makefile.am (revision 102)
+++ /trunk/src/game/Makefile.am (revision 174)
@@ -218,4 +218,6 @@
 $(srcdir)/PointMovementGenerator.cpp \
 $(srcdir)/PointMovementGenerator.h \
+$(srcdir)/PossessedAI.cpp \
+$(srcdir)/PossessedAI.h \
 $(srcdir)/QueryHandler.cpp \
 $(srcdir)/QuestDef.cpp \
Index: /trunk/src/game/WorldSession.h
===================================================================
--- /trunk/src/game/WorldSession.h (revision 173)
+++ /trunk/src/game/WorldSession.h (revision 174)
@@ -32,4 +32,5 @@
 struct AuctionEntry;
 struct DeclinedName;
+struct MovementInfo;
 
 class Creature;
@@ -318,4 +319,5 @@
 
         void HandleMovementOpcodes(WorldPacket& recvPacket);
+        void HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags);
         void HandleSetActiveMoverOpcode(WorldPacket &recv_data);
         void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data);
Index: /trunk/src/game/Spell.h
===================================================================
--- /trunk/src/game/Spell.h (revision 173)
+++ /trunk/src/game/Spell.h (revision 174)
@@ -241,4 +241,5 @@
         void EffectPickPocket(uint32 i);
         void EffectAddFarsight(uint32 i);
+        void EffectSummonPossessed(uint32 i);
         void EffectSummonWild(uint32 i);
         void EffectSummonGuardian(uint32 i);
Index: /trunk/src/game/WorldSession.cpp
===================================================================
--- /trunk/src/game/WorldSession.cpp (revision 173)
+++ /trunk/src/game/WorldSession.cpp (revision 174)
@@ -367,4 +367,11 @@
             _player->RemoveFromGroup();
 
+        // Unpossess the current possessed unit of player
+        if (_player->isPossessing())
+            _player->RemovePossess(false);
+
+        // Remove any possession of this player on logout
+        _player->UnpossessSelf(false);
+
         ///- Remove the player from the world
         // the player may not be in the world when logging out
Index: /trunk/src/game/SpellAuras.cpp
===================================================================
--- /trunk/src/game/SpellAuras.cpp (revision 173)
+++ /trunk/src/game/SpellAuras.cpp (revision 174)
@@ -50,4 +50,5 @@
 #include "GridNotifiersImpl.h"
 #include "CellImpl.h"
+#include "TemporarySummon.h"
 
 #define NULL_AURA_SLOT 0xFF
@@ -528,6 +529,6 @@
     }
 
-    // Channeled aura required check distance from caster
-    if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID())
+    // Channeled aura required check distance from caster except in possessed cases
+    if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID() && !m_target->isPossessed())
     {
         Unit* caster = GetCaster();
@@ -2004,4 +2005,5 @@
             return;
         }
+
         // Dark Fiend
         if(GetId()==45934)
@@ -2017,4 +2019,11 @@
         {
             m_target->CastSpell(m_target,47287,true,NULL,this);
+            return;
+        }
+
+        // Eye of Kilrogg, unsummon eye when aura is gone
+        if(GetId() == 126 && caster->GetTypeId() == TYPEID_PLAYER && caster->GetCharm())
+        {
+            ((TemporarySummon*)caster->GetCharm())->UnSummon();
             return;
         }
@@ -2887,54 +2896,9 @@
     if( apply )
     {
-        m_target->SetCharmerGUID(GetCasterGUID());
-        m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
-        caster->SetCharm(m_target);
-
-        m_target->CombatStop();
-        m_target->DeleteThreatList();
-        if(m_target->GetTypeId() == TYPEID_UNIT)
-        {
-            m_target->StopMoving();
-            m_target->GetMotionMaster()->Clear();
-            m_target->GetMotionMaster()->MoveIdle();
-            CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
-            charmInfo->InitPossessCreateSpells();
-        }
-
-        if(caster->GetTypeId() == TYPEID_PLAYER)
-        {
-            ((Player*)caster)->PossessSpellInitialize();
-        }
+        if (caster->GetTypeId() == TYPEID_PLAYER)
+            ((Player*)caster)->Possess(m_target);
     }
     else
-    {
-        m_target->SetCharmerGUID(0);
-
-        if(m_target->GetTypeId() == TYPEID_PLAYER)
-            ((Player*)m_target)->setFactionForRace(m_target->getRace());
-        else if(m_target->GetTypeId() == TYPEID_UNIT)
-        {
-            CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
-            m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
-        }
-
-        caster->SetCharm(0);
-
-        if(caster->GetTypeId() == TYPEID_PLAYER)
-        {
-            WorldPacket data(SMSG_PET_SPELLS, 8);
-            data << uint64(0);
-            ((Player*)caster)->GetSession()->SendPacket(&data);
-        }
-        if(m_target->GetTypeId() == TYPEID_UNIT)
-        {
-            ((Creature*)m_target)->AIM_Initialize();
-
-            if (((Creature*)m_target)->AI())
-                ((Creature*)m_target)->AI()->AttackStart(caster);
-        }
-    }
-    if(caster->GetTypeId() == TYPEID_PLAYER)
-        caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0);
+        m_target->UnpossessSelf(true);
 }
 
@@ -2952,11 +2916,9 @@
     if(apply)
     {
-        caster->SetUInt64Value(PLAYER_FARSIGHT, m_target->GetGUID());
-        m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
+        ((Player*)caster)->Possess(m_target);
     }
     else
     {
-        caster->SetUInt64Value(PLAYER_FARSIGHT, 0);
-        m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
+        ((Player*)caster)->RemovePossess(false);
     }
 }
Index: /trunk/src/game/Creature.cpp
===================================================================
--- /trunk/src/game/Creature.cpp (revision 173)
+++ /trunk/src/game/Creature.cpp (revision 174)
@@ -47,4 +47,5 @@
 #include "OutdoorPvPMgr.h"
 #include "GameEvent.h"
+#include "PossessedAI.h"
 // apply implementation of the singletons
 #include "Policies/SingletonImp.h"
@@ -118,5 +119,5 @@
 
 Creature::Creature() :
-Unit(), i_AI(NULL),
+Unit(), i_AI(NULL), i_AI_possessed(NULL),
 lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
 m_lootMoney(0), m_lootRecipient(0),
@@ -146,4 +147,6 @@
     delete i_AI;
     i_AI = NULL;
+
+    DeletePossessedAI();
 }
 
@@ -365,5 +368,5 @@
 
                 //Call AI respawn virtual function
-                i_AI->JustRespawned();
+                AI()->JustRespawned();
 
                 MapManager::Instance().GetMap(GetMapId(), this)->Add(this);
@@ -429,5 +432,5 @@
                 // do not allow the AI to be changed during update
                 m_AI_locked = true;
-                i_AI->UpdateAI(diff);
+                AI()->UpdateAI(diff);
                 m_AI_locked = false;
             }
@@ -526,4 +529,8 @@
     }
 
+    // don't allow AI switch when possessed
+    if (isPossessed())
+        return false;
+
     CreatureAI * oldAI = i_AI;
     i_motionMaster.Initialize();
@@ -532,4 +539,26 @@
         delete oldAI;
     return true;
+}
+
+void Creature::InitPossessedAI()
+{
+    if (!isPossessed()) return;
+
+    if (!i_AI_possessed)
+        i_AI_possessed = new PossessedAI(*this);
+
+    // Signal the old AI that it's been disabled
+    i_AI->OnPossess(true);
+}
+
+void Creature::DeletePossessedAI()
+{
+    if (!i_AI_possessed) return;
+
+    delete i_AI_possessed;
+    i_AI_possessed = NULL;
+
+    // Signal the old AI that it's been re-enabled
+    i_AI->OnPossess(false);
 }
 
Index: /trunk/src/game/CreatureAIRegistry.cpp
===================================================================
--- /trunk/src/game/CreatureAIRegistry.cpp (revision 145)
+++ /trunk/src/game/CreatureAIRegistry.cpp (revision 174)
@@ -25,4 +25,5 @@
 #include "GuardAI.h"
 #include "PetAI.h"
+#include "PossessedAI.h"
 #include "TotemAI.h"
 #include "OutdoorPvPObjectiveAI.h"
@@ -45,4 +46,5 @@
         (new CreatureAIFactory<TotemAI>("TotemAI"))->RegisterSelf();
         (new CreatureAIFactory<OutdoorPvPObjectiveAI>("OutdoorPvPObjectiveAI"))->RegisterSelf();
+        (new CreatureAIFactory<PossessedAI>("PossessedAI"))->RegisterSelf();
 
         (new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf();
Index: /trunk/src/game/Map.cpp
===================================================================
--- /trunk/src/game/Map.cpp (revision 173)
+++ /trunk/src/game/Map.cpp (revision 174)
@@ -256,5 +256,5 @@
 {
     // add to world object registry in grid
-    if(obj->isPet())
+    if(obj->isPet() || obj->isPossessedByPlayer())
     {
         (*grid)(cell.CellX(), cell.CellY()).AddWorldObject<Creature>(obj, obj->GetGUID());
@@ -300,5 +300,5 @@
 {
     // remove from world object registry in grid
-    if(obj->isPet())
+    if(obj->isPet() || obj->isPossessedByPlayer())
     {
         (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<Creature>(obj, obj->GetGUID());
@@ -310,4 +310,25 @@
     }
 }
+
+template<class T>
+void Map::SwitchGridContainers(T* obj, bool active)
+{
+    CellPair pair = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
+    Cell cell(pair);
+    NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
+
+    if (active)
+    {
+        (*grid)(cell.CellX(), cell.CellY()).RemoveGridObject<T>(obj, obj->GetGUID());
+        (*grid)(cell.CellX(), cell.CellY()).AddWorldObject<T>(obj, obj->GetGUID());
+    } else
+    {
+        (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<T>(obj, obj->GetGUID());
+        (*grid)(cell.CellX(), cell.CellY()).AddGridObject<T>(obj, obj->GetGUID());
+    }
+}
+
+template void Map::SwitchGridContainers(Creature *, bool);
+template void Map::SwitchGridContainers(Corpse *, bool);
 
 template<class T>
@@ -468,5 +489,5 @@
 }
 
-void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self)
+void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self, bool to_possessor)
 {
     CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
@@ -484,5 +505,5 @@
         return;
 
-    Trinity::MessageDeliverer post_man(*player, msg, to_self);
+    Trinity::MessageDeliverer post_man(*player, msg, to_possessor, to_self);
     TypeContainerVisitor<Trinity::MessageDeliverer, WorldTypeMapContainer > message(post_man);
     CellLock<ReadGuard> cell_lock(cell, p);
@@ -490,5 +511,5 @@
 }
 
-void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg)
+void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg, bool to_possessor)
 {
     CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
@@ -507,5 +528,5 @@
         return;
 
-    Trinity::ObjectMessageDeliverer post_man(msg);
+    Trinity::ObjectMessageDeliverer post_man(*obj, msg, to_possessor);
     TypeContainerVisitor<Trinity::ObjectMessageDeliverer, WorldTypeMapContainer > message(post_man);
     CellLock<ReadGuard> cell_lock(cell, p);
@@ -513,5 +534,5 @@
 }
 
-void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool own_team_only)
+void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool own_team_only, bool to_possessor)
 {
     CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
@@ -529,5 +550,5 @@
         return;
 
-    Trinity::MessageDistDeliverer post_man(*player, msg, dist, to_self, own_team_only);
+    Trinity::MessageDistDeliverer post_man(*player, msg, to_possessor, dist, to_self, own_team_only);
     TypeContainerVisitor<Trinity::MessageDistDeliverer , WorldTypeMapContainer > message(post_man);
     CellLock<ReadGuard> cell_lock(cell, p);
@@ -535,5 +556,5 @@
 }
 
-void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist)
+void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist, bool to_possessor)
 {
     CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
@@ -552,5 +573,5 @@
         return;
 
-    Trinity::ObjectMessageDistDeliverer post_man(*obj, msg,dist);
+    Trinity::ObjectMessageDistDeliverer post_man(*obj, msg, to_possessor, dist);
     TypeContainerVisitor<Trinity::ObjectMessageDistDeliverer, WorldTypeMapContainer > message(post_man);
     CellLock<ReadGuard> cell_lock(cell, p);
@@ -650,4 +671,5 @@
 
     obj->RemoveFromWorld();
+
     RemoveFromGrid(obj,grid,cell);
 
@@ -698,4 +720,9 @@
     UpdatePlayerVisibility(player,new_cell,new_val);
     UpdateObjectsVisibilityFor(player,new_cell,new_val);
+
+    // also update what possessing player sees
+    if(player->isPossessedByPlayer())
+        UpdateObjectsVisibilityFor((Player*)player->GetCharmer(), new_cell, new_val);
+
     PlayerRelocationNotify(player,new_cell,new_val);
     NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY());
@@ -726,8 +753,14 @@
         AddCreatureToMoveList(creature,x,y,z,ang);
         // in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList
+        if(creature->isPossessedByPlayer())
+            EnsureGridLoadedForPlayer(new_cell, (Player*)creature->GetCharmer(), false);
     }
     else
     {
         creature->Relocate(x, y, z, ang);
+        // Update visibility back to player who is controlling the creature
+        if(creature->isPossessedByPlayer())
+            UpdateObjectsVisibilityFor((Player*)creature->GetCharmer(), new_cell, new_val);
+
         CreatureRelocationNotify(creature,new_cell,new_val);
     }
Index: /trunk/src/game/CreatureAI.h
===================================================================
--- /trunk/src/game/CreatureAI.h (revision 130)
+++ /trunk/src/game/CreatureAI.h (revision 174)
@@ -122,4 +122,7 @@
         // Called at waypoint reached or point movement finished
         virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {}
+
+        // Called when AI is temporarily replaced or put back when possess is applied or removed
+        virtual void OnPossess(bool apply) {}
 };
 
Index: /trunk/src/game/Object.cpp
===================================================================
--- /trunk/src/game/Object.cpp (revision 145)
+++ /trunk/src/game/Object.cpp (revision 174)
@@ -1412,12 +1412,12 @@
 }
 
-void WorldObject::SendMessageToSet(WorldPacket *data, bool /*bToSelf*/)
-{
-    MapManager::Instance().GetMap(m_mapId, this)->MessageBroadcast(this, data);
-}
-
-void WorldObject::SendMessageToSetInRange(WorldPacket *data, float dist, bool /*bToSelf*/)
-{
-    MapManager::Instance().GetMap(m_mapId, this)->MessageDistBroadcast(this, data, dist);
+void WorldObject::SendMessageToSet(WorldPacket *data, bool /*fake*/, bool bToPossessor)
+{
+    MapManager::Instance().GetMap(m_mapId, this)->MessageBroadcast(this, data, bToPossessor);
+}
+
+void WorldObject::SendMessageToSetInRange(WorldPacket *data, float dist, bool /*bToSelf*/, bool bToPossessor)
+{
+    MapManager::Instance().GetMap(m_mapId, this)->MessageDistBroadcast(this, data, dist, bToPossessor);
 }
 
Index: /trunk/src/game/Creature.h
===================================================================
--- /trunk/src/game/Creature.h (revision 168)
+++ /trunk/src/game/Creature.h (revision 174)
@@ -396,4 +396,5 @@
 {
     CreatureAI *i_AI;
+    CreatureAI *i_AI_possessed;
 
     public:
@@ -456,7 +457,9 @@
 
         bool AIM_Initialize();
+        void InitPossessedAI();
+        void DeletePossessedAI();
 
         void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type);
-        CreatureAI* AI() { return i_AI; }
+        CreatureAI* AI() { return isPossessed() && i_AI_possessed ? i_AI_possessed : i_AI; }
 
         uint32 GetShieldBlockValue() const                  //dunno mob block value
Index: /trunk/src/game/Chat.h
===================================================================
--- /trunk/src/game/Chat.h (revision 168)
+++ /trunk/src/game/Chat.h (revision 174)
@@ -450,4 +450,6 @@
         bool HandleDebugThreatList(const char * args);
         bool HandleDebugHostilRefList(const char * args);
+        bool HandlePossessCommand(const char* args);
+        bool HandleUnPossessCommand(const char* args);
 
         Player*   getSelectedPlayer();
Index: /trunk/src/game/MovementHandler.cpp
===================================================================
--- /trunk/src/game/MovementHandler.cpp (revision 102)
+++ /trunk/src/game/MovementHandler.cpp (revision 174)
@@ -190,7 +190,4 @@
     CHECK_PACKET_SIZE(recv_data, 4+1+4+4+4+4+4);
 
-    if(GetPlayer()->GetDontMove())
-        return;
-
     /* extract packet */
     MovementInfo movementInfo;
@@ -205,7 +202,4 @@
     recv_data >> movementInfo.o;
 
-    //Save movement flags
-    _player->SetUnitMovementFlags(MovementFlags);
-
     if(MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
     {
@@ -264,4 +258,18 @@
         return;
 
+    // Handle possessed unit movement separately
+    Unit* pos_unit = GetPlayer()->GetCharm();
+    if (pos_unit && pos_unit->isPossessed()) // can be charmed but not possessed
+    {
+        HandlePossessedMovement(recv_data, movementInfo, MovementFlags);
+        return;
+    }
+
+    if (GetPlayer()->GetDontMove())
+        return;
+
+    //Save movement flags
+    GetPlayer()->SetUnitMovementFlags(MovementFlags);
+
     /* handle special cases */
     if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
@@ -285,5 +293,5 @@
                 {
                     // unmount before boarding
-                    _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+                    GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
 
                     GetPlayer()->m_transport = (*iter);
@@ -305,58 +313,7 @@
     }
 
-    // fall damage generation (ignore in flight case that can be triggred also at lags in moment teleportation to another map).
-    if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
-    {
-        Player *target = GetPlayer();
-
-        //Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored
-        if (movementInfo.fallTime > 1100 && !target->isDead() && !target->isGameMaster() &&
-            !target->HasAuraType(SPELL_AURA_HOVER) && !target->HasAuraType(SPELL_AURA_FEATHER_FALL) &&
-            !target->HasAuraType(SPELL_AURA_FLY) && !target->IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) )
-        {
-            //Safe fall, fall time reduction
-            int32 safe_fall = target->GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
-            uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0;
-
-            if(fall_time > 1100)                            //Prevent damage if fall time < 1100
-            {
-                //Fall Damage calculation
-                float fallperc = float(fall_time)/1100;
-                uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * target->GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL));
-
-                float height = movementInfo.z;
-                target->UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
-
-                if (damage > 0)
-                {
-                    //Prevent fall damage from being more than the player maximum health
-                    if (damage > target->GetMaxHealth())
-                        damage = target->GetMaxHealth();
-
-                    // Gust of Wind
-                    if (target->GetDummyAura(43621))
-                        damage = target->GetMaxHealth()/2;
-
-                    target->EnvironmentalDamage(target->GetGUID(), DAMAGE_FALL, damage);
-                }
-
-                //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
-                DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, target->GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
-            }
-        }
-
-        //handle fall and logout at the same time (logout started before fall finished)
-        /* outdated and create problems with sit at stun sometime
-        if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE))
-        {
-            target->SetStandState(PLAYER_STATE_SIT);
-            // Can't move
-            WorldPacket data( SMSG_FORCE_MOVE_ROOT, 12 );
-            data.append(target->GetPackGUID());
-            data << (uint32)2;
-            SendPacket( &data );
-        }
-        */
-    }
+    // handle fall damage
+    if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)
+        GetPlayer()->HandleFallDamage(movementInfo);
 
     if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
@@ -382,28 +339,64 @@
 
     if(movementInfo.z < -500.0f)
-    {
-        if(GetPlayer()->InBattleGround() 
-            && GetPlayer()->GetBattleGround() 
-            && GetPlayer()->GetBattleGround()->HandlePlayerUnderMap(_player))
-        {
-            // do nothing, the handle already did if returned true
-        }
-        else
-        {
-            // NOTE: this is actually called many times while falling
-            // even after the player has been teleported away
-            // TODO: discard movement packets after the player is rooted
-            if(GetPlayer()->isAlive())
-            {
-                GetPlayer()->EnvironmentalDamage(GetPlayer()->GetGUID(),DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
-                // change the death state to CORPSE to prevent the death timer from
-                // starting in the next player update
-                GetPlayer()->KillPlayer();
-                GetPlayer()->BuildPlayerRepop();
-            }
-
-            // cancel the death timer here if started
-            GetPlayer()->RepopAtGraveyard();
-        }
+        GetPlayer()->HandleFallUnderMap();
+}
+
+void WorldSession::HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags)
+{
+    // Whatever the client is controlling, it will send the GUID of the original player.
+    // If current player is controlling, it must be handled like the controlled player sent these opcodes
+
+    Unit* pos_unit = GetPlayer()->GetCharm();
+
+    if (pos_unit->GetTypeId() == TYPEID_PLAYER && ((Player*)pos_unit)->GetDontMove())
+        return;
+
+    //Save movement flags
+    pos_unit->SetUnitMovementFlags(MovementFlags);
+
+    // Remove possession if possessed unit enters a transport
+    if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
+    {
+        GetPlayer()->RemovePossess(true);
+        return;
+    }
+
+    recv_data.put<uint32>(5, getMSTime());
+    WorldPacket data(recv_data.GetOpcode(), pos_unit->GetPackGUID().size()+recv_data.size());
+    data.append(pos_unit->GetPackGUID());
+    data.append(recv_data.contents(), recv_data.size());
+    // Send the packet to self but not to the possessed player; for creatures the first bool is irrelevant
+    pos_unit->SendMessageToSet(&data, true, false);
+
+    // Possessed is a player
+    if (pos_unit->GetTypeId() == TYPEID_PLAYER)
+    {
+        Player* plr = (Player*)pos_unit;
+        
+        if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)
+            plr->HandleFallDamage(movementInfo);
+
+        if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != plr->IsInWater())
+        {
+            // Now client not include swimming flag in case jumping under water
+            plr->SetInWater( !plr->IsInWater() || plr->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
+        }
+        
+        plr->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o, false);
+        plr->m_movementInfo = movementInfo;
+
+        if(plr->isMovingOrTurning())
+            plr->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+
+        if(movementInfo.z < -500.0f)
+        {
+            GetPlayer()->RemovePossess(false);
+            plr->HandleFallUnderMap();
+        }
+    } 
+    else // Possessed unit is a creature
+    {
+        Map* map = MapManager::Instance().GetMap(pos_unit->GetMapId(), pos_unit);
+        map->CreatureRelocation((Creature*)pos_unit, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
     }
 }
Index: /trunk/src/game/Player.h
===================================================================
--- /trunk/src/game/Player.h (revision 136)
+++ /trunk/src/game/Player.h (revision 174)
@@ -906,4 +906,8 @@
         void setActive(bool) {}
 
+        void SetViewport(uint64 guid, bool movable);
+        void Possess(Unit *target);
+        void RemovePossess(bool attack = true); 
+
         bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0);
 
@@ -1422,4 +1426,5 @@
         PlayerSpellMap const& GetSpellMap() const { return m_spells; }
         PlayerSpellMap      & GetSpellMap()       { return m_spells; }
+        ActionButtonList const& GetActionButtonList() const { return m_actionButtons; }
 
         void AddSpellMod(SpellModifier* mod, bool apply);
@@ -1620,8 +1625,8 @@
         void UpdateUnderwaterState( Map * m, float x, float y, float z );
 
-        void SendMessageToSet(WorldPacket *data, bool self);// overwrite Object::SendMessageToSet
-        void SendMessageToSetInRange(WorldPacket *data, float fist, bool self);
+        void SendMessageToSet(WorldPacket *data, bool self, bool to_possessor = true);// overwrite Object::SendMessageToSet
+        void SendMessageToSetInRange(WorldPacket *data, float fist, bool self, bool to_possessor = true);
                                                             // overwrite Object::SendMessageToSetInRange
-        void SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only);
+        void SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only, bool to_possessor);
 
         static void DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmChars = true);
@@ -1949,4 +1954,6 @@
 
         void HandleDrowning();
+        void HandleFallDamage(MovementInfo& movementInfo);
+        void HandleFallUnderMap();
 
         void SetClientControl(Unit* target, uint8 allowMove);
Index: /trunk/src/game/Unit.cpp
===================================================================
--- /trunk/src/game/Unit.cpp (revision 173)
+++ /trunk/src/game/Unit.cpp (revision 174)
@@ -227,4 +227,5 @@
     m_charmInfo = NULL;
     m_unit_movement_flags = 0;
+    m_isPossessed = false;
 
     // remove aurastates allowing special moves
@@ -702,8 +703,4 @@
             ((Player*)pVictim)->SetPvPDeath(player!=NULL);
 
-        // Call KilledUnit for creatures
-        if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI())
-            ((Creature*)this)->AI()->KilledUnit(pVictim);
-
         // 10% durability loss on death
         // clean InHateListOf
@@ -719,4 +716,7 @@
                 ((Player*)pVictim)->GetSession()->SendPacket(&data);
             }
+            // Call KilledUnit for creatures
+            if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI())
+                ((Creature*)this)->AI()->KilledUnit(pVictim);
         }
         else                                                // creature died
@@ -730,4 +730,9 @@
                 cVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
             }
+
+            // Call KilledUnit for creatures, this needs to be called after the lootable flag is set
+            if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI())
+                ((Creature*)this)->AI()->KilledUnit(pVictim);
+
             // Call creature just died function
             if (cVictim->AI())
@@ -773,4 +778,11 @@
             he->DuelComplete(DUEL_INTERUPTED);
         }
+
+        // Possessed unit died, restore control to possessor
+        pVictim->UnpossessSelf(false);
+
+        // Possessor died, remove possession
+        if(pVictim->GetTypeId() == TYPEID_PLAYER && pVictim->isPossessing())
+            ((Player*)pVictim)->RemovePossess(false);
 
         // battleground things (do this at the end, so the death state flag will be properly set to handle in the bg->handlekill)
@@ -7170,4 +7182,27 @@
 }
 
+void Unit::UncharmSelf()
+{
+    if (!GetCharmer())
+        return;
+
+    RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
+}
+
+void Unit::UnpossessSelf(bool attack)
+{
+    if (!isPossessed() || !GetCharmer())
+        return;
+
+    if (GetCharmer()->GetTypeId() == TYPEID_PLAYER)
+        ((Player*)GetCharmer())->RemovePossess(attack);
+    else
+    {
+        GetCharmer()->SetCharm(0);
+        SetCharmerGUID(0);
+        m_isPossessed = false;
+    }
+}
+
 void Unit::UnsummonAllTotems()
 {
@@ -8589,14 +8624,17 @@
     }
 
+    // If the player is currently possessing, update visibility from the possessed unit's location
+    const Unit* target = u->GetTypeId() == TYPEID_PLAYER && u->isPossessing() ? u->GetCharm() : u;
+
     // different visible distance checks
     if(u->isInFlight())                                     // what see player in flight
     {
         // use object grey distance for all (only see objects any way)
-        if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)))
+        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)))
             return false;
     }
     else if(!isAlive())                                     // distance for show body
     {
-        if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)))
+        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)))
             return false;
     }
@@ -8606,5 +8644,5 @@
         {
             // Players far than max visible distance for player or not in our map are not visible too
-            if (!at_same_transport && !IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
+            if (!at_same_transport && !IsWithinDistInMap(target,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
                 return false;
         }
@@ -8613,5 +8651,5 @@
             // Units far than max visible distance for creature or not in our map are not visible too
             // Active unit should always be visibile
-            if (!IsWithinDistInMap(u, u->isActive() 
+            if (!IsWithinDistInMap(target, target->isActive() 
                 ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance()))
                 : (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))))
@@ -8622,5 +8660,5 @@
     {
         // Pet/charmed far than max visible distance for player or not in our map are not visible too
-        if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
+        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
             return false;
     }
@@ -8628,5 +8666,5 @@
     {
         // Units far than max visible distance for creature or not in our map are not visible too
-        if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
+        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
             return false;
     }
@@ -9872,4 +9910,6 @@
         RemoveAllDynObjects();
         GetMotionMaster()->Clear(false);                    // remove different non-standard movement generators.
+
+        UnpossessSelf(false);
     }
     RemoveFromWorld();
@@ -9924,15 +9964,15 @@
 void CharmInfo::InitPossessCreateSpells()
 {
-    if(m_unit->GetTypeId() == TYPEID_PLAYER)
-        return;
-
-    InitEmptyActionBar();                                   //charm action bar
-
-    for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x)
-    {
-        if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x]))
-            m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true);
-        else
-            AddSpellToAB(0, ((Creature*)m_unit)->m_spells[x], ACT_CAST);
+    InitEmptyActionBar();
+    if(m_unit->GetTypeId() == TYPEID_UNIT)
+    {
+        for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+        {
+            uint32 spellid = ((Creature*)m_unit)->m_spells[i];
+            if(IsPassiveSpell(spellid))
+                m_unit->CastSpell(m_unit, spellid, true);
+            else
+                AddSpellToAB(0, spellid, ACT_CAST);
+        }
     }
 }
Index: /trunk/src/game/Player.cpp
===================================================================
--- /trunk/src/game/Player.cpp (revision 168)
+++ /trunk/src/game/Player.cpp (revision 174)
@@ -470,4 +470,7 @@
             itr->second.save->RemovePlayer(this);
 
+    if (isPossessing())
+        RemovePossess(false);
+
     delete m_declinedname;
 }
@@ -1254,5 +1257,5 @@
 
     Pet* pet = GetPet();
-    if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE))
+    if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && !pet->isPossessed())
     {
         RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);
@@ -1535,4 +1538,8 @@
     SetSemaphoreTeleport(true);
 
+    // Remove any possession on the player before teleporting
+    if (isPossessedByPlayer())
+        ((Player*)GetCharmer())->RemovePossess();
+
     // The player was ported to another map and looses the duel immediatly.
     // We have to perform this check before the teleport, otherwise the
@@ -1748,4 +1755,5 @@
     {
         ///- Release charmed creatures, unsummon totems and remove pets/guardians
+        RemovePossess(false);
         Uncharm();
         UnsummonAllTotems();
@@ -5267,17 +5275,17 @@
 }
 
-void Player::SendMessageToSet(WorldPacket *data, bool self)
-{
-    MapManager::Instance().GetMap(GetMapId(), this)->MessageBroadcast(this, data, self);
-}
-
-void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self)
-{
-    MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self);
-}
-
-void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only)
-{
-    MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self,own_team_only);
+void Player::SendMessageToSet(WorldPacket *data, bool self, bool to_possessor)
+{
+    MapManager::Instance().GetMap(GetMapId(), this)->MessageBroadcast(this, data, self, to_possessor);
+}
+
+void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool to_possessor)
+{
+    MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self, to_possessor);
+}
+
+void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only, bool to_possessor)
+{
+    MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self, to_possessor, own_team_only);
 }
 
@@ -15974,5 +15982,4 @@
 
     charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
-    charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS);
 }
 
@@ -16007,5 +16014,5 @@
     WorldPacket data(SMSG_MESSAGECHAT, 200);
     BuildPlayerChat(&data, CHAT_MSG_EMOTE, text, LANG_UNIVERSAL);
-    SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true, !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) );
+    SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true, !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT), true );
 }
 
@@ -18506,11 +18513,251 @@
 }
 
-bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
-{
-    for(ItemPosCountVec::const_iterator itr = vec.begin(); itr != vec.end();++itr)
-        if(itr->pos == this->pos)
-            return true;
-
-    return false;
+void Player::HandleFallDamage(MovementInfo& movementInfo)
+{
+    //Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored
+    if (!isInFlight() && movementInfo.fallTime > 1100 && !isDead() && !isGameMaster() &&
+        !HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) &&
+        !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) )
+    {
+        //Safe fall, fall time reduction
+        int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
+        uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0;
+
+        if(fall_time > 1100)                            //Prevent damage if fall time < 1100
+        {
+            //Fall Damage calculation
+            float fallperc = float(fall_time)/1100;
+            uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL));
+
+            float height = movementInfo.z;
+            UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
+
+            if (damage > 0)
+            {
+                //Prevent fall damage from being more than the player maximum health
+                if (damage > GetMaxHealth())
+                    damage = GetMaxHealth();
+
+                // Gust of Wind
+                if (GetDummyAura(43621))
+                    damage = GetMaxHealth()/2;
+
+                EnvironmentalDamage(GetGUID(), DAMAGE_FALL, damage);
+            }
+
+            //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
+            DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
+        }
+    }
+}
+
+void Player::HandleFallUnderMap()
+{
+    if(InBattleGround() && GetBattleGround() 
+        && GetBattleGround()->HandlePlayerUnderMap(this))
+    {
+        // do nothing, the handle already did if returned true
+    }
+    else
+    {
+        // NOTE: this is actually called many times while falling
+        // even after the player has been teleported away
+        // TODO: discard movement packets after the player is rooted
+        if(isAlive())
+        {
+            EnvironmentalDamage(GetGUID(),DAMAGE_FALL_TO_VOID, GetMaxHealth());
+            // change the death state to CORPSE to prevent the death timer from
+            // starting in the next player update
+            KillPlayer();
+            BuildPlayerRepop();
+        }
+
+        // cancel the death timer here if started
+        RepopAtGraveyard();
+    }
+}
+
+void Player::Possess(Unit *target)
+{
+    if(!target || target == this)
+        return;
+
+    // Don't allow possession of someone else's pet
+    if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && target != GetPet())
+        return;
+
+    // Don't allow possession on transports or when in flight; also remove possession from the now-to-be-possessed
+    if (target->GetTypeId() == TYPEID_PLAYER)
+    {
+        if (((Player*)target)->m_transport || ((Player*)target)->isInFlight())
+            return;
+        if (target->isPossessing())
+            ((Player*)target)->RemovePossess(true);
+    }
+
+    // Remove any previous possession from the target
+    if (target->isPossessedByPlayer())
+        ((Player*)target->GetCharmer())->RemovePossess(false);
+    else if (target->isCharmed()) 
+        target->UncharmSelf();  // Target isn't possessed, but charmed; uncharm before possessing
+
+    // Remove our previous possession
+    if (isPossessing())
+        RemovePossess(true);
+    else if (GetCharm()) // We are charming a creature, not possessing it; uncharm ourself first
+        Uncharm();
+
+    // Interrupt any current casting of the target
+    if(target->IsNonMeleeSpellCasted(true))
+        target->InterruptNonMeleeSpells(true);
+
+    // Update the proper unit fields
+    SetPossessedTarget(target);
+
+    target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction());
+    target->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+    target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
+    target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+    SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+    SetUInt64Value(PLAYER_FARSIGHT, target->GetGUID());
+
+    if(target->GetTypeId() == TYPEID_UNIT)
+    {
+        // Set target to active in the grid and place it in the world container to be picked up by all regular player cell visits
+        Map* map = target->GetMap();
+        map->SwitchGridContainers((Creature*)target, true);
+        target->setActive(true);
+
+        ((Creature*)target)->InitPossessedAI(); // Initialize the possessed AI
+        target->StopMoving();
+        target->GetMotionMaster()->Clear(false);
+        target->GetMotionMaster()->MoveIdle();
+    }
+
+    target->CombatStop();
+    target->DeleteThreatList();
+
+    // Pets already have a properly initialized CharmInfo, don't overwrite it.
+    if(target->GetTypeId() == TYPEID_PLAYER || (target->GetTypeId() == TYPEID_UNIT && !((Creature*)target)->isPet()))
+    {
+        CharmInfo* charmInfo = target->InitCharmInfo(target);
+        charmInfo->InitPossessCreateSpells();
+    }
+
+    // Disable control for target player and remove AFK
+    if(target->GetTypeId() == TYPEID_PLAYER)
+    {
+        if(((Player*)target)->isAFK())
+            ((Player*)target)->ToggleAFK();
+        ((Player*)target)->SetViewport(target->GetGUID(), false);
+    }
+
+    // Set current viewport to target unit, controllable
+    SetViewport(target->GetGUID(), true);
+
+    PossessSpellInitialize();
+}
+
+void Player::RemovePossess(bool attack)
+{
+    Unit* target = GetCharm();
+    if(!target || !target->isPossessed())
+        return;
+
+    // Remove area auras from possessed
+    Unit::AuraMap& tAuras = target->GetAuras();
+    for(Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
+    {
+        if(itr->second && itr->second->IsAreaAura())
+            target->RemoveAura(itr);
+        else
+            ++itr;
+    }
+
+    RemovePossessedTarget();
+
+    if(target->GetTypeId() == TYPEID_PLAYER)
+        ((Player*)target)->setFactionForRace(target->getRace());
+    else if(target->GetTypeId() == TYPEID_UNIT)
+    {
+        // Set creature to inactive in grid and place it back into the grid container
+        Map* map = target->GetMap();
+        target->setActive(false);
+        map->SwitchGridContainers((Creature*)target, false);
+
+        if(((Creature*)target)->isPet())
+        {
+            if(Unit* owner = target->GetOwner())
+                target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction());
+        } else
+        {
+            if(CreatureInfo const* cInfo = ((Creature*)target)->GetCreatureInfo())
+                target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, cInfo->faction_A);
+        }
+    }
+
+    target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
+    target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+    RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+    SetUInt64Value(PLAYER_FARSIGHT, 0);
+
+    // Remove pet spell action bar
+    WorldPacket data(SMSG_PET_SPELLS, 8);
+    data << uint64(0);
+    m_session->SendPacket(&data);
+
+    // Restore original view
+    SetViewport(GetGUID(), true);
+    if(target->GetTypeId() == TYPEID_PLAYER)
+        ((Player*)target)->SetViewport(target->GetGUID(), true);
+    else
+    {
+        if(((Creature*)target)->isPet())
+        {
+            ((Pet*)target)->InitPetCreateSpells();
+            PetSpellInitialize();
+        }
+
+        if (target->isAlive())
+        {
+            // If we're still hostile to our target, continue attacking otherwise reset threat and go home
+            if (target->getVictim())
+            {
+                Unit* victim = target->getVictim();
+                FactionTemplateEntry const* t_faction = target->getFactionTemplateEntry();
+                FactionTemplateEntry const* v_faction = victim->getFactionTemplateEntry();
+                // Unit::IsHostileTo will always return true since the unit is always hostile to its victim
+                if (t_faction && v_faction && !t_faction->IsHostileTo(*v_faction))
+                {
+                    // Stop combat and remove the target from the threat lists of all its victims
+                    target->CombatStop();
+                    target->getHostilRefManager().deleteReferences();
+                    target->DeleteThreatList();
+                    target->GetMotionMaster()->Clear();
+                    target->GetMotionMaster()->MoveTargetedHome();
+                }
+            } 
+            else if (target->GetTypeId() == TYPEID_UNIT)
+            {
+                target->GetMotionMaster()->Clear();
+                target->GetMotionMaster()->MoveTargetedHome();
+            }
+            
+            // Add high amount of threat on the player
+            if(target != GetPet() && attack)
+                target->AddThreat(this, 1000000.0f);
+        }
+        // Delete the assigned possessed AI
+        ((Creature*)target)->DeletePossessedAI();
+    }
+}
+
+void Player::SetViewport(uint64 guid, bool moveable)
+{
+    WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, 8+1);
+    data.appendPackGUID(guid); // Packed guid of object to set client's view to
+    data << (moveable ? uint8(0x01) : uint8(0x00)); // 0 - can't move; 1 - can move
+    m_session->SendPacket(&data);
+    sLog.outDetail("Viewport for "I64FMT" (%s) changed to "I64FMT, GetGUID(), GetName(), guid);
 }
 
@@ -18525,2 +18772,11 @@
            );
 }
+
+bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
+{
+    for(ItemPosCountVec::const_iterator itr = vec.begin(); itr != vec.end();++itr)
+        if(itr->pos == this->pos)
+            return true;
+
+    return false;
+}
Index: /trunk/src/game/Spell.cpp
===================================================================
--- /trunk/src/game/Spell.cpp (revision 173)
+++ /trunk/src/game/Spell.cpp (revision 174)
@@ -4122,5 +4122,6 @@
                     duelvsplayertar |= (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DUELVSPLAYER);
                 }
-                if(m_caster->IsFriendlyTo(target) && !duelvsplayertar)
+                // AoE spells have the caster as their target
+                if(m_caster->IsFriendlyTo(target) && m_caster != target && !duelvsplayertar)
                 {
                     return SPELL_FAILED_BAD_TARGETS;
Index: /trunk/src/game/Pet.cpp
===================================================================
--- /trunk/src/game/Pet.cpp (revision 152)
+++ /trunk/src/game/Pet.cpp (revision 174)
@@ -549,5 +549,5 @@
             // unsummon pet that lost owner
             Unit* owner = GetOwner();
-            if(!owner || !IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) || isControlled() && !owner->GetPetGUID())
+            if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && !isPossessed()) || isControlled() && !owner->GetPetGUID())
             {
                 Remove(PET_SAVE_NOT_IN_SLOT, true);
Index: /trunk/src/game/GridNotifiers.cpp
===================================================================
--- /trunk/src/game/GridNotifiers.cpp (revision 102)
+++ /trunk/src/game/GridNotifiers.cpp (revision 174)
@@ -41,4 +41,6 @@
         iter->getSource()->UpdateVisibilityOf(&i_player);
         i_player.UpdateVisibilityOf(iter->getSource());
+        if (i_player.isPossessedByPlayer())
+            ((Player*)i_player.GetCharmer())->UpdateVisibilityOf(iter->getSource());
     }
 }
@@ -140,52 +142,64 @@
 }
 
-void
-MessageDeliverer::Visit(PlayerMapType &m)
-{
-    for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
-    {
-        if( i_toSelf || iter->getSource() != &i_player)
-        {
-            if(WorldSession* session = iter->getSource()->GetSession())
-                session->SendPacket(i_message);
-        }
-    }
-}
-
-void
-ObjectMessageDeliverer::Visit(PlayerMapType &m)
-{
-    for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
-    {
-        if(WorldSession* session = iter->getSource()->GetSession())
+void 
+Deliverer::Visit(PlayerMapType &m)
+{
+    for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+    {
+        if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist)
+        {
+            // Send packet to possessor
+            if (iter->getSource()->isPossessedByPlayer())
+                SendPacket((Player*)iter->getSource()->GetCharmer());
+            VisitObject(iter->getSource());
+        }
+    }
+}
+
+void 
+Deliverer::Visit(CreatureMapType &m)
+{
+    for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+    {
+        if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist)
+        {
+            // Send packet to possessor
+            if (iter->getSource()->isPossessedByPlayer())
+                SendPacket((Player*)iter->getSource()->GetCharmer());
+        }
+    }
+}
+
+void
+Deliverer::SendPacket(Player* plr)
+{
+    if (!plr)
+        return;
+    // Don't send the packet to possesor if not supposed to
+    if (!i_toPossessor && plr->isPossessing() && plr->GetCharmGUID() == i_source.GetGUID())
+        return;
+
+    if (plr_list.find(plr->GetGUID()) == plr_list.end())
+    {
+        if (WorldSession* session = plr->GetSession())
             session->SendPacket(i_message);
-    }
-}
-
-void
-MessageDistDeliverer::Visit(PlayerMapType &m)
-{
-    for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
-    {
-        if( (i_toSelf || iter->getSource() != &i_player ) &&
-            (!i_ownTeamOnly || iter->getSource()->GetTeam() == i_player.GetTeam() ) &&
-            (!i_dist || iter->getSource()->GetDistance(&i_player) <= i_dist) )
-        {
-            if(WorldSession* session = iter->getSource()->GetSession())
-                session->SendPacket(i_message);
-        }
-    }
-}
-
-void
-ObjectMessageDistDeliverer::Visit(PlayerMapType &m)
-{
-    for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
-    {
-        if( !i_dist || iter->getSource()->GetDistance(&i_object) <= i_dist )
-        {
-            if(WorldSession* session = iter->getSource()->GetSession())
-                session->SendPacket(i_message);
-        }
+        plr_list.insert(plr->GetGUID());
+    }
+}
+
+void
+MessageDeliverer::VisitObject(Player* plr)
+{
+    if (i_toSelf || plr != &i_source)
+        SendPacket(plr);
+}
+
+void
+MessageDistDeliverer::VisitObject(Player* plr)
+{
+    if( (i_toSelf || plr != &i_source ) &&
+        (!i_ownTeamOnly || (i_source.GetTypeId() == TYPEID_PLAYER && plr->GetTeam() == ((Player&)i_source).GetTeam())) )
+    {
+        SendPacket(plr);
     }
 }
Index: /trunk/src/game/PossessedAI.cpp
===================================================================
--- /trunk/src/game/PossessedAI.cpp (revision 174)
+++ /trunk/src/game/PossessedAI.cpp (revision 174)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * Thanks to the original authors: 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 "PossessedAI.h"
+#include "Creature.h"
+#include "World.h"
+
+void PossessedAI::AttackStart(Unit *u)
+{
+    if( i_pet.getVictim() || !u )
+        return;
+
+    if(i_pet.Attack(u, true))
+        i_victimGuid = u->GetGUID();
+
+    // Do not autochase our target, and also make sure our current movement generator
+    // is removed since the motion master is reset before this function is called
+    i_pet.GetMotionMaster()->Clear(false);
+    i_pet.GetMotionMaster()->MoveIdle();
+}
+
+bool PossessedAI::_needToStop() const
+{
+    if(!i_pet.getVictim() || !i_pet.isAlive())
+        return true;
+
+    // This is needed for charmed creatures, as once their target was reset other effects can trigger threat
+    if(i_pet.getVictim() == i_pet.GetCharmer())
+        return true;
+
+    return !i_pet.getVictim()->isTargetableForAttack();
+}
+
+void PossessedAI::_stopAttack()
+{
+    if( !i_victimGuid )
+        return;
+
+    Unit* victim = Unit::GetUnit(i_pet, i_victimGuid );
+
+    if ( !victim )
+        return;
+
+    assert(!i_pet.getVictim() || i_pet.getVictim() == victim);
+
+    if( !i_pet.isAlive() )
+    {
+        i_pet.StopMoving();
+        i_pet.GetMotionMaster()->Clear(false);
+        i_pet.GetMotionMaster()->MoveIdle();
+        i_victimGuid = 0;
+        i_pet.CombatStop();
+        i_pet.getHostilRefManager().deleteReferences();
+
+        return;
+    }
+
+    i_pet.GetMotionMaster()->Clear(false);
+    i_pet.GetMotionMaster()->MoveIdle();
+    i_victimGuid = 0;
+    i_pet.AttackStop();
+}
+
+void PossessedAI::UpdateAI(const uint32 diff)
+{
+    // update i_victimGuid if i_pet.getVictim() !=0 and changed
+    if(i_pet.getVictim())
+        i_victimGuid = i_pet.getVictim()->GetGUID();
+
+    // 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( _needToStop() )
+        {
+            _stopAttack();                                  // i_victimGuid == 0 && i_pet.getVictim() == NULL now
+            return;
+        }
+        else if(i_pet.IsWithinCombatDist(i_pet.getVictim(), ATTACK_DISTANCE) && i_pet.isAttackReady())
+        {
+            i_pet.AttackerStateUpdate(i_pet.getVictim());
+
+            i_pet.resetAttackTimer();
+
+            if( _needToStop() )
+                _stopAttack();
+        }
+    }
+}
+
+bool PossessedAI::_isVisible(Unit *u) const
+{
+    return i_pet.GetDistance(u) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
+        && u->isVisibleForOrDetect(&i_pet,true);
+}
+
+void PossessedAI::JustDied(Unit *u)
+{
+    // We died while possessed, disable our loot
+    i_pet.RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+}
+
+void PossessedAI::KilledUnit(Unit* victim)
+{
+    // We killed a creature, disable victim's loot
+    if (victim->GetTypeId() == TYPEID_UNIT)
+        victim->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+}
Index: /trunk/src/game/PossessedAI.h
===================================================================
--- /trunk/src/game/PossessedAI.h (revision 174)
+++ /trunk/src/game/PossessedAI.h (revision 174)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * Thanks to the original authors: 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_POSSESSEDAI_H
+#define MANGOS_POSSESSEDAI_H
+
+#include "CreatureAI.h"
+
+class Creature;
+
+class TRINITY_DLL_DECL PossessedAI : public CreatureAI
+{
+    public:
+        PossessedAI(Creature &c) : i_pet(c), i_victimGuid(0) {}
+
+        // Possessed creatures shouldn't aggro by themselves
+        void MoveInLineOfSight(Unit *) {}
+        void AttackStart(Unit *);
+        void EnterEvadeMode() {}
+        void JustDied(Unit*);
+        void KilledUnit(Unit* victim);
+        void AttackedBy(Unit*) {}
+        bool IsVisible(Unit * u) const { return _isVisible(u); }
+
+        void UpdateAI(const uint32);
+        // Never permit this to be used, it must always be initialized with Creature::InitPossessedAI()
+        static int Permissible(const Creature *) { return PERMIT_BASE_NO; }
+
+    private:
+        bool _isVisible(Unit *) const;
+        bool _needToStop(void) const;
+        void _stopAttack(void);
+
+        Creature &i_pet;
+        uint64 i_victimGuid;
+};
+#endif
Index: /trunk/src/game/ObjectAccessor.cpp
===================================================================
--- /trunk/src/game/ObjectAccessor.cpp (revision 126)
+++ /trunk/src/game/ObjectAccessor.cpp (revision 174)
@@ -623,6 +623,28 @@
 {
     for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
-        if(iter->getSource()->HaveAtClient(&i_object))
-            ObjectAccessor::_buildPacket(iter->getSource(), &i_object, i_updateDatas);
+    {
+        BuildPacket(iter->getSource());
+        if (iter->getSource()->isPossessedByPlayer())
+            BuildPacket((Player*)iter->getSource()->GetCharmer());
+    }
+}
+
+void
+ObjectAccessor::WorldObjectChangeAccumulator::Visit(CreatureMapType &m)
+{
+    for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+        if (iter->getSource()->isPossessedByPlayer())
+            BuildPacket((Player*)iter->getSource()->GetCharmer());
+}
+
+void
+ObjectAccessor::WorldObjectChangeAccumulator::BuildPacket(Player* plr)
+{
+    // Only send update once to a player
+    if (plr_list.find(plr->GetGUID()) == plr_list.end() && plr->HaveAtClient(&i_object))
+    {
+        ObjectAccessor::_buildPacket(plr, &i_object, i_updateDatas);
+        plr_list.insert(plr->GetGUID());
+    }
 }
 
Index: /trunk/src/bindings/scripts/include/sc_creature.h
===================================================================
--- /trunk/src/bindings/scripts/include/sc_creature.h (revision 153)
+++ /trunk/src/bindings/scripts/include/sc_creature.h (revision 174)
@@ -75,4 +75,7 @@
     //Called at waypoint reached or PointMovement end
     void MovementInform(uint32, uint32){}
+
+    // Called when AI is temporarily replaced or put back when possess is applied or removed
+    void OnPossess(bool apply) {}
 
     //*************
Index: /trunk/src/bindings/scripts/scripts/npc/npc_escortAI.h
===================================================================
--- /trunk/src/bindings/scripts/scripts/npc/npc_escortAI.h (revision 90)
+++ /trunk/src/bindings/scripts/scripts/npc/npc_escortAI.h (revision 174)
@@ -52,4 +52,6 @@
         void MovementInform(uint32, uint32);
 
+        void OnPossess(bool apply);
+
         // EscortAI functions
         void AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs = 0);
Index: /trunk/src/bindings/scripts/scripts/npc/npc_escortAI.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/npc/npc_escortAI.cpp (revision 158)
+++ /trunk/src/bindings/scripts/scripts/npc/npc_escortAI.cpp (revision 174)
@@ -257,4 +257,23 @@
 }
 
+void npc_escortAI::OnPossess(bool apply)
+{
+    // We got possessed in the middle of being escorted, store the point 
+    // where we left off to come back to when possess is removed
+    if (IsBeingEscorted)
+    {
+        if (apply)
+            m_creature->GetPosition(LastPos.x, LastPos.y, LastPos.z);
+        else
+        {
+            Returning = true;
+            m_creature->GetMotionMaster()->MovementExpired();
+            m_creature->GetMotionMaster()->MovePoint(WP_LAST_POINT, LastPos.x, LastPos.y, LastPos.z);
+        }
+    }
+}
+
+
+
 void npc_escortAI::AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs)
 {
Index: /trunk/win/VC71/game.vcproj
===================================================================
--- /trunk/win/VC71/game.vcproj (revision 86)
+++ /trunk/win/VC71/game.vcproj (revision 174)
@@ -734,4 +734,12 @@
 			</File>
 			<File
+				RelativePath="..\..\src\game\PossessedAI.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\game\PossessedAI.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\game\RandomMovementGenerator.cpp">
 			</File>
Index: /trunk/win/VC80/game.vcproj
===================================================================
--- /trunk/win/VC80/game.vcproj (revision 86)
+++ /trunk/win/VC80/game.vcproj (revision 174)
@@ -1128,4 +1128,12 @@
 			</File>
 			<File
+				RelativePath="..\..\src\game\PossessedAI.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\game\PossessedAI.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\game\PointMovementGenerator.h"
 				>
Index: /trunk/win/VC90/game.vcproj
===================================================================
--- /trunk/win/VC90/game.vcproj (revision 86)
+++ /trunk/win/VC90/game.vcproj (revision 174)
@@ -2,5 +2,5 @@
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="9,00"
+	Version="9.00"
 	Name="game"
 	ProjectGUID="{1DC6C4DA-A028-41F3-877D-D5400C594F88}"
@@ -49,5 +49,5 @@
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers"
-				PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;"
+				PreprocessorDefinitions="WIN32;_DEBUG;TRINITY_DEBUG;_LIB;"
 				StringPooling="false"
 				MinimalRebuild="false"
@@ -102,87 +102,4 @@
 		</Configuration>
 		<Configuration
-			Name="Debug|x64"
-			OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
-			IntermediateDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalOptions="/MP"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers"
-				PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;"
-				StringPooling="false"
-				MinimalRebuild="false"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="3"
-				EnableFunctionLevelLinking="true"
-				RuntimeTypeInfo="true"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\game__$(PlatformName)_$(ConfigurationName)\game.pch"
-				AssemblerListingLocation=".\game__$(PlatformName)_$(ConfigurationName)\"
-				ObjectFile=".\game__$(PlatformName)_$(ConfigurationName)\"
-				ProgramDataBaseFileName=".\game__$(PlatformName)_$(ConfigurationName)\"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				Detect64BitPortabilityProblems="false"
-				DebugInformationFormat="3"
-				CallingConvention="0"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				AdditionalDependencies=".\shared__$(PlatformName)_$(ConfigurationName)\shared.lib"
-				OutputFile=".\game__$(PlatformName)_$(ConfigurationName)\game.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
 			Name="Release|Win32"
 			OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
@@ -214,7 +131,9 @@
 				InlineFunctionExpansion="1"
 				AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
-				StringPooling="true"
-				RuntimeLibrary="2"
+				PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;"
+				StringPooling="false"
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
 				EnableFunctionLevelLinking="true"
 				EnableEnhancedInstructionSet="1"
@@ -239,4 +158,85 @@
 				Name="VCResourceCompilerTool"
 				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				AdditionalDependencies=".\shared__$(PlatformName)_$(ConfigurationName)\shared.lib"
+				OutputFile=".\game__$(PlatformName)_$(ConfigurationName)\game.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
+			IntermediateDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
+			ConfigurationType="4"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/MP"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				RuntimeTypeInfo="true"
+				UsePrecompiledHeader="0"
+				PrecompiledHeaderFile=".\game__$(PlatformName)_$(ConfigurationName)\game.pch"
+				AssemblerListingLocation=".\game__$(PlatformName)_$(ConfigurationName)\"
+				ObjectFile=".\game__$(PlatformName)_$(ConfigurationName)\"
+				ProgramDataBaseFileName=".\game__$(PlatformName)_$(ConfigurationName)\"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+				CallingConvention="0"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
 				Culture="1033"
 			/>
@@ -1137,4 +1137,12 @@
 			</File>
 			<File
+				RelativePath="..\..\src\game\PossessedAI.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\game\PossessedAI.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\game\RandomMovementGenerator.cpp"
 				>
Index: /trunk/sql/updates/182_world.sql
===================================================================
--- /trunk/sql/updates/182_world.sql (revision 174)
+++ /trunk/sql/updates/182_world.sql (revision 174)
@@ -0,0 +1,4 @@
+DELETE FROM `command` WHERE name IN ('possess', 'unpossess');
+INSERT INTO `command` (name,security,help) VALUES
+('possess',3,'Syntax: .possess\r\n\r\nPossesses indefinitely the selected creature.'),
+('unpossess',3,'Syntax: .unpossess\r\n\r\nIf you are possessed, unpossesses yourself; otherwise unpossesses current possessed target.');
