Tools: Modified output files of all extractors to use 4 characters for map id and changed name format of map files to include a separator between values '_' that makes tokenization possible

* This fixes generating mmaps for maps with id >= 1000
* Fixed a crash happening when unloading last phased mmap tile
* Removed remaining references to libmpq in CMakeLists

Reextracting maps/vmaps/mmaps IS REQUIRED after this commit
This commit is contained in:
Shauren
2015-05-07 00:07:44 +02:00
parent f432821da6
commit ed75b0649a
12 changed files with 176 additions and 178 deletions

View File

@@ -32,10 +32,10 @@ endif()
if(SERVERS OR TOOLS)
add_subdirectory(g3dlite)
add_subdirectory(recastnavigation)
add_subdirectory(cppformat)
endif()
if(SERVERS)
add_subdirectory(cppformat)
add_subdirectory(gsoap)
add_subdirectory(zmqpp)
endif()

View File

@@ -24,6 +24,9 @@
namespace MMAP
{
static char const* const MAP_FILE_NAME_FORMAT = "mmaps/%04i.mmap";
static char const* const TILE_FILE_NAME_FORMAT = "mmaps/%04i%02i%02i.mmtile";
// ######################## MMapManager ########################
MMapManager::~MMapManager()
{
@@ -41,15 +44,11 @@ namespace MMAP
return true;
// load and init dtNavMesh - read parameters from file
uint32 pathLen = uint32(sWorld->GetDataPath().length() + strlen("mmaps/%03i.mmap") + 1);
char *fileName = new char[pathLen];
snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i.mmap").c_str(), mapId);
FILE* file = fopen(fileName, "rb");
std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, mapId);
FILE* file = fopen(fileName.c_str(), "rb");
if (!file)
{
TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not open mmap file '%s'", fileName);
delete [] fileName;
TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not open mmap file '%s'", fileName.c_str());
return false;
}
@@ -58,8 +57,7 @@ namespace MMAP
fclose(file);
if (count != 1)
{
TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName);
delete [] fileName;
TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName.c_str());
return false;
}
@@ -68,14 +66,11 @@ namespace MMAP
if (dtStatusFailed(mesh->init(&params)))
{
dtFreeNavMesh(mesh);
TC_LOG_ERROR("maps", "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %03u from file %s", mapId, fileName);
delete [] fileName;
TC_LOG_ERROR("maps", "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %04u from file %s", mapId, fileName.c_str());
return false;
}
delete [] fileName;
TC_LOG_DEBUG("maps", "MMAP:loadMapData: Loaded %03i.mmap", mapId);
TC_LOG_DEBUG("maps", "MMAP:loadMapData: Loaded %04i.mmap", mapId);
// store inside our map list
MMapData* mmap_data = new MMapData(mesh, mapId);
@@ -104,33 +99,27 @@ namespace MMAP
if (mmap->loadedTileRefs.find(packedGridPos) != mmap->loadedTileRefs.end())
return false;
// load this tile :: mmaps/MMMXXYY.mmtile
uint32 pathLen = uint32(sWorld->GetDataPath().length() + strlen("mmaps/%03i%02i%02i.mmtile") + 1);
char *fileName = new char[pathLen];
snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i%02i%02i.mmtile").c_str(), mapId, x, y);
FILE* file = fopen(fileName, "rb");
// load this tile :: mmaps/MMMMXXYY.mmtile
std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, mapId, x, y);
FILE* file = fopen(fileName.c_str(), "rb");
if (!file)
{
TC_LOG_DEBUG("maps", "MMAP:loadMap: Could not open mmtile file '%s'", fileName);
delete [] fileName;
TC_LOG_DEBUG("maps", "MMAP:loadMap: Could not open mmtile file '%s'", fileName.c_str());
return false;
}
delete [] fileName;
// read header
MmapTileHeader fileHeader;
if (fread(&fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || fileHeader.mmapMagic != MMAP_MAGIC)
{
TC_LOG_ERROR("maps", "MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, x, y);
TC_LOG_ERROR("maps", "MMAP:loadMap: Bad header in mmap %04u%02i%02i.mmtile", mapId, x, y);
fclose(file);
return false;
}
if (fileHeader.mmapVersion != MMAP_VERSION)
{
TC_LOG_ERROR("maps", "MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i",
TC_LOG_ERROR("maps", "MMAP:loadMap: %04u%02i%02i.mmtile was built with generator v%i, expected v%i",
mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION);
fclose(file);
return false;
@@ -142,7 +131,7 @@ namespace MMAP
size_t result = fread(data, fileHeader.size, 1, file);
if (!result)
{
TC_LOG_ERROR("maps", "MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, x, y);
TC_LOG_ERROR("maps", "MMAP:loadMap: Bad header or data in mmap %04u%02i%02i.mmtile", mapId, x, y);
fclose(file);
return false;
}
@@ -157,14 +146,14 @@ namespace MMAP
{
mmap->loadedTileRefs.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
++loadedTiles;
TC_LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile %03i[%02i, %02i] into %03i[%02i, %02i]", mapId, x, y, mapId, header->x, header->y);
TC_LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile %04i[%02i, %02i] into %04i[%02i, %02i]", mapId, x, y, mapId, header->x, header->y);
LoadPhaseTiles(mapId, x, y);
return true;
}
TC_LOG_ERROR("maps", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y);
TC_LOG_ERROR("maps", "MMAP:loadMap: Could not load %04u%02i%02i.mmtile into navmesh", mapId, x, y);
dtFree(data);
return false;
}
@@ -172,34 +161,28 @@ namespace MMAP
PhasedTile* MMapManager::LoadTile(uint32 mapId, int32 x, int32 y)
{
// load this tile :: mmaps/MMMXXYY.mmtile
uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i%02i%02i.mmtile") + 1;
char *fileName = new char[pathLen];
snprintf(fileName, pathLen, (sWorld->GetDataPath() + "mmaps/%03i%02i%02i.mmtile").c_str(), mapId, x, y);
FILE* file = fopen(fileName, "rb");
std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, mapId, x, y);
FILE* file = fopen(fileName.c_str(), "rb");
if (!file)
{
// Not all tiles have phased versions, don't flood this msg
//TC_LOG_DEBUG("phase", "MMAP:LoadTile: Could not open mmtile file '%s'", fileName);
delete[] fileName;
return NULL;
}
delete[] fileName;
PhasedTile* pTile = new PhasedTile();
// read header
if (fread(&pTile->fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || pTile->fileHeader.mmapMagic != MMAP_MAGIC)
{
TC_LOG_ERROR("phase", "MMAP:LoadTile: Bad header in mmap %03u%02i%02i.mmtile", mapId, x, y);
TC_LOG_ERROR("phase", "MMAP:LoadTile: Bad header in mmap %04u%02i%02i.mmtile", mapId, x, y);
fclose(file);
return NULL;
}
if (pTile->fileHeader.mmapVersion != MMAP_VERSION)
{
TC_LOG_ERROR("phase", "MMAP:LoadTile: %03u%02i%02i.mmtile was built with generator v%i, expected v%i",
TC_LOG_ERROR("phase", "MMAP:LoadTile: %04u%02i%02i.mmtile was built with generator v%i, expected v%i",
mapId, x, y, pTile->fileHeader.mmapVersion, MMAP_VERSION);
fclose(file);
return NULL;
@@ -211,7 +194,7 @@ namespace MMAP
size_t result = fread(pTile->data, pTile->fileHeader.size, 1, file);
if (!result)
{
TC_LOG_ERROR("phase", "MMAP:LoadTile: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, x, y);
TC_LOG_ERROR("phase", "MMAP:LoadTile: Bad header or data in mmap %04u%02i%02i.mmtile", mapId, x, y);
fclose(file);
return NULL;
}
@@ -237,7 +220,7 @@ namespace MMAP
// only a few tiles have terrain swaps, do not write error for them
if (data)
{
TC_LOG_DEBUG("phase", "MMAP:LoadPhaseTiles: Loaded phased %03u%02i%02i.mmtile for root phase map %u", map->ID, x, y, mapId);
TC_LOG_DEBUG("phase", "MMAP:LoadPhaseTiles: Loaded phased %04u%02i%02i.mmtile for root phase map %u", map->ID, x, y, mapId);
_phaseTiles[map->ID][packedGridPos] = data;
}
}
@@ -256,7 +239,7 @@ namespace MMAP
if (_phaseTiles[mapId][packedGridPos])
{
TC_LOG_DEBUG("phase", "MMAP:UnloadPhaseTile: Unloaded phased %03u%02i%02i.mmtile for root phase map %u", mapId, x, y, rootMapId);
TC_LOG_DEBUG("phase", "MMAP:UnloadPhaseTile: Unloaded phased %04u%02i%02i.mmtile for root phase map %u", mapId, x, y, rootMapId);
delete _phaseTiles[mapId][packedGridPos]->data;
delete _phaseTiles[mapId][packedGridPos];
_phaseTiles[mapId].erase(packedGridPos);
@@ -269,7 +252,7 @@ namespace MMAP
if (loadedMMaps.find(mapId) == loadedMMaps.end())
{
// file may not exist, therefore not loaded
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map. %03u%02i%02i.mmtile", mapId, x, y);
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map. %04u%02i%02i.mmtile", mapId, x, y);
return false;
}
@@ -280,7 +263,7 @@ namespace MMAP
if (mmap->loadedTileRefs.find(packedGridPos) == mmap->loadedTileRefs.end())
{
// file may not exist, therefore not loaded
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %03u%02i%02i.mmtile", mapId, x, y);
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %04u%02i%02i.mmtile", mapId, x, y);
return false;
}
@@ -292,14 +275,14 @@ namespace MMAP
// this is technically a memory leak
// if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used
// we cannot recover from this error - assert out
TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %04u%02i%02i.mmtile from navmesh", mapId, x, y);
ASSERT(false);
}
else
{
mmap->loadedTileRefs.erase(packedGridPos);
--loadedTiles;
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId);
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %04i", mapId, x, y, mapId);
UnloadPhaseTile(mapId, x, y);
return true;
@@ -313,7 +296,7 @@ namespace MMAP
if (loadedMMaps.find(mapId) == loadedMMaps.end())
{
// file may not exist, therefore not loaded
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map %03u", mapId);
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map %04u", mapId);
return false;
}
@@ -324,18 +307,18 @@ namespace MMAP
uint32 x = (i->first >> 16);
uint32 y = (i->first & 0x0000FFFF);
if (dtStatusFailed(mmap->navMesh->removeTile(i->second, NULL, NULL)))
TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %04u%02i%02i.mmtile from navmesh", mapId, x, y);
else
{
UnloadPhaseTile(mapId, x, y);
--loadedTiles;
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId);
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %04i[%02i, %02i] from %04i", mapId, x, y, mapId);
}
}
delete mmap;
loadedMMaps.erase(mapId);
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded %03i.mmap", mapId);
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded %04i.mmap", mapId);
return true;
}
@@ -346,14 +329,14 @@ namespace MMAP
if (loadedMMaps.find(mapId) == loadedMMaps.end())
{
// file may not exist, therefore not loaded
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %03u", mapId);
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %04u", mapId);
return false;
}
MMapData* mmap = loadedMMaps[mapId];
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %03u instanceId %u", mapId, instanceId);
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %04u instanceId %u", mapId, instanceId);
return false;
}
@@ -361,7 +344,7 @@ namespace MMAP
dtFreeNavMeshQuery(query);
mmap->navMeshQueries.erase(instanceId);
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId);
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId %04u instanceId %u", mapId, instanceId);
return true;
}
@@ -388,11 +371,11 @@ namespace MMAP
if (dtStatusFailed(query->init(mmap->GetNavMesh(swaps), 1024)))
{
dtFreeNavMeshQuery(query);
TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId);
return NULL;
}
TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId);
mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
}
@@ -426,25 +409,25 @@ namespace MMAP
if (loadedPhasedTiles[swap].find(packedXY) == loadedPhasedTiles[swap].end())
{
TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: mmtile %03u[%02i, %02i] unload skipped, due to not loaded", swap, x, y);
TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: mmtile %04u[%02i, %02i] unload skipped, due to not loaded", swap, x, y);
return;
}
dtMeshHeader* header = (dtMeshHeader*)ptile->data;
// remove old tile
if (dtStatusFailed(navMesh->removeTile(loadedTileRefs[packedXY], NULL, NULL)))
TC_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not unload phased %03u%02i%02i.mmtile from navmesh", swap, x, y);
TC_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not unload phased %04u%02i%02i.mmtile from navmesh", swap, x, y);
else
{
TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: Unloaded phased %03u%02i%02i.mmtile from navmesh", swap, x, y);
TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: Unloaded phased %04u%02i%02i.mmtile from navmesh", swap, x, y);
// restore base tile
if (dtStatusSucceed(navMesh->addTile(_baseTiles[packedXY]->data, _baseTiles[packedXY]->dataSize, 0, 0, &loadedTileRefs[packedXY])))
{
TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: Loaded base mmtile %03u[%02i, %02i] into %03i[%02i, %02i]", _mapId, x, y, _mapId, header->x, header->y);
TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: Loaded base mmtile %04u[%02i, %02i] into %04i[%02i, %02i]", _mapId, x, y, _mapId, header->x, header->y);
}
else
TC_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not load base %03u%02i%02i.mmtile to navmesh", _mapId, x, y);
TC_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not load base %04u%02i%02i.mmtile to navmesh", _mapId, x, y);
}
loadedPhasedTiles[swap].erase(packedXY);
@@ -464,12 +447,12 @@ namespace MMAP
if (loadedTileRefs.find(packedXY) == loadedTileRefs.end())
{
TC_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %03u[%02i, %02i] load skipped, due to not loaded base tile on map %u", swap, x, y, _mapId);
TC_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %04u[%02i, %02i] load skipped, due to not loaded base tile on map %u", swap, x, y, _mapId);
return;
}
if (loadedPhasedTiles[swap].find(packedXY) != loadedPhasedTiles[swap].end())
{
TC_LOG_DEBUG("phase", "MMapData::AddSwap: WARNING! phased mmtile %03u[%02i, %02i] load skipped, due to already loaded on map %u", swap, x, y, _mapId);
TC_LOG_DEBUG("phase", "MMapData::AddSwap: WARNING! phased mmtile %04u[%02i, %02i] load skipped, due to already loaded on map %u", swap, x, y, _mapId);
return;
}
@@ -480,25 +463,22 @@ namespace MMAP
if (!oldTile)
{
TC_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %03u[%02i, %02i] load skipped, due to not loaded base tile ref on map %u", swap, x, y, _mapId);
TC_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %04u[%02i, %02i] load skipped, due to not loaded base tile ref on map %u", swap, x, y, _mapId);
return;
}
uint32 old_x = oldTile->header->x;
uint32 old_y = oldTile->header->y;
// header xy is based on the swap map's tile set, wich doesn't have all the same tiles as root map, so copy the xy from the orignal header
memcpy(ptile->data + 8, (char*)&old_x, 4);
memcpy(ptile->data + 12, (char*)&old_y, 4);
header->x = oldTile->header->x;
header->y = oldTile->header->y;
// the removed tile's data
PhasedTile* pt = new PhasedTile();
// remove old tile
if (dtStatusFailed(navMesh->removeTile(loadedTileRefs[packedXY], &pt->data, &pt->dataSize)))
TC_LOG_ERROR("phase", "MMapData::AddSwap: Could not unload %03u%02i%02i.mmtile from navmesh", _mapId, x, y);
TC_LOG_ERROR("phase", "MMapData::AddSwap: Could not unload %04u%02i%02i.mmtile from navmesh", _mapId, x, y);
else
{
TC_LOG_DEBUG("phase", "MMapData::AddSwap: Unloaded %03u%02i%02i.mmtile from navmesh", _mapId, x, y);
TC_LOG_DEBUG("phase", "MMapData::AddSwap: Unloaded %04u%02i%02i.mmtile from navmesh", _mapId, x, y);
// store the removed data first time, this is the origonal, non-phased tile
if (_baseTiles.find(packedXY) == _baseTiles.end())
@@ -510,43 +490,38 @@ namespace MMAP
// add new swapped tile
if (dtStatusSucceed(navMesh->addTile(ptile->data, ptile->fileHeader.size, 0, 0, &loadedTileRefs[packedXY])))
{
TC_LOG_DEBUG("phase", "MMapData::AddSwap: Loaded phased mmtile %03u[%02i, %02i] into %03i[%02i, %02i]", swap, x, y, _mapId, header->x, header->y);
TC_LOG_DEBUG("phase", "MMapData::AddSwap: Loaded phased mmtile %04u[%02i, %02i] into %04i[%02i, %02i]", swap, x, y, _mapId, header->x, header->y);
}
else
TC_LOG_ERROR("phase", "MMapData::AddSwap: Could not load %03u%02i%02i.mmtile to navmesh", swap, x, y);
TC_LOG_ERROR("phase", "MMapData::AddSwap: Could not load %04u%02i%02i.mmtile to navmesh", swap, x, y);
}
}
dtNavMesh* MMapData::GetNavMesh(TerrainSet swaps)
{
for (uint32 swap : _activeSwaps)
std::set<uint32> activeSwaps = _activeSwaps; // _activeSwaps is modified inside RemoveSwap
for (uint32 swap : activeSwaps)
{
if (swaps.find(swap) == swaps.end()) // swap not active
if (!swaps.count(swap)) // swap not active
{
PhaseTileContainer ptc = MMAP::MMapFactory::createOrGetMMapManager()->GetPhaseTileContainer(swap);
for (PhaseTileContainer::const_iterator itr = ptc.begin(); itr != ptc.end(); ++itr)
{
RemoveSwap(itr->second, swap, itr->first); // remove swap
}
}
}
if (!swaps.empty())
// for each of the calling unit's terrain swaps
for (uint32 swap : swaps)
{
// for each of the calling unit's terrain swaps
for (uint32 swap : swaps)
if (!_activeSwaps.count(swap)) // swap not active
{
// for each of the terrain swap's xy tiles
PhaseTileContainer ptc = MMAP::MMapFactory::createOrGetMMapManager()->GetPhaseTileContainer(swap);
for (PhaseTileContainer::const_iterator itr = ptc.begin(); itr != ptc.end(); ++itr)
{
if (_activeSwaps.find(swap) == _activeSwaps.end()) // swap not active
{
AddSwap(itr->second, swap, itr->first); // add swap
}
}
AddSwap(itr->second, swap, itr->first); // add swap
}
}
return navMesh;
}
}

View File

@@ -66,7 +66,7 @@ namespace VMAP
std::string VMapManager2::getMapFileName(unsigned int mapId)
{
std::stringstream fname;
fname.width(3);
fname.width(4);
fname << std::setfill('0') << mapId << std::string(MAP_FILENAME_EXTENSION2);
return fname.str();

View File

@@ -90,7 +90,7 @@ namespace VMAP
{
std::stringstream tilefilename;
tilefilename.fill('0');
tilefilename << std::setw(3) << mapID << '_';
tilefilename << std::setw(4) << mapID << '_';
//tilefilename << std::setw(2) << tileX << '_' << std::setw(2) << tileY << ".vmtile";
tilefilename << std::setw(2) << tileY << '_' << std::setw(2) << tileX << ".vmtile";
return tilefilename.str();

View File

@@ -116,7 +116,7 @@ namespace VMAP
// write map tree file
std::stringstream mapfilename;
mapfilename << iDestDir << '/' << std::setfill('0') << std::setw(3) << map_iter->first << ".vmtree";
mapfilename << iDestDir << '/' << std::setfill('0') << std::setw(4) << map_iter->first << ".vmtree";
FILE* mapfile = fopen(mapfilename.str().c_str(), "wb");
if (!mapfile)
{
@@ -157,7 +157,7 @@ namespace VMAP
uint32 nSpawns = tileEntries.count(tile->first);
std::stringstream tilefilename;
tilefilename.fill('0');
tilefilename << iDestDir << '/' << std::setw(3) << map_iter->first << '_';
tilefilename << iDestDir << '/' << std::setw(4) << map_iter->first << '_';
uint32 x, y;
StaticMapTree::unpackTileID(tile->first, x, y);
tilefilename << std::setw(2) << x << '_' << std::setw(2) << y << ".vmtile";

View File

@@ -25,8 +25,8 @@
namespace VMAP
{
const char VMAP_MAGIC[] = "VMAP_4.2";
const char RAW_VMAP_MAGIC[] = "VMAP042"; // used in extracted vmap files with raw data
const char VMAP_MAGIC[] = "VMAP_4.3";
const char RAW_VMAP_MAGIC[] = "VMAP043"; // used in extracted vmap files with raw data
const char GAMEOBJECT_MODELS[] = "GameObjectModels.dtree";
// defined in TileAssembler.cpp currently...

View File

@@ -40,7 +40,7 @@
#include "Weather.h"
u_map_magic MapMagic = { {'M','A','P','S'} };
u_map_magic MapVersionMagic = { {'v','1','.','4'} };
u_map_magic MapVersionMagic = { {'v','1','.','5'} };
u_map_magic MapAreaMagic = { {'A','R','E','A'} };
u_map_magic MapHeightMagic = { {'M','H','G','T'} };
u_map_magic MapLiquidMagic = { {'M','L','I','Q'} };
@@ -78,33 +78,29 @@ Map::~Map()
bool Map::ExistMap(uint32 mapid, int gx, int gy)
{
int len = sWorld->GetDataPath().length() + strlen("maps/%03u%02u%02u.map") + 1;
char* fileName = new char[len];
snprintf(fileName, len, (char *)(sWorld->GetDataPath() + "maps/%03u%02u%02u.map").c_str(), mapid, gx, gy);
std::string fileName = Trinity::StringFormat("maps/%04u_%02u_%02u.map", mapid, gx, gy);
bool ret = false;
FILE* pf = fopen(fileName, "rb");
if (!pf)
FILE* file = fopen(fileName.c_str(), "rb");
if (!file)
{
TC_LOG_ERROR("maps", "Map file '%s' does not exist!", fileName);
TC_LOG_ERROR("maps", "Map file '%s' does not exist!", fileName.c_str());
TC_LOG_ERROR("maps", "Please place MAP-files (*.map) in the appropriate directory (%s), or correct the DataDir setting in your worldserver.conf file.", (sWorld->GetDataPath()+"maps/").c_str());
}
else
{
map_fileheader header;
if (fread(&header, sizeof(header), 1, pf) == 1)
if (fread(&header, sizeof(header), 1, file) == 1)
{
if (header.mapMagic.asUInt != MapMagic.asUInt || header.versionMagic.asUInt != MapVersionMagic.asUInt)
TC_LOG_ERROR("maps", "Map file '%s' is from an incompatible map version (%.*s %.*s), %.*s %.*s is expected. Please recreate using the mapextractor.",
fileName, 4, header.mapMagic.asChar, 4, header.versionMagic.asChar, 4, MapMagic.asChar, 4, MapVersionMagic.asChar);
fileName.c_str(), 4, header.mapMagic.asChar, 4, header.versionMagic.asChar, 4, MapMagic.asChar, 4, MapVersionMagic.asChar);
else
ret = true;
}
fclose(pf);
fclose(file);
}
delete[] fileName;
return ret;
}
@@ -191,16 +187,12 @@ void Map::LoadMap(int gx, int gy, bool reload)
}
// map file name
char* tmp = NULL;
int len = sWorld->GetDataPath().length() + strlen("maps/%03u%02u%02u.map") + 1;
tmp = new char[len];
snprintf(tmp, len, (char *)(sWorld->GetDataPath() + "maps/%03u%02u%02u.map").c_str(), GetId(), gx, gy);
TC_LOG_DEBUG("maps", "Loading map %s", tmp);
std::string fileName = Trinity::StringFormat("maps/%04u_%02u_%02u.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(tmp))
TC_LOG_ERROR("maps", "Error loading map file: \n %s\n", tmp);
delete[] tmp;
if (!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);
}

View File

@@ -4882,7 +4882,7 @@ enum PartyResult
};
const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP'
#define MMAP_VERSION 6
#define MMAP_VERSION 7
struct MmapTileHeader
{

View File

@@ -402,7 +402,7 @@ void ReadLiquidTypeTableDBC()
// Map file format data
static char const* MAP_MAGIC = "MAPS";
static char const* MAP_VERSION_MAGIC = "v1.4";
static char const* MAP_VERSION_MAGIC = "v1.5";
static char const* MAP_AREA_MAGIC = "AREA";
static char const* MAP_HEIGHT_MAGIC = "MHGT";
static char const* MAP_LIQUID_MAGIC = "MLIQ";
@@ -1091,7 +1091,7 @@ void ExtractMaps(uint32 build)
continue;
sprintf(storagePath, "World\\Maps\\%s\\%s_%u_%u.adt", map_ids[z].name, map_ids[z].name, x, y);
sprintf(output_filename, "%s/maps/%03u%02u%02u.map", output_path, map_ids[z].id, y, x);
sprintf(output_filename, "%s/maps/%04u_%02u_%02u.map", output_path, map_ids[z].id, y, x);
ConvertADT(storagePath, output_filename, y, x, build);
sprintf(storagePath, "World\\Maps\\%s\\%s_%u_%u_obj0.adt", map_ids[z].name, map_ids[z].name, x, y);

View File

@@ -12,7 +12,7 @@ file(GLOB_RECURSE mmap_gen_sources *.cpp *.h)
set(mmap_gen_Includes
${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/dep/libmpq
${CMAKE_SOURCE_DIR}/dep/cppformat
${CMAKE_SOURCE_DIR}/dep/zlib
${CMAKE_SOURCE_DIR}/dep/bzip2
${CMAKE_SOURCE_DIR}/dep/g3dlite/include
@@ -30,13 +30,6 @@ set(mmap_gen_Includes
${CMAKE_SOURCE_DIR}/src/server/collision/Models
)
if( WIN32 )
set(mmap_gen_Includes
${mmap_gen_Includes}
${CMAKE_SOURCE_DIR}/dep/libmpq/win
)
endif()
include_directories(${mmap_gen_Includes})
add_executable(mmaps_generator ${mmap_gen_sources})
@@ -46,6 +39,7 @@ target_link_libraries(mmaps_generator
g3dlib
Recast
Detour
format
${BZIP2_LIBRARIES}
${ZLIB_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}

View File

@@ -19,6 +19,7 @@
#include "PathCommon.h"
#include "MapBuilder.h"
#include "StringFormat.h"
#include "MapTree.h"
#include "ModelInstance.h"
@@ -28,7 +29,7 @@
#include "DetourCommon.h"
#define MMAP_MAGIC 0x4d4d4150 // 'MMAP'
#define MMAP_VERSION 6
#define MMAP_VERSION 7
struct MmapTileHeader
{
@@ -83,13 +84,12 @@ namespace MMAP
{
std::vector<std::string> files;
uint32 mapID, tileX, tileY, tileID, count = 0;
char filter[12];
printf("Discovering maps... ");
getDirContents(files, "maps");
for (uint32 i = 0; i < files.size(); ++i)
{
mapID = uint32(atoi(files[i].substr(0,3).c_str()));
mapID = uint32(atoi(files[i].substr(0, 4).c_str()));
if (std::find(m_tiles.begin(), m_tiles.end(), mapID) == m_tiles.end())
{
m_tiles.emplace_back(MapTiles(mapID, new std::set<uint32>));
@@ -101,7 +101,7 @@ namespace MMAP
getDirContents(files, "vmaps", "*.vmtree");
for (uint32 i = 0; i < files.size(); ++i)
{
mapID = uint32(atoi(files[i].substr(0,3).c_str()));
mapID = uint32(atoi(files[i].substr(0, 4).c_str()));
if (std::find(m_tiles.begin(), m_tiles.end(), mapID) == m_tiles.end())
{
m_tiles.emplace_back(MapTiles(mapID, new std::set<uint32>));
@@ -117,26 +117,24 @@ namespace MMAP
std::set<uint32>* tiles = (*itr).m_tiles;
mapID = (*itr).m_mapId;
sprintf(filter, "%03u*.vmtile", mapID);
files.clear();
getDirContents(files, "vmaps", filter);
getDirContents(files, "vmaps", Trinity::StringFormat("%04u*.vmtile", mapID));
for (uint32 i = 0; i < files.size(); ++i)
{
tileX = uint32(atoi(files[i].substr(7,2).c_str()));
tileY = uint32(atoi(files[i].substr(4,2).c_str()));
tileX = uint32(atoi(files[i].substr(8, 2).c_str()));
tileY = uint32(atoi(files[i].substr(5, 2).c_str()));
tileID = StaticMapTree::packTileID(tileY, tileX);
tiles->insert(tileID);
count++;
}
sprintf(filter, "%03u*", mapID);
files.clear();
getDirContents(files, "maps", filter);
getDirContents(files, "maps", Trinity::StringFormat("%04u*", mapID));
for (uint32 i = 0; i < files.size(); ++i)
{
tileY = uint32(atoi(files[i].substr(3,2).c_str()));
tileX = uint32(atoi(files[i].substr(5,2).c_str()));
tileY = uint32(atoi(files[i].substr(5, 2).c_str()));
tileX = uint32(atoi(files[i].substr(8, 2).c_str()));
tileID = StaticMapTree::packTileID(tileX, tileY);
if (tiles->insert(tileID).second)
@@ -386,12 +384,12 @@ namespace MMAP
buildNavMesh(mapID, navMesh);
if (!navMesh)
{
printf("[Map %03i] Failed creating navmesh!\n", mapID);
printf("[Map %04i] Failed creating navmesh!\n", mapID);
return;
}
// now start building mmtiles for each tile
printf("[Map %03i] We have %u tiles. \n", mapID, (unsigned int)tiles->size());
printf("[Map %04i] We have %u tiles. \n", mapID, (unsigned int)tiles->size());
for (std::set<uint32>::iterator it = tiles->begin(); it != tiles->end(); ++it)
{
uint32 tileX, tileY;
@@ -408,13 +406,13 @@ namespace MMAP
dtFreeNavMesh(navMesh);
}
printf("[Map %03i] Complete!\n", mapID);
printf("[Map %04u] Complete!\n", mapID);
}
/**************************************************************************/
void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh)
{
printf("[Map %03i] Building tile [%02u,%02u]\n", mapID, tileX, tileY);
printf("[Map %04i] Building tile [%02u,%02u]\n", mapID, tileX, tileY);
MeshData meshData;
@@ -500,22 +498,22 @@ namespace MMAP
navMeshParams.maxPolys = maxPolysPerTile;
navMesh = dtAllocNavMesh();
printf("[Map %03i] Creating navMesh...\n", mapID);
printf("[Map %04u] Creating navMesh...\n", mapID);
if (!navMesh->init(&navMeshParams))
{
printf("[Map %03i] Failed creating navmesh! \n", mapID);
printf("[Map %04u] Failed creating navmesh! \n", mapID);
return;
}
char fileName[25];
sprintf(fileName, "mmaps/%03u.mmap", mapID);
sprintf(fileName, "mmaps/%04u.mmap", mapID);
FILE* file = fopen(fileName, "wb");
if (!file)
{
dtFreeNavMesh(navMesh);
char message[1024];
sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName);
sprintf(message, "[Map %04u] Failed to open %s for writing!\n", mapID, fileName);
perror(message);
return;
}
@@ -531,9 +529,8 @@ namespace MMAP
dtNavMesh* navMesh)
{
// console output
char tileString[20];
sprintf(tileString, "[Map %03i] [%02i,%02i]: ", mapID, tileX, tileY);
printf("%s Building movemap tiles...\n", tileString);
std::string tileString = Trinity::StringFormat("[Map %04u] [%02i,%02i]: ", mapID, tileX, tileY);
printf("%s Building movemap tiles...\n", tileString.c_str());
IntermediateValues iv;
@@ -614,7 +611,7 @@ namespace MMAP
tile.solid = rcAllocHeightfield();
if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch))
{
printf("%s Failed building heightfield! \n", tileString);
printf("%s Failed building heightfield! \n", tileString.c_str());
continue;
}
@@ -635,33 +632,33 @@ namespace MMAP
tile.chf = rcAllocCompactHeightfield();
if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf))
{
printf("%s Failed compacting heightfield! \n", tileString);
printf("%s Failed compacting heightfield! \n", tileString.c_str());
continue;
}
// build polymesh intermediates
if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf))
{
printf("%s Failed eroding area! \n", tileString);
printf("%s Failed eroding area! \n", tileString.c_str());
continue;
}
if (!rcBuildDistanceField(m_rcContext, *tile.chf))
{
printf("%s Failed building distance field! \n", tileString);
printf("%s Failed building distance field! \n", tileString.c_str());
continue;
}
if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea))
{
printf("%s Failed building regions! \n", tileString);
printf("%s Failed building regions! \n", tileString.c_str());
continue;
}
tile.cset = rcAllocContourSet();
if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset))
{
printf("%s Failed building contours! \n", tileString);
printf("%s Failed building contours! \n", tileString.c_str());
continue;
}
@@ -669,14 +666,14 @@ namespace MMAP
tile.pmesh = rcAllocPolyMesh();
if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh))
{
printf("%s Failed building polymesh! \n", tileString);
printf("%s Failed building polymesh! \n", tileString.c_str());
continue;
}
tile.dmesh = rcAllocPolyMeshDetail();
if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *tile.dmesh))
{
printf("%s Failed building polymesh detail! \n", tileString);
printf("%s Failed building polymesh detail! \n", tileString.c_str());
continue;
}
@@ -699,7 +696,7 @@ namespace MMAP
iv.polyMesh = rcAllocPolyMesh();
if (!iv.polyMesh)
{
printf("%s alloc iv.polyMesh FIALED!\n", tileString);
printf("%s alloc iv.polyMesh FAILED!\n", tileString.c_str());
delete[] pmmerge;
delete[] dmmerge;
delete[] tiles;
@@ -710,7 +707,7 @@ namespace MMAP
iv.polyMeshDetail = rcAllocPolyMeshDetail();
if (!iv.polyMeshDetail)
{
printf("%s alloc m_dmesh FIALED!\n", tileString);
printf("%s alloc m_dmesh FAILED!\n", tileString.c_str());
delete[] pmmerge;
delete[] dmmerge;
delete[] tiles;
@@ -774,12 +771,12 @@ namespace MMAP
// so we have a clear error message
if (params.nvp > DT_VERTS_PER_POLYGON)
{
printf("%s Invalid verts-per-polygon value! \n", tileString);
printf("%s Invalid verts-per-polygon value! \n", tileString.c_str());
break;
}
if (params.vertCount >= 0xffff)
{
printf("%s Too many vertices! \n", tileString);
printf("%s Too many vertices! \n", tileString.c_str());
break;
}
if (!params.vertCount || !params.verts)
@@ -788,7 +785,7 @@ namespace MMAP
// loaded but those models don't span into this tile
// message is an annoyance
//printf("%sNo vertices to build tile! \n", tileString);
//printf("%sNo vertices to build tile! \n", tileString.c_str());
break;
}
if (!params.polyCount || !params.polys ||
@@ -797,47 +794,47 @@ namespace MMAP
// we have flat tiles with no actual geometry - don't build those, its useless
// keep in mind that we do output those into debug info
// drop tiles with only exact count - some tiles may have geometry while having less tiles
printf("%s No polygons to build on tile! \n", tileString);
printf("%s No polygons to build on tile! \n", tileString.c_str());
break;
}
if (!params.detailMeshes || !params.detailVerts || !params.detailTris)
{
printf("%s No detail mesh to build tile! \n", tileString);
printf("%s No detail mesh to build tile! \n", tileString.c_str());
break;
}
printf("%s Building navmesh tile...\n", tileString);
printf("%s Building navmesh tile...\n", tileString.c_str());
if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
{
printf("%s Failed building navmesh tile! \n", tileString);
printf("%s Failed building navmesh tile! \n", tileString.c_str());
break;
}
dtTileRef tileRef = 0;
printf("%s Adding tile to navmesh...\n", tileString);
printf("%s Adding tile to navmesh...\n", tileString.c_str());
// DT_TILE_FREE_DATA tells detour to unallocate memory when the tile
// is removed via removeTile()
dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef);
if (!tileRef || dtResult != DT_SUCCESS)
{
printf("%s Failed adding tile to navmesh! \n", tileString);
printf("%s Failed adding tile to navmesh! \n", tileString.c_str());
break;
}
// file output
char fileName[255];
sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX);
sprintf(fileName, "mmaps/%04u%02i%02i.mmtile", mapID, tileY, tileX);
FILE* file = fopen(fileName, "wb");
if (!file)
{
char message[1024];
sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName);
sprintf(message, "[Map %04u] Failed to open %s for writing!\n", mapID, fileName);
perror(message);
navMesh->removeTile(tileRef, NULL, NULL);
break;
}
printf("%s Writing to file...\n", tileString);
printf("%s Writing to file...\n", tileString.c_str());
// write header
MmapTileHeader header;
@@ -898,6 +895,8 @@ namespace MMAP
case 1:
case 530:
case 571:
case 870:
case 1116:
return true;
default:
break;
@@ -916,6 +915,12 @@ namespace MMAP
case 597: // CraigTest.wdt
case 605: // development_nonweighted.wdt
case 606: // QA_DVD.wdt
case 651: // ElevatorSpawnTest.wdt
case 1060: // LevelDesignLand-DevOnly.wdt
case 1181: // PattyMackTestGarrisonBldgMap.wdt
case 1264: // Propland-DevOnly.wdt
case 1270: // devland3.wdt
case 1427: // PattyMackTestGarrisonBldgMap2.wdt
return true;
default:
if (isTransportMap(mapID))
@@ -926,13 +931,21 @@ namespace MMAP
if (m_skipBattlegrounds)
switch (mapID)
{
case 30: // AV
case 30: // Alterac Valley
case 37: // ?
case 489: // WSG
case 529: // AB
case 566: // EotS
case 607: // SotA
case 628: // IoC
case 489: // Warsong Gulch
case 529: // Arathi Basin
case 566: // Eye of the Storm
case 607: // Strand of the Ancients
case 628: // Isle of Conquest
case 726: // Twin Peaks
case 727: // Silvershard Mines
case 761: // The Battle for Gilneas
case 968: // Rated Eye of the Storm
case 998: // Temple of Kotmogu
case 1010: // CTF3
case 1105: // Deepwind Gorge
case 1280: // Southshore vs. Tarren Mill
return true;
default:
break;
@@ -970,11 +983,35 @@ namespace MMAP
case 641:
case 642:
case 647:
case 662:
case 672:
case 673:
case 674:
case 712:
case 713:
case 718:
case 738:
case 739:
case 740:
case 741:
case 742:
case 743:
case 747:
case 748:
case 749:
case 750:
case 762:
case 763:
case 765:
case 766:
case 767:
case 1113:
case 1132:
case 1133:
case 1172:
case 1173:
case 1192:
case 1231:
return true;
default:
return false;
@@ -985,7 +1022,7 @@ namespace MMAP
bool MapBuilder::shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY)
{
char fileName[255];
sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX);
sprintf(fileName, "mmaps/%04u%02i%02i.mmtile", mapID, tileY, tileX);
FILE* file = fopen(fileName, "rb");
if (!file)
return false;

View File

@@ -72,7 +72,7 @@ bool preciseVectorData = false;
//static const char * szWorkDirMaps = ".\\Maps";
const char* szWorkDirWmo = "./Buildings";
const char* szRawVMAPMagic = "VMAP042";
const char* szRawVMAPMagic = "VMAP043";
bool OpenCascStorage()
{
@@ -249,7 +249,7 @@ void ParsMapFiles()
char id[10];
for (unsigned int i=0; i<map_count; ++i)
{
sprintf(id,"%03u",map_ids[i].id);
sprintf(id, "%04u", map_ids[i].id);
sprintf(fn,"World\\Maps\\%s\\%s.wdt", map_ids[i].name, map_ids[i].name);
WDTFile WDT(fn,map_ids[i].name);
if(WDT.init(id, map_ids[i].id))
@@ -355,7 +355,7 @@ bool processArgv(int argc, char ** argv, const char *versionString)
int main(int argc, char ** argv)
{
bool success = true;
const char *versionString = "V4.00 2012_02";
const char *versionString = "V4.03 2015_05";
// Use command line arguments, when some
if (!processArgv(argc, argv, versionString))