[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:
@@ -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 )
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -96,6 +96,7 @@ Pet::Pet(PetType type) : Creature()
|
||||
m_CreatureCategoryCooldowns.clear();
|
||||
m_autospells.clear();
|
||||
m_declinedname = NULL;
|
||||
m_isActive = true;
|
||||
}
|
||||
|
||||
Pet::~Pet()
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -425,6 +425,8 @@ Player::Player (WorldSession *session): Unit()
|
||||
m_contestedPvPTimer = 0;
|
||||
|
||||
m_declinedname = NULL;
|
||||
|
||||
m_isActive = true;
|
||||
}
|
||||
|
||||
Player::~Player ()
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user