From 0f3590ebb455a6dcf80cb437a4e984c1371b7f00 Mon Sep 17 00:00:00 2001 From: Shauren Date: Mon, 6 Jul 2020 17:45:53 +0200 Subject: [PATCH] Core/Maps: Added optional *.tilelist file to map_extractor output which contains a list of existing tiles to speed up map creation in worldserver --- src/server/game/Maps/Map.cpp | 23 ++++++++++++++++++ src/server/game/Maps/Map.h | 2 +- src/tools/map_extractor/System.cpp | 39 ++++++++++++++++++++---------- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 0e6cc0c7a65..97bd0c11886 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -98,6 +98,29 @@ Map::~Map() void Map::DiscoverGridMapFiles() { + std::string tileListName = Trinity::StringFormat("%smaps/%03u.tilelist", sWorld->GetDataPath().c_str(), GetId()); + // tile list is optional + if (FILE* tileList = fopen(tileListName.c_str(), "rb")) + { + u_map_magic mapMagic; + u_map_magic versionMagic; + uint32 build; + char tilesData[MAX_NUMBER_OF_GRIDS * MAX_NUMBER_OF_GRIDS]; + if (fread(&mapMagic.asUInt, sizeof(u_map_magic), 1, tileList) == 1 + && mapMagic.asUInt == MapMagic.asUInt + && fread(&versionMagic.asUInt, sizeof(u_map_magic), 1, tileList) == 1 + && versionMagic.asUInt == MapVersionMagic.asUInt + && fread(&build, sizeof(build), 1, tileList) == 1 + && fread(&tilesData[0], MAX_NUMBER_OF_GRIDS * MAX_NUMBER_OF_GRIDS, 1, tileList) == 1) + { + i_gridFileExists = std::bitset(tilesData, Trinity::Containers::Size(tilesData)); + fclose(tileList); + return; + } + + fclose(tileList); + } + for (uint32 gx = 0; gx < MAX_NUMBER_OF_GRIDS; ++gx) for (uint32 gy = 0; gy < MAX_NUMBER_OF_GRIDS; ++gy) i_gridFileExists[gx * MAX_NUMBER_OF_GRIDS + gy] = ExistMap(GetId(), gx, gy, false); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index b4b78868b75..686f6e1e025 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -89,7 +89,7 @@ struct map_fileheader { u_map_magic mapMagic; u_map_magic versionMagic; - u_map_magic buildMagic; + uint32 buildMagic; uint32 areaMapOffset; uint32 areaMapSize; uint32 heightMapOffset; diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 810bc5abae3..b6616955b4e 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -15,8 +15,10 @@ * with this program. If not, see . */ +#include "StringFormat.h" #include #include +#include #include #include #include @@ -1122,25 +1124,36 @@ void ExtractMapsFromMpq(uint32 build) // Loadup map grid data sprintf(mpq_map_name, "World\\Maps\\%s\\%s.wdt", map_ids[z].name, map_ids[z].name); ChunkedFile wdt; - if (!wdt.loadFile(WorldMpq, mpq_map_name, false)) - continue; - FileChunk* chunk = wdt.GetChunk("MAIN"); - for (uint32 y = 0; y < WDT_MAP_SIZE; ++y) + std::bitset<(WDT_MAP_SIZE)* (WDT_MAP_SIZE)> existingTiles; + if (wdt.loadFile(WorldMpq, mpq_map_name, false)) { - for (uint32 x = 0; x < WDT_MAP_SIZE; ++x) + FileChunk* main = wdt.GetChunk("MAIN"); + for (uint32 y = 0; y < WDT_MAP_SIZE; ++y) { - if (!(chunk->As()->adt_list[y][x].flag & 0x1)) - continue; + for (uint32 x = 0; x < WDT_MAP_SIZE; ++x) + { + if (!(main->As()->adt_list[y][x].flag & 0x1)) + continue; - sprintf(mpq_filename, "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); - bool ignoreDeepWater = IsDeepWaterIgnored(map_ids[z].id, y, x); - ConvertADT(mpq_filename, output_filename, y, x, build, ignoreDeepWater); + sprintf(mpq_filename, "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); + bool ignoreDeepWater = IsDeepWaterIgnored(map_ids[z].id, y, x); + existingTiles[y * WDT_MAP_SIZE + x] = ConvertADT(mpq_filename, output_filename, y, x, build, ignoreDeepWater); + } + + // draw progress bar + printf("Processing........................%d%%\r", (100 * (y + 1)) / WDT_MAP_SIZE); } + } - // draw progress bar - printf("Processing........................%d%%\r", (100 * (y+1)) / WDT_MAP_SIZE); + if (FILE* tileList = fopen(Trinity::StringFormat("%s/maps/%03u.tilelist", output_path, map_ids[z].id).c_str(), "wb")) + { + fwrite(MAP_MAGIC, 1, strlen(MAP_MAGIC), tileList); + fwrite(MAP_VERSION_MAGIC, 1, strlen(MAP_VERSION_MAGIC), tileList); + fwrite(&build, sizeof(build), 1, tileList); + fwrite(existingTiles.to_string().c_str(), 1, existingTiles.size(), tileList); + fclose(tileList); } }