| 1 | #ifdef WIN32 |
|---|
| 2 | #include <windows.h> |
|---|
| 3 | #endif |
|---|
| 4 | |
|---|
| 5 | #include <string.h> |
|---|
| 6 | #include <stdio.h> |
|---|
| 7 | #include <math.h> |
|---|
| 8 | #include <string> |
|---|
| 9 | #include <map> |
|---|
| 10 | #include <vector> |
|---|
| 11 | #include <set> |
|---|
| 12 | |
|---|
| 13 | #include "adt.h" |
|---|
| 14 | #include "mpq_libmpq.h" |
|---|
| 15 | |
|---|
| 16 | //#include <windows.h> |
|---|
| 17 | unsigned int iRes=256; |
|---|
| 18 | extern uint16*areas; |
|---|
| 19 | |
|---|
| 20 | #define SMALL_MAPFILES |
|---|
| 21 | #define PACK_MAPS |
|---|
| 22 | #define MAP_RESOLUTION 256 |
|---|
| 23 | |
|---|
| 24 | #define TilesCount 64 |
|---|
| 25 | #define TileSize 533.33333f |
|---|
| 26 | #define _minY (-TilesCount*TileSize/2) |
|---|
| 27 | #define _minX (-TilesCount*TileSize/2) |
|---|
| 28 | |
|---|
| 29 | #define _maxY (TilesCount*TileSize/2) |
|---|
| 30 | #define _maxX (TilesCount*TileSize/2) |
|---|
| 31 | |
|---|
| 32 | #define CellsPerTile 8 |
|---|
| 33 | #define _cellSize (TileSize/CellsPerTile) |
|---|
| 34 | #define _sizeX (TilesCount*CellsPerTile) |
|---|
| 35 | #define _sizeY (TilesCount*CellsPerTile) |
|---|
| 36 | |
|---|
| 37 | //#pragma pack(push, 1) |
|---|
| 38 | |
|---|
| 39 | typedef struct |
|---|
| 40 | { |
|---|
| 41 | uint16 AreaID[16/CellsPerTile][16/CellsPerTile]; |
|---|
| 42 | uint8 LiquidType[16/CellsPerTile][16/CellsPerTile]; |
|---|
| 43 | float LiquidLevel[16/CellsPerTile][16/CellsPerTile]; |
|---|
| 44 | float Z[MAP_RESOLUTION/CellsPerTile][MAP_RESOLUTION/CellsPerTile]; |
|---|
| 45 | }MapCellInfo; |
|---|
| 46 | |
|---|
| 47 | |
|---|
| 48 | ///This is temp. method. |
|---|
| 49 | typedef struct |
|---|
| 50 | { |
|---|
| 51 | uint16 AreaID[16][16]; |
|---|
| 52 | uint8 LiquidType[16][16]; |
|---|
| 53 | float LiquidLevel[16][16]; |
|---|
| 54 | float Z[MAP_RESOLUTION][MAP_RESOLUTION]; |
|---|
| 55 | }MapTileInfo; |
|---|
| 56 | |
|---|
| 57 | typedef struct |
|---|
| 58 | { |
|---|
| 59 | float z[256][256]; |
|---|
| 60 | }zstore; |
|---|
| 61 | //#pragma pack(pop) |
|---|
| 62 | vec wmoc; |
|---|
| 63 | |
|---|
| 64 | Cell * cell; |
|---|
| 65 | uint32 wmo_count; |
|---|
| 66 | mcell *mcells; |
|---|
| 67 | zstore * cz; |
|---|
| 68 | |
|---|
| 69 | mcell * mcell_cache[64][64]; |
|---|
| 70 | zstore * cell_cache[64][64]; |
|---|
| 71 | |
|---|
| 72 | typedef struct |
|---|
| 73 | { |
|---|
| 74 | uint32 ofsInformation; |
|---|
| 75 | uint32 layerCount; |
|---|
| 76 | uint32 ofsData; |
|---|
| 77 | }MH2Oheader; |
|---|
| 78 | |
|---|
| 79 | typedef struct |
|---|
| 80 | { |
|---|
| 81 | uint16 type; |
|---|
| 82 | uint16 flags; |
|---|
| 83 | float levels[2]; |
|---|
| 84 | char x, y, w, h; |
|---|
| 85 | uint32 offsData2a; |
|---|
| 86 | uint32 offsData2b; |
|---|
| 87 | }MH2Oinformation; |
|---|
| 88 | |
|---|
| 89 | |
|---|
| 90 | void reset() |
|---|
| 91 | { |
|---|
| 92 | for(uint32 i = 0; i < 64; ++i) |
|---|
| 93 | { |
|---|
| 94 | for(uint32 j = 0; j < 64; ++j) |
|---|
| 95 | { |
|---|
| 96 | mcell_cache[i][j] = 0; |
|---|
| 97 | cell_cache[i][j] = 0; |
|---|
| 98 | } |
|---|
| 99 | } |
|---|
| 100 | } |
|---|
| 101 | void CleanCache() |
|---|
| 102 | { |
|---|
| 103 | for(uint32 i = 0; i < 64; ++i) |
|---|
| 104 | { |
|---|
| 105 | for(uint32 j = 0; j < 64; ++j) |
|---|
| 106 | { |
|---|
| 107 | if(cell_cache[i][j] != 0) |
|---|
| 108 | { |
|---|
| 109 | delete cell_cache[i][j]; |
|---|
| 110 | cell_cache[i][j] = 0; |
|---|
| 111 | } |
|---|
| 112 | |
|---|
| 113 | if(mcell_cache[i][j] != 0) |
|---|
| 114 | { |
|---|
| 115 | delete mcell_cache[i][j]; |
|---|
| 116 | mcell_cache[i][j] = 0; |
|---|
| 117 | } |
|---|
| 118 | |
|---|
| 119 | } |
|---|
| 120 | } |
|---|
| 121 | } |
|---|
| 122 | |
|---|
| 123 | bool LoadADT(char* filename) |
|---|
| 124 | { |
|---|
| 125 | size_t size; |
|---|
| 126 | MPQFile mf(filename); |
|---|
| 127 | |
|---|
| 128 | if(mf.isEof ()) |
|---|
| 129 | { |
|---|
| 130 | //printf("No such file.\n"); |
|---|
| 131 | return false; |
|---|
| 132 | } |
|---|
| 133 | mcells=new mcell; |
|---|
| 134 | |
|---|
| 135 | wmoc.x =65*TILESIZE; |
|---|
| 136 | wmoc.z =65*TILESIZE; |
|---|
| 137 | |
|---|
| 138 | size_t mcnk_offsets[256], mcnk_sizes[256]; |
|---|
| 139 | |
|---|
| 140 | MH2Oheader mh2oheader[256]; memset(&mh2oheader,0,sizeof(MH2Oheader)*256); |
|---|
| 141 | uint32 mh2o_base=0; |
|---|
| 142 | |
|---|
| 143 | wmo_count=0; |
|---|
| 144 | bool found=false; |
|---|
| 145 | //uint32 fs=mf.getSize ()-3; |
|---|
| 146 | //while (mf.getPos ()<fs) |
|---|
| 147 | while (!mf.isEof ()) |
|---|
| 148 | { |
|---|
| 149 | uint32 fourcc; |
|---|
| 150 | mf.read(&fourcc,4); |
|---|
| 151 | mf.read(&size, 4); |
|---|
| 152 | |
|---|
| 153 | size_t nextpos = mf.getPos () + size; |
|---|
| 154 | if(fourcc==0x4d43494e) //MCIN |
|---|
| 155 | { |
|---|
| 156 | // printf("Found chunks info\n"); |
|---|
| 157 | // mapchunk offsets/sizes |
|---|
| 158 | for (int i=0; i<256; i++) |
|---|
| 159 | { |
|---|
| 160 | mf.read(&mcnk_offsets[i],4); |
|---|
| 161 | mf.read(&mcnk_sizes[i],4); |
|---|
| 162 | mf.seekRelative(8); |
|---|
| 163 | } |
|---|
| 164 | //break; |
|---|
| 165 | } |
|---|
| 166 | else |
|---|
| 167 | if(fourcc==0x4d48324f) //MH2O |
|---|
| 168 | { |
|---|
| 169 | mh2o_base=mf.getPos(); |
|---|
| 170 | for (int i=0; i<256; i++) |
|---|
| 171 | { |
|---|
| 172 | mf.read(&mh2oheader[i],sizeof(MH2Oheader)); |
|---|
| 173 | } |
|---|
| 174 | //break; |
|---|
| 175 | } |
|---|
| 176 | else |
|---|
| 177 | if(fourcc==0x4d4f4446) //MODF |
|---|
| 178 | { |
|---|
| 179 | |
|---|
| 180 | /* if(size) |
|---|
| 181 | { |
|---|
| 182 | //printf("\nwmo count %d\n",size/64); |
|---|
| 183 | wmo_count =size/64; |
|---|
| 184 | for (int i=0; i<wmo_count; i++) |
|---|
| 185 | { |
|---|
| 186 | int id; |
|---|
| 187 | mf.read(&id, 4); |
|---|
| 188 | WMO *wmo = (WMO*)wmomanager.items[wmomanager.get(wmos[id])]; |
|---|
| 189 | WMOInstance inst(wmo, mf); |
|---|
| 190 | wmois.push_back(inst); |
|---|
| 191 | } |
|---|
| 192 | |
|---|
| 193 | }*/ |
|---|
| 194 | |
|---|
| 195 | }else |
|---|
| 196 | if(fourcc==0x4d574d4f)//mwmo |
|---|
| 197 | { |
|---|
| 198 | /*if (size) |
|---|
| 199 | { |
|---|
| 200 | char *buf = new char[size]; |
|---|
| 201 | mf.read(buf, size); |
|---|
| 202 | char *p=buf; |
|---|
| 203 | while (p<buf+size) |
|---|
| 204 | { |
|---|
| 205 | std::string path(p); |
|---|
| 206 | p+=strlen(p)+1; |
|---|
| 207 | fixname(path); |
|---|
| 208 | |
|---|
| 209 | wmomanager.add(path); |
|---|
| 210 | wmos.push_back(path); |
|---|
| 211 | } |
|---|
| 212 | delete[] buf; |
|---|
| 213 | }*/ |
|---|
| 214 | } |
|---|
| 215 | // else mf.seekRelative(-3); |
|---|
| 216 | |
|---|
| 217 | mf.seek(nextpos); |
|---|
| 218 | } |
|---|
| 219 | //printf("Loading chunks info\n"); |
|---|
| 220 | // read individual map chunks |
|---|
| 221 | for (int j=0; j<16; j++) |
|---|
| 222 | for (int i=0; i<16; i++) |
|---|
| 223 | { |
|---|
| 224 | |
|---|
| 225 | mf.seek((int)mcnk_offsets[j*16+i]); |
|---|
| 226 | LoadMapChunk (mf,&(mcells->ch [i][j])); |
|---|
| 227 | |
|---|
| 228 | if (mh2oheader[j*16+i].layerCount>0) { |
|---|
| 229 | mf.seek((int)mh2oheader[j*16+i].ofsInformation+mh2o_base); |
|---|
| 230 | LoadH2OChunk(mf,&(mcells->ch [i][j]),mh2o_base); |
|---|
| 231 | } |
|---|
| 232 | |
|---|
| 233 | } |
|---|
| 234 | |
|---|
| 235 | /* for(uint32 t=0;t<wmo_count ;t++) |
|---|
| 236 | { |
|---|
| 237 | wmois[t].draw (); |
|---|
| 238 | |
|---|
| 239 | }*/ |
|---|
| 240 | mf.close (); |
|---|
| 241 | return true; |
|---|
| 242 | } |
|---|
| 243 | |
|---|
| 244 | |
|---|
| 245 | |
|---|
| 246 | struct MapChunkHeader { |
|---|
| 247 | uint32 flags; |
|---|
| 248 | uint32 ix; |
|---|
| 249 | uint32 iy; |
|---|
| 250 | uint32 nLayers; |
|---|
| 251 | uint32 nDoodadRefs; |
|---|
| 252 | uint32 ofsHeight; |
|---|
| 253 | uint32 ofsNormal; |
|---|
| 254 | uint32 ofsLayer; |
|---|
| 255 | uint32 ofsRefs; |
|---|
| 256 | uint32 ofsAlpha; |
|---|
| 257 | uint32 sizeAlpha; |
|---|
| 258 | uint32 ofsShadow; |
|---|
| 259 | uint32 sizeShadow; |
|---|
| 260 | uint32 areaid; |
|---|
| 261 | uint32 nMapObjRefs; |
|---|
| 262 | uint32 holes; |
|---|
| 263 | uint16 s1; |
|---|
| 264 | uint16 s2; |
|---|
| 265 | uint32 d1; |
|---|
| 266 | uint32 d2; |
|---|
| 267 | uint32 d3; |
|---|
| 268 | uint32 predTex; |
|---|
| 269 | uint32 nEffectDoodad; |
|---|
| 270 | uint32 ofsSndEmitters; |
|---|
| 271 | uint32 nSndEmitters; |
|---|
| 272 | uint32 ofsLiquid; |
|---|
| 273 | uint32 sizeLiquid; |
|---|
| 274 | float zpos; |
|---|
| 275 | float xpos; |
|---|
| 276 | float ypos; |
|---|
| 277 | uint32 textureId; |
|---|
| 278 | uint32 props; |
|---|
| 279 | uint32 effectId; |
|---|
| 280 | }; |
|---|
| 281 | |
|---|
| 282 | |
|---|
| 283 | inline |
|---|
| 284 | void LoadMapChunk(MPQFile & mf, chunk*_chunk) |
|---|
| 285 | { |
|---|
| 286 | |
|---|
| 287 | float h; |
|---|
| 288 | uint32 fourcc; |
|---|
| 289 | uint32 size; |
|---|
| 290 | MapChunkHeader header; |
|---|
| 291 | |
|---|
| 292 | mf.seekRelative(4); |
|---|
| 293 | mf.read(&size, 4); |
|---|
| 294 | |
|---|
| 295 | size_t lastpos = mf.getPos() + size; |
|---|
| 296 | mf.read(&header, 0x80); |
|---|
| 297 | _chunk->area_id =header.areaid ; |
|---|
| 298 | _chunk->flag =0; |
|---|
| 299 | |
|---|
| 300 | float xbase = header.xpos; |
|---|
| 301 | float ybase = header.ypos; |
|---|
| 302 | float zbase = header.zpos; |
|---|
| 303 | zbase = TILESIZE*32-zbase; |
|---|
| 304 | xbase = TILESIZE*32-xbase; |
|---|
| 305 | if(wmoc.x >xbase)wmoc.x =xbase; |
|---|
| 306 | if(wmoc.z >zbase)wmoc.z =zbase; |
|---|
| 307 | int chunkflags = header.flags; |
|---|
| 308 | float zmin=999999999.0f; |
|---|
| 309 | float zmax=-999999999.0f; |
|---|
| 310 | //must be there, bl!zz uses some crazy format |
|---|
| 311 | int nTextures; |
|---|
| 312 | while (mf.getPos ()<lastpos) |
|---|
| 313 | { |
|---|
| 314 | mf.read(&fourcc,4); |
|---|
| 315 | mf.read(&size, 4); |
|---|
| 316 | // if(size!=580) |
|---|
| 317 | // printf("\n sz=%d",size); |
|---|
| 318 | size_t nextpos = mf.getPos() + size; |
|---|
| 319 | if(fourcc==0x4d435654) //MCVT |
|---|
| 320 | { |
|---|
| 321 | for (int j=0; j<17; j++) |
|---|
| 322 | for (int i=0; i<((j%2)?8:9); i++) |
|---|
| 323 | { |
|---|
| 324 | mf.read(&h,4); |
|---|
| 325 | float z=h+ybase; |
|---|
| 326 | if (j%2) |
|---|
| 327 | _chunk->v8[i][j/2] = z; |
|---|
| 328 | else |
|---|
| 329 | _chunk->v9[i][j/2] = z; |
|---|
| 330 | |
|---|
| 331 | if(z>zmax)zmax=z; |
|---|
| 332 | // if(z<zmin)zmin=z; |
|---|
| 333 | } |
|---|
| 334 | } |
|---|
| 335 | else |
|---|
| 336 | if(fourcc==0x4d434e52) //MCNR |
|---|
| 337 | { |
|---|
| 338 | nextpos = mf.getPos() + 0x1C0; // size fix |
|---|
| 339 | |
|---|
| 340 | } |
|---|
| 341 | if(fourcc=0xefb88b70) |
|---|
| 342 | { |
|---|
| 343 | nextpos = mf.getPos() + 0x1199; |
|---|
| 344 | } |
|---|
| 345 | |
|---|
| 346 | else |
|---|
| 347 | /*if(fourcc==0x4d434c51) //MCLQ |
|---|
| 348 | { |
|---|
| 349 | // liquid / water level |
|---|
| 350 | // bool haswater; |
|---|
| 351 | char fcc1[5]; |
|---|
| 352 | mf.read(fcc1,4); |
|---|
| 353 | flipcc(fcc1); |
|---|
| 354 | fcc1[4]=0; |
|---|
| 355 | |
|---|
| 356 | if (!strcmp(fcc1,"MCSE")) |
|---|
| 357 | { |
|---|
| 358 | for(int i=0;i<9;i++) |
|---|
| 359 | for(int j=0;j<9;j++) |
|---|
| 360 | _chunk->waterlevel[i][j]=-999999; // no liquid/water |
|---|
| 361 | } |
|---|
| 362 | else |
|---|
| 363 | { |
|---|
| 364 | float maxheight; |
|---|
| 365 | mf.read(&maxheight, 4); |
|---|
| 366 | |
|---|
| 367 | for(int j=0;j<9;j++) |
|---|
| 368 | for(int i=0;i<9;i++) |
|---|
| 369 | { |
|---|
| 370 | mf.read(&h, 4); |
|---|
| 371 | mf.read(&h, 4); |
|---|
| 372 | if(h > maxheight) |
|---|
| 373 | _chunk->waterlevel[i][j]=-999999; |
|---|
| 374 | else |
|---|
| 375 | _chunk->waterlevel[i][j]=h; |
|---|
| 376 | } |
|---|
| 377 | |
|---|
| 378 | if(chunkflags & 4 || chunkflags & 8) |
|---|
| 379 | _chunk->flag |=1; |
|---|
| 380 | if(chunkflags & 16) |
|---|
| 381 | _chunk->flag |=2; |
|---|
| 382 | |
|---|
| 383 | |
|---|
| 384 | |
|---|
| 385 | } |
|---|
| 386 | |
|---|
| 387 | |
|---|
| 388 | break;*/ |
|---|
| 389 | if(fourcc==0x4d434c51) //MCLQ |
|---|
| 390 | { |
|---|
| 391 | // liquid / water level |
|---|
| 392 | // bool haswater; |
|---|
| 393 | char fcc1[5]; |
|---|
| 394 | mf.read(fcc1,4); |
|---|
| 395 | flipcc(fcc1); |
|---|
| 396 | fcc1[4]=0; |
|---|
| 397 | if (strcmp(fcc1,"MCSE")) |
|---|
| 398 | |
|---|
| 399 | // if(size) |
|---|
| 400 | |
|---|
| 401 | |
|---|
| 402 | |
|---|
| 403 | |
|---|
| 404 | |
|---|
| 405 | { |
|---|
| 406 | //chunkflag |
|---|
| 407 | |
|---|
| 408 | |
|---|
| 409 | mf.seekRelative(-4); |
|---|
| 410 | mf.read(&_chunk->waterlevel,4); |
|---|
| 411 | |
|---|
| 412 | |
|---|
| 413 | |
|---|
| 414 | |
|---|
| 415 | |
|---|
| 416 | |
|---|
| 417 | |
|---|
| 418 | |
|---|
| 419 | |
|---|
| 420 | /*if(chunkflags & 4 || chunkflags & 8) |
|---|
| 421 | _chunk->flag |=1; |
|---|
| 422 | if(chunkflags & 16) |
|---|
| 423 | _chunk->flag |=2;*/ |
|---|
| 424 | if(!_chunk->flag) |
|---|
| 425 | _chunk->flag = chunkflags; |
|---|
| 426 | else |
|---|
| 427 | printf("%02X", _chunk->flag); |
|---|
| 428 | |
|---|
| 429 | |
|---|
| 430 | |
|---|
| 431 | } |
|---|
| 432 | |
|---|
| 433 | |
|---|
| 434 | break; |
|---|
| 435 | }else if (fourcc==0x4d434c59) //MCLY |
|---|
| 436 | { |
|---|
| 437 | // texture info |
|---|
| 438 | nTextures = (int)size; |
|---|
| 439 | }else if (fourcc==0x4d43414c) //MCAL |
|---|
| 440 | { |
|---|
| 441 | |
|---|
| 442 | if (nTextures<=0) |
|---|
| 443 | continue; |
|---|
| 444 | } |
|---|
| 445 | |
|---|
| 446 | |
|---|
| 447 | |
|---|
| 448 | mf.seek(nextpos); |
|---|
| 449 | } |
|---|
| 450 | |
|---|
| 451 | |
|---|
| 452 | printf(""); |
|---|
| 453 | } |
|---|
| 454 | |
|---|
| 455 | |
|---|
| 456 | inline |
|---|
| 457 | void LoadH2OChunk(MPQFile & mf, chunk*_chunk, uint32 base) |
|---|
| 458 | { |
|---|
| 459 | MH2Oinformation mh2oinfo; memset(&mh2oinfo,0,sizeof(MH2Oinformation)); |
|---|
| 460 | mf.read(&mh2oinfo,sizeof(MH2Oinformation)); |
|---|
| 461 | // if (mh2oinfo.w>0 && mh2oinfo.h>0) { //Cell has some water... |
|---|
| 462 | //If the type flag does not contain the water bit, and the cell has lake(0) or ocean(2) water, then set it, as this was the old flag for fishable water for the MCLQ structure - compatibility above all. |
|---|
| 463 | if ( (_chunk->flag&1)==0 && (mh2oinfo.type==0 || mh2oinfo.type==2) ) _chunk->flag|=1; |
|---|
| 464 | if ( (_chunk->flag&1)==0 && mh2oinfo.type==5 && (mh2oinfo.flags==0 || mh2oinfo.flags==2)) _chunk->flag|=1; |
|---|
| 465 | //The two liquid levels are sometimes NOT equal; if they define the highest and lowest levels, then choose the lowest one for fishing; but for now this will be sufficient. |
|---|
| 466 | if ( mh2oinfo.flags & 2 ) _chunk->waterlevel=mh2oinfo.levels[0]; |
|---|
| 467 | else if (mh2oinfo.offsData2b) { |
|---|
| 468 | mf.seek((int)mh2oinfo.offsData2b+base); |
|---|
| 469 | float level; |
|---|
| 470 | mf.read(&level, 4); |
|---|
| 471 | _chunk->waterlevel=level; |
|---|
| 472 | } else _chunk->waterlevel=mh2oinfo.levels[0]; //Better than nothing. |
|---|
| 473 | // } else { //No water here - this should be impossible, as in this case this part wouldn't even exist and layerCount would be zero, but it's better to be prepared for everything. |
|---|
| 474 | // _chunk->waterlevel=-999999; |
|---|
| 475 | // } |
|---|
| 476 | |
|---|
| 477 | return; |
|---|
| 478 | } |
|---|
| 479 | |
|---|
| 480 | |
|---|
| 481 | double solve (vec *v,vec *p) |
|---|
| 482 | { |
|---|
| 483 | double a = v[0].y *(v[1].z - v[2].z) + v[1].y *(v[2].z - v[0].z) + v[2].y *(v[0].z - v[1].z); |
|---|
| 484 | double b = v[0].z *(v[1].x - v[2].x) + v[1].z *(v[2].x - v[0].x) + v[2].z *(v[0].x - v[1].x); |
|---|
| 485 | double c = v[0].x *(v[1].y - v[2].y) + v[1].x *(v[2].y - v[0].y) + v[2].x *(v[0].y - v[1].y); |
|---|
| 486 | double d = v[0].x *(v[1].y*v[2].z - v[2].y*v[1].z) + v[1].x* (v[2].y*v[0].z - v[0].y*v[2].z) + v[2].x* (v[0].y*v[1].z - v[1].y*v[0].z); |
|---|
| 487 | //-d |
|---|
| 488 | |
|---|
| 489 | //plane equation ax+by+cz+d=0 |
|---|
| 490 | return ((a*p->x+c*p->z-d)/b); |
|---|
| 491 | } |
|---|
| 492 | |
|---|
| 493 | |
|---|
| 494 | inline |
|---|
| 495 | double GetZ(double x,double z) |
|---|
| 496 | { |
|---|
| 497 | |
|---|
| 498 | vec v[3]; |
|---|
| 499 | vec p; |
|---|
| 500 | |
|---|
| 501 | //bool inWMO=false; |
|---|
| 502 | |
|---|
| 503 | //if(!inWMO) |
|---|
| 504 | { |
|---|
| 505 | //find out quadrant |
|---|
| 506 | int xc=(int)(x/UNITSIZE); |
|---|
| 507 | int zc=(int)(z/UNITSIZE); |
|---|
| 508 | if(xc>127)xc=127; |
|---|
| 509 | if(zc>127)zc=127; |
|---|
| 510 | |
|---|
| 511 | double lx=x-xc*UNITSIZE; |
|---|
| 512 | double lz=z-zc*UNITSIZE; |
|---|
| 513 | p.x=lx; |
|---|
| 514 | p.z=lz; |
|---|
| 515 | |
|---|
| 516 | |
|---|
| 517 | v[0].x=UNITSIZE/2; |
|---|
| 518 | v[0].y =cell->v8[xc][zc]; |
|---|
| 519 | v[0].z=UNITSIZE/2; |
|---|
| 520 | |
|---|
| 521 | |
|---|
| 522 | if(lx>lz) |
|---|
| 523 | { |
|---|
| 524 | v[1].x=UNITSIZE; |
|---|
| 525 | v[1].y =cell->v9[xc+1][zc]; |
|---|
| 526 | v[1].z=0; |
|---|
| 527 | }else |
|---|
| 528 | { |
|---|
| 529 | v[1].x=0.0; |
|---|
| 530 | v[1].y =cell->v9[xc][zc+1]; |
|---|
| 531 | v[1].z=UNITSIZE; |
|---|
| 532 | } |
|---|
| 533 | |
|---|
| 534 | if(lz>UNITSIZE-lx) |
|---|
| 535 | { |
|---|
| 536 | v[2].x=UNITSIZE; |
|---|
| 537 | v[2].y =cell->v9[xc+1][zc+1]; |
|---|
| 538 | v[2].z=UNITSIZE; |
|---|
| 539 | |
|---|
| 540 | }else |
|---|
| 541 | { |
|---|
| 542 | v[2].x=0; |
|---|
| 543 | v[2].y=cell->v9[xc][zc]; |
|---|
| 544 | v[2].z=0; |
|---|
| 545 | } |
|---|
| 546 | |
|---|
| 547 | return -solve(v,&p); |
|---|
| 548 | } |
|---|
| 549 | |
|---|
| 550 | } |
|---|
| 551 | |
|---|
| 552 | /*inline |
|---|
| 553 | void TransformWaterData() |
|---|
| 554 | { |
|---|
| 555 | cell= new Cell; |
|---|
| 556 | |
|---|
| 557 | for(int x=0;x<128;x++) |
|---|
| 558 | for(int y=0;y<128;y++) |
|---|
| 559 | cell->v9[x][y] = mcells->ch[x/8][y/8].waterlevel[x%8][y%8]; |
|---|
| 560 | |
|---|
| 561 | //and the last 1 |
|---|
| 562 | cell->v9[128][128] = mcells->ch[15][15].waterlevel[8][8]; |
|---|
| 563 | }*/ |
|---|
| 564 | |
|---|
| 565 | inline |
|---|
| 566 | void TransformData() |
|---|
| 567 | { |
|---|
| 568 | cell= new Cell; |
|---|
| 569 | |
|---|
| 570 | for(int x=0;x<128;x++) |
|---|
| 571 | { |
|---|
| 572 | for(int y=0;y<128;y++) |
|---|
| 573 | { |
|---|
| 574 | cell->v8[x][y] = (float)mcells->ch[x/8][y/8].v8[x%8][y%8]; |
|---|
| 575 | cell->v9[x][y] = (float)mcells->ch[x/8][y/8].v9[x%8][y%8]; |
|---|
| 576 | } |
|---|
| 577 | |
|---|
| 578 | //extra 1 point on bounds |
|---|
| 579 | cell->v9[x][128] = (float)mcells->ch[x/8][15].v9[x%8][8]; |
|---|
| 580 | //x==y |
|---|
| 581 | cell->v9[128][x] = (float)mcells->ch[15][x/8].v9[8][x%8]; |
|---|
| 582 | |
|---|
| 583 | } |
|---|
| 584 | |
|---|
| 585 | |
|---|
| 586 | //and the last 1 |
|---|
| 587 | cell->v9[128][128] = (float)mcells->ch[15][15].v9[8][8]; |
|---|
| 588 | } |
|---|
| 589 | |
|---|
| 590 | bool ConvertADT(uint32 x, uint32 y, FILE * out_file, char* name) |
|---|
| 591 | { |
|---|
| 592 | // Figure out what rock we're under :P |
|---|
| 593 | uint32 tile_x = x / CellsPerTile; |
|---|
| 594 | uint32 tile_y = y / CellsPerTile; |
|---|
| 595 | |
|---|
| 596 | // For some odd reason, this stuff is reversed.. who knows why.. |
|---|
| 597 | char mpq_filename[256]; |
|---|
| 598 | sprintf(mpq_filename, "World\\Maps\\%s\\%s_%u_%u.adt", name, name, tile_y, tile_x); |
|---|
| 599 | |
|---|
| 600 | // See if we have it cached first. |
|---|
| 601 | if(mcell_cache[tile_y][tile_x] == 0 && cell_cache[tile_y][tile_x] == 0) |
|---|
| 602 | { |
|---|
| 603 | if(!LoadADT(mpq_filename)) |
|---|
| 604 | return false; |
|---|
| 605 | |
|---|
| 606 | TransformData(); |
|---|
| 607 | mcell_cache[tile_y][tile_x] = mcells; |
|---|
| 608 | |
|---|
| 609 | // Cache z information. |
|---|
| 610 | cz = new zstore; |
|---|
| 611 | for(uint32 cx = 0; cx < MAP_RESOLUTION; ++cx) |
|---|
| 612 | { |
|---|
| 613 | for(uint32 cy = 0; cy < MAP_RESOLUTION; ++cy) |
|---|
| 614 | { |
|---|
| 615 | float cfz=(float)GetZ( |
|---|
| 616 | (((double)(cy))*TILESIZE)/((double)(iRes-1)), |
|---|
| 617 | (((double)(cx))*TILESIZE)/((double)(iRes-1))); |
|---|
| 618 | cz->z[cx][cy] = cfz; |
|---|
| 619 | } |
|---|
| 620 | } |
|---|
| 621 | |
|---|
| 622 | cell_cache[tile_y][tile_x] = cz; |
|---|
| 623 | delete cell; |
|---|
| 624 | } |
|---|
| 625 | else |
|---|
| 626 | { |
|---|
| 627 | mcells = mcell_cache[tile_y][tile_x]; |
|---|
| 628 | cz = cell_cache[tile_y][tile_x]; |
|---|
| 629 | } |
|---|
| 630 | |
|---|
| 631 | // This is our output data. |
|---|
| 632 | MapCellInfo out; |
|---|
| 633 | |
|---|
| 634 | // Write out the area/water information. |
|---|
| 635 | for(uint32 xc=(x%CellsPerTile)*16/CellsPerTile;xc<(x%CellsPerTile)*16/CellsPerTile+16/CellsPerTile;xc++) |
|---|
| 636 | { |
|---|
| 637 | for(uint32 yc=(y%CellsPerTile)*16/CellsPerTile;yc<(y%CellsPerTile)*16/CellsPerTile+16/CellsPerTile;yc++) |
|---|
| 638 | { |
|---|
| 639 | uint32 lx=xc%(16/CellsPerTile); |
|---|
| 640 | uint32 ly=yc%(16/CellsPerTile); |
|---|
| 641 | out.AreaID[lx][ly] = mcells->ch[yc][xc].area_id; |
|---|
| 642 | out.LiquidType[lx][ly] = mcells->ch[yc][xc].flag; |
|---|
| 643 | out.LiquidLevel[lx][ly] = mcells->ch[yc][xc].waterlevel; |
|---|
| 644 | } |
|---|
| 645 | } |
|---|
| 646 | |
|---|
| 647 | |
|---|
| 648 | // Convert it into antrix cell format. |
|---|
| 649 | for(uint32 cx=(x%CellsPerTile)*MAP_RESOLUTION/CellsPerTile;cx<(x%CellsPerTile)*MAP_RESOLUTION/CellsPerTile+MAP_RESOLUTION/CellsPerTile;cx++) |
|---|
| 650 | { |
|---|
| 651 | for(uint32 cy=(y%CellsPerTile)*MAP_RESOLUTION/CellsPerTile;cy<(y%CellsPerTile)*MAP_RESOLUTION/CellsPerTile+MAP_RESOLUTION/CellsPerTile;cy++) |
|---|
| 652 | { |
|---|
| 653 | uint32 lx=cx%(MAP_RESOLUTION/CellsPerTile); |
|---|
| 654 | uint32 ly=cy%(MAP_RESOLUTION/CellsPerTile); |
|---|
| 655 | out.Z[lx][ly] = cz->z[cx][cy]; |
|---|
| 656 | } |
|---|
| 657 | } |
|---|
| 658 | |
|---|
| 659 | // Write out to file. |
|---|
| 660 | fwrite(&out, sizeof(out), 1, out_file); |
|---|
| 661 | return true; |
|---|
| 662 | } |
|---|