aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Corpse.cpp13
-rw-r--r--src/game/Creature.cpp6
-rw-r--r--src/game/DynamicObject.cpp5
-rw-r--r--src/game/GameObject.cpp4
-rw-r--r--src/game/Level1.cpp2
-rw-r--r--src/game/Level3.cpp2
-rw-r--r--src/game/Map.cpp46
-rw-r--r--src/game/Map.h12
-rw-r--r--src/game/MapInstanced.cpp25
-rw-r--r--src/game/MapInstanced.h2
-rw-r--r--src/game/MapManager.cpp4
-rw-r--r--src/game/MapManager.h2
-rw-r--r--src/game/MovementHandler.cpp9
-rw-r--r--src/game/Object.cpp24
-rw-r--r--src/game/Object.h29
-rw-r--r--src/game/ObjectAccessor.cpp2
-rw-r--r--src/game/ObjectGridLoader.cpp2
-rw-r--r--src/game/OutdoorPvPSI.cpp4
-rw-r--r--src/game/Pet.cpp6
-rw-r--r--src/game/Player.cpp45
-rw-r--r--src/game/Player.h2
-rw-r--r--src/game/Spell.cpp2
-rw-r--r--src/game/SpellEffects.cpp3
-rw-r--r--src/game/Transports.cpp14
-rw-r--r--src/game/Transports.h15
-rw-r--r--src/game/World.cpp6
-rw-r--r--src/game/WorldSession.cpp9
27 files changed, 151 insertions, 144 deletions
diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp
index 9fe54be1bec..ea8ad57c910 100644
--- a/src/game/Corpse.cpp
+++ b/src/game/Corpse.cpp
@@ -74,12 +74,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)",
@@ -209,8 +212,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);
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 44270574c2f..8a15cb88167 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -698,8 +698,8 @@ bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry,
return false;
}
- 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;
@@ -2055,7 +2055,7 @@ void Creature::CallAssistance()
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AnyAssistCreatureInRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_creature_searcher, *MapManager::Instance().GetMap(GetMapId(), this));
+ cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap());
}
if (!assistList.empty())
diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp
index dc2b05e8d6a..c910e343bd7 100644
--- a/src/game/DynamicObject.cpp
+++ b/src/game/DynamicObject.cpp
@@ -72,9 +72,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())
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index 56c5bd7529e..d1cf9187aac 100644
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -137,9 +137,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, uint32 ArtKit)
{
+ ASSERT(map);
Relocate(x,y,z,ang);
- SetMapId(map->GetId());
- SetInstanceId(map->GetInstanceId());
+ SetMap(map);
SetPhaseMask(phaseMask,false);
if(!IsPositionValid())
diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp
index 4bccd8c7ffd..8e234057f94 100644
--- a/src/game/Level1.cpp
+++ b/src/game/Level1.cpp
@@ -937,7 +937,7 @@ bool ChatHandler::HandleGonameCommand(const char* args)
}
else if(cMap->IsDungeon())
{
- Map* pMap = MapManager::Instance().GetMap(_player->GetMapId(),_player);
+ Map* pMap = _player->GetMap();
// we have to go to instance, and can go to player only if:
// 1) we are in his group (either as leader or as member)
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index eb3d462d68f..4dae4f79ef2 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -6206,7 +6206,7 @@ bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, obj_worker, *MapManager::Instance().GetMap(pl->GetMapId(), pl));
+ cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
return true;
}
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index 4d6c10107eb..93fd3e21e1b 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -127,14 +127,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;
}
@@ -187,11 +185,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)
, i_lock(true)
{
m_notifyTimer.SetInterval(IN_MILISECONDS/2);
@@ -364,6 +362,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*)
{
@@ -475,8 +480,7 @@ void Map::LoadGrid(float x, float y)
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 = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
@@ -504,6 +508,8 @@ Map::Add(T *obj)
return;
}
+ obj->SetMap(this);
+
Cell cell(p);
if(obj->isActiveObject())
EnsureGridLoadedAtEnter(cell);
@@ -800,8 +806,12 @@ void Map::Remove(Player *player, bool remove)
CellPair p = Trinity::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);
@@ -821,12 +831,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);
UpdateObjectVisibility(player,cell,p);
+ player->ResetMap();
if( remove )
DeleteFromWorld(player);
}
@@ -870,6 +884,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
@@ -1166,7 +1181,8 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool unloadAll)
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);
@@ -2327,8 +2343,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)
{
@@ -2663,8 +2679,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)
{
}
diff --git a/src/game/Map.h b/src/game/Map.h
index 0e0c3cdc1c8..ed918125328 100644
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -251,7 +251,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
@@ -306,6 +306,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;
@@ -487,6 +489,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
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;
@@ -553,7 +559,7 @@ enum InstanceResetMethod
class TRINITY_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);
@@ -578,7 +584,7 @@ class TRINITY_DLL_SPEC InstanceMap : public Map
class TRINITY_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 *);
diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp
index ee668e9080a..89be57275bb 100644
--- a/src/game/MapInstanced.cpp
+++ b/src/game/MapInstanced.cpp
@@ -116,15 +116,8 @@ void MapInstanced::UnloadAll()
- 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)
{
- if(obj->GetTypeId() == TYPEID_UNIT)
- {
- assert(obj->GetMapId() == GetId() && obj->GetInstanceId());
- return _FindMap(obj->GetInstanceId());
- }
-
- Player* player = (Player*)obj;
uint32 instanceId = player->GetInstanceId();
if(instanceId)
@@ -193,10 +186,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);
@@ -212,8 +205,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;
@@ -245,9 +238,7 @@ void MapInstanced::DestroyInstance(InstancedMaps::iterator &itr)
bool MapInstanced::CanEnter(Player *player)
{
- if(Map* map = GetInstance(player))
- return map->CanEnter(player);
-
- return false;
+ //assert(false);
+ return true;
}
diff --git a/src/game/MapInstanced.h b/src/game/MapInstanced.h
index 6338726fd47..83064bc074d 100644
--- a/src/game/MapInstanced.h
+++ b/src/game/MapInstanced.h
@@ -42,7 +42,7 @@ class TRINITY_DLL_DECL MapInstanced : public Map
void UnloadAll();
bool CanEnter(Player* player);
- 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);
diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp
index fb93ba2e2f3..79a81f2afa3 100644
--- a/src/game/MapManager.cpp
+++ b/src/game/MapManager.cpp
@@ -128,13 +128,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;
}
diff --git a/src/game/MapManager.h b/src/game/MapManager.h
index b07a26ed0f0..a9ce5d73998 100644
--- a/src/game/MapManager.h
+++ b/src/game/MapManager.h
@@ -39,7 +39,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;
diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
index 0890ade01f3..08c884c7c55 100644
--- a/src/game/MovementHandler.cpp
+++ b/src/game/MovementHandler.cpp
@@ -67,18 +67,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()))
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index 8274797fda4..afe477f3310 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -1048,8 +1048,8 @@ 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_map(NULL), m_zoneScript(NULL)
+ m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), m_currMap(NULL)
+ , m_zoneScript(NULL)
, m_isActive(false), IsTempWorldObject(false)
, m_name("")
{
@@ -1100,11 +1100,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;
}
@@ -1676,19 +1674,19 @@ void WorldObject::SendObjectDeSpawnAnim(uint64 guid)
SendMessageToSet(&data, true);
}
-Map* WorldObject::_getMap()
-{
- return m_map = MapManager::Instance().GetMap(GetMapId(), this);
-}
-
-Map* WorldObject::_findMap()
+void WorldObject::SetMap(Map * map)
{
- return m_map = MapManager::Instance().FindMap(GetMapId(), GetInstanceId());
+ 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()
diff --git a/src/game/Object.h b/src/game/Object.h
index 96bd1f12d46..2eba206ae64 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -371,7 +371,7 @@ class TRINITY_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(WorldObject *obj)
{
@@ -439,9 +439,7 @@ class TRINITY_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; m_map = NULL; }
uint32 GetMapId() const { return m_mapId; }
- void SetInstanceId(uint32 val) { m_InstanceId = val; m_map = NULL; }
uint32 GetInstanceId() const { return m_InstanceId; }
virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
@@ -470,8 +468,7 @@ class TRINITY_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;
@@ -520,7 +517,6 @@ class TRINITY_DLL_SPEC WorldObject : public Object
void SendObjectDeSpawnAnim(uint64 guid);
virtual void SaveRespawnTime() {}
-
void AddObjectToRemoveList();
// main visibility check function in normal case (ignore grey zone distance check)
@@ -532,8 +528,13 @@ class TRINITY_DLL_SPEC WorldObject : public Object
// Low Level Packets
void SendPlaySound(uint32 Sound, bool OnlySelf);
- Map * GetMap() const { return m_map ? m_map : const_cast<WorldObject*>(this)->_getMap(); }
- Map * FindMap() const { return m_map ? m_map : const_cast<WorldObject*>(this)->_findMap(); }
+ void SetMap(Map * map);
+ Map * GetMap() const { ASSERT(m_currMap); return m_currMap; }
+ Map * FindMap() const { 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;
void SetZoneScript();
@@ -569,14 +570,18 @@ class TRINITY_DLL_SPEC WorldObject : public Object
bool m_isActive;
ZoneScript *m_zoneScript;
+ //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
- Map *m_map;
-
- Map* _getMap();
- Map* _findMap();
float m_positionX;
float m_positionY;
diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp
index 76fc02a7c02..cd58d564106 100644
--- a/src/game/ObjectAccessor.cpp
+++ b/src/game/ObjectAccessor.cpp
@@ -350,8 +350,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);
diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp
index 368edce0a53..d08e3010a78 100644
--- a/src/game/ObjectGridLoader.cpp
+++ b/src/game/ObjectGridLoader.cpp
@@ -126,6 +126,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);
@@ -184,6 +185,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);
diff --git a/src/game/OutdoorPvPSI.cpp b/src/game/OutdoorPvPSI.cpp
index c1f47db49c7..33a304f2f6b 100644
--- a/src/game/OutdoorPvPSI.cpp
+++ b/src/game/OutdoorPvPSI.cpp
@@ -156,7 +156,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player *plr, uint32 spellId)
{
// he dropped it further, summon mound
GameObject * go = new GameObject;
- Map * map = MapManager::Instance().GetMap(plr->GetMapId(), plr);
+ Map * map = plr->GetMap();
if(!map)
{
delete go;
@@ -186,7 +186,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player *plr, uint32 spellId)
{
// he dropped it further, summon mound
GameObject * go = new GameObject;
- Map * map = MapManager::Instance().GetMap(plr->GetMapId(), plr);
+ Map * map = plr->GetMap();
if(!map)
{
delete go;
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index 4eb615887ca..8145b4a5f45 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -715,9 +715,6 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
}
uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_PET);
- sLog.outDebug("SetInstanceID()");
- SetInstanceId(creature->GetInstanceId());
-
sLog.outDebug("Create pet");
uint32 pet_number = objmgr.GeneratePetNumber();
if(!Create(guid, creature->GetMap(), creature->GetPhaseMask(), creature->GetEntry(), pet_number))
@@ -1764,8 +1761,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);
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 7ea38d6ba0d..004019ec1e6 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -548,7 +548,7 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
for (uint8 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_);
@@ -558,6 +558,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);
@@ -12442,7 +12444,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;
@@ -14242,7 +14248,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();
@@ -14551,10 +14558,10 @@ 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
- SetInstanceId(fields[47].GetFloat());
+ SetLocationInstanceId(fields[47].GetFloat());
_LoadGroup(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGROUP));
@@ -14628,7 +14635,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);
}
@@ -14641,7 +14648,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
@@ -14695,7 +14702,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
m_transport = *iter;
m_transport->AddPassenger(this);
- SetMapId(m_transport->GetMapId());
+ SetLocationMapId(m_transport->GetMapId());
break;
}
}
@@ -14730,18 +14737,18 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// This fixes the crash. But it is not needed for a new db
if(InstanceSave *pSave = GetInstanceSave(GetMapId()))
if(pSave->GetInstanceId() != GetInstanceId())
- SetInstanceId(pSave->GetInstanceId());
+ SetLocationInstanceId(pSave->GetInstanceId());
// NOW player must have valid map
// load the player's map here if it's not already loaded
- Map *map = GetMap();
+ Map *map = MapManager::Instance().CreateMap(GetMapId(), this);
if (!map)
{
AreaTrigger const* at = objmgr.GetGoBackTrigger(GetMapId());
if(at)
{
- SetMapId(at->target_mapId);
+ SetLocationMapId(at->target_mapId);
Relocate(at->target_X, at->target_Y, at->target_Z, GetOrientation());
sLog.outError("Player (guidlow %d) is teleported to gobacktrigger (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
}
@@ -14751,7 +14758,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
sLog.outError("Player (guidlow %d) is teleported to home (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
}
- map = GetMap();
+ map = MapManager::Instance().CreateMap(GetMapId(), this);
if(!map)
{
sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
@@ -14771,9 +14778,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
}
}
- // 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(map);
// 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()))
@@ -14952,15 +14957,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())
diff --git a/src/game/Player.h b/src/game/Player.h
index 101405fade5..14e3d730e3b 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -2020,7 +2020,7 @@ class TRINITY_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;
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index fcacdccbe18..050e233313b 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -5556,7 +5556,7 @@ SpellCastResult Spell::CheckItems()
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster));
+ cell_lock->Visit(cell_lock, object_checker, *m_caster->GetMap());
if(!ok)
return SPELL_FAILED_REQUIRES_SPELL_FOCUS;
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 2d49ac5a442..2cfb3dad26a 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -746,7 +746,7 @@ void Spell::EffectDummy(uint32 i)
//pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
pGameObj->SetSpellId(m_spellInfo->Id);
- MapManager::Instance().GetMap(unitTarget->GetMapId(), pGameObj)->Add(pGameObj);
+ unitTarget->GetMap()->Add(pGameObj);
WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8);
data << uint64(pGameObj->GetGUID());
@@ -4124,7 +4124,6 @@ void Spell::EffectSummonPet(uint32 i)
return;
OldSummon->GetMap()->Remove((Creature*)OldSummon,false);
- OldSummon->SetMapId(owner->GetMapId());
float px, py, pz;
owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp
index 11089f053d1..b0a588509f4 100644
--- a/src/game/Transports.cpp
+++ b/src/game/Transports.cpp
@@ -106,8 +106,9 @@ 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);
- //MapManager::Instance().GetMap(t->GetMapId())->Add<GameObject>((GameObject *)t);
+ t->SetMap(MapManager::Instance().CreateMap(mapid, t));
+
+ //t->GetMap()->Add<GameObject>((GameObject *)t);
++count;
} while(result->NextRow());
delete result;
@@ -142,8 +143,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())
@@ -439,7 +438,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::const_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)
{
diff --git a/src/game/Transports.h b/src/game/Transports.h
index d72fa3b2124..e05a6006971 100644
--- a/src/game/Transports.h
+++ b/src/game/Transports.h
@@ -56,24 +56,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);
diff --git a/src/game/World.cpp b/src/game/World.cpp
index 8750c5417bb..8dbc68520fa 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -2218,7 +2218,7 @@ void World::ScriptsProcess()
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(summoner->GetMapId(), summoner));
+ cell_lock->Visit(cell_lock, object_checker, *summoner->GetMap());
if ( !go )
{
@@ -2278,7 +2278,7 @@ void World::ScriptsProcess()
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(caster->GetMapId(), (Unit*)source));
+ cell_lock->Visit(cell_lock, object_checker, *caster->GetMap());
if (!door)
{
@@ -2334,7 +2334,7 @@ void World::ScriptsProcess()
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(caster->GetMapId(), (Unit*)source));
+ cell_lock->Visit(cell_lock, object_checker, *caster->GetMap());
if ( !door )
{
diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
index 2b905ea835f..c2191ed3e10 100644
--- a/src/game/WorldSession.cpp
+++ b/src/game/WorldSession.cpp
@@ -391,12 +391,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 _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 );