aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2018-03-03 14:29:53 +0100
committerShauren <shauren.trinity@gmail.com>2018-03-25 19:28:36 +0300
commit3743d042017d72435d2ff8135f66808988beaf9e (patch)
tree2100274d7035a2bb8a616bd971520f457e5d3846 /src
parent6d5e25ddd45dc78894daa000c0b122a44bbdbaf6 (diff)
Core/MMaps: Implemented loading phased tiles
Closes #16909
Diffstat (limited to 'src')
-rw-r--r--src/common/Collision/Management/MMapManager.cpp142
-rw-r--r--src/common/Collision/Management/MMapManager.h14
-rw-r--r--src/server/game/Maps/Map.cpp4
-rw-r--r--src/server/game/Movement/PathGenerator.cpp4
-rw-r--r--src/server/game/World/World.cpp4
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp25
-rw-r--r--src/tools/mmaps_generator/CMakeLists.txt1
-rw-r--r--src/tools/mmaps_generator/MapBuilder.cpp10
-rw-r--r--src/tools/mmaps_generator/PathCommon.h2
-rw-r--r--src/tools/mmaps_generator/PathGenerator.cpp62
-rw-r--r--src/tools/mmaps_generator/TerrainBuilder.cpp27
11 files changed, 221 insertions, 74 deletions
diff --git a/src/common/Collision/Management/MMapManager.cpp b/src/common/Collision/Management/MMapManager.cpp
index 11fe943bfc9..f581db5f093 100644
--- a/src/common/Collision/Management/MMapManager.cpp
+++ b/src/common/Collision/Management/MMapManager.cpp
@@ -19,13 +19,12 @@
#include "MMapManager.h"
#include "Errors.h"
#include "Log.h"
-#include "Config.h"
#include "MapDefines.h"
namespace MMAP
{
- static char const* const MAP_FILE_NAME_FORMAT = "%s/mmaps/%04i.mmap";
- static char const* const TILE_FILE_NAME_FORMAT = "%s/mmaps/%04i%02i%02i.mmtile";
+ static char const* const MAP_FILE_NAME_FORMAT = "%smmaps/%04i.mmap";
+ static char const* const TILE_FILE_NAME_FORMAT = "%smmaps/%04i%02i%02i.mmtile";
// ######################## MMapManager ########################
MMapManager::~MMapManager()
@@ -37,11 +36,16 @@ namespace MMAP
// if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost!
}
- void MMapManager::InitializeThreadUnsafe(const std::vector<uint32>& mapIds)
+ void MMapManager::InitializeThreadUnsafe(std::unordered_map<uint32, std::vector<uint32>> const& mapData)
{
+ childMapData = mapData;
// the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime
- for (uint32 const& mapId : mapIds)
- loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr));
+ for (std::pair<uint32 const, std::vector<uint32>> const& mapId : mapData)
+ {
+ loadedMMaps.insert(MMapDataSet::value_type(mapId.first, nullptr));
+ for (uint32 childMapId : mapId.second)
+ parentMapData[childMapId] = mapId.first;
+ }
thread_safe_environment = false;
}
@@ -56,7 +60,7 @@ namespace MMAP
return itr;
}
- bool MMapManager::loadMapData(uint32 mapId)
+ bool MMapManager::loadMapData(std::string const& basePath, uint32 mapId)
{
// we already have this map loaded?
MMapDataSet::iterator itr = loadedMMaps.find(mapId);
@@ -74,7 +78,7 @@ namespace MMAP
}
// load and init dtNavMesh - read parameters from file
- std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, sConfigMgr->GetStringDefault("DataDir", ".").c_str(), mapId);
+ std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, basePath.c_str(), mapId);
FILE* file = fopen(fileName.c_str(), "rb");
if (!file)
{
@@ -114,10 +118,25 @@ namespace MMAP
return uint32(x << 16 | y);
}
- bool MMapManager::loadMap(const std::string& /*basePath*/, uint32 mapId, int32 x, int32 y)
+ bool MMapManager::loadMap(std::string const& basePath, uint32 mapId, int32 x, int32 y)
+ {
+ if (!loadMapImpl(basePath, mapId, x, y))
+ return false;
+
+ bool success = true;
+ auto childMaps = childMapData.find(mapId);
+ if (childMaps != childMapData.end())
+ for (uint32 childMapId : childMaps->second)
+ if (!loadMapImpl(basePath, childMapId, x, y))
+ success = false;
+
+ return success;
+ }
+
+ bool MMapManager::loadMapImpl(std::string const& basePath, uint32 mapId, int32 x, int32 y)
{
// make sure the mmap is loaded and ready to load tiles
- if (!loadMapData(mapId))
+ if (!loadMapData(basePath, mapId))
return false;
// get this mmap data
@@ -130,10 +149,20 @@ namespace MMAP
return false;
// load this tile :: mmaps/MMMMXXYY.mmtile
- std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, sConfigMgr->GetStringDefault("DataDir", ".").c_str(), mapId, x, y);
+ std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, basePath.c_str(), mapId, x, y);
FILE* file = fopen(fileName.c_str(), "rb");
if (!file)
{
+ auto parentMapItr = parentMapData.find(mapId);
+ if (parentMapItr != parentMapData.end())
+ {
+ fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, basePath.c_str(), parentMapItr->second, x, y);
+ file = fopen(fileName.c_str(), "rb");
+ }
+ }
+
+ if (!file)
+ {
TC_LOG_DEBUG("maps", "MMAP:loadMap: Could not open mmtile file '%s'", fileName.c_str());
return false;
}
@@ -198,8 +227,57 @@ namespace MMAP
}
}
+ bool MMapManager::loadMapInstance(std::string const& basePath, uint32 mapId, uint32 instanceId)
+ {
+ if (!loadMapInstanceImpl(basePath, mapId, instanceId))
+ return false;
+
+ bool success = true;
+ auto childMaps = childMapData.find(mapId);
+ if (childMaps != childMapData.end())
+ for (uint32 childMapId : childMaps->second)
+ if (!loadMapInstanceImpl(basePath, childMapId, instanceId))
+ success = false;
+
+ return success;
+ }
+
+ bool MMapManager::loadMapInstanceImpl(std::string const& basePath, uint32 mapId, uint32 instanceId)
+ {
+ if (!loadMapData(basePath, mapId))
+ return false;
+
+ MMapData* mmap = loadedMMaps[mapId];
+ if (mmap->navMeshQueries.find(instanceId) != mmap->navMeshQueries.end())
+ return true;
+
+ // allocate mesh query
+ dtNavMeshQuery* query = dtAllocNavMeshQuery();
+ ASSERT(query);
+ if (dtStatusFailed(query->init(mmap->navMesh, 1024)))
+ {
+ dtFreeNavMeshQuery(query);
+ TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId);
+ return false;
+ }
+
+ TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId);
+ mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
+ return true;
+ }
+
bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y)
{
+ auto childMaps = childMapData.find(mapId);
+ if (childMaps != childMapData.end())
+ for (uint32 childMapId : childMaps->second)
+ unloadMapImpl(childMapId, x, y);
+
+ return unloadMapImpl(mapId, x, y);
+ }
+
+ bool MMapManager::unloadMapImpl(uint32 mapId, int32 x, int32 y)
+ {
// check if we have this map loaded
MMapDataSet::const_iterator itr = GetMMapData(mapId);
if (itr == loadedMMaps.end())
@@ -213,17 +291,16 @@ namespace MMAP
// check if we have this tile loaded
uint32 packedGridPos = packTileID(x, y);
- if (mmap->loadedTileRefs.find(packedGridPos) == mmap->loadedTileRefs.end())
+ auto tileRefItr = mmap->loadedTileRefs.find(packedGridPos);
+ if (tileRefItr == mmap->loadedTileRefs.end())
{
// file may not exist, therefore not loaded
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %04u%02i%02i.mmtile", mapId, x, y);
return false;
}
- dtTileRef tileRef = mmap->loadedTileRefs[packedGridPos];
-
// unload, and mark as non loaded
- if (dtStatusFailed(mmap->navMesh->removeTile(tileRef, nullptr, nullptr)))
+ if (dtStatusFailed(mmap->navMesh->removeTile(tileRefItr->second, nullptr, nullptr)))
{
// this is technically a memory leak
// if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used
@@ -233,7 +310,7 @@ namespace MMAP
}
else
{
- mmap->loadedTileRefs.erase(packedGridPos);
+ mmap->loadedTileRefs.erase(tileRefItr);
--loadedTiles;
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %04i[%02i, %02i] from %03i", mapId, x, y, mapId);
return true;
@@ -244,6 +321,16 @@ namespace MMAP
bool MMapManager::unloadMap(uint32 mapId)
{
+ auto childMaps = childMapData.find(mapId);
+ if (childMaps != childMapData.end())
+ for (uint32 childMapId : childMaps->second)
+ unloadMapImpl(childMapId);
+
+ return unloadMapImpl(mapId);
+ }
+
+ bool MMapManager::unloadMapImpl(uint32 mapId)
+ {
MMapDataSet::iterator itr = loadedMMaps.find(mapId);
if (itr == loadedMMaps.end() || !itr->second)
{
@@ -312,27 +399,14 @@ namespace MMAP
dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId)
{
- MMapDataSet::const_iterator itr = GetMMapData(mapId);
+ auto itr = GetMMapData(mapId);
if (itr == loadedMMaps.end())
return nullptr;
- MMapData* mmap = itr->second;
- if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
- {
- // allocate mesh query
- dtNavMeshQuery* query = dtAllocNavMeshQuery();
- ASSERT(query);
- if (dtStatusFailed(query->init(mmap->navMesh, 1024)))
- {
- dtFreeNavMeshQuery(query);
- TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId);
- return nullptr;
- }
-
- TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId);
- mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
- }
+ auto queryItr = itr->second->navMeshQueries.find(instanceId);
+ if (queryItr == itr->second->navMeshQueries.end())
+ return nullptr;
- return mmap->navMeshQueries[instanceId];
+ return queryItr->second;
}
}
diff --git a/src/common/Collision/Management/MMapManager.h b/src/common/Collision/Management/MMapManager.h
index 289475427b4..151813f9b2f 100644
--- a/src/common/Collision/Management/MMapManager.h
+++ b/src/common/Collision/Management/MMapManager.h
@@ -63,8 +63,9 @@ namespace MMAP
MMapManager() : loadedTiles(0), thread_safe_environment(true) {}
~MMapManager();
- void InitializeThreadUnsafe(const std::vector<uint32>& mapIds);
- bool loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y);
+ void InitializeThreadUnsafe(std::unordered_map<uint32, std::vector<uint32>> const& mapData);
+ bool loadMap(std::string const& basePath, uint32 mapId, int32 x, int32 y);
+ bool loadMapInstance(std::string const& basePath, uint32 mapId, uint32 instanceId);
bool unloadMap(uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId);
bool unloadMapInstance(uint32 mapId, uint32 instanceId);
@@ -76,13 +77,20 @@ namespace MMAP
uint32 getLoadedTilesCount() const { return loadedTiles; }
uint32 getLoadedMapsCount() const { return uint32(loadedMMaps.size()); }
private:
- bool loadMapData(uint32 mapId);
+ bool loadMapData(std::string const& basePath, uint32 mapId);
+ bool loadMapImpl(std::string const& basePath, uint32 mapId, int32 x, int32 y);
+ bool loadMapInstanceImpl(std::string const& basePath, uint32 mapId, uint32 instanceId);
+ bool unloadMapImpl(uint32 mapId, int32 x, int32 y);
+ bool unloadMapImpl(uint32 mapId);
uint32 packTileID(int32 x, int32 y);
MMapDataSet::const_iterator GetMMapData(uint32 mapId) const;
MMapDataSet loadedMMaps;
uint32 loadedTiles;
bool thread_safe_environment;
+
+ std::unordered_map<uint32, std::vector<uint32>> childMapData;
+ std::unordered_map<uint32, uint32> parentMapData;
};
}
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index c3e1aa744d3..0e161abdf98 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -144,7 +144,7 @@ void Map::LoadMMap(int gx, int gy)
if (!DisableMgr::IsPathfindingEnabled(GetId()))
return;
- bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy);
+ bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap(sWorld->GetDataPath(), GetId(), gx, gy);
if (mmapLoadResult)
TC_LOG_DEBUG("mmaps", "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy);
@@ -306,6 +306,8 @@ i_scriptLock(false), _defaultLight(DB2Manager::GetDefaultMapLight(id))
GetGuidSequenceGenerator<HighGuid::Transport>().Set(sObjectMgr->GetGenerator<HighGuid::Transport>().GetNextAfterMaxUsed());
+ MMAP::MMapFactory::createOrGetMMapManager()->loadMapInstance(sWorld->GetDataPath(), GetId(), i_InstanceId);
+
sScriptMgr->OnCreateMap(this);
}
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 6c9e1cd01d9..16cfe366f4e 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -39,8 +39,8 @@ PathGenerator::PathGenerator(const Unit* owner) :
TC_LOG_DEBUG("maps", "++ PathGenerator::PathGenerator for %s", _sourceUnit->GetGUID().ToString().c_str());
- uint32 mapId = _sourceUnit->GetMapId();
- if (DisableMgr::IsPathfindingEnabled(mapId))
+ uint32 mapId = _sourceUnit->GetPhaseShift().GetTerrainMapId(_sourceUnit->GetMapId(), _sourceUnit->GetPositionX(), _sourceUnit->GetPositionY());
+ if (DisableMgr::IsPathfindingEnabled(_sourceUnit->GetMapId()))
{
MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager();
_navMesh = mmap->GetNavMesh(mapId);
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 9e73cc8d532..760ec282bd7 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1575,11 +1575,9 @@ void World::SetInitialWorldSettings()
//Load weighted graph on taxi nodes path
sTaxiPathGraph.Initialize();
- std::vector<uint32> mapIds;
std::unordered_map<uint32, std::vector<uint32>> mapData;
for (MapEntry const* mapEntry : sMapStore)
{
- mapIds.push_back(mapEntry->ID);
mapData.emplace(std::piecewise_construct, std::forward_as_tuple(mapEntry->ID), std::forward_as_tuple());
if (mapEntry->ParentMapID != -1)
mapData[mapEntry->ParentMapID].push_back(mapEntry->ID);
@@ -1591,7 +1589,7 @@ void World::SetInitialWorldSettings()
vmmgr2->InitializeThreadUnsafe(mapData);
MMAP::MMapManager* mmmgr = MMAP::MMapFactory::createOrGetMMapManager();
- mmmgr->InitializeThreadUnsafe(mapIds);
+ mmmgr->InitializeThreadUnsafe(mapData);
TC_LOG_INFO("server.loading", "Loading SpellInfo store...");
sSpellMgr->LoadSpellInfoStore();
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index a40fb5f65a5..bd11a31515e 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -31,6 +31,7 @@
#include "Map.h"
#include "MMapFactory.h"
#include "PathGenerator.h"
+#include "PhasingHandler.h"
#include "Player.h"
#include "PointMovementGenerator.h"
#include "RBAC.h"
@@ -130,12 +131,16 @@ public:
int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS;
int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS;
+ float x, y, z;
+ player->GetPosition(x, y, z);
+
handler->PSendSysMessage("%04u%02i%02i.mmtile", player->GetMapId(), gx, gy);
handler->PSendSysMessage("gridloc [%i, %i]", gy, gx);
// calculate navmesh tile location
- dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId());
- dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(handler->GetSession()->GetPlayer()->GetMapId(), player->GetInstanceId());
+ uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMap(), x, y);
+ dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(terrainMapId);
+ dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(terrainMapId, player->GetInstanceId());
if (!navmesh || !navmeshquery)
{
handler->PSendSysMessage("NavMesh not loaded for current map.");
@@ -143,8 +148,6 @@ public:
}
float const* min = navmesh->getParams()->orig;
- float x, y, z;
- player->GetPosition(x, y, z);
float location[VERTEX_SIZE] = { y, z, x };
float extents[VERTEX_SIZE] = { 3.0f, 5.0f, 3.0f };
@@ -185,9 +188,10 @@ public:
static bool HandleMmapLoadedTilesCommand(ChatHandler* handler, char const* /*args*/)
{
- uint32 mapid = handler->GetSession()->GetPlayer()->GetMapId();
- dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(mapid);
- dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(mapid, handler->GetSession()->GetPlayer()->GetInstanceId());
+ Player* player = handler->GetSession()->GetPlayer();
+ uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMap(), player->GetPositionX(), player->GetPositionY());
+ dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(terrainMapId);
+ dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(terrainMapId, player->GetInstanceId());
if (!navmesh || !navmeshquery)
{
handler->PSendSysMessage("NavMesh not loaded for current map.");
@@ -210,14 +214,15 @@ public:
static bool HandleMmapStatsCommand(ChatHandler* handler, char const* /*args*/)
{
- uint32 mapId = handler->GetSession()->GetPlayer()->GetMapId();
+ Player* player = handler->GetSession()->GetPlayer();
+ uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMap(), player->GetPositionX(), player->GetPositionY());
handler->PSendSysMessage("mmap stats:");
- handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(mapId) ? "en" : "dis");
+ handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(player->GetMapId()) ? "en" : "dis");
MMAP::MMapManager* manager = MMAP::MMapFactory::createOrGetMMapManager();
handler->PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount());
- dtNavMesh const* navmesh = manager->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId());
+ dtNavMesh const* navmesh = manager->GetNavMesh(terrainMapId);
if (!navmesh)
{
handler->PSendSysMessage("NavMesh not loaded for current map.");
diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt
index 9dfb0cfdede..0f4f42de20b 100644
--- a/src/tools/mmaps_generator/CMakeLists.txt
+++ b/src/tools/mmaps_generator/CMakeLists.txt
@@ -23,6 +23,7 @@ target_link_libraries(mmaps_generator
trinity-core-interface
PUBLIC
common
+ extractor_common
Recast
Detour
zlib
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp
index 251df44dfa3..acc947096de 100644
--- a/src/tools/mmaps_generator/MapBuilder.cpp
+++ b/src/tools/mmaps_generator/MapBuilder.cpp
@@ -23,6 +23,8 @@
#include "MapTree.h"
#include "ModelInstance.h"
+#include "VMapFactory.h"
+#include "VMapManager2.h"
#include "DetourNavMeshBuilder.h"
#include "DetourNavMesh.h"
@@ -470,7 +472,12 @@ namespace MMAP
/**************************************************************************/
void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh)
{
- std::set<uint32>* tiles = getTileList(mapID);
+ // if map has a parent we use that to generate dtNavMeshParams - worldserver will load all missing tiles from that map
+ int32 navMeshParamsMapId = static_cast<VMapManager2*>(VMapFactory::createOrGetVMapManager())->getParentMapId(mapID);
+ if (navMeshParamsMapId == -1)
+ navMeshParamsMapId = mapID;
+
+ std::set<uint32>* tiles = getTileList(navMeshParamsMapId);
// old code for non-statically assigned bitmask sizes:
///*** calculate number of bits needed to store tiles & polys ***/
@@ -531,6 +538,7 @@ namespace MMAP
if (!file)
{
dtFreeNavMesh(navMesh);
+ navMesh = nullptr;
char message[1024];
sprintf(message, "[Map %04u] Failed to open %s for writing!\n", mapID, fileName);
perror(message);
diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h
index 333a55419ba..414407632d6 100644
--- a/src/tools/mmaps_generator/PathCommon.h
+++ b/src/tools/mmaps_generator/PathCommon.h
@@ -103,7 +103,7 @@ namespace MMAP
return LISTFILE_DIRECTORY_NOT_FOUND;
do
{
- if ((findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
+ if (strcmp(findFileInfo.cFileName, ".") != 0 && strcmp(findFileInfo.cFileName, "..") != 0)
fileList.push_back(std::string(findFileInfo.cFileName));
}
while (FindNextFile(hFind, &findFileInfo));
diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp
index b30e28623ae..035bddd9063 100644
--- a/src/tools/mmaps_generator/PathGenerator.cpp
+++ b/src/tools/mmaps_generator/PathGenerator.cpp
@@ -16,17 +16,29 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <boost/filesystem.hpp>
-
-#include "PathCommon.h"
+#include "Banner.h"
+#include "DB2FileLoader.h"
+#include "DB2FileSystemSource.h"
+#include "ExtractorDB2LoadInfo.h"
#include "MapBuilder.h"
+#include "PathCommon.h"
#include "Timer.h"
-#include "Banner.h"
+#include "VMapFactory.h"
+#include "VMapManager2.h"
+#include <boost/filesystem/operations.hpp>
+#include <unordered_map>
+#include <vector>
using namespace MMAP;
-bool checkDirectories(bool debugOutput)
+bool checkDirectories(bool debugOutput, std::vector<std::string>& dbcLocales)
{
+ if (getDirContents(dbcLocales, "dbc") == LISTFILE_DIRECTORY_NOT_FOUND || dbcLocales.empty())
+ {
+ printf("'dbc' directory is empty or does not exist\n");
+ return false;
+ }
+
std::vector<std::string> dirFiles;
if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty())
@@ -44,15 +56,24 @@ bool checkDirectories(bool debugOutput)
dirFiles.clear();
if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND)
- return boost::filesystem::create_directory("mmaps");
+ {
+ if (!boost::filesystem::create_directory("mmaps"))
+ {
+ printf("'mmaps' directory does not exist and failed to create it\n");
+ return false;
+ }
+ }
dirFiles.clear();
if (debugOutput)
{
if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND)
{
- printf("'meshes' directory does not exist (no place to put debugOutput files)\n");
- return false;
+ if (!boost::filesystem::create_directory("meshes"))
+ {
+ printf("'meshes' directory does not exist and failed to create it (no place to put debugOutput files)\n");
+ return false;
+ }
}
}
@@ -277,9 +298,30 @@ int main(int argc, char** argv)
return 0;
}
- if (!checkDirectories(debugOutput))
+ std::vector<std::string> dbcLocales;
+ if (!checkDirectories(debugOutput, dbcLocales))
return silent ? -3 : finish("Press ENTER to close...", -3);
+ DB2FileLoader mapDb2;
+ std::unordered_map<uint32, std::vector<uint32>> mapData;
+ {
+ DB2FileSystemSource mapSource((boost::filesystem::path("dbc") / dbcLocales[0] / "Map.db2").string());
+ if (!mapDb2.Load(&mapSource, MapLoadInfo::Instance()))
+ return silent ? -4 : finish("Failed to load Map.db2", -4);
+
+ for (uint32 x = 0; x < mapDb2.GetRecordCount(); ++x)
+ {
+ DB2Record record = mapDb2.GetRecord(x);
+
+ mapData.emplace(std::piecewise_construct, std::forward_as_tuple(record.GetId()), std::forward_as_tuple());
+ int16 parentMapId = int16(record.GetUInt16("ParentMapID"));
+ if (parentMapId != -1)
+ mapData[parentMapId].push_back(record.GetId());
+ }
+
+ static_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager())->InitializeThreadUnsafe(mapData);
+ }
+
MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps,
skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath);
@@ -293,6 +335,8 @@ int main(int argc, char** argv)
else
builder.buildAllMaps(threads);
+ VMAP::VMapFactory::clear();
+
if (!silent)
printf("Finished. MMAPS were built in %u ms!\n", GetMSTimeDiffToNow(start));
return 0;
diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp
index 430abe8e21b..ca4ae090423 100644
--- a/src/tools/mmaps_generator/TerrainBuilder.cpp
+++ b/src/tools/mmaps_generator/TerrainBuilder.cpp
@@ -17,12 +17,11 @@
*/
#include "TerrainBuilder.h"
-
#include "MapBuilder.h"
-
-#include "VMapManager2.h"
#include "MapTree.h"
#include "ModelInstance.h"
+#include "VMapFactory.h"
+#include "VMapManager2.h"
// ******************************************
// Map file format defines
@@ -138,6 +137,16 @@ namespace MMAP
FILE* mapFile = fopen(mapFileName, "rb");
if (!mapFile)
+ {
+ int32 parentMapId = static_cast<VMapManager2*>(VMapFactory::createOrGetVMapManager())->getParentMapId(mapID);
+ if (parentMapId != -1)
+ {
+ sprintf(mapFileName, "maps/%04d_%02u_%02u.map", parentMapId, tileY, tileX);
+ mapFile = fopen(mapFileName, "rb");
+ }
+ }
+
+ if (!mapFile)
return false;
map_fileheader fheader;
@@ -389,7 +398,6 @@ namespace MMAP
useTerrain = true;
useLiquid = true;
uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER;
- // FIXME: "warning: the address of ‘liquid_type’ will always evaluate as ‘true’"
// if there is no liquid, don't use liquid
if (!meshData.liquidVerts.size() || !ltriangles.size())
@@ -626,8 +634,8 @@ namespace MMAP
/**************************************************************************/
bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
{
- IVMapManager* vmapManager = new VMapManager2();
- int result = vmapManager->loadMap("vmaps", mapID, tileX, tileY);
+ VMapManager2* vmapManager = static_cast<VMapManager2*>(VMapFactory::createOrGetVMapManager());
+ int result = vmapManager->loadSingleMap(mapID, "vmaps", tileX, tileY);
bool retval = false;
do
@@ -636,7 +644,7 @@ namespace MMAP
break;
InstanceTreeMap instanceTrees;
- ((VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees);
+ vmapManager->getInstanceMapTree(instanceTrees);
if (!instanceTrees[mapID])
break;
@@ -664,7 +672,7 @@ namespace MMAP
worldModel->getGroupModels(groupModels);
// all M2s need to have triangle indices reversed
- bool isM2 = instance.name.find(".m2") != std::string::npos || instance.name.find(".M2") != std::string::npos;
+ bool isM2 = (instance.flags & MOD_M2) != 0;
// transform data
float scale = instance.iScale;
@@ -779,8 +787,7 @@ namespace MMAP
}
while (false);
- vmapManager->unloadMap(mapID, tileX, tileY);
- delete vmapManager;
+ vmapManager->unloadSingleMap(mapID, tileX, tileY);
return retval;
}