Index: /trunk/src/game/Object.cpp
===================================================================
--- /trunk/src/game/Object.cpp (revision 119)
+++ /trunk/src/game/Object.cpp (revision 120)
@@ -975,4 +975,41 @@
 
     mSemaphoreTeleport  = false;
+
+    m_isActive          = false;
+}
+
+WorldObject::~WorldObject()
+{
+    if(m_isActive && IsInWorld())
+        ObjectAccessor::Instance().RemoveActiveObject(this);
+}
+
+void WorldObject::setActive(bool isActive)
+{
+    // if already in the same activity state as we try to set, do nothing
+    if(isActive == m_isActive)
+        return;
+    m_isActive = isActive;
+    if(IsInWorld())
+    {
+        if(isActive)
+            ObjectAccessor::Instance().AddActiveObject(this);
+        else
+            ObjectAccessor::Instance().RemoveActiveObject(this);
+    }
+}
+
+void WorldObject::AddToWorld()
+{
+    Object::AddToWorld();
+    if(m_isActive)
+        ObjectAccessor::Instance().AddActiveObject(this);
+}
+
+void WorldObject::RemoveFromWorld()
+{
+    if(m_isActive)
+        ObjectAccessor::Instance().RemoveActiveObject(this);
+    Object::RemoveFromWorld();
 }
 
Index: /trunk/src/game/GridStates.cpp
===================================================================
--- /trunk/src/game/GridStates.cpp (revision 102)
+++ /trunk/src/game/GridStates.cpp (revision 120)
@@ -37,5 +37,5 @@
     if( info.getTimeTracker().Passed() )
     {
-        if( grid.ActiveObjectsInGrid() == 0 && !ObjectAccessor::Instance().PlayersNearGrid(x, y, m.GetId(), m.GetInstanceId()) )
+        if( grid.ActiveObjectsInGrid() == 0 && !ObjectAccessor::Instance().ActiveObjectsNearGrid(x, y, m.GetId(), m.GetInstanceId()) )
         {
             ObjectGridStoper stoper(grid);
Index: /trunk/src/game/Object.h
===================================================================
--- /trunk/src/game/Object.h (revision 119)
+++ /trunk/src/game/Object.h (revision 120)
@@ -28,4 +28,5 @@
 #include "GameSystem/GridReference.h"
 #include "ObjectDefines.h"
+#include "GridDefines.h"
 
 #include <set>
@@ -324,5 +325,9 @@
 {
     public:
-        virtual ~WorldObject ( ) {}
+        virtual ~WorldObject ( );
+
+        virtual void AddToWorld();
+
+        virtual void RemoveFromWorld();
 
         virtual void Update ( uint32 /*time_diff*/ ) { }
@@ -449,7 +454,10 @@
         Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
         GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime);
+        bool isActive() const { return m_isActive; }
+        virtual void setActive(bool isActive);
     protected:
         explicit WorldObject();
         std::string m_name;
+        bool m_isActive;
 
     private:
Index: /trunk/src/game/Player.h
===================================================================
--- /trunk/src/game/Player.h (revision 102)
+++ /trunk/src/game/Player.h (revision 120)
@@ -903,4 +903,6 @@
         void AddToWorld();
         void RemoveFromWorld();
+        // always active
+        void setActive() {}
 
         bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0);
Index: /trunk/src/game/Pet.h
===================================================================
--- /trunk/src/game/Pet.h (revision 102)
+++ /trunk/src/game/Pet.h (revision 120)
@@ -123,4 +123,6 @@
         void AddToWorld();
         void RemoveFromWorld();
+        // always active
+        void setActive() {}
 
         PetType getPetType() const { return m_petType; }
Index: /trunk/src/game/ObjectAccessor.h
===================================================================
--- /trunk/src/game/ObjectAccessor.h (revision 102)
+++ /trunk/src/game/ObjectAccessor.h (revision 120)
@@ -194,5 +194,5 @@
         Corpse* ConvertCorpseForPlayer(uint64 player_guid);
 
-        bool PlayersNearGrid(uint32 x,uint32 y,uint32 m_id,uint32 i_id) const;
+        bool ActiveObjectsNearGrid(uint32 x,uint32 y,uint32 m_id,uint32 i_id) const;
 
         static void UpdateObject(Object* obj, Player* exceptPlayer);
@@ -201,4 +201,7 @@
         static void UpdateObjectVisibility(WorldObject* obj);
         static void UpdateVisibilityForPlayer(Player* player);
+
+        void AddActiveObject(WorldObject*);
+        void RemoveActiveObject(WorldObject*);
     private:
         struct WorldObjectChangeAccumulator
@@ -221,4 +224,5 @@
         void _update(void);
         std::set<Object *> i_objects;
+        std::set<WorldObject *> i_activeobjects;
         LockType i_playerGuard;
         LockType i_updateGuard;
Index: /trunk/src/game/DynamicObject.cpp
===================================================================
--- /trunk/src/game/DynamicObject.cpp (revision 102)
+++ /trunk/src/game/DynamicObject.cpp (revision 120)
@@ -48,5 +48,5 @@
     ///- Register the dynamicObject for guid lookup
     if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
-    Object::AddToWorld();
+    WorldObject::AddToWorld();
 }
 
@@ -55,5 +55,5 @@
     ///- Remove the dynamicObject from the accessor
     if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
-    Object::RemoveFromWorld();
+    WorldObject::RemoveFromWorld();
 }
 
Index: /trunk/src/game/GameObject.cpp
===================================================================
--- /trunk/src/game/GameObject.cpp (revision 102)
+++ /trunk/src/game/GameObject.cpp (revision 120)
@@ -83,5 +83,5 @@
     ///- Register the gameobject for guid lookup
     if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
-    Object::AddToWorld();
+    WorldObject::AddToWorld();
 }
 
@@ -90,5 +90,5 @@
     ///- Remove the gameobject from the accessor
     if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
-    Object::RemoveFromWorld();
+    WorldObject::RemoveFromWorld();
 }
 
Index: /trunk/src/game/Unit.cpp
===================================================================
--- /trunk/src/game/Unit.cpp (revision 111)
+++ /trunk/src/game/Unit.cpp (revision 120)
@@ -9827,5 +9827,5 @@
 void Unit::AddToWorld()
 {
-    Object::AddToWorld();
+    WorldObject::AddToWorld();
 }
 
@@ -9838,5 +9838,5 @@
     }
 
-    Object::RemoveFromWorld();
+    WorldObject::RemoveFromWorld();
 }
 
Index: /trunk/src/game/Player.cpp
===================================================================
--- /trunk/src/game/Player.cpp (revision 111)
+++ /trunk/src/game/Player.cpp (revision 120)
@@ -426,4 +426,6 @@
 
     m_declinedname = NULL;
+
+    m_isActive = true;
 }
 
Index: /trunk/src/game/Pet.cpp
===================================================================
--- /trunk/src/game/Pet.cpp (revision 102)
+++ /trunk/src/game/Pet.cpp (revision 120)
@@ -97,4 +97,5 @@
     m_autospells.clear();
     m_declinedname = NULL;
+    m_isActive = true;
 }
 
Index: /trunk/src/game/Map.cpp
===================================================================
--- /trunk/src/game/Map.cpp (revision 118)
+++ /trunk/src/game/Map.cpp (revision 120)
@@ -879,5 +879,5 @@
 
     {
-        if(!pForce && ObjectAccessor::Instance().PlayersNearGrid(x, y, i_id, i_InstanceId) )
+        if(!pForce && ObjectAccessor::Instance().ActiveObjectsNearGrid(x, y, i_id, i_InstanceId) )
             return false;
 
Index: /trunk/src/game/ObjectAccessor.cpp
===================================================================
--- /trunk/src/game/ObjectAccessor.cpp (revision 102)
+++ /trunk/src/game/ObjectAccessor.cpp (revision 120)
@@ -506,10 +506,20 @@
 
 void
+ObjectAccessor::AddActiveObject( WorldObject * obj )
+{
+    i_activeobjects.insert(obj);
+}
+
+void
+ObjectAccessor::RemoveActiveObject( WorldObject * obj )
+{
+    i_activeobjects.erase(obj);
+}
+
+void
 ObjectAccessor::Update(uint32 diff)
 {
     {
-        typedef std::multimap<uint32, Player *> CreatureLocationHolderType;
-        CreatureLocationHolderType creature_locations;
-        //TODO: Player guard
+        // player update might remove the player from grid, and that causes crashes. We HAVE to update players first, and then the active objects.
         HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
         for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
@@ -518,6 +528,14 @@
             {
                 iter->second->Update(diff);
-                creature_locations.insert( CreatureLocationHolderType::value_type(iter->second->GetMapId(), iter->second) );
             }
+        }
+
+        // clone the active object list, because update might remove from it
+        std::set<WorldObject *> activeobjects(i_activeobjects);
+
+        std::set<WorldObject *>::const_iterator itr;
+        for(itr = activeobjects.begin(); itr != activeobjects.end(); ++itr)
+        {
+            (*itr)->GetMap()->resetMarkedCells();
         }
 
@@ -530,15 +548,10 @@
         TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
 
-        for(CreatureLocationHolderType::iterator iter=creature_locations.begin(); iter != creature_locations.end(); ++iter)
-        {
-            MapManager::Instance().GetMap((*iter).first, (*iter).second)->resetMarkedCells();
-        }
-
-        for(CreatureLocationHolderType::iterator iter=creature_locations.begin(); iter != creature_locations.end(); ++iter)
-        {
-            Player *player = (*iter).second;
-            map = MapManager::Instance().GetMap((*iter).first, player);
-
-            CellPair standing_cell(Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()));
+        for(itr = activeobjects.begin(); itr != activeobjects.end(); ++itr)
+        {
+            WorldObject *obj = (*itr);
+            map = obj->GetMap();
+
+            CellPair standing_cell(Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()));
 
             // Check for correctness of standing_cell, it also avoids problems with update_cell
@@ -577,5 +590,5 @@
 
 bool
-ObjectAccessor::PlayersNearGrid(uint32 x, uint32 y, uint32 m_id, uint32 i_id) const
+ObjectAccessor::ActiveObjectsNearGrid(uint32 x, uint32 y, uint32 m_id, uint32 i_id) const
 {
     CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS);
@@ -586,15 +599,14 @@
     cell_max += 2;
 
-    //TODO: Guard player
-    HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
-    for(HashMapHolder<Player>::MapType::const_iterator iter=playerMap.begin(); iter != playerMap.end(); ++iter)
-    {
-        if( m_id != iter->second->GetMapId() || i_id != iter->second->GetInstanceId() )
+    for(std::set<WorldObject*>::const_iterator itr = i_activeobjects.begin(); itr != i_activeobjects.end(); ++itr)
+    {
+        if( m_id != (*itr)->GetMapId() || i_id != (*itr)->GetInstanceId() )
             continue;
 
-        CellPair p = Trinity::ComputeCellPair(iter->second->GetPositionX(), iter->second->GetPositionY());
+        CellPair p = Trinity::ComputeCellPair((*itr)->GetPositionX(), (*itr)->GetPositionY());
         if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
             (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) )
             return true;
+
     }
 
