Fix .lvl loader erroring when map had custom blocks in it, and the dimensions weren't divisible by 16

This commit is contained in:
UnknownShadow200 2018-01-13 09:37:29 +11:00
parent 35219142cd
commit 06f04355a6
2 changed files with 46 additions and 14 deletions

View File

@ -50,6 +50,11 @@ namespace ClassicalSharp.Map {
byte[] chunk = new byte[16 * 16 * 16];
byte[] data = new byte[1];
// skip bounds checks when we know chunk is entirely inside map
int adjWidth = width & ~0x0F;
int adjHeight = height & ~0x0F;
int adjLength = length & ~0x0F;
for (int y = 0; y < height; y += 16)
for (int z = 0; z < length; z += 16)
for (int x = 0; x < width; x += 16)
@ -57,15 +62,27 @@ namespace ClassicalSharp.Map {
int read = s.Read(data, 0, 1);
if (read == 0 || data[0] != 1) continue;
s.Read(chunk, 0, chunk.Length);
int baseIndex = (y * length + z) * width + x;
for (int i = 0; i < chunk.Length; i++) {
int xx = i & 0xF, yy = (i >> 8) & 0xF, zz = (i >> 4) & 0xF;
int index = baseIndex + (yy * length + zz) * width + xx;
if (blocks[index] != customTile) continue;
blocks[index] = chunk[i];
if ((x + 16) <= adjWidth && (y + 16) <= adjHeight && (z + 16) <= adjLength) {
for (int i = 0; i < chunk.Length; i++) {
int xx = i & 0xF, yy = (i >> 8) & 0xF, zz = (i >> 4) & 0xF;
int index = baseIndex + (yy * length + zz) * width + xx;
if (blocks[index] != customTile) continue;
blocks[index] = chunk[i];
}
} else {
for (int i = 0; i < chunk.Length; i++) {
int xx = i & 0xF, yy = (i >> 8) & 0xF, zz = (i >> 4) & 0xF;
if ((x + xx) >= width || (y + yy) >= height || (z + zz) >= length) continue;
int index = baseIndex + (yy * length + zz) * width + xx;
if (blocks[index] != customTile) continue;
blocks[index] = chunk[i];
}
}
}
}

View File

@ -33,6 +33,11 @@ UInt8 Lvl_table[256 - BLOCK_CPE_COUNT] = { 0, 0, 0, 0, 39, 36, 36, 10, 46, 21, 2
void Lvl_ReadCustomBlocks(Stream* stream) {
Int32 x, y, z, i;
UInt8 chunk[LVL_CHUNKSIZE * LVL_CHUNKSIZE * LVL_CHUNKSIZE];
/* skip bounds checks when we know chunk is entirely inside map */
Int32 adjWidth = World_Width & ~0x0F;
Int32 adjHeight = World_Height & ~0x0F;
Int32 adjLength = World_Length & ~0x0F;
for (y = 0; y < World_Height; y += LVL_CHUNKSIZE) {
for (z = 0; z < World_Length; z += LVL_CHUNKSIZE) {
for (x = 0; x < World_Width; x += LVL_CHUNKSIZE) {
@ -40,11 +45,21 @@ void Lvl_ReadCustomBlocks(Stream* stream) {
Stream_Read(stream, chunk, sizeof(chunk));
Int32 baseIndex = World_Pack(x, y, z);
for (i = 0; i < sizeof(chunk); i++) {
Int32 xx = i & 0xF, yy = (i >> 8) & 0xF, zz = (i >> 4) & 0xF;
Int32 index = baseIndex + World_Pack(xx, yy, zz);
World_Blocks[index] = World_Blocks[index] == LVL_CUSTOMTILE ? chunk[i] : World_Blocks[index];
if ((x + LVL_CHUNKSIZE) <= adjWidth && (y + LVL_CHUNKSIZE) <= adjHeight && (z + LVL_CHUNKSIZE) <= adjLength) {
for (i = 0; i < sizeof(chunk); i++) {
Int32 xx = i & 0xF, yy = (i >> 8) & 0xF, zz = (i >> 4) & 0xF;
Int32 index = baseIndex + World_Pack(xx, yy, zz);
World_Blocks[index] = World_Blocks[index] == LVL_CUSTOMTILE ? chunk[i] : World_Blocks[index];
}
} else {
for (i = 0; i < sizeof(chunk); i++) {
Int32 xx = i & 0xF, yy = (i >> 8) & 0xF, zz = (i >> 4) & 0xF;
if ((x + xx) >= World_Width || (y + yy) >= World_Height || (z + zz) >= World_Length) continue;
Int32 index = baseIndex + World_Pack(xx, yy, zz);
World_Blocks[index] = World_Blocks[index] == LVL_CUSTOMTILE ? chunk[i] : World_Blocks[index];
}
}
}
}
}