diff --git a/src/main/java/world/bentobox/level/panels/DetailsPanel.java b/src/main/java/world/bentobox/level/panels/DetailsPanel.java index 2445cc9..3bd84fd 100644 --- a/src/main/java/world/bentobox/level/panels/DetailsPanel.java +++ b/src/main/java/world/bentobox/level/panels/DetailsPanel.java @@ -12,10 +12,8 @@ import org.bukkit.inventory.ItemStack; import com.google.common.base.Enums; -import com.nexomc.nexo.api.NexoItems; import lv.id.bonne.panelutils.PanelUtils; -import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.TemplatedPanel; @@ -24,8 +22,6 @@ import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; -import world.bentobox.bentobox.hooks.ItemsAdderHook; -import world.bentobox.bentobox.hooks.OraxenHook; import world.bentobox.level.Level; import world.bentobox.level.objects.IslandLevels; import world.bentobox.level.util.Utils; @@ -742,12 +738,9 @@ private BlockDataRec getBlockData(Object key) { Utils.prettifyObject(key, this.user), this.user.getTranslation(this.world, "level.gui.buttons.spawner.block-name")); } else if (key instanceof String s) { - Optional optItem = getCustomBlockItemStack(s); + Optional optItem = Utils.getCustomBlockItemStack(addon, s); ItemStack icon = optItem.orElse(new ItemStack(Material.PAPER)); - String disp = optItem - .filter(is -> is.getItemMeta() != null && is.getItemMeta().hasDisplayName()) - .map(is -> is.getItemMeta().getDisplayName()) - .orElse(Utils.prettifyObject(s, this.user)); + String disp = Utils.getCustomBlockDisplayName(optItem, s, this.user); return new BlockDataRec(icon, this.user.getTranslationOrNothing(ref + "id", "[id]", s), @@ -758,29 +751,6 @@ private BlockDataRec getBlockData(Object key) { return new BlockDataRec(new ItemStack(Material.PAPER), "", 0, 0, Utils.prettifyObject(key, this.user), ""); } - /** - * Returns the best available ItemStack for a custom-block string ID. - * Checks Oraxen, Nexo, and ItemsAdder in order; returns empty when none matches. - * - * @param id the custom block ID (e.g. "oraxen:my_block", "nexo:my_block", or an ItemsAdder ID) - * @return an Optional containing the representative ItemStack, or empty - */ - private Optional getCustomBlockItemStack(String id) { - if (id.startsWith("oraxen:") && BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) { - return OraxenHook.getOptionalItemById(id.substring(7)) - .map(itemBuilder -> itemBuilder.build()); - } - if (id.startsWith("nexo:") && addon.isNexo()) { - com.nexomc.nexo.items.ItemBuilder nexoBuilder = NexoItems.itemFromId(id.substring(5)); - return nexoBuilder != null ? Optional.of(nexoBuilder.build()) : Optional.empty(); - } - if (addon.isItemsAdder() && ItemsAdderHook.isInRegistry(id)) { - return ItemsAdderHook.getItemStack(id); - } - return Optional.empty(); - } - - // --------------------------------------------------------------------- // Section: Other Methods // --------------------------------------------------------------------- diff --git a/src/main/java/world/bentobox/level/panels/ValuePanel.java b/src/main/java/world/bentobox/level/panels/ValuePanel.java index 23361ed..7a7695f 100644 --- a/src/main/java/world/bentobox/level/panels/ValuePanel.java +++ b/src/main/java/world/bentobox/level/panels/ValuePanel.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Locale; import java.util.Objects; +import java.util.Optional; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -668,6 +669,16 @@ private PanelItem createMaterialButton(ItemTemplateRecord template, TemplatedPan return this.createMaterialButton(template, this.elementList.get(index)); } + private static String stripCustomPrefix(String key) { + if (key.startsWith("oraxen:")) { + return key.substring(7); + } + if (key.startsWith("nexo:")) { + return key.substring(5); + } + return key; + } + private Material getIcon(String key) { // Filter out some names key = key.replaceAll("wall_", ""); @@ -773,18 +784,21 @@ private PanelItem createMaterialButton(ItemTemplateRecord template, BlockRecord ? this.user.getTranslationOrNothing(baseKey + "limit", TextVariables.NUMBER, String.valueOf(blockLimit)) : ""; - // Determine icon and display material text - Material icon = getIcon(key); - builder.icon((icon == null || icon == Material.AIR) ? Material.PAPER : icon); - if (key.startsWith("oraxen:")) { - key = key.substring(7); - } else if (key.startsWith("nexo:")) { - key = key.substring(5); - } - String displayMaterial = (icon == null) ? Util.prettifyText(key) : Utils.prettifyObject(key, user); - // Special handling for spawn eggs - if (icon != null && icon.name().endsWith("_SPAWN_EGG")) { - displayMaterial = Util.prettifyText(key); + // Prefer the actual custom-block ItemStack (real texture + display name) over a fallback Material icon. + Optional customStack = Utils.getCustomBlockItemStack(addon, key); + String displayMaterial; + if (customStack.isPresent()) { + builder.icon(customStack.get().clone()); + displayMaterial = Utils.getCustomBlockDisplayName(customStack, stripCustomPrefix(key), user); + } else { + Material icon = getIcon(key); + builder.icon((icon == null || icon == Material.AIR) ? Material.PAPER : icon); + String stripped = stripCustomPrefix(key); + displayMaterial = (icon == null) ? Util.prettifyText(stripped) : Utils.prettifyObject(stripped, user); + // Special handling for spawn eggs + if (icon != null && icon.name().endsWith("_SPAWN_EGG")) { + displayMaterial = Util.prettifyText(stripped); + } } // Set button title if available diff --git a/src/main/java/world/bentobox/level/util/Utils.java b/src/main/java/world/bentobox/level/util/Utils.java index b807cb9..2a40434 100644 --- a/src/main/java/world/bentobox/level/util/Utils.java +++ b/src/main/java/world/bentobox/level/util/Utils.java @@ -9,13 +9,21 @@ import java.text.NumberFormat; import java.util.List; +import java.util.Optional; import org.bukkit.Material; import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; import org.bukkit.permissions.PermissionAttachmentInfo; +import com.nexomc.nexo.api.NexoItems; + +import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.hooks.ItemsAdderHook; import world.bentobox.bentobox.hooks.LangUtilsHook; +import world.bentobox.bentobox.hooks.OraxenHook; +import world.bentobox.level.Level; public class Utils @@ -216,6 +224,45 @@ public static String prettifyObject(Object object, User user) { return ""; } + /** + * Returns the best available ItemStack for a custom-block string ID. + * Checks Oraxen, Nexo, and ItemsAdder in order; returns empty when none matches. + * + * @param addon the Level addon + * @param id the custom block ID (e.g. "oraxen:my_block", "nexo:my_block", or an ItemsAdder ID) + * @return an Optional containing the representative ItemStack, or empty + */ + public static Optional getCustomBlockItemStack(Level addon, String id) { + if (id == null) { + return Optional.empty(); + } + if (id.startsWith("oraxen:") && BentoBox.getInstance().getHooks().getHook("Oraxen").isPresent()) { + return OraxenHook.getOptionalItemById(id.substring(7)).map(itemBuilder -> itemBuilder.build()); + } + if (id.startsWith("nexo:") && addon.isNexo()) { + com.nexomc.nexo.items.ItemBuilder nexoBuilder = NexoItems.itemFromId(id.substring(5)); + return nexoBuilder != null ? Optional.of(nexoBuilder.build()) : Optional.empty(); + } + if (addon.isItemsAdder() && ItemsAdderHook.isInRegistry(id)) { + return ItemsAdderHook.getItemStack(id); + } + return Optional.empty(); + } + + /** + * Returns the display name from an ItemStack's meta when present, otherwise falls back to + * {@link #prettifyObject(Object, User)} on the original key. + * + * @param itemStack the optional ItemStack (typically from a custom-block plugin) + * @param key the raw key used as a fallback for prettification + * @param user the user for translation lookups + * @return the human-readable display name + */ + public static String getCustomBlockDisplayName(Optional itemStack, String key, User user) { + return itemStack.filter(is -> is.getItemMeta() != null && is.getItemMeta().hasDisplayName()) + .map(is -> is.getItemMeta().getDisplayName()).orElse(prettifyObject(key, user)); + } + public static String prettifyDescription(Object object, User user) { if (object instanceof String key) { String translation = user.getTranslationOrNothing(LEVEL_MATERIALS + key + DESCRIPTION);