diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Collision/Maps/MapDefines.h | 28 | ||||
-rw-r--r-- | src/common/Collision/Maps/TileAssembler.cpp | 8 | ||||
-rw-r--r-- | src/common/Collision/Maps/TileAssembler.h | 3 | ||||
-rw-r--r-- | src/server/game/Movement/PathGenerator.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Movement/PathGenerator.h | 2 | ||||
-rw-r--r-- | src/tools/mmaps_generator/MapBuilder.cpp | 13 | ||||
-rw-r--r-- | src/tools/mmaps_generator/PathGenerator.cpp | 71 | ||||
-rw-r--r-- | src/tools/mmaps_generator/TerrainBuilder.cpp | 28 |
8 files changed, 99 insertions, 63 deletions
diff --git a/src/common/Collision/Maps/MapDefines.h b/src/common/Collision/Maps/MapDefines.h index 84c5d9a010a..4935e991259 100644 --- a/src/common/Collision/Maps/MapDefines.h +++ b/src/common/Collision/Maps/MapDefines.h @@ -5,7 +5,7 @@ #include "DetourNavMesh.h" const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP' -#define MMAP_VERSION 8 +#define MMAP_VERSION 9 struct MmapTileHeader { @@ -29,18 +29,22 @@ static_assert(sizeof(MmapTileHeader) == (sizeof(MmapTileHeader::mmapMagic) + sizeof(MmapTileHeader::usesLiquids) + sizeof(MmapTileHeader::padding)), "MmapTileHeader has uninitialized padding fields"); -enum NavTerrain +enum NavArea { - NAV_EMPTY = 0x00, - NAV_GROUND = 0x01, - NAV_MAGMA = 0x02, - NAV_SLIME = 0x04, - NAV_WATER = 0x08, - NAV_UNUSED1 = 0x10, - NAV_UNUSED2 = 0x20, - NAV_UNUSED3 = 0x40, - NAV_UNUSED4 = 0x80 - // we only have 8 bits + NAV_AREA_EMPTY = 0, + // areas 1-60 will be used for destructible areas (currently skipped in vmaps, WMO with flag 1) + // ground is the highest value to make recast choose ground over water when merging surfaces very close to each other (shallow water would be walkable) + NAV_AREA_GROUND = 63, + NAV_AREA_WATER = 62, + NAV_AREA_MAGMA_SLIME = 61 // don't need to differentiate between them +}; + +enum NavTerrainFlag +{ + NAV_EMPTY = 0x00, + NAV_GROUND = 1 << (63 - NAV_AREA_GROUND), + NAV_WATER = 1 << (63 - NAV_AREA_WATER), + NAV_MAGMA_SLIME = 1 << (63 - NAV_AREA_MAGMA_SLIME) }; #endif /* _MAPDEFINES_H */ diff --git a/src/common/Collision/Maps/TileAssembler.cpp b/src/common/Collision/Maps/TileAssembler.cpp index e9203ca7378..8a17dcb14fa 100644 --- a/src/common/Collision/Maps/TileAssembler.cpp +++ b/src/common/Collision/Maps/TileAssembler.cpp @@ -54,7 +54,7 @@ namespace VMAP //================================================================= TileAssembler::TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName) - : iDestDir(pDestDirName), iSrcDir(pSrcDirName), iFilterMethod(NULL), iCurrentUniqueNameId(0) + : iDestDir(pDestDirName), iSrcDir(pSrcDirName), iCurrentUniqueNameId(0) { boost::filesystem::create_directory(iDestDir); //init(); @@ -243,8 +243,10 @@ namespace VMAP printf("spawning Map %u\n", mapID); mapData[mapID] = current = new MapSpawns(); } - else current = map_iter->second; - current->UniqueEntries.insert(pair<uint32, ModelSpawn>(spawn.ID, spawn)); + else + current = map_iter->second; + + current->UniqueEntries.emplace(spawn.ID, spawn); current->TileEntries.insert(pair<uint32, TileSpawn>(StaticMapTree::packTileID(tileX, tileY), TileSpawn{ spawn.ID, spawn.flags })); } bool success = (ferror(dirf) == 0); diff --git a/src/common/Collision/Maps/TileAssembler.h b/src/common/Collision/Maps/TileAssembler.h index 8c3b3f5b88d..0a9f1f7f1a4 100644 --- a/src/common/Collision/Maps/TileAssembler.h +++ b/src/common/Collision/Maps/TileAssembler.h @@ -101,7 +101,6 @@ namespace VMAP private: std::string iDestDir; std::string iSrcDir; - bool (*iFilterMethod)(char *pName); G3D::Table<std::string, unsigned int > iUniqueNameIds; unsigned int iCurrentUniqueNameId; MapData mapData; @@ -117,8 +116,6 @@ namespace VMAP void exportGameobjectModels(); bool convertRawFile(const std::string& pModelFilename); - void setModelNameFilterMethod(bool (*pFilterMethod)(char *pName)) { iFilterMethod = pFilterMethod; } - std::string getDirEntryNameFromModName(unsigned int pMapId, const std::string& pModPosName); }; } // VMAP diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 86151360e90..94561531a8f 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -617,12 +617,12 @@ void PathGenerator::CreateFilter() // creatures don't take environmental damage if (creature->CanSwim()) - includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim + includeFlags |= (NAV_WATER | NAV_MAGMA_SLIME); // swim } else // assume Player { // perfect support not possible, just stay 'safe' - includeFlags |= (NAV_GROUND | NAV_WATER | NAV_MAGMA | NAV_SLIME); + includeFlags |= (NAV_GROUND | NAV_WATER | NAV_MAGMA_SLIME); } _filter.setIncludeFlags(includeFlags); @@ -646,7 +646,7 @@ void PathGenerator::UpdateFilter() } } -NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) +NavTerrainFlag PathGenerator::GetNavTerrain(float x, float y, float z) { LiquidData data; ZLiquidStatus liquidStatus = _sourceUnit->GetMap()->getLiquidStatus(_sourceUnit->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &data); @@ -660,9 +660,8 @@ NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) case MAP_LIQUID_TYPE_OCEAN: return NAV_WATER; case MAP_LIQUID_TYPE_MAGMA: - return NAV_MAGMA; case MAP_LIQUID_TYPE_SLIME: - return NAV_SLIME; + return NAV_MAGMA_SLIME; default: return NAV_GROUND; } diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h index 2884f8a1220..684537e7841 100644 --- a/src/server/game/Movement/PathGenerator.h +++ b/src/server/game/Movement/PathGenerator.h @@ -122,7 +122,7 @@ class TC_GAME_API PathGenerator void BuildPointPath(float const* startPoint, float const* endPoint); void BuildShortcut(); - NavTerrain GetNavTerrain(float x, float y, float z); + NavTerrainFlag GetNavTerrain(float x, float y, float z); void CreateFilter(); void UpdateFilter(); diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 279d1fe7afc..e569693a317 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -618,7 +618,7 @@ namespace MMAP // mark all walkable tiles, both liquids and solids unsigned char* triFlags = new unsigned char[tTriCount]; - memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char)); + memset(triFlags, NAV_AREA_GROUND, tTriCount*sizeof(unsigned char)); rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); delete[] triFlags; @@ -724,8 +724,15 @@ namespace MMAP // set polygons as walkable // TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off for (int i = 0; i < iv.polyMesh->npolys; ++i) - if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA) - iv.polyMesh->flags[i] = iv.polyMesh->areas[i]; + { + if (uint8 area = iv.polyMesh->areas[i] & RC_WALKABLE_AREA) + { + if (area >= NAV_AREA_MAGMA_SLIME) + iv.polyMesh->flags[i] = 1 << (63 - area); + else + iv.polyMesh->flags[i] = NAV_GROUND; // TODO: these will be dynamic in future + } + } // setup mesh parameters dtNavMeshCreateParams params; diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 035bddd9063..185fe287848 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -31,6 +31,11 @@ using namespace MMAP; +namespace +{ + std::unordered_map<uint32, uint8> _liquidTypes; +} + bool checkDirectories(bool debugOutput, std::vector<std::string>& dbcLocales) { if (getDirContents(dbcLocales, "dbc") == LISTFILE_DIRECTORY_NOT_FOUND || dbcLocales.empty()) @@ -260,6 +265,43 @@ int finish(const char* message, int returnValue) return returnValue; } +std::unordered_map<uint32, uint8> LoadLiquid(std::string const& locale) +{ + DB2FileLoader liquidDb2; + std::unordered_map<uint32, uint8> liquidData; + DB2FileSystemSource liquidTypeSource((boost::filesystem::path("dbc") / locale / "LiquidType.db2").string()); + if (liquidDb2.Load(&liquidTypeSource, LiquidTypeLoadInfo::Instance())) + { + for (uint32 x = 0; x < liquidDb2.GetRecordCount(); ++x) + { + DB2Record record = liquidDb2.GetRecord(x); + liquidData[record.GetId()] = record.GetUInt8("SoundBank"); + } + } + + return liquidData; +} + +std::unordered_map<uint32, std::vector<uint32>> LoadMap(std::string const& locale) +{ + DB2FileLoader mapDb2; + std::unordered_map<uint32, std::vector<uint32>> mapData; + DB2FileSystemSource mapSource((boost::filesystem::path("dbc") / locale / "Map.db2").string()); + if (mapDb2.Load(&mapSource, MapLoadInfo::Instance())) + { + 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()); + } + } + + return mapData; +} + int main(int argc, char** argv) { Trinity::Banner::Show("MMAP generator", [](char const* text) { printf("%s\n", text); }, nullptr); @@ -302,25 +344,20 @@ int main(int argc, char** argv) 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); + _liquidTypes = LoadLiquid(dbcLocales[0]); + if (_liquidTypes.empty()) + return silent ? -5 : finish("Failed to load LiquidType.db2", -5); - 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()); - } + std::unordered_map<uint32, std::vector<uint32>> mapData = LoadMap(dbcLocales[0]); + if (mapData.empty()) + return silent ? -4 : finish("Failed to load Map.db2", -4); - static_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager())->InitializeThreadUnsafe(mapData); - } + static_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager())->InitializeThreadUnsafe(mapData); + static_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager())->GetLiquidFlagsPtr = [](uint32 liquidId) -> uint32 + { + auto itr = _liquidTypes.find(liquidId); + return itr != _liquidTypes.end() ? (1 << itr->second) : 0; + }; MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 91ada500f97..1921cb9af2d 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -425,11 +425,9 @@ namespace MMAP useLiquid = false; } else if ((liquidType & (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN)) != 0) - liquidType = NAV_WATER; - else if (liquidType & MAP_LIQUID_TYPE_MAGMA) - liquidType = NAV_MAGMA; - else if (liquidType & MAP_LIQUID_TYPE_SLIME) - liquidType = NAV_SLIME; + liquidType = NAV_AREA_WATER; + else if ((liquidType & (MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME)) != 0) + liquidType = NAV_AREA_MAGMA_SLIME; else useLiquid = false; } @@ -716,22 +714,14 @@ namespace MMAP vertsY = tilesY + 1; uint8* flags = liquid->GetFlagsStorage(); float* data = liquid->GetHeightStorage(); - uint8 type = NAV_EMPTY; + uint8 type = NAV_AREA_EMPTY; // convert liquid type to NavTerrain - switch (liquid->GetType() & 3) - { - case 0: - case 1: - type = NAV_WATER; - break; - case 2: - type = NAV_MAGMA; - break; - case 3: - type = NAV_SLIME; - break; - } + uint32 liquidFlags = vmapManager->GetLiquidFlagsPtr(liquid->GetType()); + if ((liquidFlags & (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN)) != 0) + type = NAV_AREA_WATER; + else if ((liquidFlags & (MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME)) != 0) + type = NAV_AREA_MAGMA_SLIME; // indexing is weird... // after a lot of trial and error, this is what works: |