mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 15:30:19 +01:00
FluidState API (#9951)
* Add new FluidState API functionality --------- Co-authored-by: Bjarne Koll <git@lynxplay.dev> Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
This commit is contained in:
parent
2d6b2baf34
commit
c4731d1330
2 changed files with 372 additions and 0 deletions
164
patches/api/Add-FluidState-API.patch
Normal file
164
patches/api/Add-FluidState-API.patch
Normal file
|
@ -0,0 +1,164 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: vicisacat <victor.branchu@gmail.com>
|
||||
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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/block/fluid/FluidData.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/block/fluid/type/FallingFluidData.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/block/fluid/type/FlowingFluidData.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/RegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/RegionAccessor.java
|
||||
@@ -0,0 +0,0 @@ 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}.
|
||||
*
|
208
patches/server/Add-FluidState-API.patch
Normal file
208
patches/server/Add-FluidState-API.patch
Normal file
|
@ -0,0 +1,208 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: vicisacat <victor.branchu@gmail.com>
|
||||
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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/block/fluid/PaperFluidData.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/block/fluid/package-info.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+@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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/block/fluid/type/PaperFallingFluidData.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/block/fluid/type/PaperFlowingFluidData.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
}
|
Loading…
Reference in a new issue