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 <cstring>
#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 
83{
84 EXTRACT_MAP = 1,
85 EXTRACT_DBC = 2,
87};
@ EXTRACT_CAMERA
Definition System.cpp:86
@ EXTRACT_MAP
Definition System.cpp:84
@ EXTRACT_DBC
Definition System.cpp:85

Function Documentation

◆ CloseMPQFiles()

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

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

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

◆ ExtractCameraFiles()

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

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

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

Referenced by main().

◆ ExtractFile()

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

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

Referenced by ExtractCameraFiles(), and ExtractDBCFiles().

◆ ExtractMapsFromMpq()

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

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)
145{
146 int fp = _open(FileName, OPEN_FLAGS);
147 if (fp != -1)
148 {
149 _close(fp);
150 return true;
151 }
152
153 return false;
154}
#define OPEN_FLAGS
Definition System.cpp:57

References OPEN_FLAGS.

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

◆ HandleArgs()

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

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

Referenced by main().

◆ LoadCommonMPQFiles()

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

References CONF_mpq_list, FileExists(), and input_path.

Referenced by main().

◆ LoadLocaleMPQFiles()

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

References FileExists(), input_path, and langs.

Referenced by main().

◆ main()

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

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

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

Referenced by main().

◆ ReadLiquidTypeTableDBC()

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

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

Referenced by ExtractMapsFromMpq().

◆ ReadMapDBC()

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

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)
392{
393 return 65535 / maxDiff;
394}

Referenced by ConvertADT().

◆ selectUInt8StepStore()

float selectUInt8StepStore ( float  maxDiff)
387{
388 return 255 / maxDiff;
389}

Referenced by ConvertADT().

◆ Usage()

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

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",
}
104{
105 "common.MPQ",
106 "common-2.MPQ",
107 "lichking.MPQ",
108 "expansion.MPQ",
109 "patch.MPQ",
110 "patch-2.MPQ",
111 "patch-3.MPQ",
112 "patch-4.MPQ",
113 "patch-5.MPQ",
114};

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
116{"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" };

Referenced by ExtractCameraFiles(), ExtractDBCFiles(), LoadLocaleMPQFiles(), main(), and ReadBuild().

◆ 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