aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorviciscat <[email protected]>2024-02-17 21:44:03 +0100
committerGitHub <[email protected]>2024-02-17 15:44:03 -0500
commitd95341e44a8ba027af80547a44300617f314e548 (patch)
tree56cb47b2195557e1f9c338aecc405f6c6a78a087
parent1964b224398de7f51f56035420a33301d3ec027a (diff)
downloadPaper-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.patch164
-rw-r--r--patches/server/1046-Add-FluidState-API.patch208
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
+ }