aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSpottedleaf <[email protected]>2019-04-10 20:36:31 -0700
committerDaniel Ennis <[email protected]>2019-04-10 23:36:31 -0400
commit237250c08d805400105adb1ba342e4690a1d68ff (patch)
tree7c148d5491f03f6a018eebbfe75e49bee8ee1b8a
parent0181fb14b6b52052194e2ee30dea5744f14ffc73 (diff)
downloadPaper-237250c08d805400105adb1ba342e4690a1d68ff.tar.gz
Paper-237250c08d805400105adb1ba342e4690a1d68ff.zip
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
-rw-r--r--Spigot-API-Patches/0182-Add-Heightmap-API.patch161
-rw-r--r--Spigot-Server-Patches/0437-Add-Heightmap-API.patch54
2 files changed, 215 insertions, 0 deletions
diff --git a/Spigot-API-Patches/0182-Add-Heightmap-API.patch b/Spigot-API-Patches/0182-Add-Heightmap-API.patch
new file mode 100644
index 0000000000..ec46f777e9
--- /dev/null
+++ b/Spigot-API-Patches/0182-Add-Heightmap-API.patch
@@ -0,0 +1,161 @@
+From 61d8f2edbf9a488e035f6308d126794e3fda2d9c Mon Sep 17 00:00:00 2001
+From: Spottedleaf <[email protected]>
+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
+
diff --git a/Spigot-Server-Patches/0437-Add-Heightmap-API.patch b/Spigot-Server-Patches/0437-Add-Heightmap-API.patch
new file mode 100644
index 0000000000..8b06d16537
--- /dev/null
+++ b/Spigot-Server-Patches/0437-Add-Heightmap-API.patch
@@ -0,0 +1,54 @@
+From aae0b5f4b74ab34bbd6d0f3bcd5c34e78bcffabb Mon Sep 17 00:00:00 2001
+From: Spottedleaf <[email protected]>
+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
+