diff options
-rw-r--r-- | sql/mangos_spell_check.sql | 3 | ||||
-rw-r--r-- | src/game/Corpse.cpp | 13 | ||||
-rw-r--r-- | src/game/Creature.cpp | 6 | ||||
-rw-r--r-- | src/game/DynamicObject.cpp | 5 | ||||
-rw-r--r-- | src/game/GameObject.cpp | 4 | ||||
-rw-r--r-- | src/game/Level1.cpp | 2 | ||||
-rw-r--r-- | src/game/Level3.cpp | 2 | ||||
-rw-r--r-- | src/game/Map.cpp | 46 | ||||
-rw-r--r-- | src/game/Map.h | 12 | ||||
-rw-r--r-- | src/game/MapInstanced.cpp | 25 | ||||
-rw-r--r-- | src/game/MapInstanced.h | 2 | ||||
-rw-r--r-- | src/game/MapManager.cpp | 4 | ||||
-rw-r--r-- | src/game/MapManager.h | 2 | ||||
-rw-r--r-- | src/game/MovementHandler.cpp | 9 | ||||
-rw-r--r-- | src/game/Object.cpp | 24 | ||||
-rw-r--r-- | src/game/Object.h | 29 | ||||
-rw-r--r-- | src/game/ObjectAccessor.cpp | 2 | ||||
-rw-r--r-- | src/game/ObjectGridLoader.cpp | 2 | ||||
-rw-r--r-- | src/game/OutdoorPvPSI.cpp | 4 | ||||
-rw-r--r-- | src/game/Pet.cpp | 6 | ||||
-rw-r--r-- | src/game/Player.cpp | 45 | ||||
-rw-r--r-- | src/game/Player.h | 2 | ||||
-rw-r--r-- | src/game/Spell.cpp | 2 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 3 | ||||
-rw-r--r-- | src/game/Transports.cpp | 14 | ||||
-rw-r--r-- | src/game/Transports.h | 15 | ||||
-rw-r--r-- | src/game/World.cpp | 6 | ||||
-rw-r--r-- | src/game/WorldSession.cpp | 9 |
28 files changed, 151 insertions, 147 deletions
diff --git a/sql/mangos_spell_check.sql b/sql/mangos_spell_check.sql index e9729c0e09e..23d0134d4f3 100644 --- a/sql/mangos_spell_check.sql +++ b/sql/mangos_spell_check.sql @@ -111,9 +111,6 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas (28006, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Arcane Cloaking', 'Spell::EffectDummy'), (28884, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'), (29294,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Naxxramas Entry Flag Effect DND', 'Spell::EffectDummy'), -(28730, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Arcane Torrent', 'Spell::EffectDummy'), -(28733,-1, -1, -1, -1, -1, -1, 30, -1, 0,'Arcane Torrent', 'Spell::EffectDummy'), -(28734,-1, -1, -1, -1, -1, -1, -1, 4,-1,'Mana Tap', 'Spell::EffectDummy'), (29200, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Purify Helboar Meat', 'Spell::EffectDummy'), (29277,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Summon Purified Helboar Meat', 'Spell::EffectDummy'), (29278,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Summon Toxic Helboar Meat', 'Spell::EffectDummy'), 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 ); |