From e8586b0bcba13416f0bf62ca8f1bbdbd8d7438e2 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Sun, 8 Apr 2018 16:30:22 +0200 Subject: [PATCH] Tools/mmaps_generator: fixed processing liquids broken in e5d23103f37c40d2e946fa0e2db66d2f527ad9af --- src/server/game/Maps/Map.cpp | 2 +- src/tools/map_extractor/System.cpp | 37 +++-- src/tools/map_extractor/adt.h | 8 + src/tools/mmaps_generator/TerrainBuilder.cpp | 161 ++++++++++--------- src/tools/mmaps_generator/TerrainBuilder.h | 2 +- 5 files changed, 116 insertions(+), 94 deletions(-) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 3b310a7b5c9..4f9a9d38261 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -46,7 +46,7 @@ #include "WeatherMgr.h" u_map_magic MapMagic = { {'M','A','P','S'} }; -u_map_magic MapVersionMagic = { {'v','1','.','6'} }; +u_map_magic MapVersionMagic = { {'v','1','.','7'} }; u_map_magic MapAreaMagic = { {'A','R','E','A'} }; u_map_magic MapHeightMagic = { {'M','H','G','T'} }; u_map_magic MapLiquidMagic = { {'M','L','I','Q'} }; diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 6a648e853a6..b84e80914aa 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -416,7 +416,7 @@ void ReadLiquidTypeTable() // Map file format data static char const* MAP_MAGIC = "MAPS"; -static char const* MAP_VERSION_MAGIC = "v1.6"; +static char const* MAP_VERSION_MAGIC = "v1.7"; static char const* MAP_AREA_MAGIC = "AREA"; static char const* MAP_HEIGHT_MAGIC = "MHGT"; static char const* MAP_LIQUID_MAGIC = "MLIQ"; @@ -464,7 +464,6 @@ struct map_heightHeader #define MAP_LIQUID_TYPE_SLIME 0x08 #define MAP_LIQUID_TYPE_DARK_WATER 0x10 -#define MAP_LIQUID_TYPE_WMO_WATER 0x20 #define MAP_LIQUID_NO_TYPE 0x0001 @@ -473,7 +472,8 @@ struct map_heightHeader struct map_liquidHeader { uint32 fourcc; - uint16 flags; + uint8 flags; + uint8 liquidFlags; uint16 liquidType; uint8 offsetX; uint8 offsetY; @@ -848,8 +848,8 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, } } - liquid_entry[i][j] = h->LiquidType; - switch (LiquidTypes.at(h->LiquidType).SoundBank) + liquid_entry[i][j] = h2o->GetLiquidType(h); + switch (LiquidTypes.at(liquid_entry[i][j]).SoundBank) { case LIQUID_TYPE_WATER: liquid_flags[i][j] |= MAP_LIQUID_TYPE_WATER; break; case LIQUID_TYPE_OCEAN: liquid_flags[i][j] |= MAP_LIQUID_TYPE_OCEAN; if (!ignoreDeepWater && attrs.Deep) liquid_flags[i][j] |= MAP_LIQUID_TYPE_DARK_WATER; break; @@ -883,13 +883,14 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, //============================================ // Pack liquid data //============================================ - uint8 type = liquid_flags[0][0]; + uint16 firstLiquidType = liquid_entry[0][0]; + uint8 firstLiquidFlag = liquid_flags[0][0]; bool fullType = false; for (int y = 0; y < ADT_CELLS_PER_GRID; y++) { for (int x = 0; x < ADT_CELLS_PER_GRID; x++) { - if (liquid_flags[y][x] != type) + if (liquid_entry[y][x] != firstLiquidType || liquid_flags[y][x] != firstLiquidFlag) { fullType = true; y = ADT_CELLS_PER_GRID; @@ -901,7 +902,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, map_liquidHeader liquidHeader; // no water data (if all grid have 0 liquid type) - if (type == 0 && !fullType) + if (firstLiquidFlag == 0 && !fullType) { // No liquid data map.liquidMapOffset = 0; @@ -953,7 +954,10 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, liquidHeader.flags |= MAP_LIQUID_NO_TYPE; if (liquidHeader.flags & MAP_LIQUID_NO_TYPE) - liquidHeader.liquidType = type; + { + liquidHeader.liquidFlags = firstLiquidFlag; + liquidHeader.liquidType = firstLiquidType; + } else map.liquidMapSize += sizeof(liquid_entry) + sizeof(liquid_flags); @@ -964,11 +968,6 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, // map hole info uint16 holes[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; - if (map.liquidMapOffset) - map.holesOffset = map.liquidMapOffset + map.liquidMapSize; - else - map.holesOffset = map.heightMapOffset + map.heightMapSize; - memset(holes, 0, sizeof(holes)); bool hasHoles = false; @@ -986,9 +985,19 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, } if (hasHoles) + { + if (map.liquidMapOffset) + map.holesOffset = map.liquidMapOffset + map.liquidMapSize; + else + map.holesOffset = map.heightMapOffset + map.heightMapSize; + map.holesSize = sizeof(holes); + } else + { + map.holesOffset = 0; map.holesSize = 0; + } // Ok all data prepared - store it FILE* output = fopen(filename2, "wb"); diff --git a/src/tools/map_extractor/adt.h b/src/tools/map_extractor/adt.h index d71ee143dd4..29d3dbde9f7 100644 --- a/src/tools/map_extractor/adt.h +++ b/src/tools/map_extractor/adt.h @@ -250,6 +250,14 @@ public: return { 0, 0 }; } + uint16 GetLiquidType(adt_liquid_instance const* h) const + { + if (GetLiquidVertexFormat(h) == LiquidVertexFormatType::Depth) + return 2; + + return h->LiquidType; + } + float GetLiquidHeight(adt_liquid_instance const* h, int32 pos) const { if (!h->OffsetVertexData) diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index e2aa8fe7f8a..9bca0dc04dd 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -60,7 +60,8 @@ struct map_heightHeader struct map_liquidHeader { uint32 fourcc; - uint16 flags; + uint8 flags; + uint8 liquidFlags; uint16 liquidType; uint8 offsetX; uint8 offsetY; @@ -75,12 +76,10 @@ struct map_liquidHeader #define MAP_LIQUID_TYPE_MAGMA 0x04 #define MAP_LIQUID_TYPE_SLIME 0x08 #define MAP_LIQUID_TYPE_DARK_WATER 0x10 -#define MAP_LIQUID_TYPE_WMO_WATER 0x20 namespace MMAP { - - char const* MAP_VERSION_MAGIC = "v1.6"; + char const* MAP_VERSION_MAGIC = "v1.7"; TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } TerrainBuilder::~TerrainBuilder() { } @@ -180,8 +179,10 @@ namespace MMAP // data used later uint16 holes[16][16]; memset(holes, 0, sizeof(holes)); - uint8 liquid_type[16][16]; - memset(liquid_type, 0, sizeof(liquid_type)); + uint16 liquid_entry[16][16]; + memset(liquid_entry, 0, sizeof(liquid_entry)); + uint8 liquid_flags[16][16]; + memset(liquid_flags, 0, sizeof(liquid_flags)); G3D::Array ltriangles; G3D::Array ttriangles; @@ -293,75 +294,87 @@ namespace MMAP float* liquid_map = nullptr; if (!(lheader.flags & MAP_LIQUID_NO_TYPE)) - if (fread(liquid_type, sizeof(liquid_type), 1, mapFile) != 1) + { + if (fread(liquid_entry, sizeof(liquid_entry), 1, mapFile) != 1) printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); + if (fread(liquid_flags, sizeof(liquid_flags), 1, mapFile) != 1) + printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); + } + else + { + std::fill_n(&liquid_entry[0][0], 16 * 16, lheader.liquidType); + std::fill_n(&liquid_flags[0][0], 16 * 16, lheader.liquidFlags); + } if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) { uint32 toRead = lheader.width * lheader.height; - liquid_map = new float [toRead]; + liquid_map = new float[toRead]; if (fread(liquid_map, sizeof(float), toRead, mapFile) != toRead) + { printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); + delete[] liquid_map; + liquid_map = nullptr; + } } - if (liquid_map) + int count = meshData.liquidVerts.size() / 3; + float xoffset = (float(tileX) - 32)*GRID_SIZE; + float yoffset = (float(tileY) - 32)*GRID_SIZE; + + float coord[3]; + int row, col; + + // generate coordinates + if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) { - int count = meshData.liquidVerts.size() / 3; - float xoffset = (float(tileX)-32)*GRID_SIZE; - float yoffset = (float(tileY)-32)*GRID_SIZE; - - float coord[3]; - int row, col; - - // generate coordinates - if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) + int j = 0; + for (int i = 0; i < V9_SIZE_SQ; ++i) { - int j = 0; - for (int i = 0; i < V9_SIZE_SQ; ++i) + row = i / V9_SIZE; + col = i % V9_SIZE; + + if (row < lheader.offsetY || row >= lheader.offsetY + lheader.height || + col < lheader.offsetX || col >= lheader.offsetX + lheader.width) { - row = i / V9_SIZE; - col = i % V9_SIZE; - - if (row < lheader.offsetY || row >= lheader.offsetY + lheader.height || - col < lheader.offsetX || col >= lheader.offsetX + lheader.width) - { - // dummy vert using invalid height - meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, INVALID_MAP_LIQ_HEIGHT, (yoffset+row*GRID_PART_SIZE)*-1); - continue; - } - - getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map); - meshData.liquidVerts.append(coord[0]); - meshData.liquidVerts.append(coord[2]); - meshData.liquidVerts.append(coord[1]); - j++; + // dummy vert using invalid height + meshData.liquidVerts.append((xoffset + col * GRID_PART_SIZE)*-1, INVALID_MAP_LIQ_HEIGHT, (yoffset + row * GRID_PART_SIZE)*-1); + continue; } + + getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map); + meshData.liquidVerts.append(coord[0]); + meshData.liquidVerts.append(coord[2]); + meshData.liquidVerts.append(coord[1]); + j++; } - else + } + else + { + for (int i = 0; i < V9_SIZE_SQ; ++i) { - for (int i = 0; i < V9_SIZE_SQ; ++i) - { - row = i / V9_SIZE; - col = i % V9_SIZE; - meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset+row*GRID_PART_SIZE)*-1); - } + row = i / V9_SIZE; + col = i % V9_SIZE; + meshData.liquidVerts.append((xoffset + col * GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset + row * GRID_PART_SIZE)*-1); } + } - delete [] liquid_map; + delete[] liquid_map; - int indices[] = { 0, 0, 0 }; - int loopStart = 0, loopEnd = 0, loopInc = 0, triInc = BOTTOM-TOP; - getLoopVars(portion, loopStart, loopEnd, loopInc); + int indices[] = { 0, 0, 0 }; + int loopStart = 0, loopEnd = 0, loopInc = 0, triInc = BOTTOM - TOP; + getLoopVars(portion, loopStart, loopEnd, loopInc); - // generate triangles - for (int i = loopStart; i < loopEnd; i+=loopInc) - for (int j = TOP; j <= BOTTOM; j+= triInc) - { - getHeightTriangle(i, Spot(j), indices, true); - ltriangles.append(indices[2] + count); - ltriangles.append(indices[1] + count); - ltriangles.append(indices[0] + count); - } + // generate triangles + for (int i = loopStart; i < loopEnd; i += loopInc) + { + for (int j = TOP; j <= BOTTOM; j += triInc) + { + getHeightTriangle(i, Spot(j), indices, true); + ltriangles.append(indices[2] + count); + ltriangles.append(indices[1] + count); + ltriangles.append(indices[0] + count); + } } } @@ -405,29 +418,21 @@ namespace MMAP useLiquid = false; else { - liquidType = getLiquidType(i, liquid_type); - switch (liquidType) + liquidType = getLiquidType(i, liquid_flags); + if (liquidType & MAP_LIQUID_TYPE_DARK_WATER) { - default: - useLiquid = false; - break; - case MAP_LIQUID_TYPE_WATER: - case MAP_LIQUID_TYPE_OCEAN: - // merge different types of water - liquidType = NAV_WATER; - break; - case MAP_LIQUID_TYPE_MAGMA: - liquidType = NAV_MAGMA; - break; - case MAP_LIQUID_TYPE_SLIME: - liquidType = NAV_SLIME; - break; - case MAP_LIQUID_TYPE_DARK_WATER: - // players should not be here, so logically neither should creatures - useTerrain = false; - useLiquid = false; - break; + // players should not be here, so logically neither should creatures + useTerrain = false; + 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; + else + useLiquid = false; } // if there is no terrain, don't use terrain @@ -705,7 +710,7 @@ namespace MMAP copyIndices(tempTriangles, meshData.solidTris, offset, isM2); // now handle liquid data - if (liquid) + if (liquid && liquid->GetFlagsStorage()) { std::vector liqVerts; std::vector liqTris; diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index 71bccd8e946..15cd974375f 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -51,7 +51,7 @@ namespace MMAP static const float GRID_PART_SIZE = GRID_SIZE/V8_SIZE; // see contrib/extractor/system.cpp, CONF_use_minHeight - static const float INVALID_MAP_LIQ_HEIGHT = -500.f; + static const float INVALID_MAP_LIQ_HEIGHT = -2000.f; static const float INVALID_MAP_LIQ_HEIGHT_MAX = 5000.0f; // see following files: