Skip to content

Commit 3179732

Browse files
authored
Merge pull request #398 from BentoBoxWorld/389_nexo_support
Add Nexo custom block and furniture support for island levelling
2 parents ff0e8ee + 6b224dc commit 3179732

File tree

5 files changed

+105
-6
lines changed

5 files changed

+105
-6
lines changed

pom.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@
171171
<name>Oraxen Repository</name>
172172
<url>https://repo.oraxen.com/releases</url>
173173
</repository>
174+
<!-- Nexo repo -->
175+
<repository>
176+
<id>nexo</id>
177+
<name>Nexo Repository</name>
178+
<url>https://repo.nexomc.com/releases</url>
179+
</repository>
174180
</repositories>
175181

176182
<dependencies>
@@ -277,6 +283,19 @@
277283
<version>4.0.10</version>
278284
<scope>provided</scope>
279285
</dependency>
286+
<!-- Nexo -->
287+
<dependency>
288+
<groupId>com.nexomc</groupId>
289+
<artifactId>nexo</artifactId>
290+
<version>1.19.1</version>
291+
<exclusions>
292+
<exclusion>
293+
<groupId>dev.triumphteam</groupId>
294+
<artifactId>triumph-gui</artifactId>
295+
</exclusion>
296+
</exclusions>
297+
<scope>provided</scope>
298+
</dependency>
280299
<!-- Oraxen -->
281300
<dependency>
282301
<groupId>io.th0rgal</groupId>

src/main/java/world/bentobox/level/Level.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,4 +488,12 @@ public boolean isItemsAdder() {
488488
return !getSettings().isDisableItemsAdder() && getPlugin().getHooks().getHook("ItemsAdder").isPresent();
489489
}
490490

491+
/**
492+
* @return true if the Nexo plugin is enabled and not disabled in config
493+
*/
494+
public boolean isNexo() {
495+
return !getSettings().getDisabledPluginHooks().contains("Nexo")
496+
&& Bukkit.getPluginManager().isPluginEnabled("Nexo");
497+
}
498+
491499
}

src/main/java/world/bentobox/level/calculators/IslandLevelCalculator.java

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
import com.google.common.collect.Multiset;
4444
import com.google.common.collect.Multiset.Entry;
4545
import com.google.common.collect.Multisets;
46+
import com.nexomc.nexo.api.NexoBlocks;
47+
import com.nexomc.nexo.api.NexoFurniture;
48+
import com.nexomc.nexo.api.NexoItems;
49+
import com.nexomc.nexo.mechanics.custom_block.CustomBlockMechanic;
4650

4751
import dev.rosewood.rosestacker.api.RoseStackerAPI;
4852
import us.lynuxcraft.deadsilenceiv.advancedchests.AdvancedChestsAPI;
@@ -426,7 +430,19 @@ private void countItemStack(ItemStack i) {
426430
}
427431
return;
428432
}
429-
433+
// Check Nexo
434+
if (addon.isNexo() && NexoItems.exists(i)) {
435+
String id = NexoItems.idFromItem(i);
436+
if (id == null) {
437+
return;
438+
}
439+
id = "nexo:" + id;
440+
for (int c = 0; c < i.getAmount(); c++) {
441+
checkBlock(id, false);
442+
}
443+
return;
444+
}
445+
430446
if (i == null || !i.getType().isBlock())
431447
return;
432448

@@ -477,8 +493,8 @@ record ChunkPair(World world, Chunk chunk, ChunkSnapshot chunkSnapshot) {
477493
}
478494

479495
private void scanAsync(ChunkPair cp) {
480-
// Track chunks for Oraxen furniture entity scanning (done on main thread later)
481-
if (BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) {
496+
// Track chunks for furniture entity scanning (Oraxen and Nexo are entity-based)
497+
if (BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent() || addon.isNexo()) {
482498
furnitureChunks.add(cp.chunk);
483499
}
484500
// Get the chunk coordinates and island boundaries once per chunk scan
@@ -526,10 +542,11 @@ private void processBlock(ChunkPair cp, int x, int y, int z, int globalX, int gl
526542
// Create a Location object only when needed for more complex checks.
527543
Location loc = null;
528544

529-
// === Custom Block Hooks (ItemsAdder, Oraxen) ===
545+
// === Custom Block Hooks (ItemsAdder, Oraxen, Nexo) ===
530546
// These hooks can define custom blocks that override vanilla behavior.
531547
// They must be checked first.
532-
if (addon.isItemsAdder() || BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) {
548+
if (addon.isItemsAdder() || BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()
549+
|| addon.isNexo()) {
533550
loc = new Location(cp.world, globalX, y, globalZ);
534551
String customBlockId = null;
535552
if (addon.isItemsAdder()) {
@@ -541,6 +558,12 @@ private void processBlock(ChunkPair cp, int x, int y, int z, int globalX, int gl
541558
customBlockId = "oraxen:" + oraxenId; // Make a namespaced ID
542559
}
543560
}
561+
if (customBlockId == null && addon.isNexo()) {
562+
CustomBlockMechanic nexoMechanic = NexoBlocks.customBlockMechanic(loc);
563+
if (nexoMechanic != null) {
564+
customBlockId = "nexo:" + nexoMechanic.getItemID();
565+
}
566+
}
544567

545568
if (customBlockId != null) {
546569
// If a custom block is found, count it and stop further processing for this block.
@@ -750,6 +773,7 @@ public void scanIsland(Pipeliner pipeliner) {
750773
// This was the last chunk. Handle stacked blocks, spawners, chests and exit
751774
handleStackedBlocks().thenCompose(v -> handleSpawners()).thenCompose(v -> handleChests())
752775
.thenCompose(v -> handleOraxenFurniture())
776+
.thenCompose(v -> handleNexoFurniture())
753777
.thenRun(() -> {
754778
this.tidyUp();
755779
this.getR().complete(getResults());
@@ -822,7 +846,7 @@ private CompletableFuture<Void> handleOraxenFurniture() {
822846
|| loc.getBlockZ() < minZ || loc.getBlockZ() >= maxZ) {
823847
continue;
824848
}
825-
FurnitureMechanic mechanic = OraxenHook.getFurnitureMechanic(entity);
849+
var mechanic = OraxenHook.getFurnitureMechanic(entity);
826850
if (mechanic == null) {
827851
continue;
828852
}
@@ -835,6 +859,47 @@ private CompletableFuture<Void> handleOraxenFurniture() {
835859
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
836860
}
837861

862+
/**
863+
* Scans entities in each island chunk for Nexo furniture and counts them toward the island level.
864+
* Nexo furniture is entity-based (ItemDisplay entities), so it is invisible to the normal block
865+
* scanner. Only entities for which a FurnitureMechanic can be resolved are counted, which
866+
* naturally filters to base furniture entities.
867+
*
868+
* @return a CompletableFuture that completes when all chunks have been checked
869+
*/
870+
private CompletableFuture<Void> handleNexoFurniture() {
871+
if (!addon.isNexo() || furnitureChunks.isEmpty()) {
872+
return CompletableFuture.completedFuture(null);
873+
}
874+
int minX = island.getMinProtectedX();
875+
int maxX = island.getMaxProtectedX();
876+
int minZ = island.getMinProtectedZ();
877+
int maxZ = island.getMaxProtectedZ();
878+
List<CompletableFuture<Void>> futures = new ArrayList<>();
879+
for (Chunk chunk : furnitureChunks) {
880+
CompletableFuture<Void> future = Util.getChunkAtAsync(chunk.getWorld(), chunk.getX(), chunk.getZ())
881+
.thenAccept(c -> {
882+
for (Entity entity : c.getEntities()) {
883+
Location loc = entity.getLocation();
884+
// Confirm entity is within the island's protected bounds
885+
if (loc.getBlockX() < minX || loc.getBlockX() >= maxX
886+
|| loc.getBlockZ() < minZ || loc.getBlockZ() >= maxZ) {
887+
continue;
888+
}
889+
// getFurnitureMechanic returns non-null only for furniture base entities
890+
var mechanic = NexoFurniture.furnitureMechanic(entity);
891+
if (mechanic == null) {
892+
continue;
893+
}
894+
boolean belowSeaLevel = seaHeight > 0 && loc.getBlockY() <= seaHeight;
895+
checkBlock("nexo:" + mechanic.getItemID(), belowSeaLevel);
896+
}
897+
});
898+
futures.add(future);
899+
}
900+
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
901+
}
902+
838903
private CompletableFuture<Void> handleStackedBlocks() {
839904
// Deal with any stacked blocks
840905
List<CompletableFuture<Void>> futures = new ArrayList<>();

src/main/java/world/bentobox/level/config/BlockConfig.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import org.bukkit.configuration.file.YamlConfiguration;
2020
import org.bukkit.entity.EntityType;
2121

22+
import com.nexomc.nexo.api.NexoItems;
23+
2224
import world.bentobox.bentobox.BentoBox;
2325
import world.bentobox.bentobox.hooks.ItemsAdderHook;
2426
import world.bentobox.bentobox.hooks.OraxenHook;
@@ -105,6 +107,9 @@ private boolean isOther(String key) {
105107
if (key.startsWith("oraxen:") && BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) {
106108
return OraxenHook.exists(key.substring(7));
107109
}
110+
if (key.startsWith("nexo:") && addon.isNexo()) {
111+
return NexoItems.exists(key.substring(5));
112+
}
108113
// Check ItemsAdder
109114
return addon.isItemsAdder() && ItemsAdderHook.isInRegistry(key);
110115
}

src/main/java/world/bentobox/level/util/Utils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ public static String prettifyObject(Object object, User user) {
161161
// Remove prefix
162162
if (key.startsWith("oraxen:")) {
163163
key = key.substring(7);
164+
} else if (key.startsWith("nexo:")) {
165+
key = key.substring(5);
164166
}
165167
}
166168

0 commit comments

Comments
 (0)