diff --git a/ClassicalSharp/Blocks/BlockInfo.cs b/ClassicalSharp/Blocks/BlockInfo.cs index 71f56261b..f5a20ed98 100644 --- a/ClassicalSharp/Blocks/BlockInfo.cs +++ b/ClassicalSharp/Blocks/BlockInfo.cs @@ -326,7 +326,7 @@ namespace ClassicalSharp { static void CalcCulling(BlockID block, BlockID other) { if (!IsHidden(block, other)) { // Block is not hidden at all, so we can just entirely skip per-face check - BlockInfo.hidden[(block * Count) | other] = 0; + BlockInfo.hidden[(block * Count) + other] = 0; } else { Vector3 bMin = MinBB[block], bMax = MaxBB[block]; Vector3 oMin = MinBB[other], oMax = MaxBB[other]; @@ -348,7 +348,7 @@ namespace ClassicalSharp { f |= occludedZ && oMin.Z == 0 && bMax.Z == 1 ? (1 << Side.Back) : 0; f |= occludedY && (bothLiquid || (oMax.Y == 1 && bMin.Y == 0)) ? (1 << Side.Bottom) : 0; f |= occludedY && (bothLiquid || (oMin.Y == 0 && bMax.Y == 1)) ? (1 << Side.Top) : 0; - BlockInfo.hidden[(block * Count) | other] = (byte)f; + BlockInfo.hidden[(block * Count) + other] = (byte)f; } } @@ -376,7 +376,7 @@ namespace ClassicalSharp { /// Returns whether the face at the given face of the block /// should be drawn with the neighbour 'other' present on the other side of the face. public static bool IsFaceHidden(BlockID block, BlockID other, int tileSide) { - return (hidden[(block * Count) | other] & (1 << tileSide)) != 0; + return (hidden[(block * Count) + other] & (1 << tileSide)) != 0; } } } diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj index 4dbfd5797..13be250a1 100644 --- a/ClassicalSharp/ClassicalSharp.csproj +++ b/ClassicalSharp/ClassicalSharp.csproj @@ -63,7 +63,7 @@ None True False - TRACE;USE_DX; + TRACE;USE_DX;USE16_BIT obj\ Project diff --git a/ClassicalSharp/MeshBuilder/Builder.cs b/ClassicalSharp/MeshBuilder/Builder.cs index fbb07b98d..5923878dd 100644 --- a/ClassicalSharp/MeshBuilder/Builder.cs +++ b/ClassicalSharp/MeshBuilder/Builder.cs @@ -32,7 +32,7 @@ namespace ClassicalSharp { protected internal int width, length, height, sidesLevel, edgeLevel; protected int maxX, maxY, maxZ, chunkEndX, chunkEndZ; protected int cIndex; - protected BlockRaw* chunk; + protected BlockID* chunk; protected byte* counts; protected int* bitFlags; protected bool useBitFlags; @@ -40,14 +40,31 @@ namespace ClassicalSharp { bool BuildChunk(int x1, int y1, int z1, ref bool allAir) { light = game.Lighting; PreStretchTiles(x1, y1, z1); - BlockRaw* chunkPtr = stackalloc BlockRaw[extChunkSize3]; chunk = chunkPtr; + BlockID* chunkPtr = stackalloc BlockID[extChunkSize3]; chunk = chunkPtr; byte* countsPtr = stackalloc byte[chunkSize3 * Side.Sides]; counts = countsPtr; int* bitsPtr = stackalloc int[extChunkSize3]; bitFlags = bitsPtr; + MemUtils.memset((IntPtr)chunkPtr, 0, 0, extChunkSize3 * sizeof(BlockID)); + + bool allSolid = false; + fixed (BlockRaw* mapPtr = map.blocks1) { + #if USE_16_BIT + if (BlockInfo.MaxDefined >= 256) { + ReadChunkData_16Bit(x1, y1, z1, mapPtr, ref allAir, ref allSolid); + } else { + ReadChunkData_8Bit(x1, y1, z1, mapPtr, ref allAir, ref allSolid); + } + #else + ReadChunkData_8Bit(x1, y1, z1, mapPtr, ref allAir, ref allSolid); + #endif + + if (x1 == 0 || y1 == 0 || z1 == 0 || x1 + chunkSize >= width || + y1 + chunkSize >= height || z1 + chunkSize >= length) allSolid = false; + + if (allAir || allSolid) return false; + light.LightHint(x1 - 1, z1 - 1, mapPtr); + } - MemUtils.memset((IntPtr)chunkPtr, 0, 0, extChunkSize3 * sizeof(BlockRaw)); - if (ReadChunkData(x1, y1, z1, ref allAir)) return false; MemUtils.memset((IntPtr)countsPtr, 1, 0, chunkSize3 * Side.Sides); - int xMax = Math.Min(width, x1 + chunkSize); int yMax = Math.Min(height, y1 + chunkSize); int zMax = Math.Min(length, z1 + chunkSize); @@ -75,10 +92,41 @@ namespace ClassicalSharp { return true; } - bool ReadChunkData(int x1, int y1, int z1, ref bool outAllAir) { // only assign this variable once + void ReadChunkData_8Bit(int x1, int y1, int z1, BlockRaw* mapPtr, ref bool outAllAir, ref bool outAllSolid) { // only assign this variable once bool allAir = true, allSolid = true; - fixed (BlockRaw* mapPtr = map.blocks1) { - + for (int yy = -1; yy < 17; yy++) { + int y = yy + y1; + if (y < 0) continue; + if (y >= height) break; + for (int zz = -1; zz < 17; zz++) { + int z = zz + z1; + if (z < 0) continue; + if (z >= length) break; + + int index = (y * length + z) * width + (x1 - 1 - 1); + int chunkIndex = (yy + 1) * extChunkSize2 + (zz + 1) * extChunkSize + (-1 + 1) - 1; + + for (int xx = -1; xx < 17; xx++) { + int x = xx + x1; + index++; + chunkIndex++; + if (x < 0) continue; + if (x >= width) break; + BlockID rawBlock = mapPtr[index]; + + allAir = allAir && BlockInfo.Draw[rawBlock] == DrawType.Gas; + allSolid = allSolid && BlockInfo.FullOpaque[rawBlock]; + chunk[chunkIndex] = rawBlock; + } + } + outAllAir = allAir; outAllSolid = allSolid; + } + } + + #if USE_16_BIT + void ReadChunkData_16Bit(int x1, int y1, int z1, BlockRaw* mapPtr, ref bool outAllAir, ref bool outAllSolid) { // only assign this variable once + bool allAir = true, allSolid = true; + fixed (BlockRaw* mapPtr2 = map.blocks2) { for (int yy = -1; yy < 17; yy++) { int y = yy + y1; if (y < 0) continue; @@ -97,24 +145,18 @@ namespace ClassicalSharp { chunkIndex++; if (x < 0) continue; if (x >= width) break; - BlockRaw rawBlock = mapPtr[index]; + BlockID rawBlock = (BlockID)(mapPtr[index] | (mapPtr2[index] << 8)); allAir = allAir && BlockInfo.Draw[rawBlock] == DrawType.Gas; allSolid = allSolid && BlockInfo.FullOpaque[rawBlock]; chunk[chunkIndex] = rawBlock; } } + outAllAir = allAir; outAllSolid = allSolid; } - outAllAir = allAir; - - if (x1 == 0 || y1 == 0 || z1 == 0 || x1 + chunkSize >= width || - y1 + chunkSize >= height || z1 + chunkSize >= length) allSolid = false; - - if (allAir || allSolid) return true; - light.LightHint(x1 - 1, z1 - 1, mapPtr); - return false; } } + #endif public void MakeChunk(ChunkInfo info) { int x = info.CentreX - 8, y = info.CentreY - 8, z = info.CentreZ - 8; diff --git a/src/Client/EntityComponents.c b/src/Client/EntityComponents.c index b9bdbf00d..fed8c9f88 100644 --- a/src/Client/EntityComponents.c +++ b/src/Client/EntityComponents.c @@ -227,12 +227,12 @@ void HacksComp_SetUserType(HacksComp* hacks, UInt8 value, bool setBlockPerms) { hacks->CanSeeAllNames = isOp; if (!setBlockPerms) return; - Block_CanPlace[BLOCK_BEDROCK] = isOp; - Block_CanDelete[BLOCK_BEDROCK] = isOp; - Block_CanPlace[BLOCK_WATER] = isOp; + Block_CanPlace[BLOCK_BEDROCK] = isOp; + Block_CanDelete[BLOCK_BEDROCK] = isOp; + Block_CanPlace[BLOCK_WATER] = isOp; Block_CanPlace[BLOCK_STILL_WATER] = isOp; - Block_CanPlace[BLOCK_LAVA] = isOp; - Block_CanPlace[BLOCK_STILL_LAVA] = isOp; + Block_CanPlace[BLOCK_LAVA] = isOp; + Block_CanPlace[BLOCK_STILL_LAVA] = isOp; } void HacksComp_CheckConsistency(HacksComp* hacks) { diff --git a/src/Client/EntityComponents.h b/src/Client/EntityComponents.h index 8faffba60..34ff1e5b0 100644 --- a/src/Client/EntityComponents.h +++ b/src/Client/EntityComponents.h @@ -68,7 +68,7 @@ typedef struct HacksComponent_ { void HacksComp_Init(HacksComp* hacks); bool HacksComp_CanJumpHigher(HacksComp* hacks); bool HacksComp_Floating(HacksComp* hacks); -void HacksComp_SetUserType(HacksComp* hacks, UInt8 value); +void HacksComp_SetUserType(HacksComp* hacks, UInt8 value, bool setBlockPerms); void HacksComp_CheckConsistency(HacksComp* hacks); void HacksComp_UpdateState(HacksComp* hacks);