From c162b1d09ef379c2828a07d816afc4bb5dbb99b2 Mon Sep 17 00:00:00 2001 From: ishland Date: Fri, 1 Nov 2024 13:29:40 +0800 Subject: [PATCH] fix: suppress ghost mushrooms outside of simulation distance Fixes #336 Squashed commit of the following: commit db66b242e229a2cf6ccd9240ec1fee36a728ce46 Author: ishland Date: Sun Sep 22 11:19:46 2024 +0800 change: allow disabling mushroom mitigation commit 1839d3c91203891662091f843e8c97db50b743ff Author: ishland Date: Sun Sep 22 10:44:27 2024 +0800 fix: ghost mushroom attempt 5 Related to #336 commit 3eb1b5e9654dfc6e2b24f0af4fafaf4ba2e6ddb3 Author: ishland Date: Sun Sep 22 10:37:23 2024 +0800 Revert "fix: ghost mushroom attempt 3" This reverts commit ebd3b85d77bebecda82e33253a45877f4cc88e4f. commit 669847490a6ce0818a03e406234db84c7ec8b1d0 Author: ishland Date: Sun Sep 22 10:37:18 2024 +0800 Revert "fix: ghost mushroom attempt 4" This reverts commit 48d9f3bc0683b44ef8453a854c11b3ab68324789. commit 48d9f3bc0683b44ef8453a854c11b3ab68324789 Author: ishland Date: Sat Sep 21 16:45:25 2024 +0800 fix: ghost mushroom attempt 4 Related to #336 commit ebd3b85d77bebecda82e33253a45877f4cc88e4f Author: ishland Date: Sat Sep 21 16:34:30 2024 +0800 fix: ghost mushroom attempt 3 Related to #336 commit d33bd29f7392a0657055ecbce61bfdccd001604e Author: ishland Date: Sat Sep 21 15:53:19 2024 +0800 Revert "fix: ghost mushroom attempt 1" This reverts commit 5054bef74cea15ab9acbeb652652c492265f502e. commit 50710be04d9bffd8f653c998f190ddb7d68eb130 Author: ishland Date: Sat Sep 21 15:53:14 2024 +0800 Revert "fix: ghost mushroom attempt 2: ensure post-processed chunk is open" This reverts commit 4f74581533e2ee062b5e05b67f8125ef7db3ac4e. commit cc0e89c7c3ffa0b96e537e227a80533407192b4a Merge: 4f745815 716d21cb Author: ishland Date: Thu Sep 19 16:53:35 2024 +0800 Merge branch 'ver/1.21.1' into fix/336-ghost-mushroom commit 4f74581533e2ee062b5e05b67f8125ef7db3ac4e Author: ishland Date: Thu Sep 19 16:47:00 2024 +0800 fix: ghost mushroom attempt 2: ensure post-processed chunk is open Related to #336 commit 5054bef74cea15ab9acbeb652652c492265f502e Author: ishland Date: Wed Sep 18 23:18:53 2024 +0800 fix: ghost mushroom attempt 1 Related to #336 --- .../rewrites/chunksystem/common/Config.java | 10 ++++++ .../common/statuses/ServerAccessible.java | 33 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/common/Config.java b/c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/common/Config.java index 4d3c2e13a..d36a387b5 100644 --- a/c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/common/Config.java +++ b/c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/common/Config.java @@ -34,6 +34,16 @@ Whether to allow POIs (Point of Interest) to be unloaded """) .getBoolean(true, false); + public static final boolean suppressGhostMushrooms = new ConfigSystem.ConfigAccessor() + .key("chunkSystem.suppressGhostMushrooms") + .comment(""" + This option workarounds MC-276863, a bug that makes mushrooms appear in non-postprocessed chunks + This bug is amplified with notickvd as it exposes non-postprocessed chunks to players + + This should not affect other worldgen behavior and game mechanics in general + """) + .getBoolean(true, false); + public static void init() { // intentionally empty } diff --git a/c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/common/statuses/ServerAccessible.java b/c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/common/statuses/ServerAccessible.java index e7da3401a..3c91a2eba 100644 --- a/c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/common/statuses/ServerAccessible.java +++ b/c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/common/statuses/ServerAccessible.java @@ -12,13 +12,21 @@ import com.ishland.c2me.rewrites.chunksystem.common.fapi.LifecycleEventInvoker; import com.ishland.flowsched.scheduler.ItemHolder; import com.ishland.flowsched.scheduler.KeyStatusPair; +import it.unimi.dsi.fastutil.shorts.ShortList; +import it.unimi.dsi.fastutil.shorts.ShortListIterator; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.entity.EntityType; import net.minecraft.nbt.NbtCompound; import net.minecraft.server.world.ChunkLevels; import net.minecraft.server.world.ServerChunkLoadingManager; import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.ChunkRegion; import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkGenerationStep; +import net.minecraft.world.chunk.ChunkGenerationSteps; import net.minecraft.world.chunk.ChunkStatus; import net.minecraft.world.chunk.ProtoChunk; import net.minecraft.world.chunk.WorldChunk; @@ -55,6 +63,31 @@ public CompletionStage upgradeToThis(ChunkLoadingContext context) { final Chunk chunk = context.holder().getItem().get().chunk(); Preconditions.checkState(chunk instanceof ProtoChunk, "Chunk must be a proto chunk"); ProtoChunk protoChunk = (ProtoChunk) chunk; + + if (Config.suppressGhostMushrooms) { + ServerWorld serverWorld = ((IThreadedAnvilChunkStorage) context.tacs()).getWorld(); + ChunkRegion chunkRegion = new ChunkRegion(serverWorld, context.chunks(), ChunkGenerationSteps.GENERATION.get(ChunkStatus.FULL), chunk); + + ChunkPos chunkPos = context.holder().getKey(); + + ShortList[] postProcessingLists = protoChunk.getPostProcessingLists(); + for (int i = 0; i < postProcessingLists.length; i++) { + if (postProcessingLists[i] != null) { + for (ShortListIterator iterator = postProcessingLists[i].iterator(); iterator.hasNext(); ) { + short short_ = iterator.nextShort(); + BlockPos blockPos = ProtoChunk.joinBlockPos(short_, protoChunk.sectionIndexToCoord(i), chunkPos); + BlockState blockState = protoChunk.getBlockState(blockPos); + + if (blockState.getBlock() == Blocks.BROWN_MUSHROOM || blockState.getBlock() == Blocks.RED_MUSHROOM) { + if (!blockState.canPlaceAt(chunkRegion, blockPos)) { + protoChunk.setBlockState(blockPos, Blocks.AIR.getDefaultState(), false); // TODO depends on the fact that the chunk system always locks the current chunk + } + } + } + } + } + } + return CompletableFuture.runAsync(() -> { ServerWorld serverWorld = ((IThreadedAnvilChunkStorage) context.tacs()).getWorld(); final WorldChunk worldChunk = toFullChunk(protoChunk, serverWorld);