Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@
<name>Oraxen Repository</name>
<url>https://repo.oraxen.com/releases</url>
</repository>
<!-- Nexo repo -->
<repository>
<id>nexo</id>
<name>Nexo Repository</name>
<url>https://repo.nexomc.com/releases</url>
</repository>
</repositories>

<dependencies>
Expand Down Expand Up @@ -277,6 +283,19 @@
<version>4.0.10</version>
<scope>provided</scope>
</dependency>
<!-- Nexo -->
<dependency>
<groupId>com.nexomc</groupId>
<artifactId>nexo</artifactId>
<version>1.19.1</version>
<exclusions>
<exclusion>
<groupId>dev.triumphteam</groupId>
<artifactId>triumph-gui</artifactId>
</exclusion>
</exclusions>
<scope>provided</scope>
</dependency>
<!-- Oraxen -->
<dependency>
<groupId>io.th0rgal</groupId>
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/world/bentobox/level/Level.java
Original file line number Diff line number Diff line change
Expand Up @@ -488,4 +488,12 @@ public boolean isItemsAdder() {
return !getSettings().isDisableItemsAdder() && getPlugin().getHooks().getHook("ItemsAdder").isPresent();
}

/**
* @return true if the Nexo plugin is enabled and not disabled in config
*/
public boolean isNexo() {
return !getSettings().getDisabledPluginHooks().contains("Nexo")
&& Bukkit.getPluginManager().isPluginEnabled("Nexo");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
import com.google.common.collect.Multiset;
import com.google.common.collect.Multiset.Entry;
import com.google.common.collect.Multisets;
import com.nexomc.nexo.api.NexoBlocks;
import com.nexomc.nexo.api.NexoFurniture;
import com.nexomc.nexo.api.NexoItems;
import com.nexomc.nexo.mechanics.custom_block.CustomBlockMechanic;

import dev.rosewood.rosestacker.api.RoseStackerAPI;
import us.lynuxcraft.deadsilenceiv.advancedchests.AdvancedChestsAPI;
Expand Down Expand Up @@ -426,7 +430,19 @@ private void countItemStack(ItemStack i) {
}
return;
}

// Check Nexo
if (addon.isNexo() && NexoItems.exists(i)) {
String id = NexoItems.idFromItem(i);
if (id == null) {
return;
}
id = "nexo:" + id;
for (int c = 0; c < i.getAmount(); c++) {
checkBlock(id, false);
}
return;
}

if (i == null || !i.getType().isBlock())
return;

Expand Down Expand Up @@ -477,8 +493,8 @@ record ChunkPair(World world, Chunk chunk, ChunkSnapshot chunkSnapshot) {
}

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

// === Custom Block Hooks (ItemsAdder, Oraxen) ===
// === Custom Block Hooks (ItemsAdder, Oraxen, Nexo) ===
// These hooks can define custom blocks that override vanilla behavior.
// They must be checked first.
if (addon.isItemsAdder() || BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) {
if (addon.isItemsAdder() || BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()
|| addon.isNexo()) {
loc = new Location(cp.world, globalX, y, globalZ);
String customBlockId = null;
if (addon.isItemsAdder()) {
Expand All @@ -541,6 +558,12 @@ private void processBlock(ChunkPair cp, int x, int y, int z, int globalX, int gl
customBlockId = "oraxen:" + oraxenId; // Make a namespaced ID
}
}
if (customBlockId == null && addon.isNexo()) {
CustomBlockMechanic nexoMechanic = NexoBlocks.customBlockMechanic(loc);
if (nexoMechanic != null) {
customBlockId = "nexo:" + nexoMechanic.getItemID();
}
}

if (customBlockId != null) {
// If a custom block is found, count it and stop further processing for this block.
Expand Down Expand Up @@ -750,6 +773,7 @@ public void scanIsland(Pipeliner pipeliner) {
// This was the last chunk. Handle stacked blocks, spawners, chests and exit
handleStackedBlocks().thenCompose(v -> handleSpawners()).thenCompose(v -> handleChests())
.thenCompose(v -> handleOraxenFurniture())
.thenCompose(v -> handleNexoFurniture())
.thenRun(() -> {
this.tidyUp();
this.getR().complete(getResults());
Expand Down Expand Up @@ -822,7 +846,7 @@ private CompletableFuture<Void> handleOraxenFurniture() {
|| loc.getBlockZ() < minZ || loc.getBlockZ() >= maxZ) {
continue;
}
FurnitureMechanic mechanic = OraxenHook.getFurnitureMechanic(entity);
var mechanic = OraxenHook.getFurnitureMechanic(entity);
if (mechanic == null) {
continue;
}
Expand All @@ -835,6 +859,47 @@ private CompletableFuture<Void> handleOraxenFurniture() {
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
}

/**
* Scans entities in each island chunk for Nexo furniture and counts them toward the island level.
* Nexo furniture is entity-based (ItemDisplay entities), so it is invisible to the normal block
* scanner. Only entities for which a FurnitureMechanic can be resolved are counted, which
* naturally filters to base furniture entities.
*
* @return a CompletableFuture that completes when all chunks have been checked
*/
private CompletableFuture<Void> handleNexoFurniture() {
if (!addon.isNexo() || furnitureChunks.isEmpty()) {
return CompletableFuture.completedFuture(null);
}
int minX = island.getMinProtectedX();
int maxX = island.getMaxProtectedX();
int minZ = island.getMinProtectedZ();
int maxZ = island.getMaxProtectedZ();
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (Chunk chunk : furnitureChunks) {
CompletableFuture<Void> future = Util.getChunkAtAsync(chunk.getWorld(), chunk.getX(), chunk.getZ())
.thenAccept(c -> {
for (Entity entity : c.getEntities()) {
Location loc = entity.getLocation();
// Confirm entity is within the island's protected bounds
if (loc.getBlockX() < minX || loc.getBlockX() >= maxX
|| loc.getBlockZ() < minZ || loc.getBlockZ() >= maxZ) {
continue;
}
// getFurnitureMechanic returns non-null only for furniture base entities
var mechanic = NexoFurniture.furnitureMechanic(entity);
if (mechanic == null) {
continue;
}
boolean belowSeaLevel = seaHeight > 0 && loc.getBlockY() <= seaHeight;
checkBlock("nexo:" + mechanic.getItemID(), belowSeaLevel);
}
});
futures.add(future);
}
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
}

private CompletableFuture<Void> handleStackedBlocks() {
// Deal with any stacked blocks
List<CompletableFuture<Void>> futures = new ArrayList<>();
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/world/bentobox/level/config/BlockConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.EntityType;

import com.nexomc.nexo.api.NexoItems;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.hooks.ItemsAdderHook;
import world.bentobox.bentobox.hooks.OraxenHook;
Expand Down Expand Up @@ -105,6 +107,9 @@ private boolean isOther(String key) {
if (key.startsWith("oraxen:") && BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) {
return OraxenHook.exists(key.substring(7));
}
if (key.startsWith("nexo:") && addon.isNexo()) {
return NexoItems.exists(key.substring(5));
}
// Check ItemsAdder
return addon.isItemsAdder() && ItemsAdderHook.isInRegistry(key);
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/world/bentobox/level/util/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ public static String prettifyObject(Object object, User user) {
// Remove prefix
if (key.startsWith("oraxen:")) {
key = key.substring(7);
} else if (key.startsWith("nexo:")) {
key = key.substring(5);
}
}

Expand Down