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. 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 e54376b463b017d5e371f8d3204a37993b0e78e7..9b7bc1c9091d20671d281fa304722ac45fbf6e2e 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 @@ -304,16 +304,33 @@ public class ChunkSerializer { BelowZeroRetrogen belowzeroretrogen = protochunk.getBelowZeroRetrogen(); boolean flag2 = chunkstatus.isOrAfter(ChunkStatus.LIGHT) || belowzeroretrogen != null && belowzeroretrogen.targetStatus().isOrAfter(ChunkStatus.LIGHT); - if (!flag && flag2) { - 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) object).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 } }