From af57a5fed5e3b3f1dccc8b192f4795373bcf0faa Mon Sep 17 00:00:00 2001 From: searchndstroy Date: Fri, 17 Aug 2018 14:55:01 -0700 Subject: [PATCH] Allow Blocks to be accessed via a long key (#1335) The key can be retrieved via methods Location#toBlockKey() and Block#getBlockKey() World provides lookup for blocks by long key via method World#getBlockAtKey(long) The formatting for the key is as follows: 10 bit y|27 bit z|27 bit x The y value is considered unsigned while z and x are considered two's complement Y range: [0, 1023] X, Z range: [-67 108 864, 67 108 863] Checked encoding and decoding via https://gist.github.com/Spottedleaf/74f4e241012ca2fa67d8f1c7e8e34722 --- ...Blocks-to-be-accessed-via-a-long-key.patch | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 Spigot-API-Patches/0129-Allow-Blocks-to-be-accessed-via-a-long-key.patch diff --git a/Spigot-API-Patches/0129-Allow-Blocks-to-be-accessed-via-a-long-key.patch b/Spigot-API-Patches/0129-Allow-Blocks-to-be-accessed-via-a-long-key.patch new file mode 100644 index 000000000..a0ea5ecf4 --- /dev/null +++ b/Spigot-API-Patches/0129-Allow-Blocks-to-be-accessed-via-a-long-key.patch @@ -0,0 +1,116 @@ +From d0451b859e9ed348881ce7b9839cc44fce4e3d3a Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Tue, 14 Aug 2018 21:42:10 -0700 +Subject: [PATCH] Allow Blocks to be accessed via a long key + +The key can be retrieved via methods Location#toBlockKey() and +Block#getBlockKey() + +World provides lookup for blocks by long key via method World#getBlockAtKey(long) + +The formatting for the key is as follows: + +10 bit y|27 bit z|27 bit x + +The y value is considered unsigned while z and x are considered two's complement + +Y range: [0, 1023] +X, Z range: [-67 108 864, 67 108 863] + +diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java +index 253f0c2d..a457abcf 100644 +--- a/src/main/java/org/bukkit/Location.java ++++ b/src/main/java/org/bukkit/Location.java +@@ -10,7 +10,6 @@ import org.bukkit.util.Vector; + + // Paper start + import java.util.Collection; +-import java.util.Collections; + import java.util.function.Predicate; + import org.bukkit.entity.Entity; + import org.bukkit.entity.LivingEntity; +@@ -558,6 +557,18 @@ public class Location implements Cloneable, ConfigurationSerializable { + blockLoc.setZ(getBlockZ()); + return blockLoc; + } ++ ++ // Paper Start ++ ++ /** ++ * @return The block key for this location's block location. ++ * @see Block#getBlockKey() ++ */ ++ public long toBlockKey() { ++ return ((long)getBlockX() & 0x7FFFFFF) | (((long)getBlockZ() & 0x7FFFFFF) << 27) | ((long)getBlockY() << 54); ++ } ++ // Paper End ++ + /** + * @return A new location where X/Y/Z are the center of the block + */ +diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java +index 7b166b21..21c43dea 100644 +--- a/src/main/java/org/bukkit/World.java ++++ b/src/main/java/org/bukkit/World.java +@@ -76,6 +76,23 @@ public interface World extends PluginMessageRecipient, Metadatable { + */ + public Block getBlockAt(Location location); + ++ // Paper Start ++ /** ++ * Gets the {@link Block} at the given block key ++ * ++ * @param key The block key. See {@link Block#getBlockKey()} ++ * @return Block at the key ++ * @see Location#toBlockKey() ++ * @see Block#getBlockKey() ++ */ ++ public default Block getBlockAtKey(long key) { ++ int x = (int) ((key << 37) >> 37); ++ int y = (int) (key >>> 54); ++ int z = (int) ((key << 10) >> 37); ++ return getBlockAt(x, y, z); ++ } ++ // Paper End ++ + /** + * Gets the block type ID at the given coordinates + * +diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java +index 359b81f3..2dbc784c 100644 +--- a/src/main/java/org/bukkit/block/Block.java ++++ b/src/main/java/org/bukkit/block/Block.java +@@ -135,6 +135,30 @@ public interface Block extends Metadatable { + */ + int getZ(); + ++ // Paper Start ++ ++ /** ++ * Returns this block's coordinates packed into a long value ++ *

++ * The return value can be computed as follows: ++ *

++ * {@code long value = ((long)getX() & 0x7FFFFFF) | (((long)getZ() & 0x7FFFFFF) << 27) | ((long)getY() << 54);} ++ *

++ * And may be unpacked as follows: ++ *

++ * {@code int x = (int) ((packed << 37) >> 37);} ++ *

++ * {@code int y = (int) (packed >>> 54);} ++ *

++ * {@code int z = (int) ((packed << 10) >> 37);} ++ * ++ * @return This block's x, y, and z coordinates packed into a long value ++ */ ++ public default long getBlockKey() { ++ return ((long)getX() & 0x7FFFFFF) | (((long)getZ() & 0x7FFFFFF) << 27) | ((long)getY() << 54); ++ } ++ // Paper End ++ + /** + * Gets the Location of the block + * +-- +2.18.0 +