aboutsummaryrefslogtreecommitdiff
path: root/contrib/map_extractor/System.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/map_extractor/System.cpp')
-rw-r--r--contrib/map_extractor/System.cpp1030
1 files changed, 0 insertions, 1030 deletions
diff --git a/contrib/map_extractor/System.cpp b/contrib/map_extractor/System.cpp
deleted file mode 100644
index 683f89ac11e..00000000000
--- a/contrib/map_extractor/System.cpp
+++ /dev/null
@@ -1,1030 +0,0 @@
-#define _CRT_SECURE_NO_DEPRECATE
-
-#include <stdio.h>
-#include <deque>
-#include <set>
-#include <cstdlib>
-
-#ifdef WIN32
-#include "direct.h"
-#else
-#include <sys/stat.h>
-#endif
-
-#include "dbcfile.h"
-#include "mpq_libmpq.h"
-
-#include "loadlib/adt.h"
-#include "loadlib/wdt.h"
-#include <fcntl.h>
-
-#if defined( __GNUC__ )
- #define _open open
- #define _close close
- #ifndef O_BINARY
- #define O_BINARY 0
- #endif
-#else
- #include <io.h>
-#endif
-
-#ifdef O_LARGEFILE
- #define OPEN_FLAGS (O_RDONLY | O_BINARY | O_LARGEFILE)
-#else
- #define OPEN_FLAGS (O_RDONLY | O_BINARY)
-#endif
-extern ArchiveSet gOpenArchives;
-
-typedef struct
-{
- char name[64];
- uint32 id;
-} map_id;
-
-map_id *map_ids;
-uint16 *areas;
-uint16 *LiqType;
-char output_path[128] = ".";
-char input_path[128] = ".";
-uint32 maxAreaId = 0;
-
-//**************************************************
-// Extractor options
-//**************************************************
-enum Extract
-{
- EXTRACT_MAP = 1,
- EXTRACT_DBC = 2
-};
-
-// Select data for extract
-int CONF_extract = EXTRACT_MAP | EXTRACT_DBC;
-// This option allow limit minimum height to some value (Allow save some memory)
-bool CONF_allow_height_limit = true;
-float CONF_use_minHeight = -500.0f;
-
-// This option allow use float to int conversion
-bool CONF_allow_float_to_int = true;
-float CONF_float_to_int8_limit = 2.0f; // Max accuracy = val/256
-float CONF_float_to_int16_limit = 2048.0f; // Max accuracy = val/65536
-float CONF_flat_height_delta_limit = 0.005f; // If max - min less this value - surface is flat
-float CONF_flat_liquid_delta_limit = 0.001f; // If max - min less this value - liquid surface is flat
-
-// List MPQ for extract from
-char *CONF_mpq_list[]={
- "common.MPQ",
- "common-2.MPQ",
- "lichking.MPQ",
- "expansion.MPQ",
- "patch.MPQ",
- "patch-2.MPQ",
- "patch-3.MPQ",
- "patch-4.MPQ",
- "patch-5.MPQ",
-};
-
-static char* const langs[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" };
-#define LANG_COUNT 12
-
-void CreateDir( const std::string& Path )
-{
- #ifdef WIN32
- _mkdir( Path.c_str());
- #else
- mkdir( Path.c_str(), 0777 );
- #endif
-}
-
-bool FileExists( const char* FileName )
-{
- int fp = _open(FileName, OPEN_FLAGS);
- if(fp != -1)
- {
- _close(fp);
- return true;
- }
-
- return false;
-}
-
-void Usage(char* prg)
-{
- printf(
- "Usage:\n"\
- "%s -[var] [value]\n"\
- "-i set input path\n"\
- "-o set output path\n"\
- "-e extract only MAP(1)/DBC(2) - standard: both(3)\n"\
- "-f height stored as int (less map size but lost some accuracy) 1 by default\n"\
- "Example: %s -f 0 -i \"c:\\games\\game\"", prg, prg);
- exit(1);
-}
-
-void HandleArgs(int argc, char * arg[])
-{
- for(int c = 1; c < argc; ++c)
- {
- // i - input path
- // o - output path
- // e - extract only MAP(1)/DBC(2) - standard both(3)
- // f - use float to int conversion
- // h - limit minimum height
- if(arg[c][0] != '-')
- Usage(arg[0]);
-
- switch(arg[c][1])
- {
- case 'i':
- if(c + 1 < argc) // all ok
- strcpy(input_path, arg[(c++) + 1]);
- else
- Usage(arg[0]);
- break;
- case 'o':
- if(c + 1 < argc) // all ok
- strcpy(output_path, arg[(c++) + 1]);
- else
- Usage(arg[0]);
- break;
- case 'f':
- if(c + 1 < argc) // all ok
- CONF_allow_float_to_int=atoi(arg[(c++) + 1])!=0;
- else
- Usage(arg[0]);
- break;
- case 'e':
- if(c + 1 < argc) // all ok
- {
- CONF_extract=atoi(arg[(c++) + 1]);
- if(!(CONF_extract > 0 && CONF_extract < 4))
- Usage(arg[0]);
- }
- else
- Usage(arg[0]);
- break;
- }
- }
-}
-
-uint32 ReadMapDBC()
-{
- printf("Read Map.dbc file... ");
- DBCFile dbc("DBFilesClient\\Map.dbc");
-
- if(!dbc.open())
- {
- printf("Fatal error: Invalid Map.dbc file format!\n");
- exit(1);
- }
-
- size_t map_count = dbc.getRecordCount();
- map_ids = new map_id[map_count];
- for(uint32 x = 0; x < map_count; ++x)
- {
- map_ids[x].id = dbc.getRecord(x).getUInt(0);
- strcpy(map_ids[x].name, dbc.getRecord(x).getString(1));
- }
- printf("Done! (%u maps loaded)\n", map_count);
- return map_count;
-}
-
-void ReadAreaTableDBC()
-{
- printf("Read AreaTable.dbc file...");
- DBCFile dbc("DBFilesClient\\AreaTable.dbc");
-
- if(!dbc.open())
- {
- printf("Fatal error: Invalid AreaTable.dbc file format!\n");
- exit(1);
- }
-
- size_t area_count = dbc.getRecordCount();
- size_t maxid = dbc.getMaxId();
- areas = new uint16[maxid + 1];
- memset(areas, 0xff, (maxid + 1) * sizeof(uint16));
-
- for(uint32 x = 0; x < area_count; ++x)
- areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
-
- maxAreaId = dbc.getMaxId();
-
- printf("Done! (%u areas loaded)\n", area_count);
-}
-
-void ReadLiquidTypeTableDBC()
-{
- printf("Read LiquidType.dbc file...");
- DBCFile dbc("DBFilesClient\\LiquidType.dbc");
- if(!dbc.open())
- {
- printf("Fatal error: Invalid LiquidType.dbc file format!\n");
- exit(1);
- }
-
- size_t LiqType_count = dbc.getRecordCount();
- size_t LiqType_maxid = dbc.getMaxId();
- LiqType = new uint16[LiqType_maxid + 1];
- memset(LiqType, 0xff, (LiqType_maxid + 1) * sizeof(uint16));
-
- for(uint32 x = 0; x < LiqType_count; ++x)
- LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
-
- printf("Done! (%u LiqTypes loaded)\n", LiqType_count);
-}
-
-//
-// Adt file convertor function and data
-//
-
-// Map file format data
-#define MAP_MAGIC 'SPAM'
-#define MAP_VERSION_MAGIC '0.1w'
-#define MAP_AREA_MAGIC 'AERA'
-#define MAP_HEIGHT_MAGIC 'TGHM'
-#define MAP_LIQUID_MAGIC 'QILM'
-
-struct map_fileheader
-{
- uint32 mapMagic;
- uint32 versionMagic;
- uint32 areaMapOffset;
- uint32 areaMapSize;
- uint32 heightMapOffset;
- uint32 heightMapSize;
- uint32 liquidMapOffset;
- uint32 liquidMapSize;
-};
-
-#define MAP_AREA_NO_AREA 0x0001
-
-struct map_areaHeader
-{
- uint32 fourcc;
- uint16 flags;
- uint16 gridArea;
-};
-
-#define MAP_HEIGHT_NO_HEIGHT 0x0001
-#define MAP_HEIGHT_AS_INT16 0x0002
-#define MAP_HEIGHT_AS_INT8 0x0004
-
-struct map_heightHeader
-{
- uint32 fourcc;
- uint32 flags;
- float gridHeight;
- float gridMaxHeight;
-};
-
-#define MAP_LIQUID_TYPE_NO_WATER 0x00
-#define MAP_LIQUID_TYPE_WATER 0x01
-#define MAP_LIQUID_TYPE_OCEAN 0x02
-#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
-
-
-#define MAP_LIQUID_NO_TYPE 0x0001
-#define MAP_LIQUID_NO_HEIGHT 0x0002
-
-struct map_liquidHeader
-{
- uint32 fourcc;
- uint16 flags;
- uint16 liquidType;
- uint8 offsetX;
- uint8 offsetY;
- uint8 width;
- uint8 height;
- float liquidLevel;
-};
-
-float selectUInt8StepStore(float maxDiff)
-{
- return 255 / maxDiff;
-}
-
-float selectUInt16StepStore(float maxDiff)
-{
- return 65535 / maxDiff;
-}
-// Temporary grid data store
-uint16 area_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
-
-float V8[ADT_GRID_SIZE][ADT_GRID_SIZE];
-float V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
-uint16 uint16_V8[ADT_GRID_SIZE][ADT_GRID_SIZE];
-uint16 uint16_V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
-uint8 uint8_V8[ADT_GRID_SIZE][ADT_GRID_SIZE];
-uint8 uint8_V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
-
-uint8 liquid_type[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
-bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE];
-float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
-
-bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x)
-{
- ADT_file adt;
-
- if (!adt.loadFile(filename))
- return false;
-
- adt_MCIN *cells = adt.a_grid->getMCIN();
- if (!cells)
- {
- printf("Can't find cells in '%s'\n", filename);
- return false;
- }
-
- memset(liquid_show, 0, sizeof(liquid_show));
- memset(liquid_type, 0, sizeof(liquid_type));
-
- // Prepare map header
- map_fileheader map;
- map.mapMagic = MAP_MAGIC;
- map.versionMagic = MAP_VERSION_MAGIC;
-
- // Get area flags data
- for (int i=0;i<ADT_CELLS_PER_GRID;i++)
- {
- for(int j=0;j<ADT_CELLS_PER_GRID;j++)
- {
- adt_MCNK * cell = cells->getMCNK(i,j);
- uint32 areaid = cell->areaid;
- if(areaid && areaid <= maxAreaId)
- {
- if(areas[areaid] != 0xffff)
- {
- area_flags[i][j] = areas[areaid];
- continue;
- }
- printf("File: filename\nCan't find area flag for areaid %u [%d, %d].\n", filename, areaid, cell->ix, cell->iy);
- }
- area_flags[i][j] = 0xffff;
- }
- }
- //============================================
- // Try pack area data
- //============================================
- bool fullAreaData = false;
- uint32 areaflag = area_flags[0][0];
- for (int y=0;y<ADT_CELLS_PER_GRID;y++)
- {
- for(int x=0;x<ADT_CELLS_PER_GRID;x++)
- {
- if(area_flags[y][x]!=areaflag)
- {
- fullAreaData = true;
- break;
- }
- }
- }
-
- map.areaMapOffset = sizeof(map);
- map.areaMapSize = sizeof(map_areaHeader);
-
- map_areaHeader areaHeader;
- areaHeader.fourcc = MAP_AREA_MAGIC;
- areaHeader.flags = 0;
- if (fullAreaData)
- {
- areaHeader.gridArea = 0;
- map.areaMapSize+=sizeof(area_flags);
- }
- else
- {
- areaHeader.flags |= MAP_AREA_NO_AREA;
- areaHeader.gridArea = (uint16)areaflag;
- }
-
- //
- // Get Height map from grid
- //
- for (int i=0;i<ADT_CELLS_PER_GRID;i++)
- {
- for(int j=0;j<ADT_CELLS_PER_GRID;j++)
- {
- adt_MCNK * cell = cells->getMCNK(i,j);
- if (!cell)
- continue;
- // Height values for triangles stored in order:
- // 1 2 3 4 5 6 7 8 9
- // 10 11 12 13 14 15 16 17
- // 18 19 20 21 22 23 24 25 26
- // 27 28 29 30 31 32 33 34
- // . . . . . . . .
- // For better get height values merge it to V9 and V8 map
- // V9 height map:
- // 1 2 3 4 5 6 7 8 9
- // 18 19 20 21 22 23 24 25 26
- // . . . . . . . .
- // V8 height map:
- // 10 11 12 13 14 15 16 17
- // 27 28 29 30 31 32 33 34
- // . . . . . . . .
-
- // Set map height as grid height
- for (int y=0; y <= ADT_CELL_SIZE; y++)
- {
- int cy = i*ADT_CELL_SIZE + y;
- for (int x=0; x <= ADT_CELL_SIZE; x++)
- {
- int cx = j*ADT_CELL_SIZE + x;
- V9[cy][cx]=cell->ypos;
- }
- }
- for (int y=0; y < ADT_CELL_SIZE; y++)
- {
- int cy = i*ADT_CELL_SIZE + y;
- for (int x=0; x < ADT_CELL_SIZE; x++)
- {
- int cx = j*ADT_CELL_SIZE + x;
- V8[cy][cx]=cell->ypos;
- }
- }
- // Get custom height
- adt_MCVT *v = cell->getMCVT();
- if (!v)
- continue;
- // get V9 height map
- for (int y=0; y <= ADT_CELL_SIZE; y++)
- {
- int cy = i*ADT_CELL_SIZE + y;
- for (int x=0; x <= ADT_CELL_SIZE; x++)
- {
- int cx = j*ADT_CELL_SIZE + x;
- V9[cy][cx]+=v->height_map[y*(ADT_CELL_SIZE*2+1)+x];
- }
- }
- // get V8 height map
- for (int y=0; y < ADT_CELL_SIZE; y++)
- {
- int cy = i*ADT_CELL_SIZE + y;
- for (int x=0; x < ADT_CELL_SIZE; x++)
- {
- int cx = j*ADT_CELL_SIZE + x;
- V8[cy][cx]+=v->height_map[y*(ADT_CELL_SIZE*2+1)+ADT_CELL_SIZE+1+x];
- }
- }
- }
- }
- //============================================
- // Try pack height data
- //============================================
- float maxHeight = -20000;
- float minHeight = 20000;
- for (int y=0; y<ADT_GRID_SIZE; y++)
- {
- for(int x=0;x<ADT_GRID_SIZE;x++)
- {
- float h = V8[y][x];
- if (maxHeight < h) maxHeight = h;
- if (minHeight > h) minHeight = h;
- }
- }
- for (int y=0; y<=ADT_GRID_SIZE; y++)
- {
- for(int x=0;x<=ADT_GRID_SIZE;x++)
- {
- float h = V9[y][x];
- if (maxHeight < h) maxHeight = h;
- if (minHeight > h) minHeight = h;
- }
- }
-
- // Check for allow limit minimum height (not store height in deep ochean - allow save some memory)
- if (CONF_allow_height_limit && minHeight < CONF_use_minHeight)
- {
- for (int y=0; y<ADT_GRID_SIZE; y++)
- for(int x=0;x<ADT_GRID_SIZE;x++)
- if (V8[y][x] < CONF_use_minHeight)
- V8[y][x] = CONF_use_minHeight;
- for (int y=0; y<=ADT_GRID_SIZE; y++)
- for(int x=0;x<=ADT_GRID_SIZE;x++)
- if (V9[y][x] < CONF_use_minHeight)
- V9[y][x] = CONF_use_minHeight;
- if (minHeight < CONF_use_minHeight)
- minHeight = CONF_use_minHeight;
- if (maxHeight < CONF_use_minHeight)
- maxHeight = CONF_use_minHeight;
- }
-
- map.heightMapOffset = map.areaMapOffset + map.areaMapSize;
- map.heightMapSize = sizeof(map_heightHeader);
-
- map_heightHeader heightHeader;
- heightHeader.fourcc = MAP_HEIGHT_MAGIC;
- heightHeader.flags = 0;
- heightHeader.gridHeight = minHeight;
- heightHeader.gridMaxHeight = maxHeight;
-
- if (maxHeight == minHeight)
- heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT;
-
- // Not need store if flat surface
- if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_height_delta_limit)
- heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT;
-
- // Try store as packed in uint16 or uint8 values
- if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT))
- {
- float step;
- // Try Store as uint values
- if (CONF_allow_float_to_int)
- {
- float diff = maxHeight - minHeight;
- if (diff < CONF_float_to_int8_limit) // As uint8 (max accuracy = CONF_float_to_int8_limit/256)
- {
- heightHeader.flags|=MAP_HEIGHT_AS_INT8;
- step = selectUInt8StepStore(diff);
- }
- else if (diff<CONF_float_to_int16_limit) // As uint16 (max accuracy = CONF_float_to_int16_limit/65536)
- {
- heightHeader.flags|=MAP_HEIGHT_AS_INT16;
- step = selectUInt16StepStore(diff);
- }
- }
-
- // Pack it to int values if need
- if (heightHeader.flags&MAP_HEIGHT_AS_INT8)
- {
- for (int y=0; y<ADT_GRID_SIZE; y++)
- for(int x=0;x<ADT_GRID_SIZE;x++)
- uint8_V8[y][x] = uint8((V8[y][x] - minHeight) * step + 0.5f);
- for (int y=0; y<=ADT_GRID_SIZE; y++)
- for(int x=0;x<=ADT_GRID_SIZE;x++)
- uint8_V9[y][x] = uint8((V9[y][x] - minHeight) * step + 0.5f);
- map.heightMapSize+= sizeof(uint8_V9) + sizeof(uint8_V8);
- }
- else if (heightHeader.flags&MAP_HEIGHT_AS_INT16)
- {
- for (int y=0; y<ADT_GRID_SIZE; y++)
- for(int x=0;x<ADT_GRID_SIZE;x++)
- uint16_V8[y][x] = uint16((V8[y][x] - minHeight) * step + 0.5f);
- for (int y=0; y<=ADT_GRID_SIZE; y++)
- for(int x=0;x<=ADT_GRID_SIZE;x++)
- uint16_V9[y][x] = uint16((V9[y][x] - minHeight) * step + 0.5f);
- map.heightMapSize+= sizeof(uint16_V9) + sizeof(uint16_V8);
- }
- else
- map.heightMapSize+= sizeof(V9) + sizeof(V8);
- }
-
- // Get liquid map for grid (in WOTLK used MH2O chunk)
- adt_MH2O * h2o = adt.a_grid->getMH2O();
- if (h2o)
- {
- for (int i=0;i<ADT_CELLS_PER_GRID;i++)
- {
- for(int j=0;j<ADT_CELLS_PER_GRID;j++)
- {
- adt_liquid_header *h = h2o->getLiquidData(i,j);
- if (!h)
- continue;
-
- int count = 0;
- uint64 show = h2o->getLiquidShowMap(h);
- for (int y=0; y < h->height;y++)
- {
- int cy = i*ADT_CELL_SIZE + y + h->yOffset;
- for (int x=0; x < h->width; x++)
- {
- int cx = j*ADT_CELL_SIZE + x + h->xOffset;
- if (show & 1)
- {
- liquid_show[cy][cx] = true;
- ++count;
- }
- show>>=1;
- }
- }
-
- uint32 type = LiqType[h->liquidType];
- switch (type)
- {
- case LIQUID_TYPE_WATER: liquid_type[i][j] |= MAP_LIQUID_TYPE_WATER; break;
- case LIQUID_TYPE_OCEAN: liquid_type[i][j] |= MAP_LIQUID_TYPE_OCEAN; break;
- case LIQUID_TYPE_MAGMA: liquid_type[i][j] |= MAP_LIQUID_TYPE_MAGMA; break;
- case LIQUID_TYPE_SLIME: liquid_type[i][j] |= MAP_LIQUID_TYPE_SLIME; break;
- default:
- printf("\nCan't find Liquid type %u for map %s\nchunk %d,%d\n", h->liquidType, filename, i, j);
- break;
- }
- // Dark water detect
- if (type == LIQUID_TYPE_OCEAN)
- {
- uint8 *lm = h2o->getLiquidLightMap(h);
- if (!lm)
- liquid_type[i][j]|=MAP_LIQUID_TYPE_DARK_WATER;
- }
-
- if (!count && liquid_type[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++)
- {
- int cy = i*ADT_CELL_SIZE + y + h->yOffset;
- for (int x=0; x<= h->width; 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;
- pos++;
- }
- }
- }
- }
- }
- else
- {
- // Get from MCLQ chunk (old)
- for (int i=0;i<ADT_CELLS_PER_GRID;i++)
- {
- for(int j=0;j<ADT_CELLS_PER_GRID;j++)
- {
- adt_MCNK *cell = cells->getMCNK(i, j);
- if (!cell)
- continue;
-
- adt_MCLQ *liquid = cell->getMCLQ();
- int count = 0;
- if (!liquid || cell->sizeMCLQ <= 8)
- continue;
-
- for (int y=0; y < ADT_CELL_SIZE; y++)
- {
- int cy = i*ADT_CELL_SIZE + y;
- for (int x=0; x < ADT_CELL_SIZE; x++)
- {
- int cx = j*ADT_CELL_SIZE + x;
- if (liquid->flags[y][x] != 0x0F)
- {
- liquid_show[cy][cx] = true;
- if (liquid->flags[y][x]&(1<<7))
- liquid_type[i][j]|=MAP_LIQUID_TYPE_DARK_WATER;
- ++count;
- }
- }
- }
-
- uint32 c_flag = cell->flags;
- if(c_flag & (1<<2))
- liquid_type[i][j]|=MAP_LIQUID_TYPE_WATER; // water
- if(c_flag & (1<<3))
- liquid_type[i][j]|=MAP_LIQUID_TYPE_OCEAN; // ochean
- if(c_flag & (1<<4))
- liquid_type[i][j]|=MAP_LIQUID_TYPE_MAGMA; // magma/slime
-
- if (!count && liquid_type[i][j])
- printf("Wrong liquid detect in MCLQ chunk");
-
- for (int y=0; y <= ADT_CELL_SIZE; y++)
- {
- int cy = i*ADT_CELL_SIZE + y;
- for (int x=0; x<= ADT_CELL_SIZE; x++)
- {
- int cx = j*ADT_CELL_SIZE + x;
- liquid_height[cy][cx] = liquid->liquid[y][x].height;
- }
- }
- }
- }
- }
-
- //============================================
- // Pack liquid data
- //============================================
- uint8 type = liquid_type[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_type[y][x]!=type)
- {
- fullType = true;
- y = ADT_CELLS_PER_GRID;
- break;
- }
- }
- }
-
- map_liquidHeader liquidHeader;
-
- // no water data (if all grid have 0 liquid type)
- if (type == 0 && !fullType)
- {
- // No liquid data
- map.liquidMapOffset = 0;
- map.liquidMapSize = 0;
- }
- else
- {
- int minX = 255, minY = 255;
- int maxX = 0, maxY = 0;
- maxHeight = -20000;
- minHeight = 20000;
- for (int y=0; y<ADT_GRID_SIZE; y++)
- {
- for(int x=0; x<ADT_GRID_SIZE; x++)
- {
- if (liquid_show[y][x])
- {
- if (minX > x) minX = x;
- if (maxX < x) maxX = x;
- if (minY > y) minY = y;
- if (maxY < y) maxY = y;
- float h = liquid_height[y][x];
- if (maxHeight < h) maxHeight = h;
- if (minHeight > h) minHeight = h;
- }
- else
- liquid_height[y][x] = CONF_use_minHeight;
- }
- }
- map.liquidMapOffset = map.heightMapOffset + map.heightMapSize;
- map.liquidMapSize = sizeof(map_liquidHeader);
- liquidHeader.fourcc = MAP_LIQUID_MAGIC;
- liquidHeader.flags = 0;
- liquidHeader.liquidType = 0;
- liquidHeader.offsetX = minX;
- liquidHeader.offsetY = minY;
- liquidHeader.width = maxX - minX + 1;
- liquidHeader.height = maxY - minY + 1;
- liquidHeader.liquidLevel = minHeight;
-
- if (maxHeight == minHeight)
- liquidHeader.flags |= MAP_LIQUID_NO_HEIGHT;
-
- // Not need store if flat surface
- if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_liquid_delta_limit)
- liquidHeader.flags |= MAP_LIQUID_NO_HEIGHT;
-
- if (!fullType)
- liquidHeader.flags |= MAP_LIQUID_NO_TYPE;
-
- if (liquidHeader.flags & MAP_LIQUID_NO_TYPE)
- liquidHeader.liquidType = type;
- else
- map.liquidMapSize+=sizeof(liquid_type);
-
- if (!(liquidHeader.flags & MAP_LIQUID_NO_HEIGHT))
- map.liquidMapSize += sizeof(float)*liquidHeader.width*liquidHeader.height;
- }
-
- // Ok all data prepared - store it
- FILE *output=fopen(filename2, "wb");
- if(!output)
- {
- printf("Can't create the output file '%s'\n", filename2);
- return false;
- }
- fwrite(&map, sizeof(map), 1, output);
- // Store area data
- fwrite(&areaHeader, sizeof(areaHeader), 1, output);
- if (!(areaHeader.flags&MAP_AREA_NO_AREA))
- fwrite(area_flags, sizeof(area_flags), 1, output);
-
- // Store height data
- fwrite(&heightHeader, sizeof(heightHeader), 1, output);
- if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT))
- {
- if (heightHeader.flags & MAP_HEIGHT_AS_INT16)
- {
- fwrite(uint16_V9, sizeof(uint16_V9), 1, output);
- fwrite(uint16_V8, sizeof(uint16_V8), 1, output);
- }
- else if (heightHeader.flags & MAP_HEIGHT_AS_INT8)
- {
- fwrite(uint8_V9, sizeof(uint8_V9), 1, output);
- fwrite(uint8_V8, sizeof(uint8_V8), 1, output);
- }
- else
- {
- fwrite(V9, sizeof(V9), 1, output);
- fwrite(V8, sizeof(V8), 1, output);
- }
- }
-
- // Store liquid data if need
- if (map.liquidMapOffset)
- {
- fwrite(&liquidHeader, sizeof(liquidHeader), 1, output);
- if (!(liquidHeader.flags&MAP_LIQUID_NO_TYPE))
- fwrite(liquid_type, sizeof(liquid_type), 1, output);
- if (!(liquidHeader.flags&MAP_LIQUID_NO_HEIGHT))
- {
- for (int y=0; y<liquidHeader.height;y++)
- fwrite(&liquid_height[y+liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output);
- }
- }
- fclose(output);
-
- return true;
-}
-
-void ExtractMapsFromMpq()
-{
- char mpq_filename[1024];
- char output_filename[1024];
- char mpq_map_name[1024];
-
- printf("Extracting maps...\n");
-
- uint32 map_count = ReadMapDBC();
-
- ReadAreaTableDBC();
- ReadLiquidTypeTableDBC();
-
- std::string path = output_path;
- path += "/maps/";
- CreateDir(path);
-
- printf("Convert map files\n");
- for(uint32 z = 0; z < map_count; ++z)
- {
- printf("Extract %s (%d/%d) \n", map_ids[z].name, z+1, map_count);
- // Loadup map grid data
- sprintf(mpq_map_name, "World\\Maps\\%s\\%s.wdt", map_ids[z].name, map_ids[z].name);
- WDT_file wdt;
- if (!wdt.loadFile(mpq_map_name, false))
- {
-// printf("Error loading %s map wdt data\n", map_ids[z].name);
- continue;
- }
-
- for(uint32 y = 0; y < WDT_MAP_SIZE; ++y)
- {
- for(uint32 x = 0; x < WDT_MAP_SIZE; ++x)
- {
- if (!wdt.main->adt_list[y][x].exist)
- 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);
- ConvertADT(mpq_filename, output_filename, y, x);
- }
- // draw progress bar
- printf("Processing........................%d%%\r", (100 * (y+1)) / WDT_MAP_SIZE);
- }
- }
- delete [] areas;
- delete [] map_ids;
-}
-
-void ExtractDBCFiles(int locale, bool basicLocale)
-{
- printf("Extracting dbc files...\n");
-
- set<string> dbcfiles;
-
- // get DBC file list
- for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i)
- {
- vector<string> files;
- (*i)->GetFileListTo(files);
- for (vector<string>::iterator iter = files.begin(); iter != files.end(); ++iter)
- if (iter->rfind(".dbc") == iter->length() - strlen(".dbc"))
- dbcfiles.insert(*iter);
- }
-
- string path = output_path;
- path += "/dbc/";
- CreateDir(path);
- if(!basicLocale)
- {
- path += langs[locale];
- path += "/";
- CreateDir(path);
- }
-
- // extract DBCs
- int count = 0;
- for (set<string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter)
- {
- string filename = path;
- filename += (iter->c_str() + strlen("DBFilesClient\\"));
-
- FILE *output = fopen(filename.c_str(), "wb");
- if(!output)
- {
- printf("Can't create the output file '%s'\n", filename.c_str());
- continue;
- }
- MPQFile m(iter->c_str());
- if(!m.isEof())
- fwrite(m.getPointer(), 1, m.getSize(), output);
-
- fclose(output);
- ++count;
- }
- printf("Extracted %u DBC files\n\n", count);
-}
-
-void LoadLocaleMPQFiles(int const locale)
-{
- char filename[512];
-
- sprintf(filename,"%s/Data/%s/locale-%s.MPQ", input_path, langs[locale], langs[locale]);
- new MPQArchive(filename);
-
- for(int i = 1; i < 5; ++i)
- {
- char ext[3] = "";
- if(i > 1)
- sprintf(ext, "-%i", i);
-
- sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ", input_path, langs[locale], langs[locale], ext);
- if(FileExists(filename))
- new MPQArchive(filename);
- }
-}
-
-void LoadCommonMPQFiles()
-{
- char filename[512];
- int count = sizeof(CONF_mpq_list)/sizeof(char*);
- for(int i = 0; i < count; ++i)
- {
- sprintf(filename, "%s/Data/%s", input_path, CONF_mpq_list[i]);
- if(FileExists(filename))
- new MPQArchive(filename);
- }
-}
-
-inline void CloseMPQFiles()
-{
- for(ArchiveSet::iterator j = gOpenArchives.begin(); j != gOpenArchives.end();++j) (*j)->close();
- gOpenArchives.clear();
-}
-
-int main(int argc, char * arg[])
-{
- printf("Map & DBC Extractor\n");
- printf("===================\n\n");
-
- HandleArgs(argc, arg);
-
- int FirstLocale = -1;
-
- for (int i = 0; i < LANG_COUNT; i++)
- {
- char tmp1[512];
- sprintf(tmp1, "%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]);
- if (FileExists(tmp1))
- {
- printf("Detected locale: %s\n", langs[i]);
-
- //Open MPQs
- LoadLocaleMPQFiles(i);
-
- if((CONF_extract & EXTRACT_DBC) == 0)
- {
- FirstLocale = i;
- break;
- }
-
- //Extract DBC files
- if(FirstLocale < 0)
- {
- ExtractDBCFiles(i, true);
- FirstLocale = i;
- }
- else
- ExtractDBCFiles(i, false);
-
- //Close MPQs
- CloseMPQFiles();
- }
- }
-
- if(FirstLocale < 0)
- {
- printf("No locales detected\n");
- return 0;
- }
-
- if (CONF_extract & EXTRACT_MAP)
- {
- printf("Using locale: %s\n", langs[FirstLocale]);
-
- // Open MPQs
- LoadLocaleMPQFiles(FirstLocale);
- LoadCommonMPQFiles();
-
- // Extract maps
- ExtractMapsFromMpq();
-
- // Close MPQs
- CloseMPQFiles();
- }
-
- return 0;
-}
-