mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-29 07:48:53 +01:00
Add Heightmap API (#1724)
Resolves #1672 This API is intended to expose useful heightmaps found in the server to API. This exposes all of the live world heightmaps currently in the server. If a heightmap becomes impossible to implement, api spec allows the implementation to throw UnsupportedOperationException (far better than returning some weird unexpected value). Tested via: https://gist.github.com/Spottedleaf/5d47f67c55a9fb870251ff344bfeb6b3
This commit is contained in:
parent
0181fb14b6
commit
237250c08d
2 changed files with 215 additions and 0 deletions
161
Spigot-API-Patches/0182-Add-Heightmap-API.patch
Normal file
161
Spigot-API-Patches/0182-Add-Heightmap-API.patch
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
From 61d8f2edbf9a488e035f6308d126794e3fda2d9c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||||
|
Date: Sat, 1 Dec 2018 19:00:36 -0800
|
||||||
|
Subject: [PATCH] Add Heightmap API
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/main/java/com/destroystokyo/paper/HeightmapType.java b/src/main/java/com/destroystokyo/paper/HeightmapType.java
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..4cd9b5ed
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/HeightmapType.java
|
||||||
|
@@ -0,0 +1,35 @@
|
||||||
|
+package com.destroystokyo.paper;
|
||||||
|
+
|
||||||
|
+import org.bukkit.World;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Enumeration of different heightmap types maintained by the server. Generally using these maps is much faster
|
||||||
|
+ * than using an iterative search for a block in a given x, z coordinate.
|
||||||
|
+ */
|
||||||
|
+public enum HeightmapType {
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * The highest block used for lighting in the world. Also the block returned by {@link World#getHighestBlockYAt(int, int)}}
|
||||||
|
+ */
|
||||||
|
+ LIGHT_BLOCKING,
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * References the highest block in the world.
|
||||||
|
+ */
|
||||||
|
+ ANY,
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * References the highest solid block in a world.
|
||||||
|
+ */
|
||||||
|
+ SOLID,
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * References the highest solid or liquid block in a world.
|
||||||
|
+ */
|
||||||
|
+ SOLID_OR_LIQUID,
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * References the highest solid or liquid block in a world, excluding leaves.
|
||||||
|
+ */
|
||||||
|
+ SOLID_OR_LIQUID_NO_LEAVES;
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
|
||||||
|
index b4f3e8ce..b78b76f3 100644
|
||||||
|
--- a/src/main/java/org/bukkit/Location.java
|
||||||
|
+++ b/src/main/java/org/bukkit/Location.java
|
||||||
|
@@ -612,6 +612,33 @@ public class Location implements Cloneable, ConfigurationSerializable {
|
||||||
|
return centerLoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Paper start - Add heightmap api
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Returns a copy of this location except with y = getWorld().getHighestBlockYAt(this.getBlockX(), this.getBlockZ())
|
||||||
|
+ * @return A copy of this location except with y = getWorld().getHighestBlockYAt(this.getBlockX(), this.getBlockZ())
|
||||||
|
+ * @throws NullPointerException if {{@link #getWorld()}} is {@code null}
|
||||||
|
+ */
|
||||||
|
+ @NotNull
|
||||||
|
+ public Location toHighestLocation() {
|
||||||
|
+ return this.toHighestLocation(com.destroystokyo.paper.HeightmapType.LIGHT_BLOCKING);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Returns a copy of this location except with y = getWorld().getHighestBlockYAt(this.getBlockX(), this.getBlockZ(), heightmap)
|
||||||
|
+ * @param heightmap The heightmap to use for finding the highest y location.
|
||||||
|
+ * @return A copy of this location except with y = getWorld().getHighestBlockYAt(this.getBlockX(), this.getBlockZ(), heightmap)
|
||||||
|
+ * @throws NullPointerException if {{@link #getWorld()}} is {@code null}
|
||||||
|
+ * @throws UnsupportedOperationException if {@link World#getHighestBlockYAt(int, int, com.destroystokyo.paper.HeightmapType)} does not support the specified heightmap
|
||||||
|
+ */
|
||||||
|
+ @NotNull
|
||||||
|
+ public Location toHighestLocation(@NotNull final com.destroystokyo.paper.HeightmapType heightmap) {
|
||||||
|
+ final Location ret = this.clone();
|
||||||
|
+ ret.setY(this.getWorld().getHighestBlockYAt(this, heightmap));
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Creates explosion at this location with given power
|
||||||
|
*
|
||||||
|
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||||
|
index 3d8ff98a..4dc813f3 100644
|
||||||
|
--- a/src/main/java/org/bukkit/World.java
|
||||||
|
+++ b/src/main/java/org/bukkit/World.java
|
||||||
|
@@ -154,6 +154,68 @@ public interface World extends PluginMessageRecipient, Metadatable {
|
||||||
|
@NotNull
|
||||||
|
public Block getHighestBlockAt(@NotNull Location location);
|
||||||
|
|
||||||
|
+ // Paper start - Add heightmap API
|
||||||
|
+ /**
|
||||||
|
+ * Returns the highest block's y-coordinate at the specified block coordinates that match the specified heightmap's conditions.
|
||||||
|
+ * @param x The block's x-coordinate.
|
||||||
|
+ * @param z The block's z-coordinate.
|
||||||
|
+ * @param heightmap The specified heightmap to use. See {@link com.destroystokyo.paper.HeightmapType}
|
||||||
|
+ * @return The highest block's y-coordinate at (x, z) that matches the specified heightmap's conditions.
|
||||||
|
+ * @throws UnsupportedOperationException If the heightmap type is not supported.
|
||||||
|
+ * @implNote Implementations are recommended to use an iterative search as a fallback before resorting to
|
||||||
|
+ * throwing an {@code UnsupportedOperationException}.
|
||||||
|
+ * @see com.destroystokyo.paper.HeightmapType
|
||||||
|
+ */
|
||||||
|
+ public int getHighestBlockYAt(int x, int z, @NotNull com.destroystokyo.paper.HeightmapType heightmap) throws UnsupportedOperationException;
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Returns the highest block's y-coordinate at the specified block coordinates that match the specified heightmap's conditions.
|
||||||
|
+ * Note that the y-coordinate of the specified location is ignored.
|
||||||
|
+ * @param location The specified block coordinates.
|
||||||
|
+ * @param heightmap The specified heightmap to use. See {@link com.destroystokyo.paper.HeightmapType}
|
||||||
|
+ * @return The highest block's y-coordinate at {@code location} that matches the specified heightmap's conditions.
|
||||||
|
+ * @throws UnsupportedOperationException If the heightmap type is not supported.
|
||||||
|
+ * @implNote Implementations are recommended to use an iterative search as a fallback before resorting to
|
||||||
|
+ * throwing an {@code UnsupportedOperationException}.
|
||||||
|
+ * @see com.destroystokyo.paper.HeightmapType
|
||||||
|
+ */
|
||||||
|
+ default int getHighestBlockYAt(@NotNull Location location, @NotNull com.destroystokyo.paper.HeightmapType heightmap) throws UnsupportedOperationException {
|
||||||
|
+ return this.getHighestBlockYAt(location.getBlockX(), location.getBlockZ(), heightmap);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Returns the highest {@link Block} at the specified block coordinates that match the specified heightmap's conditions.
|
||||||
|
+ * @param x The block's x-coordinate.
|
||||||
|
+ * @param z The block's z-coordinate.
|
||||||
|
+ * @param heightmap The specified heightmap to use. See {@link com.destroystokyo.paper.HeightmapType}
|
||||||
|
+ * @return The highest {@link Block} at (x, z) that matches the specified heightmap's conditions.
|
||||||
|
+ * @throws UnsupportedOperationException If the heightmap type is not supported.
|
||||||
|
+ * @implNote Implementations are recommended to use an iterative search as a fallback before resorting to
|
||||||
|
+ * throwing an {@code UnsupportedOperationException}.
|
||||||
|
+ * @see com.destroystokyo.paper.HeightmapType
|
||||||
|
+ */
|
||||||
|
+ @NotNull
|
||||||
|
+ default Block getHighestBlockAt(int x, int z, @NotNull com.destroystokyo.paper.HeightmapType heightmap) throws UnsupportedOperationException {
|
||||||
|
+ return this.getBlockAt(x, this.getHighestBlockYAt(x, z, heightmap), z);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Returns the highest {@link Block} at the specified block coordinates that match the specified heightmap's conditions.
|
||||||
|
+ * Note that the y-coordinate of the specified location is ignored.
|
||||||
|
+ * @param location The specified block coordinates.
|
||||||
|
+ * @param heightmap The specified heightmap to use. See {@link com.destroystokyo.paper.HeightmapType}
|
||||||
|
+ * @return The highest {@link Block} at {@code location} that matches the specified heightmap's conditions.
|
||||||
|
+ * @throws UnsupportedOperationException If the heightmap type is not supported.
|
||||||
|
+ * @implNote Implementations are recommended to use an iterative search as a fallback before resorting to
|
||||||
|
+ * throwing an {@code UnsupportedOperationException}.
|
||||||
|
+ * @see com.destroystokyo.paper.HeightmapType
|
||||||
|
+ */
|
||||||
|
+ @NotNull
|
||||||
|
+ default Block getHighestBlockAt(@NotNull Location location, @NotNull com.destroystokyo.paper.HeightmapType heightmap) throws UnsupportedOperationException {
|
||||||
|
+ return this.getHighestBlockAt(location.getBlockX(), location.getBlockZ(), heightmap);
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Gets the {@link Chunk} at the given coordinates
|
||||||
|
*
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
54
Spigot-Server-Patches/0437-Add-Heightmap-API.patch
Normal file
54
Spigot-Server-Patches/0437-Add-Heightmap-API.patch
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
From aae0b5f4b74ab34bbd6d0f3bcd5c34e78bcffabb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||||
|
Date: Tue, 1 Jan 2019 02:22:01 -0800
|
||||||
|
Subject: [PATCH] Add Heightmap API
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||||
|
index b940f95bd..d20f6ac7e 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/World.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/World.java
|
||||||
|
@@ -720,6 +720,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ public final int getHighestBlockY(final HeightMap.Type heightmap, final int x, final int z) { return this.a(heightmap, x, z); } // Paper - OBFHELPER
|
||||||
|
public int a(HeightMap.Type heightmap_type, int i, int j) {
|
||||||
|
int k;
|
||||||
|
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||||
|
index 40ee34675..457aa5a3f 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||||
|
@@ -136,6 +136,28 @@ public class CraftWorld implements World {
|
||||||
|
return world.getHighestBlockYAt(HeightMap.Type.LIGHT_BLOCKING, new BlockPosition(x, 0, z)).getY();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Paper start - Implement heightmap api
|
||||||
|
+ @Override
|
||||||
|
+ public int getHighestBlockYAt(final int x, final int z, final com.destroystokyo.paper.HeightmapType heightmap) throws UnsupportedOperationException {
|
||||||
|
+ this.loadChunk(x >> 4, z >> 4); // heightmap will ret 0 on unloaded areas
|
||||||
|
+
|
||||||
|
+ switch (heightmap) {
|
||||||
|
+ case LIGHT_BLOCKING:
|
||||||
|
+ return this.world.getHighestBlockY(HeightMap.Type.LIGHT_BLOCKING, x, z);
|
||||||
|
+ case ANY:
|
||||||
|
+ return this.world.getHighestBlockY(HeightMap.Type.WORLD_SURFACE, x, z);
|
||||||
|
+ case SOLID:
|
||||||
|
+ return this.world.getHighestBlockY(HeightMap.Type.OCEAN_FLOOR, x, z);
|
||||||
|
+ case SOLID_OR_LIQUID:
|
||||||
|
+ return this.world.getHighestBlockY(HeightMap.Type.MOTION_BLOCKING, x, z);
|
||||||
|
+ case SOLID_OR_LIQUID_NO_LEAVES:
|
||||||
|
+ return this.world.getHighestBlockY(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, x, z);
|
||||||
|
+ default:
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
+
|
||||||
|
public Location getSpawnLocation() {
|
||||||
|
BlockPosition spawn = world.getSpawn();
|
||||||
|
return new Location(this, spawn.getX(), spawn.getY(), spawn.getZ());
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
Loading…
Reference in a new issue