diff options
author | Shauren <shauren.trinity@gmail.com> | 2018-02-27 23:57:54 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2018-03-25 19:28:36 +0300 |
commit | be0f2c297c2209f2d12c1359a8f7933c1b89ec0d (patch) | |
tree | 13c4385012253cf017519b34daaa5fbce378ac90 | |
parent | bea7faa8f9d48894d836c7205b98e36126734d56 (diff) |
Core/Maps: Implemented loading swapped maps
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 148 | ||||
-rw-r--r-- | src/server/game/Maps/Map.h | 13 | ||||
-rw-r--r-- | src/server/game/Maps/MapManager.cpp | 56 | ||||
-rw-r--r-- | src/server/game/Maps/MapManager.h | 10 | ||||
-rw-r--r-- | src/server/game/Phasing/PhasingHandler.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Phasing/PhasingHandler.h | 1 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_go.cpp | 9 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_tele.cpp | 3 | ||||
-rw-r--r-- | src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp | 2 |
13 files changed, 184 insertions, 75 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 68d5024e959..ffe6349e161 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2132,7 +2132,7 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid, Gameo bool Player::IsUnderWater() const { return IsInWater() && - GetPositionZ() < (GetBaseMap()->GetWaterLevel(GetPositionX(), GetPositionY())-2); + GetPositionZ() < (GetBaseMap()->GetWaterLevel(GetPhaseShift(), GetPositionX(), GetPositionY()) - 2); } void Player::SetInWater(bool apply) @@ -6946,7 +6946,7 @@ uint32 Player::GetZoneIdFromDB(ObjectGuid guid) if (!sMapStore.LookupEntry(map)) return 0; - zone = sMapMgr->GetZoneId(PhaseShift(), map, posx, posy, posz); + zone = sMapMgr->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), map, posx, posy, posz); if (zone > 0) { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 737f1952348..dc8604fa2e8 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6252,7 +6252,7 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(WorldLocation const& lo uint32 MapId = location.GetMapId(); // search for zone associated closest graveyard - uint32 zoneId = sMapMgr->GetZoneId(PhaseShift(), MapId, x, y, z); + uint32 zoneId = sMapMgr->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), MapId, x, y, z); if (!zoneId) { diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 6ece7791b6e..c3e1aa744d3 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -85,6 +85,9 @@ Map::~Map() if (!m_scriptSchedule.empty()) sMapMgr->DecreaseScheduledScriptCount(m_scriptSchedule.size()); + if (m_parentMap == this) + delete m_childTerrainMaps; + MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(GetId(), i_InstanceId); } @@ -171,42 +174,65 @@ void Map::LoadVMap(int gx, int gy) void Map::LoadMap(int gx, int gy, bool reload) { - if (i_InstanceId != 0) + LoadMapImpl(this, gx, gy, reload); + for (Map* childBaseMap : *m_childTerrainMaps) + LoadMapImpl(childBaseMap, gx, gy, reload); +} + +void Map::LoadMapImpl(Map* map, int gx, int gy, bool reload) +{ + if (map->i_InstanceId != 0) { - if (GridMaps[gx][gy]) + if (map->GridMaps[gx][gy]) return; // load grid map for base map - if (!m_parentMap->GridMaps[gx][gy]) - m_parentMap->EnsureGridCreated(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - gx, (MAX_NUMBER_OF_GRIDS - 1) - gy)); + if (!map->m_parentMap->GridMaps[gx][gy]) + map->m_parentMap->EnsureGridCreated(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - gx, (MAX_NUMBER_OF_GRIDS - 1) - gy)); - ((MapInstanced*)(m_parentMap))->AddGridMapReference(GridCoord(gx, gy)); - GridMaps[gx][gy] = m_parentMap->GridMaps[gx][gy]; + map->m_parentMap->ToMapInstanced()->AddGridMapReference(GridCoord(gx, gy)); + map->GridMaps[gx][gy] = map->m_parentMap->GridMaps[gx][gy]; return; } - if (GridMaps[gx][gy] && !reload) + if (map->GridMaps[gx][gy] && !reload) return; //map already load, delete it before reloading (Is it necessary? Do we really need the ability the reload maps during runtime?) - if (GridMaps[gx][gy]) + if (map->GridMaps[gx][gy]) { - TC_LOG_DEBUG("maps", "Unloading previously loaded map %u before reloading.", GetId()); - sScriptMgr->OnUnloadGridMap(this, GridMaps[gx][gy], gx, gy); + TC_LOG_DEBUG("maps", "Unloading previously loaded map %u before reloading.", map->GetId()); + sScriptMgr->OnUnloadGridMap(map, map->GridMaps[gx][gy], gx, gy); - delete (GridMaps[gx][gy]); - GridMaps[gx][gy]=NULL; + delete map->GridMaps[gx][gy]; + map->GridMaps[gx][gy] = nullptr; } // map file name - std::string fileName = Trinity::StringFormat("%smaps/%04u_%02u_%02u.map", sWorld->GetDataPath().c_str(), GetId(), gx, gy); + std::string fileName = Trinity::StringFormat("%smaps/%04u_%02u_%02u.map", sWorld->GetDataPath().c_str(), map->GetId(), gx, gy); TC_LOG_DEBUG("maps", "Loading map %s", fileName.c_str()); // loading data - GridMaps[gx][gy] = new GridMap(); - if (!GridMaps[gx][gy]->loadData(fileName.c_str())) + map->GridMaps[gx][gy] = new GridMap(); + if (!map->GridMaps[gx][gy]->loadData(fileName.c_str())) TC_LOG_ERROR("maps", "Error loading map file: %s", fileName.c_str()); - sScriptMgr->OnLoadGridMap(this, GridMaps[gx][gy], gx, gy); + sScriptMgr->OnLoadGridMap(map, map->GridMaps[gx][gy], gx, gy); +} + +void Map::UnloadMap(Map* map, int gx, int gy) +{ + if (map->i_InstanceId == 0) + { + if (map->GridMaps[gx][gy]) + { + map->GridMaps[gx][gy]->unloadData(); + delete map->GridMaps[gx][gy]; + } + } + else + static_cast<MapInstanced*>(map->m_parentMap)->RemoveGridMapReference(GridCoord(gx, gy)); + + map->GridMaps[gx][gy] = nullptr; } void Map::LoadMapAndVMap(int gx, int gy) @@ -229,10 +255,10 @@ void Map::LoadAllCells() void Map::InitStateMachine() { - si_GridStates[GRID_STATE_INVALID] = new InvalidState; - si_GridStates[GRID_STATE_ACTIVE] = new ActiveState; - si_GridStates[GRID_STATE_IDLE] = new IdleState; - si_GridStates[GRID_STATE_REMOVAL] = new RemovalState; + si_GridStates[GRID_STATE_INVALID] = new InvalidState(); + si_GridStates[GRID_STATE_ACTIVE] = new ActiveState(); + si_GridStates[GRID_STATE_IDLE] = new IdleState(); + si_GridStates[GRID_STATE_REMOVAL] = new RemovalState(); } void Map::DeleteStateMachine() @@ -252,14 +278,24 @@ m_activeNonPlayersIter(m_activeNonPlayers.end()), _transportsUpdateIter(_transpo i_gridExpiry(expiry), i_scriptLock(false), _defaultLight(DB2Manager::GetDefaultMapLight(id)) { - m_parentMap = (_parent ? _parent : this); - for (unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) + if (_parent) { - for (unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j) + m_parentMap = _parent; + m_childTerrainMaps = m_parentMap->m_childTerrainMaps; + } + else + { + m_parentMap = this; + m_childTerrainMaps = new std::vector<Map*>(); + } + + for (uint32 x = 0; x < MAX_NUMBER_OF_GRIDS; ++x) + { + for (uint32 y = 0; y < MAX_NUMBER_OF_GRIDS; ++y) { //z code - GridMaps[idx][j] =NULL; - setNGrid(NULL, idx, j); + GridMaps[x][y] = nullptr; + setNGrid(nullptr, x, y); } } @@ -1782,20 +1818,16 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll) // delete grid map, but don't delete if it is from parent map (and thus only reference) //+++if (GridMaps[gx][gy]) don't check for GridMaps[gx][gy], we might have to unload vmaps { + for (Map* childBaseMap : *m_childTerrainMaps) + UnloadMap(childBaseMap, gx, gy); + + UnloadMap(this, gx, gy); + if (i_InstanceId == 0) { - if (GridMaps[gx][gy]) - { - GridMaps[gx][gy]->unloadData(); - delete GridMaps[gx][gy]; - } VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gx, gy); MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(GetId(), gx, gy); } - else - ((MapInstanced*)m_parentMap)->RemoveGridMapReference(GridCoord(gx, gy)); - - GridMaps[gx][gy] = NULL; } TC_LOG_DEBUG("maps", "Unloading grid[%u, %u] for map %u finished", x, y, GetId()); return true; @@ -1881,6 +1913,7 @@ GridMap::GridMap() _liquidEntry = nullptr; _liquidFlags = nullptr; _liquidMap = nullptr; + _fileExists = false; } GridMap::~GridMap() @@ -1899,6 +1932,7 @@ bool GridMap::loadData(const char* filename) if (!in) return true; + _fileExists = true; if (fread(&header, sizeof(header), 1, in) != 1) { fclose(in); @@ -1957,6 +1991,7 @@ void GridMap::unloadData() _liquidFlags = nullptr; _liquidMap = nullptr; _gridGetHeight = &GridMap::getHeightFromFlat; + _fileExists = false; } bool GridMap::loadAreaData(FILE* in, uint32 offset, uint32 /*size*/) @@ -2500,6 +2535,26 @@ inline GridMap* Map::GetGrid(float x, float y) return GridMaps[gx][gy]; } +GridMap* Map::GetGrid(uint32 mapId, float x, float y) +{ + if (GetId() == mapId) + return GetGrid(x, y); + + // half opt method + int gx = (int)(CENTER_GRID_ID - x / SIZE_OF_GRIDS); //grid x + int gy = (int)(CENTER_GRID_ID - y / SIZE_OF_GRIDS); //grid y + + // ensure GridMap is loaded + EnsureGridCreated(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - gx, (MAX_NUMBER_OF_GRIDS - 1) - gy)); + + GridMap* grid = GridMaps[gx][gy]; + auto childMapItr = std::find_if(m_childTerrainMaps->begin(), m_childTerrainMaps->end(), [mapId](Map* childTerrainMap) {return childTerrainMap->GetId() == mapId; }); + if (childMapItr != m_childTerrainMaps->end() && (*childMapItr)->GridMaps[gx][gy]->fileExists()) + grid = (*childMapItr)->GridMaps[gx][gy]; + + return grid; +} + float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/) const { if (const_cast<Map*>(this)->GetGrid(x, y)) @@ -2522,7 +2577,8 @@ float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float { // find raw .map surface under Z coordinates float mapHeight = VMAP_INVALID_HEIGHT_VALUE; - if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) + uint32 terrainMapId = phaseShift.GetTerrainMapId(GetId(), x, y); + if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(terrainMapId, x, y)) { float gridHeight = gmap->getHeight(x, y); // look from a bit higher pos to find the floor, ignore under surface case @@ -2535,7 +2591,7 @@ float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float { VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); if (vmgr->isHeightCalcEnabled()) - vmapHeight = vmgr->getHeight(phaseShift.GetTerrainMapId(GetId(), x, y), x, y, z + 2.0f, maxSearchDist); // look from a bit higher pos to find the floor + vmapHeight = vmgr->getHeight(terrainMapId, x, y, z + 2.0f, maxSearchDist); // look from a bit higher pos to find the floor } // mapHeight set for any above raw ground Z or <= INVALID_HEIGHT @@ -2614,11 +2670,12 @@ bool Map::IsOutdoors(PhaseShift const& phaseShift, float x, float y, float z) co bool Map::GetAreaInfo(PhaseShift const& phaseShift, float x, float y, float z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const { float vmap_z = z; + uint32 terrainMapId = phaseShift.GetTerrainMapId(GetId(), x, y); VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); - if (vmgr->getAreaInfo(phaseShift.GetTerrainMapId(GetId(), x, y), x, y, vmap_z, flags, adtId, rootId, groupId)) + if (vmgr->getAreaInfo(terrainMapId, x, y, vmap_z, flags, adtId, rootId, groupId)) { // check if there's terrain between player height and object height - if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) + if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(terrainMapId, x, y)) { float _mapheight = gmap->getHeight(x, y); // z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice... @@ -2652,7 +2709,7 @@ uint32 Map::GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, b if (!areaId) { - if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) + if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(phaseShift.GetTerrainMapId(GetId(), x, y), x, y)) areaId = gmap->getArea(x, y); // this used while not all *.map files generated (instances) @@ -2693,9 +2750,9 @@ void Map::GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& zoneid = area->ParentAreaID; } -uint8 Map::GetTerrainType(float x, float y) const +uint8 Map::GetTerrainType(PhaseShift const& phaseShift, float x, float y) const { - if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) + if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(phaseShift.GetTerrainMapId(GetId(), x, y), x, y)) return gmap->getTerrainType(x, y); else return 0; @@ -2708,7 +2765,8 @@ ZLiquidStatus Map::getLiquidStatus(PhaseShift const& phaseShift, float x, float float liquid_level = INVALID_HEIGHT; float ground_level = INVALID_HEIGHT; uint32 liquid_type = 0; - if (vmgr->GetLiquidLevel(phaseShift.GetTerrainMapId(GetId(), x, y), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type)) + uint32 terrainMapId = phaseShift.GetTerrainMapId(GetId(), x, y); + if (vmgr->GetLiquidLevel(terrainMapId, x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type)) { TC_LOG_DEBUG("maps", "getLiquidStatus(): vmap liquid level: %f ground: %f type: %u", liquid_level, ground_level, liquid_type); // Check water level and ground level @@ -2765,7 +2823,7 @@ ZLiquidStatus Map::getLiquidStatus(PhaseShift const& phaseShift, float x, float } } - if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) + if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(terrainMapId, x, y)) { LiquidData map_data; ZLiquidStatus map_result = gmap->getLiquidStatus(x, y, z, ReqLiquidType, &map_data); @@ -2786,9 +2844,9 @@ ZLiquidStatus Map::getLiquidStatus(PhaseShift const& phaseShift, float x, float return result; } -float Map::GetWaterLevel(float x, float y) const +float Map::GetWaterLevel(PhaseShift const& phaseShift, float x, float y) const { - if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) + if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(phaseShift.GetTerrainMapId(GetId(), x, y), x, y)) return gmap->getLiquidLevel(x, y); else return 0; diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 065efc203ad..b2a0cb91551 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -198,7 +198,7 @@ class TC_GAME_API GridMap uint8 _liquidOffY; uint8 _liquidWidth; uint8 _liquidHeight; - + bool _fileExists; bool loadAreaData(FILE* in, uint32 offset, uint32 size); bool loadHeightData(FILE* in, uint32 offset, uint32 size); @@ -224,6 +224,7 @@ public: float getLiquidLevel(float x, float y) const; uint8 getTerrainType(float x, float y) const; ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0); + bool fileExists() const { return _fileExists; } }; #pragma pack(push, 1) @@ -330,6 +331,8 @@ class TC_GAME_API Map : public GridRefManager<NGridType> static void DeleteStateMachine(); Map const* GetParent() const { return m_parentMap; } + void AddChildTerrainMap(Map* map) { m_childTerrainMaps->push_back(map); } + void UnlinkAllChildTerrainMaps() { m_childTerrainMaps->clear(); } // 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 @@ -346,8 +349,8 @@ class TC_GAME_API Map : public GridRefManager<NGridType> bool IsOutdoors(PhaseShift const& phaseShift, float x, float y, float z) const; - uint8 GetTerrainType(float x, float y) const; - float GetWaterLevel(float x, float y) const; + uint8 GetTerrainType(PhaseShift const& phaseShift, float x, float y) const; + float GetWaterLevel(PhaseShift const& phaseShift, float x, float y) const; bool IsInWater(PhaseShift const& phaseShift, float x, float y, float z, LiquidData* data = nullptr) const; bool IsUnderWater(PhaseShift const& phaseShift, float x, float y, float z) const; @@ -571,8 +574,11 @@ class TC_GAME_API Map : public GridRefManager<NGridType> void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); void LoadMap(int gx, int gy, bool reload = false); + static void LoadMapImpl(Map* map, int gx, int gy, bool reload); + static void UnloadMap(Map* map, int gx, int gy); void LoadMMap(int gx, int gy); GridMap* GetGrid(float x, float y); + GridMap* GetGrid(uint32 mapId, float x, float y); void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; } @@ -672,6 +678,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> //used for fast base_map (e.g. MapInstanced class object) search for //InstanceMaps and BattlegroundMaps... Map* m_parentMap; + std::vector<Map*>* m_childTerrainMaps; NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; GridMap* GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index d380e1be018..0b6bec91781 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -55,10 +55,15 @@ void MapManager::Initialize() m_updater.activate(num_threads); } +void MapManager::InitializeParentMapData(std::unordered_map<uint32, std::vector<uint32>> const& mapData) +{ + _parentMapData = mapData; +} + void MapManager::InitializeVisibilityDistanceInfo() { - for (MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) - (*iter).second->InitVisibilityDistance(); + for (auto iter = i_maps.begin(); iter != i_maps.end(); ++iter) + iter->second->InitVisibilityDistance(); } MapManager* MapManager::instance() @@ -71,29 +76,46 @@ Map* MapManager::CreateBaseMap(uint32 id) { Map* map = FindBaseMap(id); - if (map == NULL) + if (!map) { - std::lock_guard<std::mutex> lock(_mapsLock); - - MapEntry const* entry = sMapStore.LookupEntry(id); - ASSERT(entry); - - if (entry->Instanceable()) - map = new MapInstanced(id, i_gridCleanUpDelay); - else + MapEntry const* entry = sMapStore.AssertEntry(id); + if (entry->ParentMapID != -1) { - map = new Map(id, i_gridCleanUpDelay, 0, DIFFICULTY_NONE); - map->LoadRespawnTimes(); - map->LoadCorpseData(); + CreateBaseMap(entry->ParentMapID); + + // must have been created by parent map + map = FindBaseMap(id); + return ASSERT_NOTNULL(map); } - i_maps[id] = map; + std::lock_guard<std::mutex> lock(_mapsLock); + map = CreateBaseMap_i(entry); } ASSERT(map); return map; } +Map* MapManager::CreateBaseMap_i(MapEntry const* mapEntry) +{ + Map* map; + if (mapEntry->Instanceable()) + map = new MapInstanced(mapEntry->ID, i_gridCleanUpDelay); + else + { + map = new Map(mapEntry->ID, i_gridCleanUpDelay, 0, DIFFICULTY_NONE); + map->LoadRespawnTimes(); + map->LoadCorpseData(); + } + + i_maps[mapEntry->ID] = map; + + for (uint32 childMapId : _parentMapData[mapEntry->ID]) + map->AddChildTerrainMap(CreateBaseMap_i(sMapStore.AssertEntry(childMapId))); + + return map; +} + Map* MapManager::FindBaseNonInstanceMap(uint32 mapId) const { Map* map = FindBaseMap(mapId); @@ -257,6 +279,10 @@ bool MapManager::IsValidMAP(uint32 mapid, bool startUp) void MapManager::UnloadAll() { + // first unlink child maps + for (auto iter = i_maps.begin(); iter != i_maps.end(); ++iter) + iter->second->UnlinkAllChildTerrainMaps(); + for (MapMapType::iterator iter = i_maps.begin(); iter != i_maps.end();) { iter->second->UnloadAll(); diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index 892756db0d4..a8c4007118e 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -56,6 +56,7 @@ class TC_GAME_API MapManager } void Initialize(void); + void InitializeParentMapData(std::unordered_map<uint32, std::vector<uint32>> const& mapData); void Update(uint32); void SetGridCleanUpDelay(uint32 t) @@ -145,8 +146,10 @@ class TC_GAME_API MapManager return (iter == i_maps.end() ? NULL : iter->second); } - MapManager(const MapManager &); - MapManager& operator=(const MapManager &); + Map* CreateBaseMap_i(MapEntry const* mapEntry); + + MapManager(MapManager const&) = delete; + MapManager& operator=(MapManager const&) = delete; std::mutex _mapsLock; uint32 i_gridCleanUpDelay; @@ -159,6 +162,9 @@ class TC_GAME_API MapManager // atomic op counter for active scripts amount std::atomic<std::size_t> _scheduledScripts; + + // parent map links + std::unordered_map<uint32, std::vector<uint32>> _parentMapData; }; template<typename Worker> diff --git a/src/server/game/Phasing/PhasingHandler.cpp b/src/server/game/Phasing/PhasingHandler.cpp index 08ed3f729b0..44f0a9ff753 100644 --- a/src/server/game/Phasing/PhasingHandler.cpp +++ b/src/server/game/Phasing/PhasingHandler.cpp @@ -31,6 +31,8 @@ namespace { +PhaseShift const Empty; + inline PhaseFlags GetPhaseFlags(uint32 phaseId) { if (PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId)) @@ -420,6 +422,11 @@ void PhasingHandler::FillPartyMemberPhase(WorldPackets::Party::PartyMemberPhaseS [](PhaseShift::PhaseRef const& phase) -> WorldPackets::Party::PartyMemberPhase { return { phase.Flags.AsUnderlyingType(), phase.Id }; }); } +PhaseShift const& PhasingHandler::GetEmptyPhaseShift() +{ + return Empty; +} + void PhasingHandler::InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId) { phaseShift.ClearPhases(); diff --git a/src/server/game/Phasing/PhasingHandler.h b/src/server/game/Phasing/PhasingHandler.h index e759f2e68e1..9ee408ad26c 100644 --- a/src/server/game/Phasing/PhasingHandler.h +++ b/src/server/game/Phasing/PhasingHandler.h @@ -55,6 +55,7 @@ public: static void SendToPlayer(Player const* player); static void FillPartyMemberPhase(WorldPackets::Party::PartyMemberPhaseStates* partyMemberPhases, PhaseShift const& phaseShift); + static PhaseShift const& GetEmptyPhaseShift(); static void InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId); static void InitDbVisibleMapId(PhaseShift& phaseShift, int32 visibleMapId); static bool InDbPhaseShift(WorldObject const* object, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 125e9036e64..9e73cc8d532 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1585,6 +1585,8 @@ void World::SetInitialWorldSettings() mapData[mapEntry->ParentMapID].push_back(mapEntry->ID); } + sMapMgr->InitializeParentMapData(mapData); + if (VMAP::VMapManager2* vmmgr2 = dynamic_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager())) vmmgr2->InitializeThreadUnsafe(mapData); diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 09a31c885b7..cbd594f6682 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -29,6 +29,7 @@ EndScriptData */ #include "MapManager.h" #include "MotionMaster.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "Player.h" #include "RBAC.h" #include "SupportMgr.h" @@ -247,7 +248,7 @@ public: player->SaveRecallPosition(); Map const* map = sMapMgr->CreateBaseMap(mapId); - float z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + float z = std::max(map->GetStaticHeight(PhasingHandler::GetEmptyPhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(PhasingHandler::GetEmptyPhaseShift(), x, y)); player->TeleportTo(mapId, x, y, z, player->GetOrientation()); return true; @@ -369,7 +370,7 @@ public: player->SaveRecallPosition(); Map const* map = sMapMgr->CreateBaseMap(mapId); - z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + z = std::max(map->GetStaticHeight(PhasingHandler::GetEmptyPhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(PhasingHandler::GetEmptyPhaseShift(), x, y)); player->TeleportTo(mapId, x, y, z, 0.0f); return true; @@ -532,7 +533,7 @@ public: else player->SaveRecallPosition(); - float z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + float z = std::max(map->GetStaticHeight(PhasingHandler::GetEmptyPhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(PhasingHandler::GetEmptyPhaseShift(), x, y)); player->TeleportTo(zoneEntry->ContinentID, x, y, z, player->GetOrientation()); return true; @@ -580,7 +581,7 @@ public: return false; } Map const* map = sMapMgr->CreateBaseMap(mapId); - z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + z = std::max(map->GetStaticHeight(PhasingHandler::GetEmptyPhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(PhasingHandler::GetEmptyPhaseShift(), x, y)); } // stop flight if need diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index 79113971fe4..658a0ed446b 100644 --- a/src/server/scripts/Commands/cs_tele.cpp +++ b/src/server/scripts/Commands/cs_tele.cpp @@ -31,6 +31,7 @@ EndScriptData */ #include "MapManager.h" #include "MotionMaster.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "Player.h" #include "RBAC.h" #include "WorldSession.h" @@ -207,7 +208,7 @@ public: SQLTransaction dummy; Player::SavePositionInDB(WorldLocation(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation), - sMapMgr->GetZoneId(PhaseShift(), tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid, dummy); + sMapMgr->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid, dummy); } return true; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp index 1bfd96f0e35..7154bd11a9d 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp @@ -272,7 +272,7 @@ public: Position pos = me->GetRandomNearPosition(10.0f); //normalize Z-level if we can, if rift is not at ground level. - pos.m_positionZ = std::max(me->GetMap()->GetHeight(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); + pos.m_positionZ = std::max(me->GetMap()->GetHeight(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY)); if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000)) return summon; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp index 64c8bb0db1d..2f6b624bc08 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp @@ -309,7 +309,7 @@ public: Position pos = me->GetRandomNearPosition(10.0f); //normalize Z-level if we can, if rift is not at ground level. - pos.m_positionZ = std::max(me->GetMap()->GetHeight(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); + pos.m_positionZ = std::max(me->GetMap()->GetHeight(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY)); if (Unit* Summon = DoSummon(creature_entry, pos, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT)) if (Unit* temp = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_MEDIVH))) |