void ExtractMapsFromMpq(uint32 build, const int locale) { char mpq_filename[1024]; char output_filename[1024]; char mpq_map_name[1024]; printf("\nExtracting maps...\n"); if (build==17520) { build = 18273; } uint32 map_count = ReadMapDBC(locale); ReadAreaTableDBC(locale); ReadLiquidTypeTableDBC(locale); 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)) 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, build); } // draw progress bar printf("Processing........................%d%%\r", (100 * (y + 1)) / WDT_MAP_SIZE); } } delete [] areas; delete [] map_ids; }
void ExtractMapsFromMpq(uint32 build) { std::string mpqFileName; std::string outputFileName; std::string mpqMapName; printf("Extracting maps...\n"); uint32 map_count = ReadMapDBC(); 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/%u) \n", map_ids[z].name, z+1, map_count); // Loadup map grid data mpqMapName = Trinity::StringFormat("World\\Maps\\%s\\%s.wdt", map_ids[z].name, map_ids[z].name); WDT_file wdt; if (!wdt.loadFile(mpqMapName, 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; mpqFileName = Trinity::StringFormat("World\\Maps\\%s\\%s_%u_%u.adt", map_ids[z].name, map_ids[z].name, x, y); outputFileName = Trinity::StringFormat("%s/maps/%03u%02u%02u.map", output_path, map_ids[z].id, y, x); ConvertADT(mpqFileName, outputFileName, y, x, build); } // draw progress bar printf("Processing........................%d%%\r", (100 * (y+1)) / WDT_MAP_SIZE); } } printf("\n"); delete[] map_ids; }
void ExtractMapsFromMpq() { char mpq_filename[1024]; char output_filename[1024]; printf("Extracting maps...\n"); uint32 map_count = ReadMapDBC(); ReadAreaTableDBC(); ReadLiquidTypeTableDBC(); unsigned int total = map_count * ADT_RES * ADT_RES; unsigned int done = 0; std::string path = output_path; path += "/maps/"; CreateDir(path); for(uint32 x = 0; x < ADT_RES; ++x) { for(uint32 y = 0; y < ADT_RES; ++y) { for(uint32 z = 0; z < map_count; ++z) { 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); done++; } // draw progress bar printf("Processing........................%d%%\r", (100 * done) / total); } } delete [] areas; delete [] map_ids; }
void ExtractMapsFromMpq(uint32 build) { char mpq_filename[1024]; char output_filename[1024]; char mpq_map_name[1024]; printf("Extracting maps...\n"); LoadMapMPQFiles(); uint32 map_count = ReadMapDBC(); ReadAreaTableDBC(); ReadLiquidTypeTableDBC(); std::string path = "."; path += "/maps/"; CreateDir(path); std::vector<std::string> not_found; printf("Convert map files\n"); HANDLE actualMPQ = WorldMPQ; for(uint32 z = 0; z < map_count; ++z) { // Loadup map grid data sprintf(mpq_map_name, "World\\Maps\\%s\\%s.wdt", map_ids[z].name, map_ids[z].name); WDT_file wdt(mpq_map_name, actualMPQ); if (wdt.isEof()) { if (actualMPQ == WorldMPQ) { z--; actualMPQ = ExpansionsMPQ[0]; continue; } if (actualMPQ == ExpansionsMPQ[0]) { z--; actualMPQ = ExpansionsMPQ[1]; continue; } if (actualMPQ == ExpansionsMPQ[1]) { z--; actualMPQ = ExpansionsMPQ[2]; continue; } actualMPQ = WorldMPQ; not_found.push_back(map_ids[z].name); printf("Extract %s (%d/%d) -- not found\n", map_ids[z].name, z+1, map_count); continue; } if (actualMPQ == WorldMPQ) printf("Extract %s (%d/%d) -- World.MPQ\n", map_ids[z].name, z+1, map_count); if (actualMPQ == ExpansionsMPQ[0]) printf("Extract %s (%d/%d) -- expansion1.MPQ\n", map_ids[z].name, z+1, map_count); if (actualMPQ == ExpansionsMPQ[1]) printf("Extract %s (%d/%d) -- expansion2.MPQ\n", map_ids[z].name, z+1, map_count); if (actualMPQ == ExpansionsMPQ[2]) printf("Extract %s (%d/%d) -- expansion3.MPQ\n", map_ids[z].name, z+1, map_count); actualMPQ = WorldMPQ; wdt.prepareLoadedData(); 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, "./maps/%03u%02u%02u.map", map_ids[z].id, y, x); ConvertADT(mpq_filename, output_filename, y, x, build, WorldMPQ); } // draw progress bar //printf("Processing........................%d%%\r", (100 * (y+1)) / WDT_MAP_SIZE); } } printf("\n"); delete [] areas; delete [] map_ids; //printf("Map not extracted : %u\n", not_found.size()); //for(int i = 0; i < not_found.size(); i++) // printf(" %s\n", not_found[i].c_str()); }
bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32 build, HANDLE _mpq) { ADT_file adt(filename, _mpq); if (adt.isEof()) { if (_mpq == WorldMPQ) return ConvertADT(filename, filename2, cell_y, cell_x, build, ExpansionsMPQ[0]); if (_mpq == ExpansionsMPQ[0]) return ConvertADT(filename, filename2, cell_y, cell_x, build, ExpansionsMPQ[1]); if (_mpq == ExpansionsMPQ[1]) return ConvertADT(filename, filename2, cell_y, cell_x, build, ExpansionsMPQ[2]); if (_mpq == ExpansionsMPQ[2]) return false; } adt.prepareLoadedData(); memset(liquid_show, 0, sizeof(liquid_show)); memset(liquid_type, 0, sizeof(liquid_type)); // Prepare map header map_fileheader map; map.mapMagic = *(uint32 const*)MAP_MAGIC; map.versionMagic = *(uint32 const*)MAP_VERSION_MAGIC; map.buildMagic = build; // 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 = adt.getMCNK(i,j); if (cell) { uint32 areaid = cell->areaid; if (areaid && areaid <= maxAreaId) { if (areas[areaid] != 0xffff) { area_flags[i][j] = areas[areaid]; continue; } printf("File: %s\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 = *(uint32 const*)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 = adt.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 = *(uint32 const*)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++)