3
3
import java .util .Map .Entry ;
4
4
import java .util .TreeMap ;
5
5
6
+ import org .eclipse .jdt .annotation .Nullable ;
7
+
6
8
import world .bentobox .bentobox .database .objects .Island ;
7
9
8
10
/**
11
13
*
12
14
*/
13
15
class IslandGrid {
14
- private final TreeMap <Integer , TreeMap <Integer , String >> grid = new TreeMap <>();
16
+
17
+ private record IslandData (String id , int minX , int minZ , int range ) {
18
+ }
19
+
20
+ private final TreeMap <Integer , TreeMap <Integer , IslandData >> grid = new TreeMap <>();
15
21
private final IslandCache im ;
16
22
17
23
/**
@@ -29,25 +35,28 @@ public IslandGrid(IslandCache im) {
29
35
*/
30
36
public boolean addToGrid (Island island ) {
31
37
// Check if we know about this island already
32
- if (grid .containsKey (island .getMinX ())) {
33
- TreeMap <Integer , String > zEntry = grid .get (island .getMinX ());
34
- if (zEntry .containsKey (island .getMinZ ())) {
35
- if (island .getUniqueId ().equals (zEntry .get (island .getMinZ ()))) {
38
+ int minX = island .getMinX ();
39
+ int minZ = island .getMinZ ();
40
+ IslandData islandData = new IslandData (island .getUniqueId (), minZ , minZ , island .getRange ());
41
+ if (grid .containsKey (minX )) {
42
+ TreeMap <Integer , IslandData > zEntry = grid .get (minX );
43
+ if (zEntry .containsKey (minZ )) {
44
+ if (island .getUniqueId ().equals (zEntry .get (minZ ).id ())) {
36
45
// If it is the same island then it's okay
37
46
return true ;
38
47
}
39
48
// Island overlap, report error
40
49
return false ;
41
50
} else {
42
51
// Add island
43
- zEntry .put (island . getMinZ (), island . getUniqueId () );
44
- grid .put (island . getMinX () , zEntry );
52
+ zEntry .put (minZ , islandData );
53
+ grid .put (minX , zEntry );
45
54
}
46
55
} else {
47
56
// Add island
48
- TreeMap <Integer , String > zEntry = new TreeMap <>();
49
- zEntry .put (island . getMinZ (), island . getUniqueId () );
50
- grid .put (island . getMinX () , zEntry );
57
+ TreeMap <Integer , IslandData > zEntry = new TreeMap <>();
58
+ zEntry .put (minZ , islandData );
59
+ grid .put (minX , zEntry );
51
60
}
52
61
return true ;
53
62
}
@@ -60,7 +69,7 @@ public boolean addToGrid(Island island) {
60
69
public boolean removeFromGrid (Island island ) {
61
70
String id = island .getUniqueId ();
62
71
boolean removed = grid .values ().stream ()
63
- .anyMatch (innerMap -> innerMap .values ().removeIf (innerValue -> innerValue .equals (id )));
72
+ .anyMatch (innerMap -> innerMap .values ().removeIf (innerValue -> innerValue .id (). equals (id )));
64
73
65
74
grid .values ().removeIf (TreeMap ::isEmpty );
66
75
@@ -70,35 +79,55 @@ public boolean removeFromGrid(Island island) {
70
79
/**
71
80
* Retrieves the island located at the specified x and z coordinates, covering both the protected area
72
81
* and the full island space. Returns null if no island exists at the given location.
82
+ * This will load the island from the database if it is not in the cache.
73
83
*
74
84
* @param x the x coordinate of the location
75
85
* @param z the z coordinate of the location
76
86
* @return the Island at the specified location, or null if no island is found
77
87
*/
78
88
public Island getIslandAt (int x , int z ) {
89
+ String id = getIslandStringAt (x , z );
90
+ if (id == null ) {
91
+ return null ;
92
+ }
93
+
94
+ // Retrieve the island using the id found - loading from database if required
95
+ return im .getIslandById (id );
96
+ }
97
+
98
+ /**
99
+ * Checks if an island is at this coordinate or not
100
+ * @param x coord
101
+ * @param z coord
102
+ * @return true if there is an island registered in the grid
103
+ */
104
+ public boolean isIslandAt (int x , int z ) {
105
+ return getIslandStringAt (x , z ) != null ;
106
+ }
107
+
108
+ /**
109
+ * Get the island ID string for an island at this coordinates, or null if none.
110
+ * @param x coord
111
+ * @param z coord
112
+ * @return Unique Island ID string, or null if there is no island here.
113
+ */
114
+ public @ Nullable String getIslandStringAt (int x , int z ) {
79
115
// Attempt to find the closest x-coordinate entry that does not exceed 'x'
80
- Entry <Integer , TreeMap <Integer , String >> xEntry = grid .floorEntry (x );
116
+ Entry <Integer , TreeMap <Integer , IslandData >> xEntry = grid .floorEntry (x );
81
117
if (xEntry == null ) {
82
118
return null ; // No x-coordinate entry found, return null
83
119
}
84
120
85
121
// Attempt to find the closest z-coordinate entry that does not exceed 'z' within the found x-coordinate
86
- Entry <Integer , String > zEntry = xEntry .getValue ().floorEntry (z );
122
+ Entry <Integer , IslandData > zEntry = xEntry .getValue ().floorEntry (z );
87
123
if (zEntry == null ) {
88
124
return null ; // No z-coordinate entry found, return null
89
125
}
90
-
91
- // Retrieve the island using the id found in the z-coordinate entry
92
- Island island = im .getIslandById (zEntry .getValue ());
93
- if (island == null ) {
94
- return null ; // No island found by the id, return null
95
- }
96
126
// Check if the specified coordinates are within the island space
97
- if (island .inIslandSpace (x , z )) {
98
- return island ; // Coordinates are within island space, return the island
127
+ if (x >= zEntry .getValue ().minX () && x < zEntry .getValue ().minX () + zEntry .getValue ().range () * 2
128
+ && z >= zEntry .getValue ().minZ () && z < zEntry .getValue ().minZ () + zEntry .getValue ().range () * 2 ) {
129
+ return zEntry .getValue ().id ();
99
130
}
100
-
101
- // Coordinates are outside the island space, return null
102
131
return null ;
103
132
}
104
133
@@ -107,7 +136,7 @@ public Island getIslandAt(int x, int z) {
107
136
*/
108
137
public long getSize () {
109
138
long count = 0 ;
110
- for (TreeMap <Integer , String > innerMap : grid .values ()) {
139
+ for (TreeMap <Integer , IslandData > innerMap : grid .values ()) {
111
140
count += innerMap .size ();
112
141
}
113
142
return count ;
0 commit comments