summaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/map_extractor/System.cpp113
-rw-r--r--src/tools/map_extractor/adt.h137
-rw-r--r--src/tools/mmaps_generator/TerrainBuilder.cpp122
-rw-r--r--src/tools/vmap4_extractor/adtfile.h86
-rw-r--r--src/tools/vmap4_extractor/vmapexport.cpp2
-rw-r--r--src/tools/vmap4_extractor/vmapexport.h4
-rw-r--r--src/tools/vmap4_extractor/wmo.cpp125
-rw-r--r--src/tools/vmap4_extractor/wmo.h12
8 files changed, 288 insertions, 313 deletions
diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp
index 62ac294ace..6e62cfa15c 100644
--- a/src/tools/map_extractor/System.cpp
+++ b/src/tools/map_extractor/System.cpp
@@ -22,6 +22,7 @@
#include <deque>
#include <filesystem>
#include <set>
+#include <unordered_map>
#ifdef _WIN32
#include "direct.h"
@@ -62,8 +63,13 @@ typedef struct
uint32 id;
} map_id;
-map_id* map_ids;
-uint16* LiqType;
+struct LiquidTypeEntry
+{
+ uint8 SoundBank;
+};
+
+std::vector<map_id> map_ids;
+std::unordered_map<uint32, LiquidTypeEntry> LiquidTypes;
#define MAX_PATH_LENGTH 128
char output_path[MAX_PATH_LENGTH] = ".";
char input_path[MAX_PATH_LENGTH] = ".";
@@ -271,7 +277,7 @@ uint32 ReadMapDBC()
}
size_t map_count = dbc.getRecordCount();
- map_ids = new map_id[map_count];
+ map_ids.resize(map_count);
for (uint32 x = 0; x < map_count; ++x)
{
map_ids[x].id = dbc.getRecord(x).getUInt(0);
@@ -291,15 +297,13 @@ void ReadLiquidTypeTableDBC()
exit(1);
}
- size_t liqTypeCount = dbc.getRecordCount();
- size_t liqTypeMaxId = dbc.getMaxId();
- LiqType = new uint16[liqTypeMaxId + 1];
- memset(LiqType, 0xff, (liqTypeMaxId + 1) * sizeof(uint16));
-
- for (uint32 x = 0; x < liqTypeCount; ++x)
- LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
+ for (uint32 x = 0; x < dbc.getRecordCount(); ++x)
+ {
+ LiquidTypeEntry& liquidType = LiquidTypes[dbc.getRecord(x).getUInt(0)];
+ liquidType.SoundBank = dbc.getRecord(x).getUInt(3);
+ }
- printf("Done! (%u LiqTypes loaded)\n", (uint32)liqTypeCount);
+ printf("Done! (%lu LiquidTypes loaded)\n", LiquidTypes.size());
}
//
@@ -357,7 +361,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
#define MAP_LIQUID_NO_HEIGHT 0x0002
@@ -365,7 +368,8 @@ struct map_heightHeader
struct map_liquidHeader
{
uint32 fourcc;
- uint16 flags;
+ uint8 flags;
+ uint8 liquidFlags;
uint16 liquidType;
uint8 offsetX;
uint8 offsetY;
@@ -720,73 +724,57 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int
adt_MH2O* h2o = adt.a_grid->getMH2O();
if (h2o)
{
- for (int i = 0; i < ADT_CELLS_PER_GRID; i++)
+ for (int32 i = 0; i < ADT_CELLS_PER_GRID; i++)
{
- for (int j = 0; j < ADT_CELLS_PER_GRID; j++)
+ for (int32 j = 0; j < ADT_CELLS_PER_GRID; j++)
{
- adt_liquid_header* h = h2o->getLiquidData(i, j);
+ adt_liquid_instance const* h = h2o->GetLiquidInstance(i,j);
if (!h)
continue;
- int count = 0;
- uint64 show = h2o->getLiquidShowMap(h);
- for (int y = 0; y < h->height; y++)
+ adt_liquid_attributes attrs = h2o->GetLiquidAttributes(i, j);
+
+ int32 count = 0;
+ uint64 existsMask = h2o->GetLiquidExistsBitmap(h);
+ for (int32 y = 0; y < h->GetHeight(); y++)
{
- int cy = i * ADT_CELL_SIZE + y + h->yOffset;
- for (int x = 0; x < h->width; x++)
+ int32 cy = i * ADT_CELL_SIZE + y + h->GetOffsetY();
+ for (int32 x = 0; x < h->GetWidth(); x++)
{
- int cx = j * ADT_CELL_SIZE + x + h->xOffset;
- if (show & 1)
+ int32 cx = j * ADT_CELL_SIZE + x + h->GetOffsetX();
+ if (existsMask & 1)
{
liquid_show[cy][cx] = true;
++count;
}
- show >>= 1;
+ existsMask >>= 1;
}
}
- liquid_entry[i][j] = h->liquidType;
- switch (LiqType[h->liquidType])
+ liquid_entry[i][j] = h->LiquidType;
+ switch (LiquidTypes.at(h->LiquidType).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;
- break;
- case LIQUID_TYPE_MAGMA:
- liquid_flags[i][j] |= MAP_LIQUID_TYPE_MAGMA;
- break;
- case LIQUID_TYPE_SLIME:
- liquid_flags[i][j] |= MAP_LIQUID_TYPE_SLIME;
- break;
+ 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 (attrs.Deep) liquid_flags[i][j] |= MAP_LIQUID_TYPE_DARK_WATER; break;
+ case LIQUID_TYPE_MAGMA: liquid_flags[i][j] |= MAP_LIQUID_TYPE_MAGMA; break;
+ case LIQUID_TYPE_SLIME: liquid_flags[i][j] |= MAP_LIQUID_TYPE_SLIME; break;
default:
- printf("\nCan't find Liquid type %u for map %s\nchunk %d,%d\n", h->liquidType, inputPath.c_str(), i, j);
+ printf("\nCan't find Liquid type %u for map %s\nchunk %d,%d\n", h->LiquidType, inputPath.c_str(), i, j);
break;
}
- // Dark water detect
- if (LiqType[h->liquidType] == LIQUID_TYPE_OCEAN)
- {
- uint8* lm = h2o->getLiquidLightMap(h);
- if (!lm)
- liquid_flags[i][j] |= MAP_LIQUID_TYPE_DARK_WATER;
- }
if (!count && liquid_flags[i][j])
printf("Wrong liquid detect in MH2O chunk");
- float* height = h2o->getLiquidHeightMap(h);
- int pos = 0;
- for (int y = 0; y <= h->height; y++)
+ int32 pos = 0;
+ for (int32 y = 0; y <= h->GetHeight(); y++)
{
- int cy = i * ADT_CELL_SIZE + y + h->yOffset;
- for (int x = 0; x <= h->width; x++)
+ int cy = i * ADT_CELL_SIZE + y + h->GetOffsetY();
+ for (int32 x = 0; x <= h->GetWidth(); x++)
{
- int cx = j * ADT_CELL_SIZE + x + h->xOffset;
- if (height)
- liquid_height[cy][cx] = height[pos];
- else
- liquid_height[cy][cx] = h->heightLevel1;
+ int32 cx = j * ADT_CELL_SIZE + x + h->GetOffsetX();
+ liquid_height[cy][cx] = h2o->GetLiquidHeight(h, pos);
+
pos++;
}
}
@@ -796,13 +784,14 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int
//============================================
// 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;
@@ -814,7 +803,7 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int
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;
@@ -873,7 +862,10 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int
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);
@@ -1020,7 +1012,6 @@ void ExtractMapsFromMpq(uint32 build)
}
}
printf("\n");
- delete[] map_ids;
}
bool ExtractFile( char const* mpq_name, std::string const& filename )
diff --git a/src/tools/map_extractor/adt.h b/src/tools/map_extractor/adt.h
index e6f94a8825..01917e66f9 100644
--- a/src/tools/map_extractor/adt.h
+++ b/src/tools/map_extractor/adt.h
@@ -177,21 +177,36 @@ public:
}
};
-#define ADT_LIQUID_HEADER_FULL_LIGHT 0x01
-#define ADT_LIQUID_HEADER_NO_HIGHT 0x02
+enum class LiquidVertexFormatType : uint16
+{
+ HeightDepth = 0,
+ HeightTextureCoord = 1,
+ Depth = 2,
+};
-struct adt_liquid_header
+struct adt_liquid_instance
{
- uint16 liquidType; // Index from LiquidType.dbc
- uint16 formatFlags;
- float heightLevel1;
- float heightLevel2;
- uint8 xOffset;
- uint8 yOffset;
- uint8 width;
- uint8 height;
- uint32 offsData2a;
- uint32 offsData2b;
+ uint16 LiquidType; // Index from LiquidType.db2
+ LiquidVertexFormatType LiquidVertexFormat;
+ float MinHeightLevel;
+ float MaxHeightLevel;
+ uint8 OffsetX;
+ uint8 OffsetY;
+ uint8 Width;
+ uint8 Height;
+ uint32 OffsetExistsBitmap;
+ uint32 OffsetVertexData;
+
+ uint8 GetOffsetX() const { return OffsetX; }
+ uint8 GetOffsetY() const { return OffsetY; }
+ uint8 GetWidth() const { return Width; }
+ uint8 GetHeight() const { return Height; }
+};
+
+struct adt_liquid_attributes
+{
+ uint64 Fishable;
+ uint64 Deep;
};
//
@@ -209,59 +224,99 @@ public:
struct adt_LIQUID
{
- uint32 offsData1;
+ uint32 OffsetInstances;
uint32 used;
- uint32 offsData2;
+ uint32 OffsetAttributes;
} liquid[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
bool prepareLoadedData();
- adt_liquid_header* getLiquidData(int x, int y)
+ adt_liquid_instance const* GetLiquidInstance(int32 x, int32 y) const
{
- if (liquid[x][y].used && liquid[x][y].offsData1)
- return (adt_liquid_header*)((uint8*)this + 8 + liquid[x][y].offsData1);
+ if (liquid[x][y].used && liquid[x][y].OffsetInstances)
+ return (adt_liquid_instance *)((uint8*)this + 8 + liquid[x][y].OffsetInstances);
return nullptr;
}
- float* getLiquidHeightMap(adt_liquid_header* h)
+ adt_liquid_attributes GetLiquidAttributes(int32 x, int32 y) const
{
- if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT)
- return nullptr;
- if (h->offsData2b)
- return (float*)((uint8*)this + 8 + h->offsData2b);
- return nullptr;
+ if (liquid[x][y].used)
+ {
+ if (liquid[x][y].OffsetAttributes)
+ return *((adt_liquid_attributes *)((uint8*)this + 8 + liquid[x][y].OffsetAttributes));
+ return { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF };
+ }
+ return { 0, 0 };
}
- uint8* getLiquidLightMap(adt_liquid_header* h)
+ uint16 GetLiquidType(adt_liquid_instance const* h) const
{
- if (h->formatFlags & ADT_LIQUID_HEADER_FULL_LIGHT)
- return nullptr;
- if (h->offsData2b)
+ if (h->LiquidVertexFormat == LiquidVertexFormatType::Depth)
+ return 2;
+
+ return h->LiquidType;
+ }
+
+ float GetLiquidHeight(adt_liquid_instance const* h, int32 pos) const
+ {
+ if (!h->OffsetVertexData)
+ return 0.0f;
+
+ switch (h->LiquidVertexFormat)
{
- if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT)
- return (uint8*)((uint8*)this + 8 + h->offsData2b);
- return (uint8*)((uint8*)this + 8 + h->offsData2b + (h->width + 1) * (h->height + 1) * 4);
+ case LiquidVertexFormatType::HeightDepth:
+ case LiquidVertexFormatType::HeightTextureCoord:
+ return ((float const*)((uint8*)this + 8 + h->OffsetVertexData))[pos];
+ case LiquidVertexFormatType::Depth:
+ return 0.0f;
+ default:
+ break;
}
- return nullptr;
+
+ return 0.0f;
+ }
+
+ int8 GetLiquidDepth(adt_liquid_instance const* h, int32 pos) const
+ {
+ if (!h->OffsetVertexData)
+ return -1;
+
+ switch (h->LiquidVertexFormat)
+ {
+ case LiquidVertexFormatType::HeightDepth:
+ return ((int8 const*)((int8 const*)this + 8 + h->OffsetVertexData + (h->GetWidth() + 1) * (h->GetHeight() + 1) * 4))[pos];
+ case LiquidVertexFormatType::HeightTextureCoord:
+ return 0;
+ case LiquidVertexFormatType::Depth:
+ return ((int8 const*)((uint8*)this + 8 + h->OffsetVertexData))[pos];
+ default:
+ break;
+ }
+ return 0;
}
- uint32* getLiquidFullLightMap(adt_liquid_header* h)
+ uint16 const* GetLiquidTextureCoordMap(adt_liquid_instance const* h, int32 pos) const
{
- if (!(h->formatFlags & ADT_LIQUID_HEADER_FULL_LIGHT))
+ if (!h->OffsetVertexData)
return nullptr;
- if (h->offsData2b)
+
+ switch (h->LiquidVertexFormat)
{
- if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT)
- return (uint32*)((uint8*)this + 8 + h->offsData2b);
- return (uint32*)((uint8*)this + 8 + h->offsData2b + (h->width + 1) * (h->height + 1) * 4);
+ case LiquidVertexFormatType::HeightDepth:
+ case LiquidVertexFormatType::Depth:
+ return nullptr;
+ case LiquidVertexFormatType::HeightTextureCoord:
+ return (uint16 const*)((uint8 const*)this + 8 + h->OffsetVertexData + 4 * ((h->GetWidth() + 1) * (h->GetHeight() + 1) + pos));
+ default:
+ break;
}
return nullptr;
}
- uint64 getLiquidShowMap(adt_liquid_header* h)
+ uint64 GetLiquidExistsBitmap(adt_liquid_instance const* h) const
{
- if (h->offsData2a)
- return *((uint64*)((uint8*)this + 8 + h->offsData2a));
+ if (h->OffsetExistsBitmap)
+ return *((uint64 *)((uint8*)this + 8 + h->OffsetExistsBitmap));
else
return 0xFFFFFFFFFFFFFFFFuLL;
}
diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp
index fa0581f98c..04e4ac76cd 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,7 +76,6 @@ 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
uint32 GetLiquidFlags(uint32 liquidId);
@@ -172,8 +172,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<int> ltriangles;
G3D::Array<int> ttriangles;
@@ -284,75 +286,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];
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;
+ 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;
+ float coord[3];
+ int row, col;
- // generate coordinates
- if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT))
+ // 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;
+ 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++;
+ 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++;
}
- 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);
+ }
}
}
@@ -399,7 +413,7 @@ namespace MMAP
}
else
{
- liquidType = getLiquidType(i, liquid_type);
+ liquidType = getLiquidType(i, liquid_flags);
if (liquidType & MAP_LIQUID_TYPE_DARK_WATER)
{
// players should not be here, so logically neither should creatures
@@ -708,7 +722,7 @@ namespace MMAP
copyIndices(tempTriangles, meshData.solidTris, offset, isM2);
// now handle liquid data
- if (liquid)
+ if (liquid && liquid->GetFlagsStorage())
{
std::vector<G3D::Vector3> liqVerts;
std::vector<int> liqTris;
diff --git a/src/tools/vmap4_extractor/adtfile.h b/src/tools/vmap4_extractor/adtfile.h
index ce6182cc28..f91a215dd8 100644
--- a/src/tools/vmap4_extractor/adtfile.h
+++ b/src/tools/vmap4_extractor/adtfile.h
@@ -22,91 +22,7 @@
#include "mpq_libmpq04.h"
#include "wmo.h"
-#define TILESIZE (533.33333f)
-#define CHUNKSIZE ((TILESIZE) / 16.0f)
-#define UNITSIZE (CHUNKSIZE / 8.0f)
-
-class Liquid;
-
-typedef struct
-{
- float x;
- float y;
- float z;
-} svec;
-
-struct vec
-{
- double x;
- double y;
- double z;
-};
-
-struct triangle
-{
- vec v[3];
-};
-
-typedef struct
-{
- float v9[16 * 8 + 1][16 * 8 + 1];
- float v8[16 * 8][16 * 8];
-} Cell;
-
-typedef struct
-{
- double v9[9][9];
- double v8[8][8];
- uint16 area_id;
- //Liquid *lq;
- float waterlevel[9][9];
- uint8 flag;
-} chunk;
-
-typedef struct
-{
- chunk ch[16][16];
-} mcell;
-
-struct MapChunkHeader
-{
- uint32 flags;
- uint32 ix;
- uint32 iy;
- uint32 nLayers;
- uint32 nDoodadRefs;
- uint32 ofsHeight;
- uint32 ofsNormal;
- uint32 ofsLayer;
- uint32 ofsRefs;
- uint32 ofsAlpha;
- uint32 sizeAlpha;
- uint32 ofsShadow;
- uint32 sizeShadow;
- uint32 areaid;
- uint32 nMapObjRefs;
- uint32 holes;
- uint16 s1;
- uint16 s2;
- uint32 d1;
- uint32 d2;
- uint32 d3;
- uint32 predTex;
- uint32 nEffectDoodad;
- uint32 ofsSndEmitters;
- uint32 nSndEmitters;
- uint32 ofsLiquid;
- uint32 sizeLiquid;
- float zpos;
- float xpos;
- float ypos;
- uint32 textureId;
- uint32 props;
- uint32 effectId;
-};
-
#pragma pack(push, 1)
-
namespace ADT
{
struct MDDF
@@ -127,7 +43,7 @@ namespace ADT
Vec3D Rotation;
AaBox3D Bounds;
uint16 Flags;
- uint16 DoodadSet; // can be larger than number of doodad sets in WMO
+ uint16 DoodadSet;
uint16 NameSet;
uint16 Scale;
};
diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp
index 1b334d432a..38ae3b9355 100644
--- a/src/tools/vmap4_extractor/vmapexport.cpp
+++ b/src/tools/vmap4_extractor/vmapexport.cpp
@@ -163,7 +163,7 @@ bool ExtractSingleWmo(std::string& fname)
string s = groupFileName;
WMOGroup fgroup(s);
- if (!fgroup.open())
+ if (!fgroup.open(&froot))
{
printf("Could not open all Group file for: %s\n", plain_name);
file_ok = false;
diff --git a/src/tools/vmap4_extractor/vmapexport.h b/src/tools/vmap4_extractor/vmapexport.h
index 096f84b7f9..4f51ae165f 100644
--- a/src/tools/vmap4_extractor/vmapexport.h
+++ b/src/tools/vmap4_extractor/vmapexport.h
@@ -24,8 +24,8 @@
namespace VMAP
{
- const char VMAP_MAGIC[] = "VMAP_4.6";
- const char RAW_VMAP_MAGIC[] = "VMAP046"; // used in extracted vmap files with raw data
+ const char VMAP_MAGIC[] = "VMAP_4.7";
+ const char RAW_VMAP_MAGIC[] = "VMAP047"; // used in extracted vmap files with raw data
}
enum ModelFlags
diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp
index 885a8f4bdf..a7b94a24f2 100644
--- a/src/tools/vmap4_extractor/wmo.cpp
+++ b/src/tools/vmap4_extractor/wmo.cpp
@@ -30,7 +30,7 @@
WMORoot::WMORoot(std::string const& filename)
: filename(filename), color(0), nTextures(0), nGroups(0), nPortals(0), nLights(0),
- nDoodadNames(0), nDoodadDefs(0), nDoodadSets(0), RootWMOID(0), liquidType(0)
+ nDoodadNames(0), nDoodadDefs(0), nDoodadSets(0), RootWMOID(0), flags(0)
{
memset(bbcorn1, 0, sizeof(bbcorn1));
memset(bbcorn2, 0, sizeof(bbcorn2));
@@ -71,7 +71,7 @@ bool WMORoot::open()
f.read(&RootWMOID, 4);
f.read(bbcorn1, 12);
f.read(bbcorn2, 12);
- f.read(&liquidType, 4);
+ f.read(&flags, 4);
}
else if (!strcmp(fourcc, "MODS"))
{
@@ -158,14 +158,14 @@ WMOGroup::WMOGroup(std::string const& filename) :
filename(std::move(filename)), MOPY(nullptr), MOVI(nullptr), MoviEx(nullptr), MOVT(nullptr), MOBA(nullptr), MobaEx(nullptr),
hlq(nullptr), LiquEx(nullptr), LiquBytes(nullptr), groupName(0), descGroupName(0), mogpFlags(0),
moprIdx(0), moprNItems(0), nBatchA(0), nBatchB(0), nBatchC(0), fogIdx(0),
- liquidType(0), groupWMOID(0), mopy_size(0), moba_size(0), LiquEx_size(0),
+ groupLiquid(0), groupWMOID(0), mopy_size(0), moba_size(0), LiquEx_size(0),
nVertices(0), nTriangles(0), liquflags(0)
{
memset(bbcorn1, 0, sizeof(bbcorn1));
memset(bbcorn2, 0, sizeof(bbcorn2));
}
-bool WMOGroup::open()
+bool WMOGroup::open(WMORoot* rootWMO)
{
MPQFile f(filename.c_str());
if (f.isEof ())
@@ -202,8 +202,19 @@ bool WMOGroup::open()
f.read(&nBatchB, 2);
f.read(&nBatchC, 4);
f.read(&fogIdx, 4);
- f.read(&liquidType, 4);
+ f.read(&groupLiquid, 4);
f.read(&groupWMOID, 4);
+
+ // according to WoW.Dev Wiki:
+ if (rootWMO->flags & 4)
+ groupLiquid = GetLiquidTypeId(groupLiquid);
+ else if (groupLiquid == 15)
+ groupLiquid = 0;
+ else
+ groupLiquid = GetLiquidTypeId(groupLiquid + 1);
+
+ if (groupLiquid)
+ liquflags |= 2;
}
else if (!strcmp(fourcc, "MOPY"))
{
@@ -252,6 +263,19 @@ bool WMOGroup::open()
LiquBytes = new char[nLiquBytes];
f.read(LiquBytes, nLiquBytes);
+ // Determine legacy liquid type
+ if (!groupLiquid)
+ {
+ for (int i = 0; i < hlq->xtiles * hlq->ytiles; ++i)
+ {
+ if ((LiquBytes[i] & 0xF) != 15)
+ {
+ groupLiquid = GetLiquidTypeId((LiquBytes[i] & 0xF) + 1);
+ break;
+ }
+ }
+ }
+
/* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
llog << filename;
llog << "\nbbox: " << bbcorn1[0] << ", " << bbcorn1[1] << ", " << bbcorn1[2] << " | " << bbcorn2[0] << ", " << bbcorn2[1] << ", " << bbcorn2[2];
@@ -423,78 +447,55 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool precise
}
//------LIQU------------------------
- if (LiquEx_size != 0)
+ if (liquflags & 3)
{
- int LIQU_h[] = { 0x5551494C, static_cast<int>(sizeof(WMOLiquidHeader) + LiquEx_size) + hlq->xtiles * hlq->ytiles }; // "LIQU"
- fwrite(LIQU_h, 4, 2, output);
-
- // according to WoW.Dev Wiki:
- uint32 liquidEntry;
- if (rootWMO->liquidType & 4)
- liquidEntry = liquidType;
- else if (liquidType == 15)
- liquidEntry = 0;
- else
- liquidEntry = liquidType + 1;
-
- if (!liquidEntry)
+ int LIQU_totalSize = sizeof(uint32);
+ if (liquflags & 1)
{
- int v1; // edx@1
- int v2; // eax@1
-
- v1 = hlq->xtiles * hlq->ytiles;
- v2 = 0;
- if (v1 > 0)
- {
- while ((LiquBytes[v2] & 0xF) == 15)
- {
- ++v2;
- if (v2 >= v1)
- break;
- }
-
- if (v2 < v1 && (LiquBytes[v2] & 0xF) != 15)
- liquidEntry = (LiquBytes[v2] & 0xF) + 1;
- }
- }
-
- if (liquidEntry && liquidEntry < 21)
- {
- switch ((liquidEntry - 1) & 3)
- {
- case 0:
- liquidEntry = ((mogpFlags & 0x80000) != 0) + 13;
- break;
- case 1:
- liquidEntry = 14;
- break;
- case 2:
- liquidEntry = 19;
- break;
- case 3:
- liquidEntry = 20;
- break;
- }
+ LIQU_totalSize += sizeof(WMOLiquidHeader);
+ LIQU_totalSize += LiquEx_size / sizeof(WMOLiquidVert) * sizeof(float);
+ LIQU_totalSize += hlq->xtiles * hlq->ytiles;
}
- hlq->type = liquidEntry;
+ int LIQU_h[] = { 0x5551494C, LIQU_totalSize };// "LIQU"
+ fwrite(LIQU_h, 4, 2, output);
/* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
llog << filename;
llog << ":\nliquidEntry: " << liquidEntry << " type: " << hlq->type << " (root:" << rootWMO->liquidType << " group:" << liquidType << ")\n";
llog.close(); */
- fwrite(hlq, sizeof(WMOLiquidHeader), 1, output);
- // only need height values, the other values are unknown anyway
- for (uint32 i = 0; i < LiquEx_size / sizeof(WMOLiquidVert); ++i)
- fwrite(&LiquEx[i].height, sizeof(float), 1, output);
- // todo: compress to bit field
- fwrite(LiquBytes, 1, hlq->xtiles * hlq->ytiles, output);
+ fwrite(&groupLiquid, sizeof(uint32), 1, output);
+ if (liquflags & 1)
+ {
+ fwrite(hlq, sizeof(WMOLiquidHeader), 1, output);
+ // only need height values, the other values are unknown anyway
+ for (uint32 i = 0; i < LiquEx_size / sizeof(WMOLiquidVert); ++i)
+ fwrite(&LiquEx[i].height, sizeof(float), 1, output);
+ // todo: compress to bit field
+ fwrite(LiquBytes, 1, hlq->xtiles * hlq->ytiles, output);
+ }
}
return nColTriangles;
}
+uint32 WMOGroup::GetLiquidTypeId(uint32 liquidTypeId)
+{
+ if (liquidTypeId < 21 && liquidTypeId)
+ {
+ switch (((static_cast<uint8>(liquidTypeId) - 1) & 3))
+ {
+ case 0: return ((mogpFlags & 0x80000) != 0) + 13;
+ case 1: return 14;
+ case 2: return 19;
+ case 3: return 20;
+ default: break;
+ }
+ }
+ return liquidTypeId;
+}
+
WMOGroup::~WMOGroup()
{
delete [] MOPY;
diff --git a/src/tools/vmap4_extractor/wmo.h b/src/tools/vmap4_extractor/wmo.h
index c7437247eb..d87edf3c83 100644
--- a/src/tools/vmap4_extractor/wmo.h
+++ b/src/tools/vmap4_extractor/wmo.h
@@ -26,9 +26,6 @@
#include "vec3d.h"
#include "loadlib/loadlib.h"
-#define TILESIZE (533.33333f)
-#define CHUNKSIZE ((TILESIZE) / 16.0f)
-
// MOPY flags
enum MopyFlags
{
@@ -84,7 +81,7 @@ private:
std::string filename;
public:
unsigned int color;
- uint32 nTextures, nGroups, nPortals, nLights, nDoodadNames, nDoodadDefs, nDoodadSets, RootWMOID, liquidType;
+ uint32 nTextures, nGroups, nPortals, nLights, nDoodadNames, nDoodadDefs, nDoodadSets, RootWMOID, flags;
float bbcorn1[3];
float bbcorn2[3];
@@ -105,7 +102,7 @@ struct WMOLiquidHeader
float pos_x;
float pos_y;
float pos_z;
- short type;
+ short material;
};
struct WMOLiquidVert
@@ -141,7 +138,7 @@ public:
uint16 moprNItems;
uint16 nBatchA;
uint16 nBatchB;
- uint32 nBatchC, fogIdx, liquidType, groupWMOID;
+ uint32 nBatchC, fogIdx, groupLiquid, groupWMOID;
int mopy_size, moba_size;
int LiquEx_size;
@@ -154,8 +151,9 @@ public:
WMOGroup(std::string const& filename);
~WMOGroup();
- bool open();
+ bool open(WMORoot* rootWMO);
int ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool preciseVectorData);
+ uint32 GetLiquidTypeId(uint32 liquidTypeId);
};
namespace MapObject