Skip to content

Commit 84b0fa3

Browse files
authored
Merge pull request #2536 from BentoBoxWorld/2534_new_island_scaling
2534 new island scaling
2 parents ca9c81e + 3d696e1 commit 84b0fa3

21 files changed

+848
-344
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
<!-- Do not change unless you want different name for local builds. -->
8989
<build.number>-LOCAL</build.number>
9090
<!-- This allows to change between versions. -->
91-
<build.version>2.6.0</build.version>
91+
<build.version>2.7.0</build.version>
9292
<sonar.organization>bentobox-world</sonar.organization>
9393
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
9494
<server.jars>${project.basedir}/lib</server.jars>

src/main/java/world/bentobox/bentobox/BentoBox.java

-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package world.bentobox.bentobox;
22

3-
import java.nio.file.Files;
4-
import java.nio.file.Path;
53
import java.util.List;
64
import java.util.Optional;
75

@@ -466,16 +464,6 @@ public boolean loadSettings() {
466464
return false;
467465
}
468466

469-
log("Saving default panels...");
470-
if (!Files.exists(Path.of(this.getDataFolder().getPath(), "panels", "island_creation_panel.yml"))) {
471-
log("Saving default island_creation_panel...");
472-
this.saveResource("panels/island_creation_panel.yml", false);
473-
}
474-
475-
if (!Files.exists(Path.of(this.getDataFolder().getPath(), "panels", "language_panel.yml"))) {
476-
log("Saving default language_panel...");
477-
this.saveResource("panels/language_panel.yml", false);
478-
}
479467
return true;
480468
}
481469

src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ private CompositeCommand getCommandFromArgs(String[] args) {
346346
*
347347
* @return IslandsManager
348348
*/
349-
protected IslandsManager getIslands() {
349+
public IslandsManager getIslands() {
350350
return plugin.getIslands();
351351
}
352352

src/main/java/world/bentobox/bentobox/api/commands/island/IslandGoCommand.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ public boolean canExecute(User user, String label, List<String> args) {
6161

6262
@Override
6363
public boolean execute(User user, String label, List<String> args) {
64+
Map<String, IslandInfo> names = getNameIslandMap(user);
6465
// Check if the home is known
6566
if (!args.isEmpty()) {
66-
Map<String, IslandInfo> names = getNameIslandMap(user);
6767
final String name = String.join(" ", args);
6868
if (!names.containsKey(name)) {
6969
// Failed home name check
@@ -113,7 +113,11 @@ public Optional<List<String>> tabComplete(User user, String alias, List<String>
113113

114114
}
115115

116-
private record IslandInfo(Island island, boolean islandName) {}
116+
/**
117+
* Record of islands and the name to type
118+
*/
119+
private record IslandInfo(Island island, boolean islandName) {
120+
}
117121

118122
private Map<String, IslandInfo> getNameIslandMap(User user) {
119123
Map<String, IslandInfo> islandMap = new HashMap<>();
@@ -129,7 +133,8 @@ private Map<String, IslandInfo> getNameIslandMap(User user) {
129133
islandMap.put(text, new IslandInfo(island, true));
130134
}
131135
// Add homes. Homes do not need an island specified
132-
island.getHomes().keySet().forEach(n -> islandMap.put(n, new IslandInfo(island, false)));
136+
island.getHomes().keySet().stream().filter(n -> !n.isBlank())
137+
.forEach(n -> islandMap.put(n, new IslandInfo(island, false)));
133138
}
134139

135140
return islandMap;
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
package world.bentobox.bentobox.api.commands.island;
22

3-
import java.util.ArrayList;
43
import java.util.List;
5-
import java.util.Optional;
64

75
import world.bentobox.bentobox.api.commands.CompositeCommand;
8-
import world.bentobox.bentobox.api.commands.ConfirmableCommand;
9-
import world.bentobox.bentobox.api.localization.TextVariables;
106
import world.bentobox.bentobox.api.user.User;
11-
import world.bentobox.bentobox.database.objects.Island;
12-
import world.bentobox.bentobox.util.Util;
7+
import world.bentobox.bentobox.panels.customizable.IslandHomesPanel;
138

14-
public class IslandHomesCommand extends ConfirmableCommand {
15-
16-
private List<Island> islands;
9+
public class IslandHomesCommand extends CompositeCommand {
1710

1811
public IslandHomesCommand(CompositeCommand islandCommand) {
1912
super(islandCommand, "homes");
@@ -28,9 +21,8 @@ public void setup() {
2821

2922
@Override
3023
public boolean canExecute(User user, String label, List<String> args) {
31-
islands = getIslands().getIslands(getWorld(), user);
3224
// Check island
33-
if (islands.isEmpty()) {
25+
if (getIslands().getIslands(getWorld(), user).isEmpty()) {
3426
user.sendMessage("general.errors.no-island");
3527
return false;
3628
}
@@ -39,22 +31,8 @@ public boolean canExecute(User user, String label, List<String> args) {
3931

4032
@Override
4133
public boolean execute(User user, String label, List<String> args) {
42-
user.sendMessage("commands.island.sethome.homes-are");
43-
islands.forEach(island ->
44-
island.getHomes().keySet().stream().filter(s -> !s.isEmpty())
45-
.forEach(s -> user.sendMessage("commands.island.sethome.home-list-syntax", TextVariables.NAME, s)));
34+
IslandHomesPanel.openPanel(this, user);
4635
return true;
4736
}
4837

49-
@Override
50-
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
51-
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
52-
List<String> result = new ArrayList<>();
53-
for (Island island : getIslands().getIslands(getWorld(), user.getUniqueId())) {
54-
result.addAll(island.getHomes().keySet());
55-
}
56-
return Optional.of(Util.tabLimit(result, lastArg));
57-
58-
}
59-
6038
}

src/main/java/world/bentobox/bentobox/api/panels/TemplatedPanel.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,8 @@ ItemSlot nextItemSlot() {
362362
* this button is present.
363363
*
364364
* @return Map that links button type to amount in the gui.
365-
* @deprecated Use {@link #amount(String)} instead.
365+
* Use {@link #amount(String)} instead.
366366
*/
367-
@Deprecated
368367
public Map<String, Integer> amountMap() {
369368
return this.parentPanel.typeSlotMap;
370369
}

src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java

+19-5
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,29 @@ public static PanelTemplateRecord readTemplatePanel(@NonNull String panelName, @
9090
}
9191

9292
File file = new File(panelLocation, templateName.endsWith(YML) ? templateName : templateName + YML);
93-
93+
String absolutePath = file.getAbsolutePath();
9494
if (!file.exists())
9595
{
96-
BentoBox.getInstance().logError(file.getAbsolutePath() + " does not exist for panel template");
97-
// Return as file does not exist.
98-
return null;
96+
// Try to get it from the JAR
97+
98+
String keyword = "panels/";
99+
100+
// Find the index of the keyword "panels/"
101+
int index = absolutePath.indexOf(keyword);
102+
103+
// If the keyword is found, extract the substring starting from that index
104+
if (index != -1) {
105+
BentoBox.getInstance().saveResource(absolutePath.substring(index), false);
106+
file = new File(panelLocation, templateName.endsWith(YML) ? templateName : templateName + YML);
107+
} else {
108+
BentoBox.getInstance().logError(file.getAbsolutePath() + " does not exist for panel template");
109+
// Return as file does not exist.
110+
return null;
111+
}
112+
99113
}
100114

101-
final String panelKey = file.getAbsolutePath() + ":" + panelName;
115+
final String panelKey = absolutePath + ":" + panelName;
102116

103117
// Check if panel is already crafted.
104118
if (TemplateReader.loadedPanels.containsKey(panelKey))

src/main/java/world/bentobox/bentobox/managers/IslandsManager.java

+4
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,10 @@ public Optional<Island> getIslandAt(@NonNull Location location) {
442442
: Optional.empty();
443443
}
444444

445+
public boolean isIslandAt(@NonNull Location location) {
446+
return plugin.getIWM().inWorld(location) ? islandCache.isIslandAt(location) : false;
447+
}
448+
445449
/**
446450
* Returns an <strong>unmodifiable collection</strong> of all existing islands
447451
* (even those who may be unowned).

src/main/java/world/bentobox/bentobox/managers/island/DefaultNewIslandLocationStrategy.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ public Location getNextLocation(World world) {
7474
*/
7575
protected Result isIsland(Location location) {
7676
// Quick check
77-
if (plugin.getIslands().getIslandAt(location).isPresent()) return Result.ISLAND_FOUND;
77+
if (plugin.getIslands().isIslandAt(location)) {
78+
return Result.ISLAND_FOUND;
79+
}
7880

7981
World world = location.getWorld();
8082

src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java

+17
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,23 @@ public void setPrimaryIsland(@NonNull UUID uuid, @NonNull Island island) {
257257
}
258258
}
259259

260+
/**
261+
* Returns if there is island at the location. This includes
262+
* the full island space, not just the protected area.
263+
* Does not cause a database load of the island.
264+
*
265+
* @param location the location
266+
* @return true if there is an island there
267+
*/
268+
@Nullable
269+
public boolean isIslandAt(@NonNull Location location) {
270+
World w = Util.getWorld(location.getWorld());
271+
if (w == null || !grids.containsKey(w)) {
272+
return false;
273+
}
274+
return grids.get(w).isIslandAt(location.getBlockX(), location.getBlockZ());
275+
}
276+
260277
/**
261278
* Returns the island at the location or null if there is none. This includes
262279
* the full island space, not just the protected area

src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java

+53-24
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.util.Map.Entry;
44
import java.util.TreeMap;
55

6+
import org.eclipse.jdt.annotation.Nullable;
7+
68
import world.bentobox.bentobox.database.objects.Island;
79

810
/**
@@ -11,7 +13,11 @@
1113
*
1214
*/
1315
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<>();
1521
private final IslandCache im;
1622

1723
/**
@@ -29,25 +35,28 @@ public IslandGrid(IslandCache im) {
2935
*/
3036
public boolean addToGrid(Island island) {
3137
// 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(), minX, 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())) {
3645
// If it is the same island then it's okay
3746
return true;
3847
}
3948
// Island overlap, report error
4049
return false;
4150
} else {
4251
// 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);
4554
}
4655
} else {
4756
// 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);
5160
}
5261
return true;
5362
}
@@ -60,7 +69,7 @@ public boolean addToGrid(Island island) {
6069
public boolean removeFromGrid(Island island) {
6170
String id = island.getUniqueId();
6271
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)));
6473

6574
grid.values().removeIf(TreeMap::isEmpty);
6675

@@ -70,35 +79,55 @@ public boolean removeFromGrid(Island island) {
7079
/**
7180
* Retrieves the island located at the specified x and z coordinates, covering both the protected area
7281
* 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.
7383
*
7484
* @param x the x coordinate of the location
7585
* @param z the z coordinate of the location
7686
* @return the Island at the specified location, or null if no island is found
7787
*/
7888
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 here 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) {
79115
// 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);
81117
if (xEntry == null) {
82118
return null; // No x-coordinate entry found, return null
83119
}
84120

85121
// 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);
87123
if (zEntry == null) {
88124
return null; // No z-coordinate entry found, return null
89125
}
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-
}
96126
// 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();
99130
}
100-
101-
// Coordinates are outside the island space, return null
102131
return null;
103132
}
104133

@@ -107,7 +136,7 @@ public Island getIslandAt(int x, int z) {
107136
*/
108137
public long getSize() {
109138
long count = 0;
110-
for (TreeMap<Integer, String> innerMap : grid.values()) {
139+
for (TreeMap<Integer, IslandData> innerMap : grid.values()) {
111140
count += innerMap.size();
112141
}
113142
return count;

0 commit comments

Comments
 (0)