diff options
author | viciscat <[email protected]> | 2024-02-17 21:44:03 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2024-02-17 15:44:03 -0500 |
commit | d95341e44a8ba027af80547a44300617f314e548 (patch) | |
tree | 56cb47b2195557e1f9c338aecc405f6c6a78a087 | |
parent | 1964b224398de7f51f56035420a33301d3ec027a (diff) | |
download | Paper-d95341e44a8ba027af80547a44300617f314e548.tar.gz Paper-d95341e44a8ba027af80547a44300617f314e548.zip |
FluidState API (#9951)
* Add new FluidState API functionality
---------
Co-authored-by: Bjarne Koll <[email protected]>
Co-authored-by: Owen1212055 <[email protected]>
-rw-r--r-- | patches/api/0463-Add-FluidState-API.patch | 164 | ||||
-rw-r--r-- | patches/server/1046-Add-FluidState-API.patch | 208 |
2 files changed, 372 insertions, 0 deletions
diff --git a/patches/api/0463-Add-FluidState-API.patch b/patches/api/0463-Add-FluidState-API.patch new file mode 100644 index 0000000000..3235c393f5 --- /dev/null +++ b/patches/api/0463-Add-FluidState-API.patch @@ -0,0 +1,164 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: vicisacat <[email protected]> +Date: Fri, 17 Nov 2023 20:21:47 +0100 +Subject: [PATCH] Add FluidState API + + +diff --git a/src/main/java/io/papermc/paper/block/fluid/FluidData.java b/src/main/java/io/papermc/paper/block/fluid/FluidData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..913acd58547d97cafc1466f6e2b3b4d22cf0b02d +--- /dev/null ++++ b/src/main/java/io/papermc/paper/block/fluid/FluidData.java +@@ -0,0 +1,68 @@ ++package io.papermc.paper.block.fluid; ++ ++import org.bukkit.Fluid; ++import org.bukkit.Location; ++import org.bukkit.util.Vector; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Range; ++ ++/** ++ * A representation of a fluid in a specific state of data. ++ * This type is not linked to a specific location and hence mostly resembles a {@link org.bukkit.block.data.BlockData}. ++ */ ++public interface FluidData extends Cloneable { ++ ++ /** ++ * Gets the fluid type of this fluid data. ++ * ++ * @return the fluid type ++ */ ++ @NotNull Fluid getFluidType(); ++ ++ /** ++ * Returns a copy of this FluidData. ++ * ++ * @return a copy of the fluid data ++ */ ++ @NotNull FluidData clone(); ++ ++ /** ++ * Computes the direction of the flow of the liquid at the given location as a vector. ++ * <p> ++ * This method requires the passed location's chunk to be loaded. ++ * If said chunk is not loaded when this method is called, the chunk will first be loaded prior to the computation ++ * which leads to a potentially slow sync chunk load. ++ * ++ * @param location - the location to check the liquid flow ++ * @return the flow direction vector at the given location ++ */ ++ @NotNull Vector computeFlowDirection(@NotNull Location location); ++ ++ /** ++ * Returns the level of liquid this fluid data holds. ++ * ++ * @return the amount as an integer, between 0 and 8 ++ */ ++ @Range(from = 0, to = 8) ++ int getLevel(); ++ ++ /** ++ * Computes the height of the fluid in the world. ++ * <p> ++ * This method requires the passed location's chunk to be loaded. ++ * If said chunk is not loaded when this method is called, the chunk will first be loaded prior to the computation ++ * which leads to a potentially slow sync chunk load. ++ * ++ * @param location the location at which to check the high of this fluid data. ++ * @return the height as a float value ++ */ ++ @Range(from = 0, to = 1) ++ float computeHeight(@NotNull Location location); ++ ++ /** ++ * Returns whether this fluid is a source block ++ * ++ * @return true if the fluid is a source block, false otherwise ++ */ ++ boolean isSource(); ++} +diff --git a/src/main/java/io/papermc/paper/block/fluid/type/FallingFluidData.java b/src/main/java/io/papermc/paper/block/fluid/type/FallingFluidData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7bd9f28ba646f09080b5c29b9d3be5af676c912e +--- /dev/null ++++ b/src/main/java/io/papermc/paper/block/fluid/type/FallingFluidData.java +@@ -0,0 +1,16 @@ ++package io.papermc.paper.block.fluid.type; ++ ++import io.papermc.paper.block.fluid.FluidData; ++ ++/** ++ * A specific subtype of {@link FluidData} that is returned by the API for fluid data of potentially falling fluids. ++ */ ++public interface FallingFluidData extends FluidData { ++ ++ /** ++ * Get if this liquid is falling. ++ * ++ * @return true if falling ++ */ ++ boolean isFalling(); ++} +diff --git a/src/main/java/io/papermc/paper/block/fluid/type/FlowingFluidData.java b/src/main/java/io/papermc/paper/block/fluid/type/FlowingFluidData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fbccdffe8d73e517204081c73bca9154f8c7d69f +--- /dev/null ++++ b/src/main/java/io/papermc/paper/block/fluid/type/FlowingFluidData.java +@@ -0,0 +1,10 @@ ++package io.papermc.paper.block.fluid.type; ++ ++import io.papermc.paper.block.fluid.FluidData; ++ ++/** ++ * A specific subtype of {@link FluidData} that is returned by the API for fluid data of potentially falling fluids. ++ */ ++public interface FlowingFluidData extends FallingFluidData { ++ ++} +diff --git a/src/main/java/org/bukkit/RegionAccessor.java b/src/main/java/org/bukkit/RegionAccessor.java +index 43dd6c59cceba12f27e6b265acc3ad97eea37abd..eb33e8e671972aa308ad75a7ce9aa9ac526f470f 100644 +--- a/src/main/java/org/bukkit/RegionAccessor.java ++++ b/src/main/java/org/bukkit/RegionAccessor.java +@@ -102,6 +102,41 @@ public interface RegionAccessor extends Keyed { // Paper + @NotNull + BlockState getBlockState(int x, int y, int z); + ++ // Paper start - FluidState API ++ /** ++ * Gets the {@link io.papermc.paper.block.fluid.FluidData} at the specified position. ++ * ++ * @param x The x-coordinate of the position ++ * @param y The y-coordinate of the position ++ * @param z The z-coordinate of the position ++ * @return The {@link io.papermc.paper.block.fluid.FluidData} at the specified position ++ */ ++ @NotNull ++ io.papermc.paper.block.fluid.FluidData getFluidData(int x, int y, int z); ++ ++ /** ++ * Gets the {@link io.papermc.paper.block.fluid.FluidData} at the given position ++ * ++ * @param position The position of the fluid ++ * @return The fluid data at the given position ++ */ ++ @NotNull ++ default io.papermc.paper.block.fluid.FluidData getFluidData(@NotNull io.papermc.paper.math.Position position) { ++ return getFluidData(position.blockX(), position.blockY(), position.blockZ()); ++ } ++ ++ /** ++ * Gets the {@link io.papermc.paper.block.fluid.FluidData} at the given position ++ * ++ * @param location The location of the fluid ++ * @return The fluid data at the given position ++ */ ++ @NotNull ++ default io.papermc.paper.block.fluid.FluidData getFluidData(@NotNull Location location) { ++ return getFluidData(location.blockX(), location.blockY(), location.blockZ()); ++ } ++ // Paper end ++ + /** + * Gets the {@link BlockData} at the given {@link Location}. + * diff --git a/patches/server/1046-Add-FluidState-API.patch b/patches/server/1046-Add-FluidState-API.patch new file mode 100644 index 0000000000..93e022238d --- /dev/null +++ b/patches/server/1046-Add-FluidState-API.patch @@ -0,0 +1,208 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: vicisacat <[email protected]> +Date: Fri, 17 Nov 2023 20:22:43 +0100 +Subject: [PATCH] Add FluidState API + + +diff --git a/src/main/java/io/papermc/paper/block/fluid/PaperFluidData.java b/src/main/java/io/papermc/paper/block/fluid/PaperFluidData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..479bc32241ebadf8bbc1080b601f61391ad37fa4 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/block/fluid/PaperFluidData.java +@@ -0,0 +1,110 @@ ++package io.papermc.paper.block.fluid; ++ ++import com.google.common.base.Preconditions; ++import io.papermc.paper.block.fluid.type.PaperFallingFluidData; ++import io.papermc.paper.block.fluid.type.PaperFlowingFluidData; ++import io.papermc.paper.util.MCUtil; ++import java.util.HashMap; ++import java.util.Map; ++import java.util.function.Function; ++import net.minecraft.world.level.material.FluidState; ++import net.minecraft.world.level.material.LavaFluid; ++import net.minecraft.world.level.material.WaterFluid; ++import org.bukkit.Fluid; ++import org.bukkit.Location; ++import org.bukkit.craftbukkit.CraftFluid; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.util.CraftVector; ++import org.bukkit.util.Vector; ++import org.jetbrains.annotations.NotNull; ++ ++public class PaperFluidData implements FluidData { ++ ++ private final FluidState state; ++ ++ protected PaperFluidData(final FluidState state) { ++ this.state = state; ++ } ++ ++ /** ++ * Provides the internal server representation of this fluid data. ++ * @return the fluid state. ++ */ ++ public FluidState getState() { ++ return this.state; ++ } ++ ++ @Override ++ public final @NotNull Fluid getFluidType() { ++ return CraftFluid.minecraftToBukkit(this.state.getType()); ++ } ++ ++ @Override ++ public @NotNull PaperFluidData clone() { ++ try { ++ return (PaperFluidData) super.clone(); ++ } catch (final CloneNotSupportedException ex) { ++ throw new AssertionError("Clone not supported", ex); ++ } ++ } ++ ++ @Override ++ public @NotNull Vector computeFlowDirection(final Location location) { ++ Preconditions.checkArgument(location.getWorld() != null, "Cannot compute flow direction on world-less location"); ++ return CraftVector.toBukkit(this.state.getFlow( ++ ((CraftWorld) location.getWorld()).getHandle(), ++ MCUtil.toBlockPosition(location) ++ )); ++ } ++ ++ @Override ++ public int getLevel() { ++ return this.state.getAmount(); ++ } ++ ++ @Override ++ public float computeHeight(@NotNull final Location location) { ++ Preconditions.checkArgument(location.getWorld() != null, "Cannot compute height on world-less location"); ++ return this.state.getHeight(((CraftWorld) location.getWorld()).getHandle(), MCUtil.toBlockPos(location)); ++ } ++ ++ @Override ++ public boolean isSource() { ++ return this.state.isSource(); ++ } ++ ++ @Override ++ public int hashCode() { ++ return this.state.hashCode(); ++ } ++ ++ @Override ++ public boolean equals(final Object obj) { ++ return obj instanceof final PaperFluidData paperFluidData && this.state.equals(paperFluidData.state); ++ } ++ ++ @Override ++ public String toString() { ++ return "PaperFluidData{" + this.state + "}"; ++ } ++ ++ /* Registry */ ++ private static final Map<Class<? extends net.minecraft.world.level.material.Fluid>, Function<FluidState, PaperFluidData>> MAP = new HashMap<>(); ++ static { ++ //<editor-fold desc="PaperFluidData Registration" defaultstate="collapsed"> ++ register(LavaFluid.Source.class, PaperFallingFluidData::new); ++ register(WaterFluid.Source.class, PaperFallingFluidData::new); ++ register(LavaFluid.Flowing.class, PaperFlowingFluidData::new); ++ register(WaterFluid.Flowing.class, PaperFlowingFluidData::new); ++ //</editor-fold> ++ } ++ ++ static void register(final Class<? extends net.minecraft.world.level.material.Fluid> fluid, final Function<FluidState, PaperFluidData> creator) { ++ Preconditions.checkState(MAP.put(fluid, creator) == null, "Duplicate mapping %s->%s", fluid, creator); ++ MAP.put(fluid, creator); ++ } ++ ++ public static PaperFluidData createData(final FluidState state) { ++ return MAP.getOrDefault(state.getType().getClass(), PaperFluidData::new).apply(state); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/block/fluid/package-info.java b/src/main/java/io/papermc/paper/block/fluid/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..cfabb814ebd281aab299c6c655266ff357e08806 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/block/fluid/package-info.java +@@ -0,0 +1,5 @@ ++@DefaultQualifier(NonNull.class) ++package io.papermc.paper.block.fluid; ++ ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; +diff --git a/src/main/java/io/papermc/paper/block/fluid/type/PaperFallingFluidData.java b/src/main/java/io/papermc/paper/block/fluid/type/PaperFallingFluidData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..655dbd83ff4e632f1168b75e9b402b05aa9d8edf +--- /dev/null ++++ b/src/main/java/io/papermc/paper/block/fluid/type/PaperFallingFluidData.java +@@ -0,0 +1,18 @@ ++ ++package io.papermc.paper.block.fluid.type; ++ ++import io.papermc.paper.block.fluid.PaperFluidData; ++import net.minecraft.world.level.material.FlowingFluid; ++import net.minecraft.world.level.material.FluidState; ++ ++public class PaperFallingFluidData extends PaperFluidData implements FallingFluidData { ++ ++ public PaperFallingFluidData(final FluidState state) { ++ super(state); ++ } ++ ++ @Override ++ public boolean isFalling() { ++ return this.getState().getValue(FlowingFluid.FALLING); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/block/fluid/type/PaperFlowingFluidData.java b/src/main/java/io/papermc/paper/block/fluid/type/PaperFlowingFluidData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c0c2805cb045cdd835b402776a6923fe2ecc2a99 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/block/fluid/type/PaperFlowingFluidData.java +@@ -0,0 +1,11 @@ ++package io.papermc.paper.block.fluid.type; ++ ++import net.minecraft.world.level.material.FluidState; ++ ++public class PaperFlowingFluidData extends PaperFallingFluidData implements FlowingFluidData { ++ ++ public PaperFlowingFluidData(final FluidState state) { ++ super(state); ++ } ++ ++} +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +index 9dd6012556979514f9879f867138bc836c58ef3f..1df2202277ab58d7de844f7bebc07e494a0ecdf3 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +@@ -107,6 +107,13 @@ public abstract class CraftRegionAccessor implements RegionAccessor { + return CraftBlock.at(this.getHandle(), new BlockPos(x, y, z)).getState(); + } + ++ // Paper start - FluidState API ++ @Override ++ public io.papermc.paper.block.fluid.FluidData getFluidData(final int x, final int y, final int z) { ++ return io.papermc.paper.block.fluid.PaperFluidData.createData(getHandle().getFluidState(new BlockPos(x, y, z))); ++ } ++ // Paper end ++ + @Override + public BlockData getBlockData(Location location) { + return this.getBlockData(location.getBlockX(), location.getBlockY(), location.getBlockZ()); +diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java +index ca9bb98ccfc3863c2ba538953470ab9e2b8a2f29..a2edef9739bad941f8e581da126bbfeac7cab5d8 100644 +--- a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java ++++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java +@@ -303,4 +303,11 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe + return centerChunkZ; + } + // Paper end - Add more LimitedRegion API ++ // Paper start - Fluid API ++ @Override ++ public io.papermc.paper.block.fluid.FluidData getFluidData(int x, int y, int z) { ++ Preconditions.checkArgument(this.isInRegion(x, y, z), "Coordinates %s, %s, %s are not in the region", x, y, z); ++ return super.getFluidData(x, y, z); ++ } ++ // Paper end + } |