void OutdoorLightStats::init(MPQFile &f) { float h,m; f.seekRelative(4); f.read(&h,4); f.seekRelative(4); f.read(&m,4); f.seekRelative(4); f.read(&dayIntensity,4); f.seekRelative(4); f.read(&dayColor.x,4); f.seekRelative(4); f.read(&dayColor.y,4); f.seekRelative(4); f.read(&dayColor.z,4); f.seekRelative(4); f.read(&dayDir.x,4); f.seekRelative(4); f.read(&dayDir.y,4); f.seekRelative(4); f.read(&dayDir.z,4); f.seekRelative(4); f.read(&nightIntensity, 4); f.seekRelative(4); f.read(&nightColor.x,4); f.seekRelative(4); f.read(&nightColor.y,4); f.seekRelative(4); f.read(&nightColor.z,4); f.seekRelative(4); f.read(&nightDir.x,4); f.seekRelative(4); f.read(&nightDir.y,4); f.seekRelative(4); f.read(&nightDir.z,4); f.seekRelative(4); f.read(&ambientIntensity, 4); f.seekRelative(4); f.read(&ambientColor.x,4); f.seekRelative(4); f.read(&ambientColor.y,4); f.seekRelative(4); f.read(&ambientColor.z,4); f.seekRelative(4); f.read(&fogDepth, 4); f.seekRelative(4); f.read(&fogIntensity, 4); f.seekRelative(4); f.read(&fogColor.x,4); f.seekRelative(4); f.read(&fogColor.y,4); f.seekRelative(4); f.read(&fogColor.z,4); time = (int)h * 60 * 2 + (int)m * 2; // HACK: make day & night intensity exclusive; set day intensity to 1.0 if (dayIntensity > 0) { dayIntensity = 1.0f; nightIntensity = 0.0f; } }
inline void LoadMapChunk(MPQFile & mf, chunk*_chunk) { float h; uint32 fourcc; uint32 size; MapChunkHeader header; mf.seekRelative(4); mf.read(&size, 4); size_t lastpos = mf.getPos() + size; mf.read(&header, 0x80); _chunk->area_id =header.areaid ; _chunk->flag =0; float xbase = header.xpos; float ybase = header.ypos; float zbase = header.zpos; zbase = TILESIZE*32-zbase; xbase = TILESIZE*32-xbase; if(wmoc.x >xbase)wmoc.x =xbase; if(wmoc.z >zbase)wmoc.z =zbase; int chunkflags = header.flags; float zmin=999999999.0f; float zmax=-999999999.0f; //must be there, bl!zz uses some crazy format 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 { for (int j=0; j<17; j++) for (int i=0; i<((j%2)?8:9); i++) { mf.read(&h,4); float z=h+ybase; if (j%2) { if(isHole(header.holes,i,j)) _chunk->v8[i][j/2] = -1000; else _chunk->v8[i][j/2] = z; } else { if(isHole(header.holes,i,j)) _chunk->v9[i][j/2] = -1000; else _chunk->v9[i][j/2] = z; } if(z>zmax)zmax=z; //if(z<zmin)zmin=z; } } else if(fourcc==0x4d434e52) // MCNR { nextpos = mf.getPos() + 0x1C0; // size fix } else if(fourcc==0x4d434c51) // MCLQ { // liquid / water level //bool haswater; char fcc1[5]; mf.read(fcc1,4); flipcc(fcc1); fcc1[4]=0; 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 } 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; } if(chunkflags & 4 || chunkflags & 8) _chunk->flag |=1; if(chunkflags & 16) _chunk->flag |=2; } break; } else if (fourcc==0x4d434c59) // MCLY { // texture info nTextures = (int)size; } else if (fourcc==0x4d43414c) // MCAL { if (nTextures<=0) continue; } mf.seek(nextpos); } }
inline void LoadMapChunk(MPQFile &mf, chunk *_chunk) { float h; uint32 fourcc; uint32 size; MapChunkHeader header; mf.seekRelative(4); mf.read(&size, 4); size_t lastpos = mf.getPos() + size; mf.read(&header, 0x80); // what if header size got changed? _chunk->area_id = header.areaid; float xbase = header.xpos; float ybase = header.ypos; float zbase = header.zpos; zbase = TILESIZE * 32 - zbase; xbase = TILESIZE * 32 - xbase; 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 while (mf.getPos() < lastpos) { mf.read(&fourcc, 4); mf.read(&size, 4); size_t nextpos = mf.getPos() + size; if(fourcc == 0x4d435654) // MCVT { for (int j = 0; j < 17; ++j) { for (int i = 0; i < ((j % 2) ? 8 : 9); ++i) { mf.read(&h, 4); float z = h + ybase; if (j % 2) { if(isHole(header.holes, i, j)) _chunk->v8[i][j / 2] = -1000; else _chunk->v8[i][j / 2] = z; } else { if(isHole(header.holes, i, j)) _chunk->v9[i][j / 2] = -1000; else _chunk->v9[i][j / 2] = z; } if(z > zmax) zmax = z; //if(z < zmin) zmin = z; } } } else if(fourcc == 0x4d434e52) // MCNR { nextpos = mf.getPos() + 0x1C0; // size fix } else if(fourcc == 0x4d434c51) // MCLQ { // liquid / water level char fcc1[5]; mf.read(fcc1, 4); flipcc(fcc1); fcc1[4] = 0; float *ChunkLiqHeight = new float[81]; if (!strcmp(fcc1, "MCSE")) { for(int j = 0; j < 81; ++j) { ChunkLiqHeight[j] = -999999; // no liquid/water } } else { float maxheight; mf.read(&maxheight, 4); for(int j = 0; j < 81; ++j) { LiqData liq; mf.read(&liq, 8); if(liq.height > maxheight) ChunkLiqHeight[j] = -999999; else ChunkLiqHeight[j] = h; } if(chunkflags & 4 || chunkflags & 8) MapLiqFlag[chunk_num] |= 1; // water if(chunkflags & 16) MapLiqFlag[chunk_num] |= 2; // magma/slime } 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] = ChunkLiqHeight[p + s]; ++k; } k = k + 120; } delete []ChunkLiqHeight; break; } mf.seek(nextpos); } }