aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-API-Patches/0129-Allow-Blocks-to-be-accessed-via-a-long-key.patch
blob: 715caeba8820324d906dfe56b1f2ba4d3fca2061 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
From 95832fe51208a8832ea7aa293c95720a4eb7ade3 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
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 8dcb15fb8..7e1ee875e 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 9b46e8892..a6facc4b0 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -76,6 +76,37 @@ 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);
+    }
+    /**
+     * Gets the {@link Location} at the given block key
+     *
+     * @param key The block key. See {@link Location#toBlockKey()}
+     * @return Location at the key
+     * @see Location#toBlockKey()
+     * @see Block#getBlockKey()
+     */
+    public default Location getLocationAtKey(long key) {
+        int x = (int) ((key << 37) >> 37);
+        int y = (int) (key >>> 54);
+        int z = (int) ((key << 10) >> 37);
+        return new Location(this, 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 359b81f31..2dbc784cb 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
+     * <p></p>
+     * The return value can be computed as follows:
+     * <p></p>
+     * {@code long value = ((long)getX() & 0x7FFFFFF) | (((long)getZ() & 0x7FFFFFF) << 27) | ((long)getY() << 54);}
+     * <p></p>
+     * And may be unpacked as follows:
+     * <p></p>
+     * {@code int x = (int) ((packed << 37) >> 37);}
+     * <p></p>
+     * {@code int y = (int) (packed >>> 54);}
+     * <p></p>
+     * {@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