From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 1 Dec 2018 19:00:36 -0800 Subject: [PATCH] Add Heightmap API Changed to use upstream's heightmap API - Machine_Maker 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 0000000000000000000000000000000000000000..1c832d69bb3717dcfccf21e45f6f060a64eb4f11 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/HeightmapType.java @@ -0,0 +1,39 @@ +package com.destroystokyo.paper; + +import org.jetbrains.annotations.ApiStatus; + +/** + * 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. + * + * @deprecated Upstream has added their own API for using the game heightmaps. See {@link org.bukkit.HeightMap} and the + * non-deprecated getHighestBlock methods on World such as {@link org.bukkit.World#getHighestBlockAt(org.bukkit.Location, org.bukkit.HeightMap)}. + */ +@Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") +public enum HeightmapType { + + /** + * The highest block used for lighting in the world. Also the block returned by {@link org.bukkit.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 2b9a117804a8ca54b47e51e23359bd6e01087641..1a60a18e15780128a1914826daa952ffacb92e9e 100644 --- a/src/main/java/org/bukkit/Location.java +++ b/src/main/java/org/bukkit/Location.java @@ -640,6 +640,47 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm 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(HeightMap.WORLD_SURFACE); + } + + /** + * 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 + * @deprecated Use {@link org.bukkit.Location#toHighestLocation(HeightMap)} + */ + @NotNull + @Deprecated(forRemoval = true) @org.jetbrains.annotations.ApiStatus.ScheduledForRemoval(inVersion = "1.21") + public Location toHighestLocation(@NotNull final com.destroystokyo.paper.HeightmapType heightmap) { + final Location ret = this.clone(); + ret.setY(this.getWorld().getHighestBlockYAt(this, heightmap)); + return ret; + } + + /** + * 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) + */ + @NotNull + public Location toHighestLocation(@NotNull final HeightMap 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 31fc272b0e82e4eef6d9bf01dd25d39513d354b3..0c5ce79c04e8193db248a221f519d80a944ef6ba 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -150,6 +150,87 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient @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. + *

+ * implNote: Implementations are recommended to use an iterative search as a fallback before resorting to + * throwing an {@code UnsupportedOperationException}. + *

+ * + * @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. + * @deprecated Upstream has added support for this, use {@link World#getHighestBlockYAt(int, int, HeightMap)} + * + * @see com.destroystokyo.paper.HeightmapType + */ + @Deprecated(forRemoval = true) @org.jetbrains.annotations.ApiStatus.ScheduledForRemoval(inVersion = "1.21") + 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. + *

+ * implNote: Implementations are recommended to use an iterative search as a fallback before resorting to + * throwing an {@code UnsupportedOperationException}. + *

+ * + * @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. + * @deprecated Upstream has added support for this, use {@link World#getHighestBlockYAt(Location, HeightMap)} + * @see com.destroystokyo.paper.HeightmapType + */ + @Deprecated(forRemoval = true) @org.jetbrains.annotations.ApiStatus.ScheduledForRemoval(inVersion = "1.21") + 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. + *

+ * implNote: Implementations are recommended to use an iterative search as a fallback before resorting to + * throwing an {@code UnsupportedOperationException}. + *

+ * @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. + * @deprecated Upstream has added support for this, use {@link World#getHighestBlockAt(int, int, HeightMap)} + * @see com.destroystokyo.paper.HeightmapType + */ + @Deprecated(forRemoval = true) @org.jetbrains.annotations.ApiStatus.ScheduledForRemoval(inVersion = "1.21") + @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. + *

+ * implNote: Implementations are recommended to use an iterative search as a fallback before resorting to + * throwing an {@code UnsupportedOperationException}. + *

+ * @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. + * @deprecated Upstream has added support for this, use {@link World#getHighestBlockAt(Location, HeightMap)} + * @see com.destroystokyo.paper.HeightmapType + */ + @Deprecated(forRemoval = true) @org.jetbrains.annotations.ApiStatus.ScheduledForRemoval(inVersion = "1.21") + @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 highest block corresponding to the {@link HeightMap} at the * given coordinates.