From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Mon, 23 Aug 2021 04:50:05 -0700 Subject: [PATCH] Always parse protochunk light sources unless it is marked as non-lit Chunks not marked as lit will always go through the light engine, so they should always have their block sources parsed. Protochunks no longer serialize light sources like this. diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java index 34a1976699571608ae19e20dc1b6020759dad909..0ec80b83a99bfdb1f985045d98a81905a8a5a3ac 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java @@ -327,16 +327,33 @@ public class ChunkSerializer { BelowZeroRetrogen belowzeroretrogen = protochunk.getBelowZeroRetrogen(); boolean flag5 = chunkstatus.isOrAfter(ChunkStatus.LIGHT) || belowzeroretrogen != null && belowzeroretrogen.targetStatus().isOrAfter(ChunkStatus.LIGHT); - if (!flag && flag5) { - Iterator iterator = BlockPos.betweenClosed(chunkPos.getMinBlockX(), world.getMinBuildHeight(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), world.getMaxBuildHeight() - 1, chunkPos.getMaxBlockZ()).iterator(); + if (!flag) { // Paper - fix incorrect parsing of blocks that emit light - it should always parse it, unless the chunk is marked as lit + // Paper start - let's make sure the implementation isn't as slow as possible + int offX = chunkPos.x << 4; + int offZ = chunkPos.z << 4; + + int minChunkSection = io.papermc.paper.util.WorldUtil.getMinSection(world); + int maxChunkSection = io.papermc.paper.util.WorldUtil.getMaxSection(world); + + LevelChunkSection[] sections = achunksection; + for (int sectionY = minChunkSection; sectionY <= maxChunkSection; ++sectionY) { + LevelChunkSection section = sections[sectionY - minChunkSection]; + if (section == null || section.hasOnlyAir()) { + // no sources in empty sections + continue; + } + int offY = sectionY << 4; - while (iterator.hasNext()) { - BlockPos blockposition = (BlockPos) iterator.next(); + for (int index = 0; index < (16 * 16 * 16); ++index) { + if (section.states.get(index).getLightEmission() <= 0) { + continue; + } - if (((ChunkAccess) object1).getBlockState(blockposition).getLightEmission() != 0) { - protochunk.addLight(blockposition); + // index = x | (z << 4) | (y << 8) + protochunk.addLight(new BlockPos(offX | (index & 15), offY | (index >>> 8), offZ | ((index >>> 4) & 15))); } } + // Paper end } }