aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0803-Always-parse-protochunk-light-sources-unless-it-is-m.patch
blob: a1b655d7c1c855cc956d63f0011d764a5f5f18ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
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 54ade15cdab222e9818f2635a8a12418e78e1ce6..887b3bc6370d23d2ff38e8fdbe286d678b035cc7 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
@@ -312,16 +312,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
             }
         }