[8182] Store and use Map* pointer in WorldObject instead map ids for speedup

Also some code logic cleanups.
Changes let make more cleanups in base map access and other places,
but this chnages not inlcuded in patch.

Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
Ambal 2009-07-15 01:30:13 +04:00 committed by VladimirMangos
parent fcb34b3928
commit 58209ee79a
25 changed files with 180 additions and 193 deletions

View file

@ -72,12 +72,15 @@ bool Corpse::Create( uint32 guidlow )
bool Corpse::Create( uint32 guidlow, Player *owner)
{
SetInstanceId(owner->GetInstanceId());
WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetMapId(), owner->GetPhaseMask());
ASSERT(owner);
WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetPhaseMask());
Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
//we need to assign owner's map for corpse
//in other way we will get a crash in Corpse::SaveToDB()
SetMap(owner->GetMap());
if(!IsPositionValid())
{
sLog.outError("Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
@ -207,8 +210,8 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE));
// place
SetInstanceId(instanceid);
SetMapId(mapid);
SetLocationInstanceId(instanceid);
SetLocationMapId(mapid);
SetPhaseMask(phaseMask, false);
Relocate(positionX, positionY, positionZ, ort);

View file

@ -563,8 +563,8 @@ bool Creature::AIM_Initialize()
bool Creature::Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, const CreatureData *data)
{
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
ASSERT(map);
SetMap(map);
SetPhaseMask(phaseMask,false);
//oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0;
@ -572,6 +572,12 @@ bool Creature::Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry,
if (bResult)
{
//Notify the map's instance data.
//Only works if you create the object in it, not if it is moves to that map.
//Normally non-players do not teleport to other maps.
if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData())
((InstanceMap*)map)->GetInstanceData()->OnCreatureCreate(this);
switch (GetCreatureInfo()->rank)
{
case CREATURE_ELITE_RARE:
@ -1312,15 +1318,6 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const
if(!UpdateEntry(Entry, team, data))
return false;
//Notify the map's instance data.
//Only works if you create the object in it, not if it is moves to that map.
//Normally non-players do not teleport to other maps.
Map *map = MapManager::Instance().FindMap(GetMapId(), GetInstanceId());
if(map && map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData())
{
((InstanceMap*)map)->GetInstanceData()->OnCreatureCreate(this);
}
return true;
}

View file

@ -56,9 +56,8 @@ void DynamicObject::RemoveFromWorld()
bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32 effIndex, float x, float y, float z, int32 duration, float radius )
{
SetInstanceId(caster->GetInstanceId());
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetMapId(), caster->GetPhaseMask());
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetPhaseMask());
SetMap(caster->GetMap());
Relocate(x, y, z, 0);
if(!IsPositionValid())

View file

@ -109,9 +109,9 @@ void GameObject::RemoveFromWorld()
bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state)
{
ASSERT(map);
Relocate(x,y,z,ang);
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
SetMap(map);
SetPhaseMask(phaseMask,false);
if(!IsPositionValid())

View file

@ -124,14 +124,12 @@ void Map::LoadMap(int gx,int gy, bool reload)
if(GridMaps[gx][gy])
return;
Map* baseMap = const_cast<Map*>(MapManager::Instance().CreateBaseMap(i_id));
// load grid map for base map
if (!baseMap->GridMaps[gx][gy])
baseMap->EnsureGridCreated(GridPair(63-gx,63-gy));
if (!m_parentMap->GridMaps[gx][gy])
m_parentMap->EnsureGridCreated(GridPair(63-gx,63-gy));
((MapInstanced*)(baseMap))->AddGridMapReference(GridPair(gx,gy));
GridMaps[gx][gy] = baseMap->GridMaps[gx][gy];
((MapInstanced*)(m_parentMap))->AddGridMapReference(GridPair(gx,gy));
GridMaps[gx][gy] = m_parentMap->GridMaps[gx][gy];
return;
}
@ -184,11 +182,11 @@ void Map::DeleteStateMachine()
delete si_GridStates[GRID_STATE_REMOVAL];
}
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent)
: i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode),
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
m_activeNonPlayersIter(m_activeNonPlayers.end()),
i_gridExpiry(expiry)
i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this)
{
for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
{
@ -295,6 +293,13 @@ void Map::DeleteFromWorld(T* obj)
delete obj;
}
template<>
void Map::DeleteFromWorld(Player* pl)
{
ObjectAccessor::Instance().RemoveObject(pl);
delete pl;
}
template<class T>
void Map::AddNotifier(T* , Cell const& , CellPair const& )
{
@ -399,8 +404,7 @@ void Map::LoadGrid(const Cell& cell, bool no_unload)
bool Map::Add(Player *player)
{
player->GetMapRef().link(this, player);
player->SetInstanceId(GetInstanceId());
player->SetMap(this);
// update player state for other player and visa-versa
CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
@ -431,6 +435,8 @@ Map::Add(T *obj)
return;
}
obj->SetMap(this);
Cell cell(p);
if(obj->isActiveObject())
EnsureGridLoadedAtEnter(cell);
@ -688,8 +694,12 @@ void Map::Remove(Player *player, bool remove)
CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
{
if(remove)
player->CleanupsBeforeDelete();
// invalid coordinates
player->RemoveFromWorld();
player->ResetMap();
if( remove )
DeleteFromWorld(player);
@ -709,13 +719,16 @@ void Map::Remove(Player *player, bool remove)
NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
assert(grid != NULL);
if(remove)
player->CleanupsBeforeDelete();
player->RemoveFromWorld();
RemoveFromGrid(player,grid,cell);
SendRemoveTransports(player);
UpdateObjectsVisibilityFor(player,cell,p);
player->ResetMap();
if( remove )
DeleteFromWorld(player);
}
@ -760,6 +773,7 @@ Map::Remove(T *obj, bool remove)
UpdateObjectVisibility(obj,cell,p);
obj->ResetMap();
if( remove )
{
// if option set then object already saved at this moment
@ -1029,7 +1043,8 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gy, gx);
}
else
((MapInstanced*)(MapManager::Instance().CreateBaseMap(i_id)))->RemoveGridMapReference(GridPair(gx, gy));
((MapInstanced*)m_parentMap)->RemoveGridMapReference(GridPair(gx, gy));
GridMaps[gx][gy] = NULL;
}
DEBUG_LOG("Unloading grid[%u,%u] for map %u finished", x,y, i_id);
@ -2196,8 +2211,8 @@ template void Map::Remove(DynamicObject *, bool);
/* ******* Dungeon Instance Maps ******* */
InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
: Map(id, expiry, InstanceId, SpawnMode),
InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent)
: Map(id, expiry, InstanceId, SpawnMode, _parent),
m_resetAfterUnload(false), m_unloadWhenEmpty(false),
i_data(NULL), i_script_id(0)
{
@ -2534,8 +2549,8 @@ uint32 InstanceMap::GetMaxPlayers() const
/* ******* Battleground Instance Maps ******* */
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId)
: Map(id, expiry, InstanceId, DIFFICULTY_NORMAL)
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent)
: Map(id, expiry, InstanceId, DIFFICULTY_NORMAL, _parent)
{
}

View file

@ -245,7 +245,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
{
friend class MapReference;
public:
Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode);
Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = NULL);
virtual ~Map();
// currently unused for normal maps
@ -300,6 +300,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
static void InitStateMachine();
static void DeleteStateMachine();
Map const * GetParent() const { return m_parentMap; }
// some calls like isInWater should not use vmaps due to processor power
// can return INVALID_HEIGHT if under z+2 z coord not found height
float GetHeight(float x, float y, float z, bool pCheckVMap=true) const;
@ -461,6 +463,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
ActiveNonPlayers m_activeNonPlayers;
ActiveNonPlayers::iterator m_activeNonPlayersIter;
private:
//used for fast base_map (e.g. MapInstanced class object) search for
//InstanceMaps and BattleGroundMaps...
Map* m_parentMap;
typedef GridReadGuard ReadGuard;
typedef GridWriteGuard WriteGuard;
@ -520,7 +526,7 @@ enum InstanceResetMethod
class MANGOS_DLL_SPEC InstanceMap : public Map
{
public:
InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode);
InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent);
~InstanceMap();
bool Add(Player *);
void Remove(Player *, bool);
@ -545,7 +551,7 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
class MANGOS_DLL_SPEC BattleGroundMap : public Map
{
public:
BattleGroundMap(uint32 id, time_t, uint32 InstanceId);
BattleGroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent);
~BattleGroundMap();
bool Add(Player *);

View file

@ -108,55 +108,30 @@ void MapInstanced::UnloadAll(bool pForce)
- create the instance if it's not created already
- the player is not actually added to the instance (only in InstanceMap::Add)
*/
Map* MapInstanced::GetInstance(const WorldObject* obj)
Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player)
{
uint32 CurInstanceId = obj->GetInstanceId();
Map* map = NULL;
if (obj->GetMapId() == GetId() && CurInstanceId != 0)
{
// the object wants to be put in a certain instance of this map
map = _FindMap(CurInstanceId);
if(!map)
{
// For players if the instanceId is set, it's assumed they are already in a map,
// hence the map must be loaded. For Creatures, GameObjects etc the map must exist
// prior to calling GetMap, they are not allowed to create maps for themselves.
sLog.outError("GetInstance: object %s(%d), typeId %d, in world %d, should be in map %d,%d but that's not loaded yet.", obj->GetName(), obj->GetGUIDLow(), obj->GetTypeId(), obj->IsInWorld(), obj->GetMapId(), obj->GetInstanceId());
assert(false);
}
return(map);
}
else
{
// instance not specified, find an existing or create a new one
if(obj->GetTypeId() != TYPEID_PLAYER)
{
sLog.outError("MAPINSTANCED: WorldObject '%u' (Entry: %u TypeID: %u) is in map %d,%d and requested base map instance of map %d, this must not happen", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), obj->GetMapId(), obj->GetInstanceId(), GetId());
assert(false);
if(GetId() != mapId || !player)
return NULL;
}
else
{
Map* map = NULL;
uint32 NewInstanceId = 0; // instanceId of the resulting map
Player* player = (Player*)obj;
if(IsBattleGroundOrArena())
{
// instantiate or find existing bg map for player
// the instance id is set in battlegroundid
NewInstanceId = player->GetBattleGroundId();
assert(NewInstanceId);
ASSERT(NewInstanceId);
map = _FindMap(NewInstanceId);
if(!map)
map = CreateBattleGround(NewInstanceId);
return map;
}
else
{
InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDifficulty());
InstanceSave *pSave = pBind ? pBind->save : NULL;
// the player's permanet player bind is taken into consideration first
// the player's permanent player bind is taken into consideration first
// then the player's group bind and finally the solo bind.
if(!pBind || !pBind->perm)
{
@ -175,17 +150,17 @@ Map* MapInstanced::GetInstance(const WorldObject* obj)
// it is possible that the save exists but the map doesn't
if(!map)
map = CreateInstance(NewInstanceId, pSave, pSave->GetDifficulty());
return map;
}
else
{
// if no instanceId via group members or instance saves is found
// the instance will be created for the first time
NewInstanceId = MapManager::Instance().GenerateInstanceId();
return CreateInstance(NewInstanceId, NULL, player->GetDifficulty());
}
map = CreateInstance(NewInstanceId, NULL, player->GetDifficulty());
}
}
return map;
}
InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, uint8 difficulty)
@ -210,10 +185,10 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save,
// some instances only have one difficulty
if (entry && !entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL;
sLog.outDebug("MapInstanced::CreateInstance: %smap instance %d for %d created with difficulty %s", save?"":"new ", InstanceId, GetId(), difficulty?"heroic":"normal");
sLog.outDebug("MapInstanced::CreateInstance: %s map instance %d for %d created with difficulty %s", save?"":"new ", InstanceId, GetId(), difficulty?"heroic":"normal");
InstanceMap *map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty);
assert(map->IsDungeon());
InstanceMap *map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty, this);
ASSERT(map->IsDungeon());
bool load_data = save != NULL;
map->CreateInstanceData(load_data);
@ -229,8 +204,8 @@ BattleGroundMap* MapInstanced::CreateBattleGround(uint32 InstanceId)
sLog.outDebug("MapInstanced::CreateBattleGround: map bg %d for %d created.", InstanceId, GetId());
BattleGroundMap *map = new BattleGroundMap(GetId(), GetGridExpiry(), InstanceId);
assert(map->IsBattleGroundOrArena());
BattleGroundMap *map = new BattleGroundMap(GetId(), GetGridExpiry(), InstanceId, this);
ASSERT(map->IsBattleGroundOrArena());
m_InstancedMaps[InstanceId] = map;
return map;

View file

@ -38,7 +38,7 @@ class MANGOS_DLL_DECL MapInstanced : public Map
bool RemoveBones(uint64 guid, float x, float y);
void UnloadAll(bool pForce);
Map* GetInstance(const WorldObject* obj);
Map* CreateInstance(const uint32 mapId, Player * player);
Map* FindMap(uint32 InstanceId) const { return _FindMap(InstanceId); }
void DestroyInstance(uint32 InstanceId);
void DestroyInstance(InstancedMaps::iterator &itr);

View file

@ -122,13 +122,13 @@ MapManager::_createBaseMap(uint32 id)
return m;
}
Map* MapManager::GetMap(uint32 id, const WorldObject* obj)
Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
{
ASSERT(obj);
//if(!obj->IsInWorld()) sLog.outError("GetMap: called for map %d with object (typeid %d, guid %d, mapid %d, instanceid %d) who is not in world!", id, obj->GetTypeId(), obj->GetGUIDLow(), obj->GetMapId(), obj->GetInstanceId());
Map *m = _createBaseMap(id);
if (m && obj && m->Instanceable()) m = ((MapInstanced*)m)->GetInstance(obj);
if (m && (obj->GetTypeId() == TYPEID_PLAYER) && m->Instanceable()) m = ((MapInstanced*)m)->CreateInstance(id, (Player*)obj);
return m;
}

View file

@ -37,7 +37,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
public:
Map* GetMap(uint32, const WorldObject* obj);
Map* CreateMap(uint32, const WorldObject* obj);
Map const* CreateBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_createBaseMap(id); }
Map* FindMap(uint32 mapid, uint32 instanceId = 0) const;

View file

@ -65,18 +65,17 @@ void WorldSession::HandleMoveWorldportAckOpcode()
GetPlayer()->SetSemaphoreTeleportFar(false);
// relocate the player to the teleport destination
GetPlayer()->SetMapId(loc.mapid);
GetPlayer()->SetMap(MapManager::Instance().CreateMap(loc.mapid, GetPlayer())); GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);
GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);
// since the MapId is set before the GetInstance call, the InstanceId must be set to 0
// to let GetInstance() determine the proper InstanceId based on the player's binds
GetPlayer()->SetInstanceId(0);
GetPlayer()->SendInitialPacketsBeforeAddToMap();
// the CanEnter checks are done in TeleporTo but conditions may change
// while the player is in transit, for example the map may get full
if(!GetPlayer()->GetMap()->Add(GetPlayer()))
{
//if player wasn't added to map, reset his map pointer!
GetPlayer()->ResetMap();
sLog.outDebug("WORLD: teleport of player %s (%d) to location %d, %f, %f, %f, %f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);
// teleport the player home
if(!GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()))

View file

@ -1049,7 +1049,7 @@ bool Object::PrintIndexError(uint32 index, bool set) const
WorldObject::WorldObject()
: m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f)
m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), m_currMap(NULL)
{
}
@ -1057,11 +1057,9 @@ void WorldObject::CleanupsBeforeDelete()
{
}
void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask )
void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 phaseMask )
{
Object::_Create(guidlow, 0, guidhigh);
m_mapId = mapid;
m_phaseMask = phaseMask;
}
@ -1538,14 +1536,19 @@ void WorldObject::SendObjectDeSpawnAnim(uint64 guid)
SendMessageToSet(&data, true);
}
Map* WorldObject::GetMap() const
void WorldObject::SetMap(Map * map)
{
return MapManager::Instance().GetMap(GetMapId(), this);
ASSERT(map);
m_currMap = map;
//lets save current map's Id/instanceId
m_mapId = map->GetId();
m_InstanceId = map->GetInstanceId();
}
Map const* WorldObject::GetBaseMap() const
{
return MapManager::Instance().CreateBaseMap(GetMapId());
ASSERT(m_currMap);
return m_currMap->GetParent();
}
void WorldObject::AddObjectToRemoveList()
@ -1557,7 +1560,6 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
{
TemporarySummon* pCreature = new TemporarySummon(GetGUID());
pCreature->SetInstanceId(GetInstanceId());
uint32 team = 0;
if (GetTypeId()==TYPEID_PLAYER)
team = ((Player*)this)->GetTeam();

View file

@ -346,7 +346,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
virtual void Update ( uint32 /*time_diff*/ ) { }
void _Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask);
void _Create( uint32 guidlow, HighGuid guidhigh, uint32 phaseMask);
void Relocate(float x, float y, float z, float orientation)
{
@ -395,8 +395,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
void GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z ) const;
void SetMapId(uint32 newMap) { m_mapId = newMap; }
uint32 GetMapId() const { return m_mapId; }
uint32 GetInstanceId() const { return m_InstanceId; }
virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
uint32 GetPhaseMask() const { return m_phaseMask; }
@ -421,8 +421,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
float GetDistanceZ(const WorldObject* obj) const;
bool IsInMap(const WorldObject* obj) const
{
return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() &&
GetInstanceId()==obj->GetInstanceId() && InSamePhase(obj);
return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap()) && InSamePhase(obj);
}
bool IsWithinDist3d(float x, float y, float z, float dist2compare) const;
bool IsWithinDist2d(float x, float y, float dist2compare) const;
@ -469,10 +468,6 @@ class MANGOS_DLL_SPEC WorldObject : public Object
void SendObjectDeSpawnAnim(uint64 guid);
virtual void SaveRespawnTime() {}
uint32 GetInstanceId() const { return m_InstanceId; }
void SetInstanceId(uint32 val) { m_InstanceId = val; }
void AddObjectToRemoveList();
// main visibility check function in normal case (ignore grey zone distance check)
@ -481,15 +476,29 @@ class MANGOS_DLL_SPEC WorldObject : public Object
// low level function for visibility change code, must be define in all main world object subclasses
virtual bool isVisibleForInState(Player const* u, bool inVisibleList) const = 0;
Map * GetMap() const;
void SetMap(Map * map);
Map * GetMap() const { ASSERT(m_currMap); return m_currMap; }
//used to check all object's GetMap() calls when object is not in world!
void ResetMap() { m_currMap = NULL; }
//this function should be removed in nearest time...
Map const* GetBaseMap() const;
Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
protected:
explicit WorldObject();
std::string m_name;
//these functions are used mostly for Relocate() and Corpse/Player specific stuff...
//use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
//mapId/instanceId should be set in SetMap() function!
void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }
private:
Map * m_currMap; //current object's Map location
uint32 m_mapId; // object at map with map_id
uint32 m_InstanceId; // in map copy with instance id
uint32 m_phaseMask; // in area phase state

View file

@ -363,8 +363,6 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia)
// bones->m_inWorld = m_inWorld; // don't overwrite world state
// bones->m_type = m_type; // don't overwrite type
bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
bones->SetMapId(corpse->GetMapId());
bones->SetInstanceId(corpse->GetInstanceId());
bones->SetPhaseMask(corpse->GetPhaseMask(), false);
bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);

View file

@ -123,6 +123,7 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &
obj->GetGridRef().link(&m, obj);
addUnitState(obj,cell);
obj->SetMap(map);
obj->AddToWorld();
if(obj->isActiveObject())
map->AddToActive(obj);
@ -151,6 +152,7 @@ void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType
obj->GetGridRef().link(&m, obj);
addUnitState(obj,cell);
obj->SetMap(map);
obj->AddToWorld();
if(obj->isActiveObject())
map->AddToActive(obj);

View file

@ -744,9 +744,6 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
}
uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_PET);
sLog.outBasic("SetInstanceID()");
SetInstanceId(creature->GetInstanceId());
sLog.outBasic("Create pet");
uint32 pet_number = objmgr.GeneratePetNumber();
if(!Create(guid, creature->GetMap(), creature->GetPhaseMask(), creature->GetEntry(), pet_number))
@ -1841,8 +1838,7 @@ bool Pet::IsPermanentPetFor(Player* owner)
bool Pet::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number)
{
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
SetMap(map);
SetPhaseMask(phaseMask,false);
Object::_Create(guidlow, pet_number, HIGHGUID_PET);

View file

@ -540,7 +540,7 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
for (int i = 0; i < PLAYER_SLOTS_COUNT; ++i)
m_items[i] = NULL;
SetMapId(info->mapId);
SetLocationMapId(info->mapId);
Relocate(info->positionX,info->positionY,info->positionZ);
ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(class_);
@ -550,6 +550,8 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
return false;
}
SetMap(MapManager::Instance().CreateMap(info->mapId, this));
uint8 powertype = cEntry->powerType;
SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE);
@ -12031,7 +12033,11 @@ void Player::PrepareQuestMenu( uint64 guid )
}
else
{
GameObject *pGameObject = GetMap()->GetGameObject(guid);
//we should obtain map pointer from GetMap() in 99% of cases. Special case
//only for quests which cast teleport spells on player
Map * _map = IsInWorld() ? GetMap() : MapManager::Instance().FindMap(GetMapId(), GetInstanceId());
ASSERT(_map);
GameObject *pGameObject = _map->GetGameObject(guid);
if( pGameObject )
{
pObject = (Object*)pGameObject;
@ -13829,7 +13835,8 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid )
m_name = fields[2].GetCppString();
Relocate(fields[3].GetFloat(),fields[4].GetFloat(),fields[5].GetFloat());
SetMapId(fields[6].GetUInt32());
SetLocationMapId(fields[6].GetUInt32());
// the instance id is not needed at character enum
m_Played_time[0] = fields[7].GetUInt32();
@ -14108,7 +14115,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// init saved position, and fix it later if problematic
uint32 transGUID = fields[31].GetUInt32();
Relocate(fields[13].GetFloat(),fields[14].GetFloat(),fields[15].GetFloat(),fields[17].GetFloat());
SetMapId(fields[16].GetUInt32());
SetLocationMapId(fields[16].GetUInt32());
SetDifficulty(fields[39].GetUInt32()); // may be changed in _LoadGroup
_LoadGroup(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGROUP));
@ -14183,7 +14190,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
else
{
const WorldLocation& _loc = GetBattleGroundEntryPoint();
SetMapId(_loc.mapid);
SetLocationMapId(_loc.mapid);
Relocate(_loc.coord_x, _loc.coord_y, _loc.coord_z, _loc.orientation);
//RemoveArenaAuras(true);
}
@ -14196,7 +14203,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
if(!mapEntry || mapEntry->IsBattleGroundOrArena())
{
// return to BG master
SetMapId(fields[43].GetUInt32());
SetLocationMapId(fields[43].GetUInt32());
Relocate(fields[44].GetFloat(),fields[45].GetFloat(),fields[46].GetFloat(),fields[47].GetFloat());
// check entry point and fix to homebind if need
@ -14250,7 +14257,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
m_transport = *iter;
m_transport->AddPassenger(this);
SetMapId(m_transport->GetMapId());
SetLocationMapId(m_transport->GetMapId());
break;
}
}
@ -14283,11 +14290,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// NOW player must have valid map
// load the player's map here if it's not already loaded
Map *map = GetMap();
// since the player may not be bound to the map yet, make sure subsequent
// getmap calls won't create new maps
SetInstanceId(map->GetInstanceId());
SetMap(MapManager::Instance().CreateMap(GetMapId(), this));
// if the player is in an instance and it has been reset in the meantime teleport him to the entrance
if(GetInstanceId() && !sInstanceSaveManager.GetInstanceSave(GetInstanceId()))
@ -14465,15 +14468,19 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
{
sLog.outError("Character %u have wrong data in taxi destination list, teleport to homebind.",GetGUIDLow());
RelocateToHomebind();
SaveRecallPosition(); // save as recall also to prevent recall and fall from sky
}
else // have start node, to it
{
sLog.outError("Character %u have too short taxi destination list, teleport to original node.",GetGUIDLow());
SetMapId(nodeEntry->map_id);
SetLocationMapId(nodeEntry->map_id);
Relocate(nodeEntry->x, nodeEntry->y, nodeEntry->z,0.0f);
SaveRecallPosition(); // save as recall also to prevent recall and fall from sky
}
//we can be relocated from taxi and still have an outdated Map pointer!
//so we need to get a new Map pointer!
SetMap(MapManager::Instance().CreateMap(GetMapId(), this));
SaveRecallPosition(); // save as recall also to prevent recall and fall from sky
m_taxi.ClearTaxiDestinations();
}
else if(uint32 node_id = m_taxi.GetTaxiSource())

View file

@ -2071,7 +2071,7 @@ class MANGOS_DLL_SPEC Player : public Unit
float m_homebindX;
float m_homebindY;
float m_homebindZ;
void RelocateToHomebind() { SetMapId(m_homebindMapId); Relocate(m_homebindX,m_homebindY,m_homebindZ); }
void RelocateToHomebind() { SetLocationMapId(m_homebindMapId); Relocate(m_homebindX,m_homebindY,m_homebindZ); }
// currently visible objects at player client
typedef std::set<uint64> ClientGUIDs;

View file

@ -4080,7 +4080,6 @@ void Spell::EffectSummonPet(uint32 i)
return;
OldSummon->GetMap()->Remove((Creature*)OldSummon,false);
OldSummon->SetMapId(m_caster->GetMapId());
float px, py, pz;
m_caster->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());

View file

@ -54,8 +54,6 @@ void Totem::Update( uint32 time )
void Totem::Summon(Unit* owner)
{
sLog.outDebug("AddObject at Totem.cpp line 49");
SetInstanceId(owner->GetInstanceId());
owner->GetMap()->Add((Creature*)this);
// select totem model in dependent from owner team

View file

@ -102,7 +102,8 @@ void MapManager::LoadTransports()
m_TransportsByMap[*i].insert(t);
//If we someday decide to use the grid to track transports, here:
//MapManager::Instance().LoadGrid(mapid,x,y,true);
t->SetMap(MapManager::Instance().CreateMap(mapid, t));
//t->GetMap()->Add<GameObject>((GameObject *)t);
++count;
} while(result->NextRow());
@ -138,8 +139,6 @@ Transport::Transport() : GameObject()
bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags)
{
Relocate(x,y,z,ang);
SetMapId(mapid);
// instance id and phaseMask isn't set to values different from std.
if(!IsPositionValid())
@ -432,7 +431,6 @@ Transport::WayPointMap::const_iterator Transport::GetNextWayPoint()
void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
{
Map const* oldMap = GetMap();
SetMapId(newMapid);
Relocate(x, y, z);
for(PlayerSet::iterator itr = m_passengers.begin(); itr != m_passengers.end();)
@ -458,7 +456,11 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
//plr->GetSession()->SendPacket(&data);
}
Map const* newMap = GetMap();
//we need to create and save new Map object with 'newMapid' because if not done -> lead to invalid Map object reference...
//player far teleport would try to create same instance, but we need it NOW for transport...
//correct me if I'm wrong O.o
Map * newMap = MapManager::Instance().CreateMap(newMapid, this);
SetMap(newMap);
if(oldMap != newMap)
{

View file

@ -54,24 +54,11 @@ class TransportPath
std::vector<PathNode> i_nodes;
};
class Transport : protected GameObject
class Transport : public GameObject
{
public:
explicit Transport();
// prevent using Transports as normal GO, but allow call some inherited functions
using GameObject::IsTransport;
using GameObject::GetEntry;
using GameObject::GetGUID;
using GameObject::GetGUIDLow;
using GameObject::GetMapId;
using GameObject::GetPositionX;
using GameObject::GetPositionY;
using GameObject::GetPositionZ;
using GameObject::BuildCreateUpdateBlockForPlayer;
using GameObject::BuildOutOfRangeUpdateBlock;
using GameObject::GetPackGUID;
bool Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags);
bool GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids);
void Update(uint32 p_time);

View file

@ -62,8 +62,7 @@ void Vehicle::Update(uint32 diff)
bool Vehicle::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team)
{
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
SetMap(map);
Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);

View file

@ -385,15 +385,9 @@ void WorldSession::LogoutPlayer(bool Save)
// the player may not be in the world when logging out
// e.g if he got disconnected during a transfer to another map
// calls to GetMap in this case may cause crashes
if(_player->IsInWorld()) _player->GetMap()->Remove(_player, false);
// RemoveFromWorld does cleanup that requires the player to be in the accessor
ObjectAccessor::Instance().RemoveObject(_player);
///- Delete the player object
_player->CleanupsBeforeDelete(); // do some cleanup before deleting to prevent crash at crossreferences to already deleted data
delete _player;
_player = NULL;
Map* _map = _player->GetMap();
_map->Remove(_player, true);
_player = NULL; // deleted in Remove call
///- Send the 'logout complete' packet to the client
WorldPacket data( SMSG_LOGOUT_COMPLETE, 0 );

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8181"
#define REVISION_NR "8182"
#endif // __REVISION_NR_H__