Some more map extractor fixes. Patch provided by andstan.

Coding style fix.
Removed hack from lava detection code.
Please test water/lava detection. Should work fine now.
This commit is contained in:
tomrus88 2008-12-06 19:19:46 +03:00
parent 129c0797a7
commit bfe899b126
6 changed files with 254 additions and 250 deletions

View file

@ -17,3 +17,4 @@
debug
release
*.user
*.ilk

View file

@ -29,6 +29,7 @@ typedef unsigned int uint32;
map_id *map_ids;
uint16 *areas;
uint16 *LiqType;
char output_path[128] = ".";
char input_path[128] = ".";
uint32 maxAreaId = 0;
@ -67,14 +68,13 @@ bool FileExists( const char* FileName )
void Usage(char* prg)
{
printf("Usage:\n%s -[var] [value]\n-i set input path\n-o set output path\n-r set resolution\n-e extract only MAP(1)/DBC(2) - standard: both(3)\nExample: %s -r 256 -i \"c:\\games\\game\"",
prg,prg);
printf("Usage:\n%s -[var] [value]\n-i set input path\n-o set output path\n-r set resolution\n-e extract only MAP(1)/DBC(2) - standard: both(3)\nExample: %s -r 256 -i \"c:\\games\\game\"", prg, prg);
exit(1);
}
void HandleArgs(int argc, char * arg[])
{
for(int c=1;c<argc;c++)
for(int c = 1; c < argc; ++c)
{
// i - input path
// o - output path
@ -123,9 +123,9 @@ uint32 ReadMapDBC()
DBCFile dbc("DBFilesClient\\Map.dbc");
dbc.open();
uint32 map_count=dbc.getRecordCount();
size_t map_count = dbc.getRecordCount();
map_ids = new map_id[map_count];
for(unsigned int x=0;x<map_count;x++)
for(uint32 x = 0; x < map_count; ++x)
{
map_ids[x].id = dbc.getRecord(x).getUInt(0);
strcpy(map_ids[x].name, dbc.getRecord(x).getString(1));
@ -140,11 +140,12 @@ void ReadAreaTableDBC()
DBCFile dbc("DBFilesClient\\AreaTable.dbc");
dbc.open();
unsigned int area_count=dbc.getRecordCount();
uint32 maxid = dbc.getMaxId();
size_t area_count = dbc.getRecordCount();
size_t maxid = dbc.getMaxId();
areas = new uint16[maxid + 1];
memset(areas, 0xff, sizeof(areas));
for(unsigned int x=0; x<area_count;++x)
for(uint32 x = 0; x < area_count; ++x)
areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
maxAreaId = dbc.getMaxId();
@ -152,6 +153,22 @@ void ReadAreaTableDBC()
printf("Done! (%u areas loaded)\n", area_count);
}
void ReadLiquidTypeTableDBC()
{
printf("Read LiquidType.dbc file...");
DBCFile dbc("DBFilesClient\\LiquidType.dbc");
dbc.open();
size_t LiqType_count = dbc.getRecordCount();
size_t LiqType_maxid = dbc.getMaxId();
LiqType = new uint16[LiqType_maxid + 1];
memset(LiqType, 0xff, (LiqType_maxid + 1) * sizeof(uint16));
for(uint32 x = 0; x < LiqType_count; ++x)
LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
printf("Done! (%u LiqTypes loaded)\n", LiqType_count);
}
void ExtractMapsFromMpq()
{
char mpq_filename[1024];
@ -162,6 +179,7 @@ void ExtractMapsFromMpq()
uint32 map_count = ReadMapDBC();
ReadAreaTableDBC();
ReadLiquidTypeTableDBC();
unsigned int total = map_count * ADT_RES * ADT_RES;
unsigned int done = 0;
@ -170,11 +188,11 @@ void ExtractMapsFromMpq()
path += "/maps/";
CreateDir(path);
for(unsigned int x = 0; x < ADT_RES; ++x)
for(uint32 x = 0; x < ADT_RES; ++x)
{
for(unsigned int y = 0; y < ADT_RES; ++y)
for(uint32 y = 0; y < ADT_RES; ++y)
{
for(unsigned int z = 0; z < map_count; ++z)
for(uint32 z = 0; z < map_count; ++z)
{
sprintf(mpq_filename, "World\\Maps\\%s\\%s_%u_%u.adt", map_ids[z].name, map_ids[z].name, x, y);
sprintf(output_filename, "%s/maps/%03u%02u%02u.map", output_path, map_ids[z].id, y, x);

Binary file not shown.

View file

@ -17,13 +17,13 @@
unsigned int iRes = 256;
extern uint16 *areas;
extern uint16 *LiqType;
extern uint32 maxAreaId;
vec wmoc;
Cell *cell;
uint32 wmo_count;
//uint32 wmo_count;
mcell *mcells;
int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888};
int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000};
@ -38,6 +38,15 @@ bool LoadADT(char* filename)
//printf("No such file %s\n", filename);
return false;
}
MapLiqFlag = new uint8[256];
for(int j = 0; j < 256; ++j)
MapLiqFlag[j] = 0; // no water
MapLiqHeight = new float[16384];
for(int j = 0; j < 16384; ++j)
MapLiqHeight[j] = -999999; // no water
mcells=new mcell;
wmoc.x =65 * TILESIZE;
@ -45,8 +54,8 @@ bool LoadADT(char* filename)
size_t mcnk_offsets[256], mcnk_sizes[256];
wmo_count=0;
bool found=false;
//wmo_count = 0;
//bool found = false;
MH2O_presence = false;
chunk_num = 0;
@ -96,10 +105,12 @@ bool LoadADT(char* filename)
mf.seek(base_pos + LiqOffsData->offsData1);
mf.read(LiqChunkData1, 24); // ñ÷èòûâàåì ñàìè äàííûå â ñòðóêòóðó òèïà MH2O_Data1
// çàíîñèì äàííûå ôëàãà äëÿ êóñêà
if(LiqChunkData1->flags & 4 || LiqChunkData1->flags & 8)
MapLiqFlag[chunk_num] |= 1;
if(LiqChunkData1->flags & 16)
MapLiqFlag[chunk_num] |= 2;
if(LiqType[LiqChunkData1->LiquidTypeId] == 0xffff)
printf("\nCan't find Liquid type for map %s\nchunk %d\n", filename, chunk_num);
else if(LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_WATER || LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_OCEAN)
MapLiqFlag[chunk_num] |= 1; // water/ocean
else if(LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_MAGMA || LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_SLIME)
MapLiqFlag[chunk_num] |= 2; // magma/slime
// ïðåäâàðèòåëüíî çàïîëíÿåì âåñü êóñîê äàííûìè - íåò âîäû
for(int j = 0; j < 81; ++j)
{
@ -193,6 +204,7 @@ inline void LoadMapChunk(MPQFile & mf, chunk*_chunk)
if(wmoc.x > xbase) wmoc.x = xbase;
if(wmoc.z > zbase) wmoc.z = zbase;
int chunkflags = header.flags;
//printf("LMC: flags %X\n", chunkflags);
float zmin = 999999999.0f;
float zmax = -999999999.0f;
// must be there, bl!zz uses some crazy format
@ -264,9 +276,9 @@ inline void LoadMapChunk(MPQFile & mf, chunk*_chunk)
}
if(chunkflags & 4 || chunkflags & 8)
MapLiqFlag[chunk_num] |= 1;
MapLiqFlag[chunk_num] |= 1; // water
if(chunkflags & 16)
MapLiqFlag[chunk_num] |= 2;
MapLiqFlag[chunk_num] |= 2; // magma/slime
}
// çàïîëíåì òàê æå êàê â MH2O
if(!(chunk_num % 16))
@ -325,11 +337,11 @@ inline double GetZ(double x, double z)
{
v[1].x = UNITSIZE;
v[1].y = cell->v9[xc + 1][zc];
v[1].z=0;
v[1].z = 0.0f;
}
else
{
v[1].x=0.0;
v[1].x = 0.0f;
v[1].y = cell->v9[xc][zc + 1];
v[1].z = UNITSIZE;
}
@ -342,9 +354,9 @@ inline double GetZ(double x, double z)
}
else
{
v[2].x=0;
v[2].x = 0.0f;
v[2].y = cell->v9[xc][zc];
v[2].z=0;
v[2].z = 0.0f;
}
return -solve(v, &p);
@ -355,9 +367,9 @@ inline void TransformData()
{
cell = new Cell;
for(int x=0;x<128;++x)
for(uint32 x = 0; x < 128; ++x)
{
for(int y=0;y<128;++y)
for(uint32 y = 0; y < 128; ++y)
{
cell->v8[x][y] = (float)mcells->ch[x / 8][y / 8].v8[x % 8][y % 8];
cell->v9[x][y] = (float)mcells->ch[x / 8][y / 8].v9[x % 8][y % 8];
@ -380,19 +392,8 @@ const char MAP_MAGIC[] = "MAP_2.01";
bool ConvertADT(char *filename, char *filename2)
{
MapLiqHeight = new float[16384];
MapLiqFlag = new char[256];
for(int j = 0; j < 256; ++j)
MapLiqFlag[j] = 0;
for(int j = 0; j < 16384; ++j)
MapLiqHeight[j] = -999999;
if(!LoadADT(filename))
{
delete [] MapLiqHeight;
delete [] MapLiqFlag;
return false;
}
FILE *output=fopen(filename2, "wb");
if(!output)
@ -406,9 +407,9 @@ bool ConvertADT(char * filename,char * filename2)
// write magic header
fwrite(MAP_MAGIC, 1, 8, output);
for(unsigned int x=0;x<16;++x)
for(uint32 x = 0; x < 16; ++x)
{
for(unsigned int y=0;y<16;++y)
for(uint32 y = 0; y < 16; ++y)
{
if(mcells->ch[y][x].area_id && mcells->ch[y][x].area_id <= maxAreaId)
{
@ -433,9 +434,9 @@ bool ConvertADT(char * filename,char * filename2)
TransformData();
for(unsigned int x=0;x<iRes;++x)
for(uint32 x = 0; x < iRes; ++x)
{
for(unsigned int y=0;y<iRes;++y)
for(uint32 y = 0; y < iRes; ++y)
{
float z = (float)GetZ(
(((double)(y)) * TILESIZE) / ((double)(iRes - 1)),

View file

@ -88,7 +88,7 @@ typedef struct {
} MH2O_offsData;
typedef struct {
uint16 flags;
uint16 LiquidTypeId;
uint16 type;
float heightLevel1;
float heightLevel2;
@ -100,13 +100,21 @@ typedef struct {
uint32 ofsData2b;
} MH2O_Data1;
enum LiquidType
{
LIQUID_TYPE_WATER = 0,
LIQUID_TYPE_OCEAN = 1,
LIQUID_TYPE_MAGMA = 2,
LIQUID_TYPE_SLIME = 3
};
class MPQFile;
bool MH2O_presence;
MH2O_offsData *LiqOffsData;
MH2O_Data1 *LiqChunkData1;
float *ChunkLiqHeight, *MapLiqHeight;
char* MapLiqFlag;
uint8* MapLiqFlag;
uint32 k, m, chunk_num;
void LoadMapChunk(MPQFile &, chunk*);
bool LoadWMO(char* filename);

View file

@ -907,8 +907,6 @@ void Player::HandleDrowning()
void Player::HandleLava()
{
bool ValidArea = false;
if ((m_isunderwater & 0x80) && isAlive())
{
// Single trigger Set BreathTimer
@ -917,43 +915,21 @@ void Player::HandleLava()
m_isunderwater|= 0x04;
m_breathTimer = 1000;
}
// Reset BreathTimer and still in the lava
if (!m_breathTimer)
{
uint64 guid = GetGUID();
uint32 damage = urand(600, 700); // TODO: Get more detailed information about lava damage
uint32 dmgZone = GetZoneId(); // TODO: Find correct "lava dealing zone" flag in Area Table
// Deal lava damage only in lava zones.
switch(dmgZone)
{
case 0x8D:
ValidArea = false;
break;
case 0x94:
ValidArea = false;
break;
case 0x2CE:
ValidArea = false;
break;
case 0x2CF:
ValidArea = false;
break;
default:
if (dmgZone / 5 & 0x408)
ValidArea = true;
}
// if is valid area and is not gamemaster then deal damage
if ( ValidArea && !isGameMaster() )
// if not gamemaster then deal damage
if ( !isGameMaster() )
EnvironmentalDamage(guid, DAMAGE_LAVA, damage);
m_breathTimer = 1000;
}
}
//Death timer disabled and WaterFlags reset
else if (m_deathState == DEAD)
else if (m_deathState == DEAD) // Disable breath timer and reset underwater flags
{
m_breathTimer = 0;
m_isunderwater = 0;