From 65bca01f52639f50a37f410f3c0248345fe39950 Mon Sep 17 00:00:00 2001 From: ABKQPO <93412322+ABKQPO@users.noreply.github.com> Date: Fri, 11 Sep 2026 10:17:00 +0800 Subject: [PATCH] Leave a fluid alone when an air position is emptied --- .../structure/StructureUtility.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java index 4a0f311e..c74b2994 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java @@ -29,6 +29,7 @@ import java.util.function.Supplier; import javax.annotation.Nullable; import net.minecraft.block.Block; +import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.event.HoverEvent; @@ -194,6 +195,9 @@ public class StructureUtility { @Override public boolean placeBlock(Object o, World world, int x, int y, int z, ItemStack trigger) { + // A position that holds a fluid is left alone, as emptying it destroys the fluid instead of just clearing + // the position. It is up to whatever else the structure allows there to deal with it. + if (holdsFluid(world, x, y, z)) return false; world.setBlock(x, y, z, Blocks.air, 0, 3); return false; } @@ -203,6 +207,10 @@ public class StructureUtility { public PlaceResult survivalPlaceBlock(Object o, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { if (check(o, world, x, y, z)) return PlaceResult.SKIP; + // Emptying a position that holds a fluid would destroy that fluid, which is not the same as clearing some + // grass out of the way. Defer instead, so that a fluid element this one is chained with, e.g. one asking + // for water, still gets its chance to turn the fluid into what the structure wants. + if (holdsFluid(world, x, y, z)) return PlaceResult.REJECT_CONTINUE; if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) return PlaceResult.REJECT; // Notify the neighbours, so that e.g. a fluid next to a position that had to be emptied flows back into it. world.setBlock(x, y, z, Blocks.air, 0, 3); @@ -210,6 +218,18 @@ public class StructureUtility { } }; + /** + * Whether the given position holds a fluid. Such a position is not merely occupied, as whatever removes the fluid + * destroys it, and a structure is often built where a fluid was placed by the player or leaked out of one. + */ + private static boolean holdsFluid(World world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + if (block == null) return false; + if (FluidPlacementRegistry.getFluidOf(block) != null) return true; + Material material = block.getMaterial(); + return material != null && material.isLiquid(); + } + @SuppressWarnings("rawtypes") private static final IStructureElement NOT_AIR = new StructureElement_Bridge() {