AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
System.cpp File Reference
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <filesystem>
#include <set>
#include <unordered_map>
#include <sys/stat.h>
#include <unistd.h>
#include "dbcfile.h"
#include "mpq_libmpq04.h"
#include "StringFormat.h"
#include "adt.h"
#include "wdt.h"
#include <fcntl.h>
#include <io.h>

Go to the source code of this file.

Classes

struct  map_id
 
struct  LiquidTypeEntry
 
struct  map_fileheader
 
struct  map_areaHeader
 
struct  map_heightHeader
 
struct  map_liquidHeader
 

Macros

#define _CRT_SECURE_NO_DEPRECATE
 
#define OPEN_FLAGS   (O_RDONLY | O_BINARY)
 
#define MAX_PATH_LENGTH   128
 
#define LANG_COUNT   12
 
#define MAP_AREA_NO_AREA   0x0001
 
#define MAP_HEIGHT_NO_HEIGHT   0x0001
 
#define MAP_HEIGHT_AS_INT16   0x0002
 
#define MAP_HEIGHT_AS_INT8   0x0004
 
#define MAP_HEIGHT_HAS_FLIGHT_BOUNDS   0x0008
 
#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_NO_TYPE   0x0001
 
#define MAP_LIQUID_NO_HEIGHT   0x0002
 

Enumerations

enum  Extract {
  EXTRACT_MAP = 1 ,
  EXTRACT_DBC = 2 ,
  EXTRACT_CAMERA = 4
}
 

Functions

void CreateDir (const std::string &Path)
 
bool FileExists (const char *FileName)
 
void Usage (char *prg)
 
void HandleArgs (int argc, char *arg[])
 
uint32 ReadBuild (int locale)
 
uint32 ReadMapDBC ()
 
void ReadLiquidTypeTableDBC ()
 
float selectUInt8StepStore (float maxDiff)
 
float selectUInt16StepStore (float maxDiff)
 
bool ConvertADT (std::string const &inputPath, std::string const &outputPath, int, int, uint32 build)
 
void ExtractMapsFromMpq (uint32 build)
 
bool ExtractFile (char const *mpq_name, std::string const &filename)
 
void ExtractDBCFiles (int locale, bool basicLocale)
 
void ExtractCameraFiles (int locale, bool basicLocale)
 
void LoadLocaleMPQFiles (int const locale)
 
void LoadCommonMPQFiles ()
 
void CloseMPQFiles ()
 
int main (int argc, char *arg[])
 

Variables

ArchiveSet gOpenArchives
 
std::vector< map_idmap_ids
 
std::unordered_map< uint32, LiquidTypeEntryLiquidTypes
 
char output_path [MAX_PATH_LENGTH] = "."
 
char input_path [MAX_PATH_LENGTH] = "."
 
int CONF_extract = EXTRACT_MAP | EXTRACT_DBC | EXTRACT_CAMERA
 
bool CONF_allow_height_limit = true
 
float CONF_use_minHeight = -500.0f
 
bool CONF_allow_float_to_int = true
 
float CONF_float_to_int8_limit = 2.0f
 
float CONF_float_to_int16_limit = 2048.0f
 
float CONF_flat_height_delta_limit = 0.005f
 
float CONF_flat_liquid_delta_limit = 0.001f
 
const char * CONF_mpq_list []
 
static const char *const langs [] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }
 
static char const * MAP_MAGIC = "MAPS"
 
static uint32 const MAP_VERSION_MAGIC = 9
 
static char const * MAP_AREA_MAGIC = "AREA"
 
static char const * MAP_HEIGHT_MAGIC = "MHGT"
 
static char const * MAP_LIQUID_MAGIC = "MLIQ"
 
uint16 area_ids [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]
 
uint16 liquid_entry [ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
 
uint8 liquid_flags [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]
 
uint16 holes [ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
 
int16 flight_box_max [3][3]
 
int16 flight_box_min [3][3]
 

Macro Definition Documentation

◆ _CRT_SECURE_NO_DEPRECATE

#define _CRT_SECURE_NO_DEPRECATE

◆ LANG_COUNT

#define LANG_COUNT   12

◆ MAP_AREA_NO_AREA

#define MAP_AREA_NO_AREA   0x0001

◆ MAP_HEIGHT_AS_INT16

#define MAP_HEIGHT_AS_INT16   0x0002

◆ MAP_HEIGHT_AS_INT8

#define MAP_HEIGHT_AS_INT8   0x0004

◆ MAP_HEIGHT_HAS_FLIGHT_BOUNDS

#define MAP_HEIGHT_HAS_FLIGHT_BOUNDS   0x0008

◆ MAP_HEIGHT_NO_HEIGHT

#define MAP_HEIGHT_NO_HEIGHT   0x0001

◆ MAP_LIQUID_NO_HEIGHT

#define MAP_LIQUID_NO_HEIGHT   0x0002

◆ MAP_LIQUID_NO_TYPE

#define MAP_LIQUID_NO_TYPE   0x0001

◆ MAP_LIQUID_TYPE_DARK_WATER

#define MAP_LIQUID_TYPE_DARK_WATER   0x10

◆ MAP_LIQUID_TYPE_MAGMA

#define MAP_LIQUID_TYPE_MAGMA   0x04

◆ MAP_LIQUID_TYPE_NO_WATER

#define MAP_LIQUID_TYPE_NO_WATER   0x00

◆ MAP_LIQUID_TYPE_OCEAN

#define MAP_LIQUID_TYPE_OCEAN   0x02

◆ MAP_LIQUID_TYPE_SLIME

#define MAP_LIQUID_TYPE_SLIME   0x08

◆ MAP_LIQUID_TYPE_WATER

#define MAP_LIQUID_TYPE_WATER   0x01

◆ MAX_PATH_LENGTH

#define MAX_PATH_LENGTH   128

◆ OPEN_FLAGS

#define OPEN_FLAGS   (O_RDONLY | O_BINARY)

Enumeration Type Documentation

◆ Extract

enum Extract
Enumerator
EXTRACT_MAP 
EXTRACT_DBC 
EXTRACT_CAMERA 
82{
83 EXTRACT_MAP = 1,
84 EXTRACT_DBC = 2,
86};
@ EXTRACT_CAMERA
Definition: System.cpp:85
@ EXTRACT_MAP
Definition: System.cpp:83
@ EXTRACT_DBC
Definition: System.cpp:84

Function Documentation

◆ CloseMPQFiles()

void CloseMPQFiles ( )
inline
1172{
1173 for (auto & gOpenArchive : gOpenArchives) gOpenArchive->close();
1174 gOpenArchives.clear();
1175}
ArchiveSet gOpenArchives
Definition: mpq_libmpq.cpp:22

References gOpenArchives.

Referenced by main().

◆ ConvertADT()

bool ConvertADT ( std::string const &  inputPath,
std::string const &  outputPath,
int  ,
int  ,
uint32  build 
)
411{
412 ADT_file adt;
413
414 if (!adt.loadFile(inputPath))
415 return false;
416
417 adt_MCIN* cells = adt.a_grid->getMCIN();
418 if (!cells)
419 {
420 printf("Can't find cells in '%s'\n", inputPath.c_str());
421 return false;
422 }
423
424 memset(liquid_show, 0, sizeof(liquid_show));
425 memset(liquid_flags, 0, sizeof(liquid_flags));
426 memset(liquid_entry, 0, sizeof(liquid_entry));
427
428 memset(holes, 0, sizeof(holes));
429
430 // Prepare map header
431 map_fileheader map;
432 map.mapMagic = *reinterpret_cast<uint32 const*>(MAP_MAGIC);
434 map.buildMagic = build;
435
436 // Get area flags data
437 for (int i = 0; i < ADT_CELLS_PER_GRID; i++)
438 for (int j = 0; j < ADT_CELLS_PER_GRID; j++)
439 area_ids[i][j] = cells->getMCNK(i, j)->areaid;
440
441 //============================================
442 // Try pack area data
443 //============================================
444 bool fullAreaData = false;
445 uint32 areaId = area_ids[0][0];
446 for (auto & area_id : area_ids)
447 {
448 for (int x = 0; x < ADT_CELLS_PER_GRID; ++x)
449 {
450 if (area_id[x] != areaId)
451 {
452 fullAreaData = true;
453 break;
454 }
455 }
456 }
457
458 map.areaMapOffset = sizeof(map);
459 map.areaMapSize = sizeof(map_areaHeader);
460
461 map_areaHeader areaHeader;
462 areaHeader.fourcc = *reinterpret_cast<uint32 const*>(MAP_AREA_MAGIC);
463 areaHeader.flags = 0;
464 if (fullAreaData)
465 {
466 areaHeader.gridArea = 0;
467 map.areaMapSize += sizeof(area_ids);
468 }
469 else
470 {
471 areaHeader.flags |= MAP_AREA_NO_AREA;
472 areaHeader.gridArea = static_cast<uint16>(areaId);
473 }
474
475 //
476 // Get Height map from grid
477 //
478 for (int i = 0; i < ADT_CELLS_PER_GRID; i++)
479 {
480 for (int j = 0; j < ADT_CELLS_PER_GRID; j++)
481 {
482 adt_MCNK* cell = cells->getMCNK(i, j);
483 if (!cell)
484 continue;
485 // Height values for triangles stored in order:
486 // 1 2 3 4 5 6 7 8 9
487 // 10 11 12 13 14 15 16 17
488 // 18 19 20 21 22 23 24 25 26
489 // 27 28 29 30 31 32 33 34
490 // . . . . . . . .
491 // For better get height values merge it to V9 and V8 map
492 // V9 height map:
493 // 1 2 3 4 5 6 7 8 9
494 // 18 19 20 21 22 23 24 25 26
495 // . . . . . . . .
496 // V8 height map:
497 // 10 11 12 13 14 15 16 17
498 // 27 28 29 30 31 32 33 34
499 // . . . . . . . .
500
501 // Set map height as grid height
502 for (int y = 0; y <= ADT_CELL_SIZE; y++)
503 {
504 int cy = i * ADT_CELL_SIZE + y;
505 for (int x = 0; x <= ADT_CELL_SIZE; x++)
506 {
507 int cx = j * ADT_CELL_SIZE + x;
508 V9[cy][cx] = cell->ypos;
509 }
510 }
511 for (int y = 0; y < ADT_CELL_SIZE; y++)
512 {
513 int cy = i * ADT_CELL_SIZE + y;
514 for (int x = 0; x < ADT_CELL_SIZE; x++)
515 {
516 int cx = j * ADT_CELL_SIZE + x;
517 V8[cy][cx] = cell->ypos;
518 }
519 }
520 // Get custom height
521 adt_MCVT* v = cell->getMCVT();
522 if (!v)
523 continue;
524 // get V9 height map
525 for (int y = 0; y <= ADT_CELL_SIZE; y++)
526 {
527 int cy = i * ADT_CELL_SIZE + y;
528 for (int x = 0; x <= ADT_CELL_SIZE; x++)
529 {
530 int cx = j * ADT_CELL_SIZE + x;
531 V9[cy][cx] += v->height_map[y * (ADT_CELL_SIZE * 2 + 1) + x];
532 }
533 }
534 // get V8 height map
535 for (int y = 0; y < ADT_CELL_SIZE; y++)
536 {
537 int cy = i * ADT_CELL_SIZE + y;
538 for (int x = 0; x < ADT_CELL_SIZE; x++)
539 {
540 int cx = j * ADT_CELL_SIZE + x;
541 V8[cy][cx] += v->height_map[y * (ADT_CELL_SIZE * 2 + 1) + ADT_CELL_SIZE + 1 + x];
542 }
543 }
544 }
545 }
546 //============================================
547 // Try pack height data
548 //============================================
549 float maxHeight = -20000;
550 float minHeight = 20000;
551 for (auto & y : V8)
552 {
553 for (int x = 0; x < ADT_GRID_SIZE; x++)
554 {
555 float h = y[x];
556 if (maxHeight < h) maxHeight = h;
557 if (minHeight > h) minHeight = h;
558 }
559 }
560 for (int y = 0; y <= ADT_GRID_SIZE; y++)
561 {
562 for (int x = 0; x <= ADT_GRID_SIZE; x++)
563 {
564 float h = V9[y][x];
565 if (maxHeight < h) maxHeight = h;
566 if (minHeight > h) minHeight = h;
567 }
568 }
569
570 // Check for allow limit minimum height (not store height in deep ochean - allow save some memory)
572 {
573 for (auto & y : V8)
574 for (int x = 0; x < ADT_GRID_SIZE; x++)
575 if (y[x] < CONF_use_minHeight)
576 y[x] = CONF_use_minHeight;
577 for (int y = 0; y <= ADT_GRID_SIZE; y++)
578 for (int x = 0; x <= ADT_GRID_SIZE; x++)
579 if (V9[y][x] < CONF_use_minHeight)
580 V9[y][x] = CONF_use_minHeight;
581 if (minHeight < CONF_use_minHeight)
582 minHeight = CONF_use_minHeight;
583 if (maxHeight < CONF_use_minHeight)
584 maxHeight = CONF_use_minHeight;
585 }
586
587 bool hasFlightBox = false;
588 if (adt_MFBO* mfbo = adt.a_grid->getMFBO())
589 {
590 memcpy(flight_box_max, &mfbo->max, sizeof(flight_box_max));
591 memcpy(flight_box_min, &mfbo->min, sizeof(flight_box_min));
592 hasFlightBox = true;
593 }
594
596 map.heightMapSize = sizeof(map_heightHeader);
597
598 map_heightHeader heightHeader;
599 heightHeader.fourcc = *reinterpret_cast<uint32 const*>(MAP_HEIGHT_MAGIC);
600 heightHeader.flags = 0;
601 heightHeader.gridHeight = minHeight;
602 heightHeader.gridMaxHeight = maxHeight;
603
604 if (maxHeight == minHeight)
605 heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT;
606
607 // Not need store if flat surface
608 if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_height_delta_limit)
609 heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT;
610
611 if (hasFlightBox)
612 {
613 heightHeader.flags |= MAP_HEIGHT_HAS_FLIGHT_BOUNDS;
614 map.heightMapSize += sizeof(flight_box_max) + sizeof(flight_box_min);
615 }
616
617 // Try store as packed in uint16 or uint8 values
618 if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT))
619 {
620 float step = 0;
621 // Try Store as uint values
623 {
624 float diff = maxHeight - minHeight;
625 if (diff < CONF_float_to_int8_limit) // As uint8 (max accuracy = CONF_float_to_int8_limit/256)
626 {
627 heightHeader.flags |= MAP_HEIGHT_AS_INT8;
628 step = selectUInt8StepStore(diff);
629 }
630 else if (diff < CONF_float_to_int16_limit) // As uint16 (max accuracy = CONF_float_to_int16_limit/65536)
631 {
632 heightHeader.flags |= MAP_HEIGHT_AS_INT16;
633 step = selectUInt16StepStore(diff);
634 }
635 }
636
637 // Pack it to int values if need
638 if (heightHeader.flags & MAP_HEIGHT_AS_INT8)
639 {
640 for (int y = 0; y < ADT_GRID_SIZE; y++)
641 for (int x = 0; x < ADT_GRID_SIZE; x++)
642 uint8_V8[y][x] = uint8((V8[y][x] - minHeight) * step + 0.5f);
643 for (int y = 0; y <= ADT_GRID_SIZE; y++)
644 for (int x = 0; x <= ADT_GRID_SIZE; x++)
645 uint8_V9[y][x] = uint8((V9[y][x] - minHeight) * step + 0.5f);
646 map.heightMapSize += sizeof(uint8_V9) + sizeof(uint8_V8);
647 }
648 else if (heightHeader.flags & MAP_HEIGHT_AS_INT16)
649 {
650 for (int y = 0; y < ADT_GRID_SIZE; y++)
651 for (int x = 0; x < ADT_GRID_SIZE; x++)
652 uint16_V8[y][x] = uint16((V8[y][x] - minHeight) * step + 0.5f);
653 for (int y = 0; y <= ADT_GRID_SIZE; y++)
654 for (int x = 0; x <= ADT_GRID_SIZE; x++)
655 uint16_V9[y][x] = uint16((V9[y][x] - minHeight) * step + 0.5f);
656 map.heightMapSize += sizeof(uint16_V9) + sizeof(uint16_V8);
657 }
658 else
659 map.heightMapSize += sizeof(V9) + sizeof(V8);
660 }
661
662 // Get from MCLQ chunk (old)
663 for (int i = 0; i < ADT_CELLS_PER_GRID; i++)
664 {
665 for (int j = 0; j < ADT_CELLS_PER_GRID; j++)
666 {
667 adt_MCNK* cell = cells->getMCNK(i, j);
668 if (!cell)
669 continue;
670
671 adt_MCLQ* liquid = cell->getMCLQ();
672 int count = 0;
673 if (!liquid || cell->sizeMCLQ <= 8)
674 continue;
675
676 for (int y = 0; y < ADT_CELL_SIZE; y++)
677 {
678 int cy = i * ADT_CELL_SIZE + y;
679 for (int x = 0; x < ADT_CELL_SIZE; x++)
680 {
681 int cx = j * ADT_CELL_SIZE + x;
682 if (liquid->flags[y][x] != 0x0F)
683 {
684 liquid_show[cy][cx] = true;
685 if (liquid->flags[y][x] & (1 << 7))
687 ++count;
688 }
689 }
690 }
691
692 uint32 c_flag = cell->flags;
693 if (c_flag & (1 << 2))
694 {
695 liquid_entry[i][j] = 1;
696 liquid_flags[i][j] |= MAP_LIQUID_TYPE_WATER; // water
697 }
698 if (c_flag & (1 << 3))
699 {
700 liquid_entry[i][j] = 2;
701 liquid_flags[i][j] |= MAP_LIQUID_TYPE_OCEAN; // ocean
702 }
703 if (c_flag & (1 << 4))
704 {
705 liquid_entry[i][j] = 3;
706 liquid_flags[i][j] |= MAP_LIQUID_TYPE_MAGMA; // magma/slime
707 }
708
709 if (!count && liquid_flags[i][j])
710 fprintf(stderr, "Wrong liquid detect in MCLQ chunk");
711
712 for (int y = 0; y <= ADT_CELL_SIZE; y++)
713 {
714 int cy = i * ADT_CELL_SIZE + y;
715 for (int x = 0; x <= ADT_CELL_SIZE; x++)
716 {
717 int cx = j * ADT_CELL_SIZE + x;
718 liquid_height[cy][cx] = liquid->liquid[y][x].height;
719 }
720 }
721 }
722 }
723
724 // Get liquid map for grid (in WOTLK used MH2O chunk)
725 adt_MH2O* h2o = adt.a_grid->getMH2O();
726 if (h2o)
727 {
728 for (int32 i = 0; i < ADT_CELLS_PER_GRID; i++)
729 {
730 for (int32 j = 0; j < ADT_CELLS_PER_GRID; j++)
731 {
732 adt_liquid_instance const* h = h2o->GetLiquidInstance(i,j);
733 if (!h)
734 continue;
735
737
738 int32 count = 0;
739 uint64 existsMask = h2o->GetLiquidExistsBitmap(h);
740 for (int32 y = 0; y < h->GetHeight(); y++)
741 {
742 int32 cy = i * ADT_CELL_SIZE + y + h->GetOffsetY();
743 for (int32 x = 0; x < h->GetWidth(); x++)
744 {
745 int32 cx = j * ADT_CELL_SIZE + x + h->GetOffsetX();
746 if (existsMask & 1)
747 {
748 liquid_show[cy][cx] = true;
749 ++count;
750 }
751 existsMask >>= 1;
752 }
753 }
754
755 liquid_entry[i][j] = h->LiquidType;
756 switch (LiquidTypes.at(h->LiquidType).SoundBank)
757 {
762 default:
763 printf("\nCan't find Liquid type %u for map %s\nchunk %d,%d\n", h->LiquidType, inputPath.c_str(), i, j);
764 break;
765 }
766
767 if (!count && liquid_flags[i][j])
768 printf("Wrong liquid detect in MH2O chunk");
769
770 int32 pos = 0;
771 for (int32 y = 0; y <= h->GetHeight(); y++)
772 {
773 int cy = i * ADT_CELL_SIZE + y + h->GetOffsetY();
774 for (int32 x = 0; x <= h->GetWidth(); x++)
775 {
776 int32 cx = j * ADT_CELL_SIZE + x + h->GetOffsetX();
777 liquid_height[cy][cx] = h2o->GetLiquidHeight(h, pos);
778
779 pos++;
780 }
781 }
782 }
783 }
784 }
785 //============================================
786 // Pack liquid data
787 //============================================
788 uint16 firstLiquidType = liquid_entry[0][0];
789 uint8 firstLiquidFlag = liquid_flags[0][0];
790 bool fullType = false;
791 for (int y = 0; y < ADT_CELLS_PER_GRID; y++)
792 {
793 for (int x = 0; x < ADT_CELLS_PER_GRID; x++)
794 {
795 if (liquid_entry[y][x] != firstLiquidType || liquid_flags[y][x] != firstLiquidFlag)
796 {
797 fullType = true;
799 break;
800 }
801 }
802 }
803
804 map_liquidHeader liquidHeader;
805
806 // no water data (if all grid have 0 liquid type)
807 if (firstLiquidFlag == 0 && !fullType)
808 {
809 // No liquid data
810 map.liquidMapOffset = 0;
811 map.liquidMapSize = 0;
812 }
813 else
814 {
815 int minX = 255, minY = 255;
816 int maxX = 0, maxY = 0;
817 maxHeight = -20000;
818 minHeight = 20000;
819 for (int y = 0; y < ADT_GRID_SIZE; y++)
820 {
821 for (int x = 0; x < ADT_GRID_SIZE; x++)
822 {
823 if (liquid_show[y][x])
824 {
825 if (minX > x) minX = x;
826 if (maxX < x) maxX = x;
827 if (minY > y) minY = y;
828 if (maxY < y) maxY = y;
829 float h = liquid_height[y][x];
830 if (maxHeight < h) maxHeight = h;
831 if (minHeight > h) minHeight = h;
832 }
833 else
834 {
836
837 if (minHeight > CONF_use_minHeight)
838 {
839 minHeight = CONF_use_minHeight;
840 }
841 }
842 }
843 }
845 map.liquidMapSize = sizeof(map_liquidHeader);
846 liquidHeader.fourcc = *(uint32 const*)MAP_LIQUID_MAGIC;
847 liquidHeader.flags = 0;
848 liquidHeader.liquidType = 0;
849 liquidHeader.offsetX = minX;
850 liquidHeader.offsetY = minY;
851 liquidHeader.width = maxX - minX + 1 + 1;
852 liquidHeader.height = maxY - minY + 1 + 1;
853 liquidHeader.liquidLevel = minHeight;
854
855 if (maxHeight == minHeight)
856 liquidHeader.flags |= MAP_LIQUID_NO_HEIGHT;
857
858 // Not need store if flat surface
859 if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_liquid_delta_limit)
860 liquidHeader.flags |= MAP_LIQUID_NO_HEIGHT;
861
862 if (!fullType)
863 liquidHeader.flags |= MAP_LIQUID_NO_TYPE;
864
865 if (liquidHeader.flags & MAP_LIQUID_NO_TYPE)
866 {
867 liquidHeader.liquidFlags = firstLiquidFlag;
868 liquidHeader.liquidType = firstLiquidType;
869 }
870 else
871 map.liquidMapSize += sizeof(liquid_entry) + sizeof(liquid_flags);
872
873 if (!(liquidHeader.flags & MAP_LIQUID_NO_HEIGHT))
874 map.liquidMapSize += sizeof(float) * liquidHeader.width * liquidHeader.height;
875 }
876
877 bool hasHoles = false;
878
879 for (int i = 0; i < ADT_CELLS_PER_GRID; ++i)
880 {
881 for (int j = 0; j < ADT_CELLS_PER_GRID; ++j)
882 {
883 adt_MCNK* cell = cells->getMCNK(i, j);
884 if (!cell)
885 continue;
886 holes[i][j] = cell->holes;
887 if (!hasHoles && cell->holes != 0)
888 hasHoles = true;
889 }
890 }
891
892 if (hasHoles)
893 {
894 if (map.liquidMapOffset)
896 else
898
899 map.holesSize = sizeof(holes);
900 }
901 else
902 {
903 map.holesOffset = 0;
904 map.holesSize = 0;
905 }
906
907 // Ok all data prepared - store it
908 FILE* output = fopen(outputPath.c_str(), "wb");
909 if (!output)
910 {
911 printf("Can't create the output file '%s'\n", outputPath.c_str());
912 return false;
913 }
914 fwrite(&map, sizeof(map), 1, output);
915 // Store area data
916 fwrite(&areaHeader, sizeof(areaHeader), 1, output);
917 if (!(areaHeader.flags & MAP_AREA_NO_AREA))
918 fwrite(area_ids, sizeof(area_ids), 1, output);
919
920 // Store height data
921 fwrite(&heightHeader, sizeof(heightHeader), 1, output);
922 if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT))
923 {
924 if (heightHeader.flags & MAP_HEIGHT_AS_INT16)
925 {
926 fwrite(uint16_V9, sizeof(uint16_V9), 1, output);
927 fwrite(uint16_V8, sizeof(uint16_V8), 1, output);
928 }
929 else if (heightHeader.flags & MAP_HEIGHT_AS_INT8)
930 {
931 fwrite(uint8_V9, sizeof(uint8_V9), 1, output);
932 fwrite(uint8_V8, sizeof(uint8_V8), 1, output);
933 }
934 else
935 {
936 fwrite(V9, sizeof(V9), 1, output);
937 fwrite(V8, sizeof(V8), 1, output);
938 }
939 }
940
941 if (heightHeader.flags & MAP_HEIGHT_HAS_FLIGHT_BOUNDS)
942 {
943 fwrite(flight_box_max, sizeof(flight_box_max), 1, output);
944 fwrite(flight_box_min, sizeof(flight_box_min), 1, output);
945 }
946
947 // Store liquid data if need
948 if (map.liquidMapOffset)
949 {
950 fwrite(&liquidHeader, sizeof(liquidHeader), 1, output);
951 if (!(liquidHeader.flags & MAP_LIQUID_NO_TYPE))
952 {
953 fwrite(liquid_entry, sizeof(liquid_entry), 1, output);
954 fwrite(liquid_flags, sizeof(liquid_flags), 1, output);
955 }
956 if (!(liquidHeader.flags & MAP_LIQUID_NO_HEIGHT))
957 {
958 for (int y = 0; y < liquidHeader.height; y++)
959 fwrite(&liquid_height[y + liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output);
960 }
961 }
962
963 // store hole data
964 if (hasHoles)
965 fwrite(holes, map.holesSize, 1, output);
966
967 fclose(output);
968
969 return true;
970}
std::int32_t int32
Definition: Define.h:104
std::uint8_t uint8
Definition: Define.h:110
std::uint32_t uint32
Definition: Define.h:108
std::uint64_t uint64
Definition: Define.h:107
std::uint16_t uint16
Definition: Define.h:109
#define ADT_CELL_SIZE
Definition: adt.h:39
@ LIQUID_TYPE_WATER
Definition: adt.h:29
@ LIQUID_TYPE_SLIME
Definition: adt.h:32
@ LIQUID_TYPE_MAGMA
Definition: adt.h:31
@ LIQUID_TYPE_OCEAN
Definition: adt.h:30
#define ADT_GRID_SIZE
Definition: adt.h:40
#define ADT_CELLS_PER_GRID
Definition: adt.h:38
float selectUInt8StepStore(float maxDiff)
Definition: System.cpp:382
float CONF_float_to_int8_limit
Definition: System.cpp:96
uint16 uint16_V8[ADT_GRID_SIZE][ADT_GRID_SIZE]
Definition: System.cpp:396
uint16 holes[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
Definition: System.cpp:405
#define MAP_HEIGHT_HAS_FLIGHT_BOUNDS
Definition: System.cpp:348
bool CONF_allow_height_limit
Definition: System.cpp:91
#define MAP_LIQUID_TYPE_MAGMA
Definition: System.cpp:361
#define MAP_HEIGHT_AS_INT8
Definition: System.cpp:347
#define MAP_AREA_NO_AREA
Definition: System.cpp:336
bool CONF_allow_float_to_int
Definition: System.cpp:95
static char const * MAP_AREA_MAGIC
Definition: System.cpp:317
#define MAP_LIQUID_NO_TYPE
Definition: System.cpp:366
std::unordered_map< uint32, LiquidTypeEntry > LiquidTypes
Definition: System.cpp:73
#define MAP_LIQUID_NO_HEIGHT
Definition: System.cpp:367
uint16 uint16_V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]
Definition: System.cpp:397
#define MAP_LIQUID_TYPE_WATER
Definition: System.cpp:359
static char const * MAP_MAGIC
Definition: System.cpp:315
#define MAP_LIQUID_TYPE_DARK_WATER
Definition: System.cpp:364
float CONF_flat_liquid_delta_limit
Definition: System.cpp:99
#define MAP_LIQUID_TYPE_OCEAN
Definition: System.cpp:360
float CONF_use_minHeight
Definition: System.cpp:92
uint16 liquid_entry[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
Definition: System.cpp:401
static uint32 const MAP_VERSION_MAGIC
Definition: System.cpp:316
int16 flight_box_min[3][3]
Definition: System.cpp:408
float selectUInt16StepStore(float maxDiff)
Definition: System.cpp:387
uint16 area_ids[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
Definition: System.cpp:392
static char const * MAP_LIQUID_MAGIC
Definition: System.cpp:319
int16 flight_box_max[3][3]
Definition: System.cpp:407
float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]
Definition: System.cpp:404
#define MAP_LIQUID_TYPE_SLIME
Definition: System.cpp:362
#define MAP_HEIGHT_NO_HEIGHT
Definition: System.cpp:345
uint8 liquid_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
Definition: System.cpp:402
float V8[ADT_GRID_SIZE][ADT_GRID_SIZE]
Definition: System.cpp:394
uint8 uint8_V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]
Definition: System.cpp:399
float V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]
Definition: System.cpp:395
static char const * MAP_HEIGHT_MAGIC
Definition: System.cpp:318
float CONF_float_to_int16_limit
Definition: System.cpp:97
#define MAP_HEIGHT_AS_INT16
Definition: System.cpp:346
uint8 uint8_V8[ADT_GRID_SIZE][ADT_GRID_SIZE]
Definition: System.cpp:398
bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE]
Definition: System.cpp:403
float CONF_flat_height_delta_limit
Definition: System.cpp:98
Definition: Map.h:90
uint32 mapMagic
Definition: Map.h:91
uint32 holesSize
Definition: Map.h:101
uint32 liquidMapSize
Definition: Map.h:99
uint32 areaMapOffset
Definition: Map.h:94
uint32 heightMapSize
Definition: Map.h:97
uint32 heightMapOffset
Definition: Map.h:96
uint32 buildMagic
Definition: Map.h:93
uint32 holesOffset
Definition: Map.h:100
uint32 versionMagic
Definition: Map.h:92
uint32 liquidMapOffset
Definition: Map.h:98
uint32 areaMapSize
Definition: Map.h:95
Definition: Map.h:107
uint32 fourcc
Definition: Map.h:108
uint16 gridArea
Definition: Map.h:110
uint16 flags
Definition: Map.h:109
Definition: Map.h:119
float gridMaxHeight
Definition: Map.h:123
uint32 flags
Definition: Map.h:121
float gridHeight
Definition: Map.h:122
uint32 fourcc
Definition: Map.h:120
Definition: Map.h:130
uint8 offsetX
Definition: Map.h:135
uint32 fourcc
Definition: Map.h:131
uint8 liquidFlags
Definition: Map.h:133
uint8 width
Definition: Map.h:137
uint8 height
Definition: Map.h:138
uint8 flags
Definition: Map.h:132
uint16 liquidType
Definition: Map.h:134
uint8 offsetY
Definition: Map.h:136
float liquidLevel
Definition: Map.h:139
Definition: adt.h:46
float height_map[(ADT_CELL_SIZE+1) *(ADT_CELL_SIZE+1)+ADT_CELL_SIZE *ADT_CELL_SIZE]
Definition: adt.h:54
Definition: adt.h:63
struct adt_MCLQ::liquid_data liquid[ADT_CELL_SIZE+1][ADT_CELL_SIZE+1]
uint8 flags[ADT_CELL_SIZE][ADT_CELL_SIZE]
Definition: adt.h:85
float height
Definition: adt.h:76
Definition: adt.h:94
uint32 sizeMCLQ
Definition: adt.h:127
adt_MCVT * getMCVT()
Definition: adt.h:136
uint32 holes
Definition: adt.h:117
adt_MCLQ * getMCLQ()
Definition: adt.h:142
uint32 flags
Definition: adt.h:102
uint32 areaid
Definition: adt.h:115
float ypos
Definition: adt.h:130
Definition: adt.h:154
adt_MCNK * getMCNK(int x, int y)
Definition: adt.h:172
Definition: adt.h:188
uint8 GetWidth() const
Definition: adt.h:202
uint8 GetOffsetX() const
Definition: adt.h:200
uint16 LiquidType
Definition: adt.h:189
uint8 GetHeight() const
Definition: adt.h:203
uint8 GetOffsetY() const
Definition: adt.h:201
Definition: adt.h:207
uint64 Deep
Definition: adt.h:209
Definition: adt.h:216
adt_liquid_attributes GetLiquidAttributes(int32 x, int32 y) const
Definition: adt.h:241
adt_liquid_instance const * GetLiquidInstance(int32 x, int32 y) const
Definition: adt.h:234
float GetLiquidHeight(adt_liquid_instance const *h, int32 pos) const
Definition: adt.h:260
uint64 GetLiquidExistsBitmap(adt_liquid_instance const *h) const
Definition: adt.h:316
Definition: adt.h:328
adt_MFBO * getMFBO()
Definition: adt.h:387
adt_MCIN * getMCIN()
Definition: adt.h:377
adt_MH2O * getMH2O()
Definition: adt.h:381
Definition: adt.h:396
adt_MHDR * a_grid
Definition: adt.h:403
bool loadFile(std::string const &filename, bool log=true)
Definition: loadlib.cpp:40

References ADT_file::a_grid, ADT_CELL_SIZE, ADT_CELLS_PER_GRID, ADT_GRID_SIZE, area_ids, adt_MCNK::areaid, map_fileheader::areaMapOffset, map_fileheader::areaMapSize, map_fileheader::buildMagic, CONF_allow_float_to_int, CONF_allow_height_limit, CONF_flat_height_delta_limit, CONF_flat_liquid_delta_limit, CONF_float_to_int16_limit, CONF_float_to_int8_limit, CONF_use_minHeight, adt_liquid_attributes::Deep, map_areaHeader::flags, map_heightHeader::flags, map_liquidHeader::flags, adt_MCLQ::flags, adt_MCNK::flags, flight_box_max, flight_box_min, map_areaHeader::fourcc, map_heightHeader::fourcc, map_liquidHeader::fourcc, adt_liquid_instance::GetHeight(), adt_MH2O::GetLiquidAttributes(), adt_MH2O::GetLiquidExistsBitmap(), adt_MH2O::GetLiquidHeight(), adt_MH2O::GetLiquidInstance(), adt_MHDR::getMCIN(), adt_MCNK::getMCLQ(), adt_MCIN::getMCNK(), adt_MCNK::getMCVT(), adt_MHDR::getMFBO(), adt_MHDR::getMH2O(), adt_liquid_instance::GetOffsetX(), adt_liquid_instance::GetOffsetY(), adt_liquid_instance::GetWidth(), map_areaHeader::gridArea, map_heightHeader::gridHeight, map_heightHeader::gridMaxHeight, map_liquidHeader::height, adt_MCLQ::liquid_data::height, adt_MCVT::height_map, map_fileheader::heightMapOffset, map_fileheader::heightMapSize, adt_MCNK::holes, holes, map_fileheader::holesOffset, map_fileheader::holesSize, adt_MCLQ::liquid, liquid_entry, liquid_flags, liquid_height, liquid_show, LIQUID_TYPE_MAGMA, LIQUID_TYPE_OCEAN, LIQUID_TYPE_SLIME, LIQUID_TYPE_WATER, map_liquidHeader::liquidFlags, map_liquidHeader::liquidLevel, map_fileheader::liquidMapOffset, map_fileheader::liquidMapSize, map_liquidHeader::liquidType, adt_liquid_instance::LiquidType, LiquidTypes, FileLoader::loadFile(), MAP_AREA_MAGIC, MAP_AREA_NO_AREA, MAP_HEIGHT_AS_INT16, MAP_HEIGHT_AS_INT8, MAP_HEIGHT_HAS_FLIGHT_BOUNDS, MAP_HEIGHT_MAGIC, MAP_HEIGHT_NO_HEIGHT, MAP_LIQUID_MAGIC, MAP_LIQUID_NO_HEIGHT, MAP_LIQUID_NO_TYPE, MAP_LIQUID_TYPE_DARK_WATER, MAP_LIQUID_TYPE_MAGMA, MAP_LIQUID_TYPE_OCEAN, MAP_LIQUID_TYPE_SLIME, MAP_LIQUID_TYPE_WATER, MAP_MAGIC, MAP_VERSION_MAGIC, map_fileheader::mapMagic, map_liquidHeader::offsetX, map_liquidHeader::offsetY, selectUInt16StepStore(), selectUInt8StepStore(), adt_MCNK::sizeMCLQ, uint16_V8, uint16_V9, uint8_V8, uint8_V9, V8, V9, map_fileheader::versionMagic, map_liquidHeader::width, and adt_MCNK::ypos.

Referenced by ExtractMapsFromMpq().

◆ CreateDir()

void CreateDir ( const std::string &  Path)
119{
120 if (chdir(Path.c_str()) == 0)
121 {
122 int ret = chdir("../");
123 if (ret < 0)
124 {
125 printf("Error while executing chdir");
126 }
127 return;
128 }
129
130 int ret;
131#ifdef _WIN32
132 ret = _mkdir( Path.c_str());
133#else
134 ret = mkdir( Path.c_str(), 0777 );
135#endif
136 if (ret != 0)
137 {
138 printf("Fatal Error: Could not create directory %s check your permissions", Path.c_str());
139 exit(1);
140 }
141}

Referenced by ExtractCameraFiles(), ExtractDBCFiles(), and ExtractMapsFromMpq().

◆ ExtractCameraFiles()

void ExtractCameraFiles ( int  locale,
bool  basicLocale 
)
1085{
1086 printf("Extracting camera files...\n");
1087 DBCFile camdbc("DBFilesClient\\CinematicCamera.dbc");
1088
1089 if (!camdbc.open())
1090 {
1091 printf("Unable to open CinematicCamera.dbc. Camera extract aborted.\n");
1092 return;
1093 }
1094
1095 // get camera file list from DBC
1096 std::vector<std::string> camerafiles;
1097 size_t cam_count = camdbc.getRecordCount();
1098
1099 for (size_t i = 0; i < cam_count; ++i)
1100 {
1101 std::string camFile(camdbc.getRecord(i).getString(1));
1102 size_t loc = camFile.find(".mdx");
1103 if (loc != std::string::npos)
1104 {
1105 camFile.replace(loc, 4, ".m2");
1106 }
1107 camerafiles.push_back(std::string(camFile));
1108 }
1109
1110 std::string path = output_path;
1111 path += "/Cameras/";
1112 CreateDir(path);
1113 if (!basicLocale)
1114 {
1115 path += langs[locale];
1116 path += "/";
1117 CreateDir(path);
1118 }
1119
1120 // extract M2s
1121 uint32 count = 0;
1122 for (std::string thisFile : camerafiles)
1123 {
1124 std::string filename = path;
1125 filename += (thisFile.c_str() + strlen("Cameras\\"));
1126
1127 if (std::filesystem::exists(filename))
1128 {
1129 continue;
1130 }
1131
1132 if (ExtractFile(thisFile.c_str(), filename))
1133 {
1134 ++count;
1135 }
1136 }
1137 printf("Extracted %u camera files\n", count);
1138}
bool ExtractFile(char const *mpq_name, std::string const &filename)
Definition: System.cpp:1018
char output_path[MAX_PATH_LENGTH]
Definition: System.cpp:75
static const char *const langs[]
Definition: System.cpp:115
void CreateDir(const std::string &Path)
Definition: System.cpp:118
Definition: dbcfile.h:26

References CreateDir(), ExtractFile(), DBCFile::getRecord(), DBCFile::getRecordCount(), DBCFile::Record::getString(), langs, DBCFile::open(), and output_path.

Referenced by main().

◆ ExtractDBCFiles()

void ExtractDBCFiles ( int  locale,
bool  basicLocale 
)
1035{
1036 printf("Extracting dbc files...\n");
1037
1038 std::set<std::string> dbcfiles;
1039
1040 // get DBC file list
1041 for (auto & gOpenArchive : gOpenArchives)
1042 {
1043 vector<string> files;
1044 gOpenArchive->GetFileListTo(files);
1045 for (auto & file : files)
1046 if (file.rfind(".dbc") == file.length() - strlen(".dbc"))
1047 dbcfiles.insert(file);
1048 }
1049
1050 std::string path = output_path;
1051 path += "/dbc/";
1052 CreateDir(path);
1053 if (!basicLocale)
1054 {
1055 path += langs[locale];
1056 path += "/";
1057 CreateDir(path);
1058 }
1059
1060 // extract Build info file
1061 {
1062 string mpq_name = std::string("component.wow-") + langs[locale] + ".txt";
1063 string filename = path + mpq_name;
1064
1065 ExtractFile(mpq_name.c_str(), filename);
1066 }
1067
1068 // extract DBCs
1069 uint32 count = 0;
1070 for (const auto & dbcfile : dbcfiles)
1071 {
1072 string filename = path;
1073 filename += (dbcfile.c_str() + strlen("DBFilesClient\\"));
1074
1075 if (FileExists(filename.c_str()))
1076 continue;
1077
1078 if (ExtractFile(dbcfile.c_str(), filename))
1079 ++count;
1080 }
1081 printf("Extracted %u DBC files\n\n", count);
1082}
bool FileExists(const char *FileName)
Definition: System.cpp:143

References CreateDir(), ExtractFile(), FileExists(), gOpenArchives, langs, and output_path.

Referenced by main().

◆ ExtractFile()

bool ExtractFile ( char const *  mpq_name,
std::string const &  filename 
)
1019{
1020 FILE* output = fopen(filename.c_str(), "wb");
1021 if (!output)
1022 {
1023 printf("Can't create the output file '%s'\n", filename.c_str());
1024 return false;
1025 }
1026 MPQFile m(mpq_name);
1027 if (!m.isEof())
1028 fwrite(m.getPointer(), 1, m.getSize(), output);
1029
1030 fclose(output);
1031 return true;
1032}
Definition: mpq_libmpq04.h:75

References MPQFile::getPointer(), MPQFile::getSize(), and MPQFile::isEof().

Referenced by ExtractCameraFiles(), and ExtractDBCFiles().

◆ ExtractMapsFromMpq()

void ExtractMapsFromMpq ( uint32  build)
973{
974 std::string mpqFileName;
975 std::string outputFileName;
976 std::string mpqMapName;
977
978 printf("Extracting maps...\n");
979
981
983
984 std::string path = output_path;
985 path += "/maps/";
986 CreateDir(path);
987
988 printf("Convert map files\n");
989 for (uint32 z = 0; z < map_count; ++z)
990 {
991 printf("Extract %s (%d/%u) \n", map_ids[z].name, z + 1, map_count);
992 // Loadup map grid data
993 mpqMapName = Acore::StringFormat(R"(World\Maps\%s\%s.wdt)", map_ids[z].name, map_ids[z].name);
994 WDT_file wdt;
995 if (!wdt.loadFile(mpqMapName, false))
996 {
997 // printf("Error loading %s map wdt data\n", map_ids[z].name);
998 continue;
999 }
1000
1001 for (uint32 y = 0; y < WDT_MAP_SIZE; ++y)
1002 {
1003 for (uint32 x = 0; x < WDT_MAP_SIZE; ++x)
1004 {
1005 if (!wdt.main->adt_list[y][x].exist)
1006 continue;
1007 mpqFileName = Acore::StringFormat(R"(World\Maps\%s\%s_%u_%u.adt)", map_ids[z].name, map_ids[z].name, x, y);
1008 outputFileName = Acore::StringFormat("%s/maps/%03u%02u%02u.map", output_path, map_ids[z].id, y, x);
1009 ConvertADT(mpqFileName, outputFileName, y, x, build);
1010 }
1011 // draw progress bar
1012 printf("Processing........................%d%%\r", (100 * (y + 1)) / WDT_MAP_SIZE);
1013 }
1014 }
1015 printf("\n");
1016}
bool ConvertADT(std::string const &inputPath, std::string const &outputPath, int, int, uint32 build)
Definition: System.cpp:410
std::vector< map_id > map_ids
Definition: System.cpp:72
uint32 ReadMapDBC()
Definition: System.cpp:269
void ReadLiquidTypeTableDBC()
Definition: System.cpp:291
#define WDT_MAP_SIZE
Definition: wdt.h:25
uint32 map_count
Definition: vmapexport.cpp:59
std::string StringFormat(Format &&fmt, Args &&... args)
Default AC string format function.
Definition: StringFormat.h:30
struct wdt_MAIN::adtData adt_list[64][64]
uint32 exist
Definition: wdt.h:60
Definition: wdt.h:68
wdt_MAIN * main
Definition: wdt.h:77

References wdt_MAIN::adt_list, ConvertADT(), CreateDir(), wdt_MAIN::adtData::exist, FileLoader::loadFile(), WDT_file::main, map_count, map_ids, output_path, ReadLiquidTypeTableDBC(), ReadMapDBC(), Acore::StringFormat(), and WDT_MAP_SIZE.

Referenced by main().

◆ FileExists()

bool FileExists ( const char *  FileName)
144{
145 int fp = _open(FileName, OPEN_FLAGS);
146 if (fp != -1)
147 {
148 _close(fp);
149 return true;
150 }
151
152 return false;
153}
#define OPEN_FLAGS
Definition: System.cpp:56

References OPEN_FLAGS.

Referenced by ExtractDBCFiles(), ExtractSingleModel(), LoadCommonMPQFiles(), LoadLocaleMPQFiles(), and main().

◆ HandleArgs()

void HandleArgs ( int  argc,
char *  arg[] 
)
169{
170 for (int c = 1; c < argc; ++c)
171 {
172 // i - input path
173 // o - output path
174 // e - extract only MAP(1)/DBC(2) - standard both(3)
175 // f - use float to int conversion
176 // h - limit minimum height
177 if (arg[c][0] != '-')
178 {
179 Usage(arg[0]);
180 }
181
182 switch (arg[c][1])
183 {
184 case 'i':
185 if (c + 1 < argc) // all ok
186 {
187 strcpy(input_path, arg[(c++) + 1]);
188 }
189 else
190 {
191 Usage(arg[0]);
192 }
193 break;
194 case 'o':
195 if (c + 1 < argc) // all ok
196 {
197 strcpy(output_path, arg[(c++) + 1]);
198 }
199 else
200 {
201 Usage(arg[0]);
202 }
203 break;
204 case 'f':
205 if (c + 1 < argc) // all ok
206 {
207 CONF_allow_float_to_int = atoi(arg[(c++) + 1]) != 0;
208 }
209 else
210 {
211 Usage(arg[0]);
212 }
213 break;
214 case 'e':
215 if (c + 1 < argc) // all ok
216 {
217 CONF_extract = atoi(arg[(c++) + 1]);
218 if (!(CONF_extract > 0 && CONF_extract < 8))
219 {
220 Usage(arg[0]);
221 }
222 }
223 else
224 {
225 Usage(arg[0]);
226 }
227 break;
228 }
229 }
230}
char input_path[MAX_PATH_LENGTH]
Definition: System.cpp:76
void Usage(char *prg)
Definition: System.cpp:155
int CONF_extract
Definition: System.cpp:89

References CONF_allow_float_to_int, CONF_extract, input_path, output_path, and Usage().

Referenced by main().

◆ LoadCommonMPQFiles()

void LoadCommonMPQFiles ( )
1160{
1161 char filename[512];
1162 int count = sizeof(CONF_mpq_list) / sizeof(char*);
1163 for (int i = 0; i < count; ++i)
1164 {
1165 sprintf(filename, "%s/Data/%s", input_path, CONF_mpq_list[i]);
1166 if (FileExists(filename))
1167 new MPQArchive(filename);
1168 }
1169}
const char * CONF_mpq_list[]
Definition: System.cpp:102
Definition: mpq_libmpq04.h:33

References CONF_mpq_list, FileExists(), and input_path.

Referenced by main().

◆ LoadLocaleMPQFiles()

void LoadLocaleMPQFiles ( int const  locale)
1141{
1142 char filename[512];
1143
1144 sprintf(filename, "%s/Data/%s/locale-%s.MPQ", input_path, langs[locale], langs[locale]);
1145 new MPQArchive(filename);
1146
1147 for (int i = 1; i < 5; ++i)
1148 {
1149 char ext[3] = "";
1150 if (i > 1)
1151 sprintf(ext, "-%i", i);
1152
1153 sprintf(filename, "%s/Data/%s/patch-%s%s.MPQ", input_path, langs[locale], langs[locale], ext);
1154 if (FileExists(filename))
1155 new MPQArchive(filename);
1156 }
1157}

References FileExists(), input_path, and langs.

Referenced by main().

◆ main()

int main ( int  argc,
char *  arg[] 
)
1178{
1179 printf("Map & DBC Extractor\n");
1180 printf("===================\n\n");
1181
1182 HandleArgs(argc, arg);
1183
1184 int FirstLocale = -1;
1185 uint32 build = 0;
1186
1187 for (int i = 0; i < LANG_COUNT; i++)
1188 {
1189 char tmp1[512];
1190 sprintf(tmp1, "%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]);
1191 if (FileExists(tmp1))
1192 {
1193 printf("Detected locale: %s\n", langs[i]);
1194
1195 //Open MPQs
1197
1198 if ((CONF_extract & EXTRACT_DBC) == 0)
1199 {
1200 FirstLocale = i;
1201 build = ReadBuild(FirstLocale);
1202 printf("Detected client build: %u\n", build);
1203 break;
1204 }
1205
1206 //Extract DBC files
1207 if (FirstLocale < 0)
1208 {
1209 FirstLocale = i;
1210 build = ReadBuild(FirstLocale);
1211 printf("Detected client build: %u\n", build);
1212 ExtractDBCFiles(i, true);
1213 }
1214 else
1215 ExtractDBCFiles(i, false);
1216
1217 //Close MPQs
1218 CloseMPQFiles();
1219 }
1220 }
1221
1222 if (FirstLocale < 0)
1223 {
1224 printf("No locales detected\n");
1225 return 0;
1226 }
1227
1229 {
1230 printf("Using locale: %s\n", langs[FirstLocale]);
1231
1232 // Open MPQs
1233 LoadLocaleMPQFiles(FirstLocale);
1235
1236 ExtractCameraFiles(FirstLocale, true);
1237 // Close MPQs
1238 CloseMPQFiles();
1239 }
1240
1242 {
1243 printf("Using locale: %s\n", langs[FirstLocale]);
1244
1245 // Open MPQs
1246 LoadLocaleMPQFiles(FirstLocale);
1248
1249 // Extract maps
1250 ExtractMapsFromMpq(build);
1251
1252 // Close MPQs
1253 CloseMPQFiles();
1254 }
1255
1256 return 0;
1257}
#define LANG_COUNT
Definition: System.cpp:116
void HandleArgs(int argc, char *arg[])
Definition: System.cpp:168
void LoadLocaleMPQFiles(int const locale)
Definition: System.cpp:1140
void CloseMPQFiles()
Definition: System.cpp:1171
void ExtractMapsFromMpq(uint32 build)
Definition: System.cpp:972
void ExtractDBCFiles(int locale, bool basicLocale)
Definition: System.cpp:1034
uint32 ReadBuild(int locale)
Definition: System.cpp:232
void LoadCommonMPQFiles()
Definition: System.cpp:1159
void ExtractCameraFiles(int locale, bool basicLocale)
Definition: System.cpp:1084

References CloseMPQFiles(), CONF_extract, EXTRACT_CAMERA, EXTRACT_DBC, EXTRACT_MAP, ExtractCameraFiles(), ExtractDBCFiles(), ExtractMapsFromMpq(), FileExists(), HandleArgs(), input_path, LANG_COUNT, langs, LoadCommonMPQFiles(), LoadLocaleMPQFiles(), and ReadBuild().

◆ ReadBuild()

uint32 ReadBuild ( int  locale)
233{
234 // include build info file also
235 std::string filename = std::string("component.wow-") + langs[locale] + ".txt";
236 //printf("Read %s file... ", filename.c_str());
237
238 MPQFile m(filename.c_str());
239 if (m.isEof())
240 {
241 printf("Fatal error: Not found %s file!\n", filename.c_str());
242 exit(1);
243 }
244
245 std::string text = std::string(m.getPointer(), m.getSize());
246 m.close();
247
248 size_t pos = text.find("version=\"");
249 size_t pos1 = pos + strlen("version=\"");
250 size_t pos2 = text.find("\"", pos1);
251 if (pos == text.npos || pos2 == text.npos || pos1 >= pos2)
252 {
253 printf("Fatal error: Invalid %s file format!\n", filename.c_str());
254 exit(1);
255 }
256
257 std::string build_str = text.substr(pos1, pos2 - pos1);
258
259 int build = atoi(build_str.c_str());
260 if (build <= 0)
261 {
262 printf("Fatal error: Invalid %s file format!\n", filename.c_str());
263 exit(1);
264 }
265
266 return build;
267}

References MPQFile::close(), MPQFile::getPointer(), MPQFile::getSize(), MPQFile::isEof(), and langs.

Referenced by main().

◆ ReadLiquidTypeTableDBC()

void ReadLiquidTypeTableDBC ( )
292{
293 printf("Read LiquidType.dbc file...");
294 DBCFile dbc("DBFilesClient\\LiquidType.dbc");
295 if (!dbc.open())
296 {
297 printf("Fatal error: Invalid LiquidType.dbc file format!\n");
298 exit(1);
299 }
300
301 for (uint32 x = 0; x < dbc.getRecordCount(); ++x)
302 {
303 LiquidTypeEntry& liquidType = LiquidTypes[dbc.getRecord(x).getUInt(0)];
304 liquidType.SoundBank = dbc.getRecord(x).getUInt(3);
305 }
306
307 printf("Done! (%lu LiquidTypes loaded)\n", LiquidTypes.size());
308}
Definition: DBCStructure.h:1281
uint8 SoundBank
Definition: System.cpp:69

References DBCFile::getRecord(), DBCFile::getRecordCount(), DBCFile::Record::getUInt(), LiquidTypes, DBCFile::open(), and LiquidTypeEntry::SoundBank.

Referenced by ExtractMapsFromMpq().

◆ ReadMapDBC()

uint32 ReadMapDBC ( )
270{
271 printf("Read Map.dbc file... ");
272 DBCFile dbc("DBFilesClient\\Map.dbc");
273
274 if (!dbc.open())
275 {
276 printf("Fatal error: Invalid Map.dbc file format!\n");
277 exit(1);
278 }
279
280 size_t map_count = dbc.getRecordCount();
281 map_ids.resize(map_count);
282 for (uint32 x = 0; x < map_count; ++x)
283 {
284 map_ids[x].id = dbc.getRecord(x).getUInt(0);
285 strcpy(map_ids[x].name, dbc.getRecord(x).getString(1));
286 }
287 printf("Done! (%u maps loaded)\n", (uint32)map_count);
288 return map_count;
289}

References DBCFile::getRecord(), DBCFile::getRecordCount(), DBCFile::Record::getString(), DBCFile::Record::getUInt(), map_count, map_ids, and DBCFile::open().

Referenced by ExtractMapsFromMpq().

◆ selectUInt16StepStore()

float selectUInt16StepStore ( float  maxDiff)
388{
389 return 65535 / maxDiff;
390}

Referenced by ConvertADT().

◆ selectUInt8StepStore()

float selectUInt8StepStore ( float  maxDiff)
383{
384 return 255 / maxDiff;
385}

Referenced by ConvertADT().

◆ Usage()

void Usage ( char *  prg)
156{
157 printf(
158 "Usage:\n"\
159 "%s -[var] [value]\n"\
160 "-i set input path\n"\
161 "-o set output path\n"\
162 "-e extract only MAP(1)/DBC(2)/Camera(4) - standard: all(7)\n"\
163 "-f height stored as int (less map size but lost some accuracy) 1 by default\n"\
164 "Example: %s -f 0 -i \"c:\\games\\game\"", prg, prg);
165 exit(1);
166}

Referenced by HandleArgs().

Variable Documentation

◆ area_ids

◆ CONF_allow_float_to_int

bool CONF_allow_float_to_int = true

Referenced by ConvertADT(), and HandleArgs().

◆ CONF_allow_height_limit

bool CONF_allow_height_limit = true

Referenced by ConvertADT().

◆ CONF_extract

int CONF_extract = EXTRACT_MAP | EXTRACT_DBC | EXTRACT_CAMERA

Referenced by HandleArgs(), and main().

◆ CONF_flat_height_delta_limit

float CONF_flat_height_delta_limit = 0.005f

Referenced by ConvertADT().

◆ CONF_flat_liquid_delta_limit

float CONF_flat_liquid_delta_limit = 0.001f

Referenced by ConvertADT().

◆ CONF_float_to_int16_limit

float CONF_float_to_int16_limit = 2048.0f

Referenced by ConvertADT().

◆ CONF_float_to_int8_limit

float CONF_float_to_int8_limit = 2.0f

Referenced by ConvertADT().

◆ CONF_mpq_list

const char* CONF_mpq_list[]
Initial value:
=
{
"common.MPQ",
"common-2.MPQ",
"lichking.MPQ",
"expansion.MPQ",
"patch.MPQ",
"patch-2.MPQ",
"patch-3.MPQ",
"patch-4.MPQ",
"patch-5.MPQ",
}

Referenced by LoadCommonMPQFiles().

◆ CONF_use_minHeight

float CONF_use_minHeight = -500.0f

Referenced by ConvertADT().

◆ flight_box_max

int16 flight_box_max[3][3]

Referenced by ConvertADT().

◆ flight_box_min

int16 flight_box_min[3][3]

Referenced by ConvertADT().

◆ gOpenArchives

ArchiveSet gOpenArchives
extern

Referenced by CloseMPQFiles(), and ExtractDBCFiles().

◆ holes

◆ input_path

char input_path[MAX_PATH_LENGTH] = "."

◆ langs

const char* const langs[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }
static

◆ liquid_entry

◆ liquid_flags

◆ liquid_height

float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]

Referenced by ConvertADT().

◆ liquid_show

bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE]

Referenced by ConvertADT().

◆ LiquidTypes

std::unordered_map<uint32, LiquidTypeEntry> LiquidTypes

◆ MAP_AREA_MAGIC

char const* MAP_AREA_MAGIC = "AREA"
static

Referenced by ConvertADT().

◆ MAP_HEIGHT_MAGIC

char const* MAP_HEIGHT_MAGIC = "MHGT"
static

Referenced by ConvertADT().

◆ map_ids

std::vector<map_id> map_ids

Referenced by ExtractMapsFromMpq(), and ReadMapDBC().

◆ MAP_LIQUID_MAGIC

char const* MAP_LIQUID_MAGIC = "MLIQ"
static

Referenced by ConvertADT().

◆ MAP_MAGIC

char const* MAP_MAGIC = "MAPS"
static

Referenced by ConvertADT().

◆ MAP_VERSION_MAGIC

uint32 const MAP_VERSION_MAGIC = 9
static

Referenced by ConvertADT().

◆ output_path

◆ uint16_V8

Referenced by ConvertADT().

◆ uint16_V9

Referenced by ConvertADT().

◆ uint8_V8

Referenced by ConvertADT().

◆ uint8_V9

Referenced by ConvertADT().

◆ V8

◆ V9