diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/Chunk.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/Chunk.kt index 74ea3b526..31b7cf9c4 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/chunk/Chunk.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/Chunk.kt @@ -556,11 +556,14 @@ class Chunk( val section = sections?.get(sectionHeight - lowestSection) ?: continue section.light.update = true // ToDo: bare tracing + val baseY = sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y for (y in ProtocolDefinition.SECTION_MAX_Y downTo 0) { - section.light.traceSkylight(x, y, z, ProtocolDefinition.MAX_LIGHT_LEVEL.toInt(), Directions.UP, true) + section.light.traceSkylight(x, y, z, ProtocolDefinition.MAX_LIGHT_LEVEL.toInt(), null, baseY + y, true) } } + val sectionHeight = maxHeight.sectionHeight val maxSection = sections?.get(maxHeight.sectionHeight - lowestSection) + val baseY = sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y if (maxSection != null) { for (y in ProtocolDefinition.SECTION_MAX_Y downTo maxHeight.inSectionHeight) { val index = (y shl 8) or heightmapIndex @@ -568,12 +571,15 @@ class Chunk( if (block != null && !block.propagatesSkylight) { continue } - maxSection.light.traceSkylight(x, y, z, ProtocolDefinition.MAX_LIGHT_LEVEL.toInt(), Directions.UP, true) + maxSection.light.traceSkylight(x, y, z, ProtocolDefinition.MAX_LIGHT_LEVEL.toInt(), null, baseY + y, true) } maxSection.light.update = true } + } + fun getMaxHeight(x: Int, z: Int): Int { + return skylightHeightmap[(z shl 4) or x] } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/light/SectionLight.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/light/SectionLight.kt index 2c99bcff3..99871cdeb 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/chunk/light/SectionLight.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/light/SectionLight.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.world.chunk.light import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.data.registries.blocks.BlockState +import de.bixilon.minosoft.data.registries.blocks.light.TransparentProperty import de.bixilon.minosoft.data.world.chunk.ChunkNeighbours import de.bixilon.minosoft.data.world.chunk.ChunkSection import de.bixilon.minosoft.data.world.chunk.ChunkSection.Companion.getIndex @@ -238,40 +239,43 @@ class SectionLight( } } - fun traceSkylight(x: Int, y: Int, z: Int, nextLevel: Int, direction: Directions, force: Boolean) { + fun traceSkylight(x: Int, y: Int, z: Int, nextLevel: Int, direction: Directions?, totalY: Int, force: Boolean) { + if (direction == Directions.UP && totalY >= section.chunk!!.getMaxHeight(x, z)) { + // this light level will be 15, don't care + return + } val index = getIndex(x, y, z) val currentLight = this[index].toInt() - val currentSkylight = (currentLight and SKY_LIGHT_MASK) shr 4 - if (!force && currentSkylight >= nextLevel) { + if (!force && ((currentLight and SKY_LIGHT_MASK) shr 4) >= nextLevel) { return } - val light = section.blocks.unsafeGet(index)?.lightProperties + val light = section.blocks.unsafeGet(index)?.lightProperties ?: TransparentProperty - if (light != null && !light.propagatesLight) { + if (!light.propagatesLight) { return } this.light[index] = ((currentLight and BLOCK_LIGHT_MASK) or (nextLevel shl 4)).toByte() val nextNeighbourLevel = nextLevel - 1 // ToDo: Neighbours - if (y > 0 && (light == null || light.propagatesLight(direction, Directions.DOWN))) { - traceSkylight(x, y - 1, z, nextNeighbourLevel, Directions.DOWN, false) + if (y > 0 && direction != Directions.DOWN && (direction == null || light.propagatesLight(direction, Directions.DOWN))) { + traceSkylight(x, y - 1, z, nextNeighbourLevel, Directions.DOWN, totalY - 1, false) } - if (y < ProtocolDefinition.SECTION_MAX_Y && (light == null || light.propagatesLight(direction, Directions.UP))) { - traceSkylight(x, y + 1, z, nextNeighbourLevel, Directions.UP, false) + if (y < ProtocolDefinition.SECTION_MAX_Y && direction != Directions.UP && direction != null && (light.propagatesLight(direction, Directions.UP))) { + traceSkylight(x, y + 1, z, nextNeighbourLevel, Directions.UP, totalY + 1, false) } - if (z > 0 && (light == null || light.propagatesLight(direction, Directions.NORTH))) { - traceSkylight(x, y, z - 1, nextNeighbourLevel, Directions.NORTH, false) + if (z > 0 && direction != Directions.NORTH && (direction == null || light.propagatesLight(direction, Directions.NORTH))) { + traceSkylight(x, y, z - 1, nextNeighbourLevel, Directions.NORTH, totalY, false) } - if (z < ProtocolDefinition.SECTION_MAX_Z && (light == null || light.propagatesLight(direction, Directions.SOUTH))) { - traceSkylight(x, y, z + 1, nextNeighbourLevel, Directions.SOUTH, false) + if (z < ProtocolDefinition.SECTION_MAX_Z && direction != Directions.SOUTH && (direction == null || light.propagatesLight(direction, Directions.SOUTH))) { + traceSkylight(x, y, z + 1, nextNeighbourLevel, Directions.SOUTH, totalY, false) } - if (x > 0 && (light == null || light.propagatesLight(direction, Directions.WEST))) { - traceSkylight(x - 1, y, z, nextNeighbourLevel, Directions.WEST, false) + if (x > 0 && direction != Directions.WEST && (direction == null || light.propagatesLight(direction, Directions.WEST))) { + traceSkylight(x - 1, y, z, nextNeighbourLevel, Directions.WEST, totalY, false) } - if (x < ProtocolDefinition.SECTION_MAX_X && (light == null || light.propagatesLight(direction, Directions.EAST))) { - traceSkylight(x + 1, y, z, nextNeighbourLevel, Directions.EAST, false) + if (x < ProtocolDefinition.SECTION_MAX_X && direction != Directions.EAST && (direction == null || light.propagatesLight(direction, Directions.EAST))) { + traceSkylight(x + 1, y, z, nextNeighbourLevel, Directions.EAST, totalY, false) } }