diff --git a/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/ChunkSkyLightProviderMixin.java b/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/ChunkSkyLightProviderMixin.java index 1d1525e..38cc831 100644 --- a/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/ChunkSkyLightProviderMixin.java +++ b/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/ChunkSkyLightProviderMixin.java @@ -14,6 +14,7 @@ import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkSectionPos; import net.minecraft.util.math.Direction; import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkNibbleArray; import net.minecraft.world.chunk.ChunkProvider; import net.minecraft.world.chunk.ChunkToNibbleArrayMap; import net.minecraft.world.chunk.light.ChunkLightProvider; @@ -232,4 +233,101 @@ public abstract class ChunkSkyLightProviderMixin= bottomSectionY; sectionY--) { + long packedSectionPos = ChunkSectionPos.asLong(chunkPos.x, sectionY, chunkPos.z); + lightArrays[sectionY - bottomSectionY] = lightStorageAccessor.crystalline_sky$method_51547(packedSectionPos); + } + + for (int localZ = 0; localZ < 16; localZ++) { + for (int localX = 0; localX < 16; localX++) { + if (weepingStorage.isColumnEmpty(localX, localZ)) continue; + + int lowestSourceY = sourcesO.get(localX, localZ); + int effectiveLowestSourceY = lowestSourceY <= minY ? Integer.MIN_VALUE : lowestSourceY; + if (effectiveLowestSourceY == Integer.MIN_VALUE) continue; + + int minSourceY_ZN = localZ == 0 ? sourcesZN.get(localX, 15) : sourcesO.get(localX, localZ - 1); + int minSourceY_ZP = localZ == 15 ? sourcesZP.get(localX, 0) : sourcesO.get(localX, localZ + 1); + int minSourceY_XN = localX == 0 ? sourcesXN.get(15, localZ) : sourcesO.get(localX - 1, localZ); + int minSourceY_XP = localX == 15 ? sourcesXP.get(0, localZ) : sourcesO.get(localX + 1, localZ); + int minSourceY_max = Math.max(Math.max(minSourceY_ZN, minSourceY_ZP), Math.max(minSourceY_XN, minSourceY_XP)); + + for (WeepingStorage.Run run : weepingStorage.iterateLitRuns(localX, localZ, effectiveLowestSourceY)) { + if (run.topY() == Integer.MAX_VALUE) { + if (run.bottomY() == effectiveLowestSourceY) { + continue; + } else { + run = run.withTopY(effectiveLowestSourceY - 1); + } + } + + int lowestRelevantY = Math.max(run.bottomY(), minY); + for (int sectionY = ChunkSectionPos.getSectionCoord(lowestRelevantY); sectionY <= topSectionY - 1; sectionY++) { + ChunkNibbleArray lightArray = lightArrays[sectionY - bottomSectionY]; + if (lightArray == null) continue; + + int minYInSection = ChunkSectionPos.getBlockCoord(sectionY); + int maxYInSection = minYInSection + 15; + + if (minYInSection > run.topY()) { // todone break outer early if we're above run.topY() + break; + } + + for (int it_y = Math.max(minYInSection, lowestRelevantY); it_y <= Math.min(maxYInSection, run.topY()); it_y++) { + lightArray.set(localX, ChunkSectionPos.getLocalCoord(it_y), localZ, 15); + + if (it_y == lowestRelevantY || it_y < minSourceY_max) { + long it_pos = BlockPos.asLong(baseX + localX, it_y, baseZ + localZ); + enqueueIncrease( + it_pos, + QueueEntry.increaseSkySourceInDirections( + it_y == lowestRelevantY, + it_y < minSourceY_ZN, + it_y < minSourceY_ZP, + it_y < minSourceY_XN, + it_y < minSourceY_XP + ) + ); + } + } + } + } + } + } + } } diff --git a/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/LightStorageAccessor.java b/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/LightStorageAccessor.java index d7a9528..a9a7183 100644 --- a/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/LightStorageAccessor.java +++ b/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/LightStorageAccessor.java @@ -1,6 +1,8 @@ package io.github.slimeistdev.crystalline_sky.mixin; +import net.minecraft.world.chunk.ChunkNibbleArray; import net.minecraft.world.chunk.light.LightStorage; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; @@ -17,4 +19,7 @@ public interface LightStorageAccessor { @Invoker("set") void crystalline_sky$set(long blockPos, int lightLevel); + + @Invoker("method_51547") + @Nullable ChunkNibbleArray crystalline_sky$method_51547(long sectionPos); } diff --git a/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/SkyLightStorageAccessor.java b/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/SkyLightStorageAccessor.java index b00e483..79ae19c 100644 --- a/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/SkyLightStorageAccessor.java +++ b/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/SkyLightStorageAccessor.java @@ -11,4 +11,10 @@ public interface SkyLightStorageAccessor extends LightStorageAccessor { @Invoker("isAtOrAboveTopmostSection") boolean crystalline_sky$isAtOrAboveTopmostSection(long sectionPos); + + @Invoker("getTopSectionForColumn") + int crystalline_sky$getTopSectionForColumn(long columnPos); + + @Invoker("getMinSectionY") + int crystalline_sky$getMinSectionY(); }