[svn] * Allow WorldObjects to keep the grid active, and prevent it from being unloaded. This can be done through calling WorldObject::setActive(bool) from the scripting library. Note that entire instances are still unloaded if no player is present on that map to save resources. This behavior can be changed if the need arises.

--HG--
branch : trunk
This commit is contained in:
w12x
2008-10-27 08:41:55 -05:00
parent 0e18e4330c
commit e72a13c3dd
13 changed files with 97 additions and 29 deletions
+2 -2
View File
@@ -47,14 +47,14 @@ void DynamicObject::AddToWorld()
{
///- Register the dynamicObject for guid lookup
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
Object::AddToWorld();
WorldObject::AddToWorld();
}
void DynamicObject::RemoveFromWorld()
{
///- Remove the dynamicObject from the accessor
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
Object::RemoveFromWorld();
WorldObject::RemoveFromWorld();
}
bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32 effIndex, float x, float y, float z, int32 duration, float radius )
+2 -2
View File
@@ -82,14 +82,14 @@ void GameObject::AddToWorld()
{
///- Register the gameobject for guid lookup
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
Object::AddToWorld();
WorldObject::AddToWorld();
}
void GameObject::RemoveFromWorld()
{
///- Remove the gameobject from the accessor
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
Object::RemoveFromWorld();
WorldObject::RemoveFromWorld();
}
bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state, uint32 ArtKit)
+1 -1
View File
@@ -36,7 +36,7 @@ ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 &x, c
info.UpdateTimeTracker(t_diff);
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);
stoper.StopN();
+1 -1
View File
@@ -878,7 +878,7 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
assert( grid != NULL);
{
if(!pForce && ObjectAccessor::Instance().PlayersNearGrid(x, y, i_id, i_InstanceId) )
if(!pForce && ObjectAccessor::Instance().ActiveObjectsNearGrid(x, y, i_id, i_InstanceId) )
return false;
DEBUG_LOG("Unloading grid[%u,%u] for map %u", x,y, i_id);
+37
View File
@@ -974,6 +974,43 @@ WorldObject::WorldObject()
m_name = "";
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();
}
void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid )
+9 -1
View File
@@ -27,6 +27,7 @@
#include "UpdateData.h"
#include "GameSystem/GridReference.h"
#include "ObjectDefines.h"
#include "GridDefines.h"
#include <set>
#include <string>
@@ -323,7 +324,11 @@ class TRINITY_DLL_SPEC Object
class TRINITY_DLL_SPEC WorldObject : public Object
{
public:
virtual ~WorldObject ( ) {}
virtual ~WorldObject ( );
virtual void AddToWorld();
virtual void RemoveFromWorld();
virtual void Update ( uint32 /*time_diff*/ ) { }
@@ -448,9 +453,12 @@ class TRINITY_DLL_SPEC WorldObject : public Object
Map const* GetBaseMap() const;
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:
uint32 m_mapId;
+31 -19
View File
@@ -504,23 +504,41 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
return bones;
}
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)
{
if(iter->second->IsInWorld())
{
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();
}
Map *map;
Trinity::ObjectUpdater updater(diff);
@@ -529,17 +547,12 @@ ObjectAccessor::Update(uint32 diff)
// for pets
TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
for(CreatureLocationHolderType::iterator iter=creature_locations.begin(); iter != creature_locations.end(); ++iter)
for(itr = activeobjects.begin(); itr != activeobjects.end(); ++itr)
{
MapManager::Instance().GetMap((*iter).first, (*iter).second)->resetMarkedCells();
}
WorldObject *obj = (*itr);
map = obj->GetMap();
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()));
CellPair standing_cell(Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()));
// Check for correctness of standing_cell, it also avoids problems with update_cell
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
@@ -576,7 +589,7 @@ ObjectAccessor::Update(uint32 diff)
}
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);
CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
@@ -585,17 +598,16 @@ ObjectAccessor::PlayersNearGrid(uint32 x, uint32 y, uint32 m_id, uint32 i_id) co
cell_max >> 2;
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)
for(std::set<WorldObject*>::const_iterator itr = i_activeobjects.begin(); itr != i_activeobjects.end(); ++itr)
{
if( m_id != iter->second->GetMapId() || i_id != iter->second->GetInstanceId() )
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;
}
return false;
+5 -1
View File
@@ -193,13 +193,16 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
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);
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
static void UpdateObjectVisibility(WorldObject* obj);
static void UpdateVisibilityForPlayer(Player* player);
void AddActiveObject(WorldObject*);
void RemoveActiveObject(WorldObject*);
private:
struct WorldObjectChangeAccumulator
{
@@ -220,6 +223,7 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
static void _buildPacket(Player *, Object *, UpdateDataMapType &);
void _update(void);
std::set<Object *> i_objects;
std::set<WorldObject *> i_activeobjects;
LockType i_playerGuard;
LockType i_updateGuard;
LockType i_corpseGuard;
+1
View File
@@ -96,6 +96,7 @@ Pet::Pet(PetType type) : Creature()
m_CreatureCategoryCooldowns.clear();
m_autospells.clear();
m_declinedname = NULL;
m_isActive = true;
}
Pet::~Pet()
+2
View File
@@ -122,6 +122,8 @@ class Pet : public Creature
void AddToWorld();
void RemoveFromWorld();
// always active
void setActive() {}
PetType getPetType() const { return m_petType; }
void setPetType(PetType type) { m_petType = type; }
+2
View File
@@ -425,6 +425,8 @@ Player::Player (WorldSession *session): Unit()
m_contestedPvPTimer = 0;
m_declinedname = NULL;
m_isActive = true;
}
Player::~Player ()
+2
View File
@@ -902,6 +902,8 @@ class TRINITY_DLL_SPEC Player : public Unit
void AddToWorld();
void RemoveFromWorld();
// always active
void setActive() {}
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0);
+2 -2
View File
@@ -9826,7 +9826,7 @@ uint32 Unit::GetCreatePowers( Powers power ) const
void Unit::AddToWorld()
{
Object::AddToWorld();
WorldObject::AddToWorld();
}
void Unit::RemoveFromWorld()
@@ -9837,7 +9837,7 @@ void Unit::RemoveFromWorld()
RemoveNotOwnSingleTargetAuras();
}
Object::RemoveFromWorld();
WorldObject::RemoveFromWorld();
}
void Unit::CleanupsBeforeDelete()