diff --git a/contrib/extractor/ad.exe b/contrib/extractor/ad.exe index 2ee6e5be8..5d8e52326 100755 Binary files a/contrib/extractor/ad.exe and b/contrib/extractor/ad.exe differ diff --git a/contrib/extractor/adt.cpp b/contrib/extractor/adt.cpp index 1c1373874..a42141210 100644 --- a/contrib/extractor/adt.cpp +++ b/contrib/extractor/adt.cpp @@ -24,7 +24,6 @@ vec wmoc; Cell * cell; uint32 wmo_count; mcell *mcells; - int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; @@ -35,7 +34,7 @@ bool LoadADT(char* filename) if(mf.isEof()) { - //printf("No such file.\n"); + //printf("No such file %s\n",filename); return false; } mcells=new mcell; @@ -47,8 +46,10 @@ bool LoadADT(char* filename) wmo_count=0; bool found=false; - //uint32 fs=mf.getSize()-3; - //while (mf.getPos()offsData1 !=0) // если данные в Data1 о воде есть, то их надо конвертировать + { + mf.seek(base_pos + LiqOffsData->offsData1);// переходим по смещению из 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; + // предварительно заполняем весь кусок данными - нет воды + for(int j=0;j<81;j++) + { + ChunkLiqHeght[j] = -999999; // no liquid/water + } + // теперь вычисляем те что с водой и перезаписываем их в куске + for(int b=0; b <= LiqChunkData1->height; b++) + { + for(int c=LiqChunkData1->xOffset; c <= (LiqChunkData1->xOffset+LiqChunkData1->width); c++) + { + int n = (9*(LiqChunkData1->yOffset + b))+c; + ChunkLiqHeght[n] = LiqChunkData1->heightLevel1; + } + } + mf.seek(header_pos); // и не забыть вернуться на исходную позицию именно В ХИДЕРЕ + } + else // если данных в Data1 нет, то надо заполнить весь кусок, но данными - нет воды + { + for(int j=0; j<81; j++) + ChunkLiqHeght[j] = -999999; // no liquid/water + } + if(!(chunk_num%16)) + m = 1024*(chunk_num/16); // смещение по рядам кусков с перекрытием = 1024 + k = m +(chunk_num%16)*8; // устанавливаемся на начальный индекс для заполнения ряда + // заносим данные куска в массив для карты, с перекрытием и обрезанием кусков тк данных 81 + // это аналог старого обрезания граничных правых-боковых и нижних данных + for(int p=0;p<72;p+=9) // нижние 8 не заносим тк они дублируется след куском + { + for(int s=0; s<8; s++) // 9 значение в строке не заносим тк оно дублируется след куском, а в правых-боковых обрезается для 128х128 + { + MapLiqHeight[k] = ChunkLiqHeght[p+s];// :) + k++; + } + k=k+120; + } + } + delete LiqOffsData; + delete LiqChunkData1; + delete []ChunkLiqHeght; + + } + //case 0x4d434e4b: // MCNK + //case 0x4d46424f: // MFBO new in BC + //case 0x4d545846: // MTXF new in WotLK mf.seek(nextpos); } //printf("Loading chunks info\n"); // read individual map chunks for (int j=0; j<16; j++) + { for (int i=0; i<16; i++) { mf.seek((int)mcnk_offsets[j*16+i]); LoadMapChunk(mf,&(mcells->ch[i][j])); + chunk_num++; } - - /* - for(uint32 t=0;t3) testi = 3; if(testj>3) testj = 3; - return (holes & holetab_h[testi] & holetab_v[testj])!=0; + return (holes & holetab_h[testi] & holetab_v[testj])!=0; } inline @@ -207,9 +181,8 @@ void LoadMapChunk(MPQFile & mf, chunk*_chunk) mf.read(&size, 4); size_t lastpos = mf.getPos() + size; - mf.read(&header, 0x80); + mf.read(&header, 0x80); // what if header size got changed? _chunk->area_id =header.areaid ; - _chunk->flag =0; float xbase = header.xpos; float ybase = header.ypos; @@ -222,13 +195,11 @@ void LoadMapChunk(MPQFile & mf, chunk*_chunk) float zmin=999999999.0f; float zmax=-999999999.0f; //must be there, bl!zz uses some crazy format - int nTextures; + //int nTextures; while (mf.getPos() < lastpos) { mf.read(&fourcc,4); mf.read(&size, 4); - //if(size!=580) - // printf("\n sz=%d",size); size_t nextpos = mf.getPos() + size; if(fourcc==0x4d435654) // MCVT { @@ -258,9 +229,9 @@ void LoadMapChunk(MPQFile & mf, chunk*_chunk) } else if(fourcc==0x4d434e52) // MCNR { - nextpos = mf.getPos() + 0x1C0; // size fix + nextpos = mf.getPos() + 0x1C0; // size fix } - else if(fourcc==0x4d434c51) // MCLQ + else if(fourcc==0x4d434c51 && !MH2O_presence) // не будем учитывать если уже были данные в MH2O, перестраховка :) // MCLQ { // liquid / water level //bool haswater; @@ -268,47 +239,51 @@ void LoadMapChunk(MPQFile & mf, chunk*_chunk) mf.read(fcc1,4); flipcc(fcc1); fcc1[4]=0; + ChunkLiqHeght = new float[81]; if (!strcmp(fcc1,"MCSE")) { - for(int i=0;i<9;i++) - for(int j=0;j<9;j++) - _chunk->waterlevel[i][j]=-999999; // no liquid/water + for(int j=0;j<81;j++) + { + ChunkLiqHeght[j] = -999999; // no liquid/water + } } else { float maxheight; mf.read(&maxheight, 4); - - for(int j=0;j<9;j++) - for(int i=0;i<9;i++) - { - mf.read(&h, 4); - mf.read(&h, 4); - if(h > maxheight) - _chunk->waterlevel[i][j]=-999999; - else - _chunk->waterlevel[i][j]=h; - } + for(int j=0;j<81;j++) + { + mf.read(&h, 4); + mf.read(&h, 4); + if(h > maxheight) + ChunkLiqHeght[j] = -999999; + else + ChunkLiqHeght[j] = h; + } if(chunkflags & 4 || chunkflags & 8) - _chunk->flag |=1; + MapLiqFlag[chunk_num] |= 1; if(chunkflags & 16) - _chunk->flag |=2; + MapLiqFlag[chunk_num] |= 2; } + // заполнем так же как в MH2O + if(!(chunk_num%16)) + m = 1024*(chunk_num/16); + k = m +(chunk_num%16)*8; + + for(int p=0;p<72;p+=9) + { + for(int s=0; s<8; s++) + { + MapLiqHeight[k] = ChunkLiqHeght[p+s]; // :) + k++; + } + k=k+120; + } + delete []ChunkLiqHeght; break; } - else if (fourcc==0x4d434c59) // MCLY - { - // texture info - nTextures = (int)size; - } - else if (fourcc==0x4d43414c) // MCAL - { - if (nTextures<=0) - continue; - } - mf.seek(nextpos); } } @@ -330,10 +305,6 @@ double GetZ(double x,double z) { vec v[3]; vec p; - - //bool inWMO=false; - - //if(!inWMO) { //find out quadrant int xc=(int)(x/UNITSIZE); @@ -380,19 +351,6 @@ double GetZ(double x,double z) } } -inline -void TransformWaterData() -{ - cell= new Cell; - - for(int x=0;x<128;x++) - for(int y=0;y<128;y++) - cell->v9[x][y] = mcells->ch[x/8][y/8].waterlevel[x%8][y%8]; - - //and the last 1 - cell->v9[128][128] = mcells->ch[15][15].waterlevel[8][8]; -} - inline void TransformData() { @@ -423,14 +381,24 @@ const char MAP_MAGIC[] = "MAP_2.01"; bool ConvertADT(char * filename,char * filename2) { - //if(!strstr(filename,"oth_32_48"))return false; + MapLiqHeight = new float[16384]; + MapLiqFlag = new char[256]; + for(int j=0; j<256; j++) + MapLiqFlag[j] = 0; + if(!LoadADT(filename)) + { + delete [] MapLiqHeight; + delete [] MapLiqFlag; return false; + } FILE *output=fopen(filename2,"wb"); if(!output) { printf("Can't create the output file '%s'\n",filename2); + delete [] MapLiqHeight; + delete [] MapLiqFlag; return false; } @@ -441,7 +409,7 @@ bool ConvertADT(char * filename,char * filename2) { for(unsigned int y=0;y<16;y++) { - if(mcells->ch[y][x].area_id && mcells->ch[y][x].area_id < 0x121F) + if(mcells->ch[y][x].area_id && mcells->ch[y][x].area_id < 0x102D) { if(areas[mcells->ch[y][x].area_id]==0xffff) printf("\nCan't find area flag for areaid %u.\n",mcells->ch[y][x].area_id); @@ -456,17 +424,12 @@ bool ConvertADT(char * filename,char * filename2) } } - for(unsigned int x=0;x<16;x++) - for(unsigned int y=0;y<16;y++) - fwrite(&mcells->ch[y][x].flag,1,1,output); - - TransformWaterData(); - - for(unsigned int x=0;x<128;x++) - for(unsigned int y=0;y<128;y++) - fwrite(&cell->v9[y][x],1,sizeof(float),output); - - delete cell; + fwrite(MapLiqFlag,1,256,output); //!!!!!!!! + delete [] MapLiqFlag; + + fwrite(MapLiqHeight,sizeof(float),16384,output); //!!!!!!!! + delete [] MapLiqHeight; + TransformData(); for(unsigned int x=0;x::iterator it = wmos.begin(); it != wmos.end(); ++it) - wmomanager.delbyname(*it); - - wmos.clear(); - wmois.clear(); - - for (std::vector::iterator it = wmomodel.begin(); it != wmomodel.end(); ++it) - { - it->tr.clear(); - - } - //printf("\n %d \n",in); - wmomodel.clear(); - //polygons.clear();*/ + return true; } diff --git a/contrib/extractor/adt.h b/contrib/extractor/adt.h index bae687f6b..4514b6a58 100644 --- a/contrib/extractor/adt.h +++ b/contrib/extractor/adt.h @@ -10,34 +10,31 @@ typedef unsigned short uint16; typedef unsigned int uint32; class Liquid; typedef struct { -float x; -float y; -float z; -}svec; + float x; + float y; + float z; +} svec; typedef struct { -double x; -double y; -double z; -}vec; + double x; + double y; + double z; +} vec; typedef struct{ vec v[3]; -}triangle; +} triangle; typedef struct{ -float v9[16*8+1][16*8+1]; -float v8[16*8][16*8]; -}Cell; + float v9[16*8+1][16*8+1]; + float v8[16*8][16*8]; +} Cell; typedef struct{ double v9[9][9]; double v8[8][8]; -uint16 area_id; -//Liquid *lq; -float waterlevel[9][9]; -uint8 flag; -}chunk; + uint16 area_id; +} chunk; class WMO; class WMOManager; @@ -45,9 +42,72 @@ void fixname(std::string &name); typedef struct { -chunk ch[16][16]; -}mcell; + chunk ch[16][16]; +} mcell; + +struct MapChunkHeader { + uint32 flags; + uint32 ix; + uint32 iy; + uint32 nLayers; + uint32 nDoodadRefs; + uint32 ofsHeight; + uint32 ofsNormal; + uint32 ofsLayer; + uint32 ofsRefs; + uint32 ofsAlpha; + uint32 sizeAlpha; + uint32 ofsShadow; + uint32 sizeShadow; + uint32 areaid; + uint32 nMapObjRefs; + uint32 holes; + uint16 s1; + uint16 s2; + uint32 d1; + uint32 d2; + uint32 d3; + uint32 predTex; + uint32 nEffectDoodad; + uint32 ofsSndEmitters; + uint32 nSndEmitters; + uint32 ofsLiquid; // not use in WotLK + uint32 sizeLiquid; // not use in WotLK + float zpos; + float xpos; + float ypos; + uint32 textureId; // new offsColorValues in WotLK + uint32 props; + uint32 effectId; +}; + +typedef struct { + uint32 offsData1; + uint32 used; + uint32 offsData2; +} MH2O_offsData; + +typedef struct { + uint16 flags; + uint16 type; + float heightLevel1; + float heightLevel2; + byte xOffset; + byte yOffset; + byte width; + byte height; + uint32 ofsData2a; + uint32 ofsData2b; +} MH2O_Data1; + class MPQFile; -void LoadMapChunk(MPQFile &,chunk*); + +bool MH2O_presence; +MH2O_offsData *LiqOffsData; +MH2O_Data1 *LiqChunkData1; +float *ChunkLiqHeght, *MapLiqHeight; +char* MapLiqFlag; +uint32 k, m, chunk_num; +void LoadMapChunk(MPQFile &, chunk*); bool LoadWMO(char* filename); #endif