diff --git a/gradle.properties b/gradle.properties index 5dc1287..45577e5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,5 +19,5 @@ loader_version_range=[1,) mod_id=bnstoolkit mod_name=Brass and Sigil Toolkit mod_license=All Rights Reserved -mod_version=0.8.0 +mod_version=0.8.1 mod_group_id=uk.sijbers.bnstoolkit diff --git a/src/main/java/uk/sijbers/bnstoolkit/client/OpenScreenDispatcher.java b/src/main/java/uk/sijbers/bnstoolkit/client/OpenScreenDispatcher.java index 31341c6..1f900af 100644 --- a/src/main/java/uk/sijbers/bnstoolkit/client/OpenScreenDispatcher.java +++ b/src/main/java/uk/sijbers/bnstoolkit/client/OpenScreenDispatcher.java @@ -22,13 +22,12 @@ public final class OpenScreenDispatcher { // Each branch requests the matching snapshot then opens the screen // so the panel renders with data instead of zeros. switch (which) { - case "tier" -> { NetSend.requestSnapshot("TIER"); new TierUpgradeScreen().openGui(); } - case "bounty" -> { NetSend.requestSnapshot("BOUNTY"); new BountyBoardScreen().openGui(); } - case "plot" -> { NetSend.requestSnapshot("PLOT"); new PlotPurchaseScreen().openGui(); } - case "counthouse", "shop" - -> { NetSend.requestSnapshot("SELL"); new CountingHouseScreen().openGui(); } - case "questlog" -> { NetSend.requestSnapshot("ALL"); new QuestLogScreen().openGui(); } - case "hub" -> { NetSend.requestSnapshot("ALL"); new HubScreen().openGui(); } + case "tier" -> { NetSend.requestSnapshot("TIER"); new TierUpgradeScreen().openGui(); } + case "bounty" -> { NetSend.requestSnapshot("BOUNTY"); new BountyBoardScreen().openGui(); } + case "plot" -> { NetSend.requestSnapshot("PLOT"); new PlotPurchaseScreen().openGui(); } + case "counthouse" -> { NetSend.requestSnapshot("SELL"); new CountingHouseScreen().openGui(); } + case "journal" -> { NetSend.requestSnapshot("ALL"); new QuestLogScreen().openGui(); } + case "hub" -> { NetSend.requestSnapshot("ALL"); new HubScreen().openGui(); } default -> BnsToolkit.LOG.warn("[bnstoolkit] unknown screen requested: {}", which); } } diff --git a/src/main/java/uk/sijbers/bnstoolkit/client/screens/BountyBoardScreen.java b/src/main/java/uk/sijbers/bnstoolkit/client/screens/BountyBoardScreen.java index 101da3d..6f78a80 100644 --- a/src/main/java/uk/sijbers/bnstoolkit/client/screens/BountyBoardScreen.java +++ b/src/main/java/uk/sijbers/bnstoolkit/client/screens/BountyBoardScreen.java @@ -36,25 +36,22 @@ public final class BountyBoardScreen extends BaseBnsScreen { public void addWidgets() { BountyList list = new BountyList(this); list.setPos(8, contentTop()); - list.setSize(170, getHeight() - 30); + list.setSize(170, getHeight() - 50); add(list); BountyDetail detail = new BountyDetail(this); detail.setPos(186, contentTop()); - detail.setSize(getWidth() - 194, getHeight() - 30); + detail.setSize(getWidth() - 194, getHeight() - 50); add(detail); - add(SimpleTextButton.create(this, - Component.literal("Refresh"), - Icons.REFRESH, - btn -> NetSend.requestSnapshot("BOUNTY"))); + add(BaseBnsScreen.makeBackOrClose(this)); } @Override public void alignWidgets() { - Widget rf = getWidgets().get(2); - rf.setSize(60, 16); - rf.setPos(getWidth() - 68, getHeight() - 22); + Widget close = getWidgets().get(2); + close.setSize(72, 16); + close.setPos(getWidth() - 80, getHeight() - 22); } private static final class BountyList extends Panel { diff --git a/src/main/java/uk/sijbers/bnstoolkit/client/screens/CountingHouseScreen.java b/src/main/java/uk/sijbers/bnstoolkit/client/screens/CountingHouseScreen.java index 6e28373..bb9fe36 100644 --- a/src/main/java/uk/sijbers/bnstoolkit/client/screens/CountingHouseScreen.java +++ b/src/main/java/uk/sijbers/bnstoolkit/client/screens/CountingHouseScreen.java @@ -2,13 +2,12 @@ package uk.sijbers.bnstoolkit.client.screens; import dev.ftb.mods.ftblibrary.icon.Color4I; import dev.ftb.mods.ftblibrary.icon.Icon; -import dev.ftb.mods.ftblibrary.icon.Icons; -import dev.ftb.mods.ftblibrary.icon.ItemIcon; import dev.ftb.mods.ftblibrary.ui.Panel; import dev.ftb.mods.ftblibrary.ui.SimpleTextButton; import dev.ftb.mods.ftblibrary.ui.Theme; import dev.ftb.mods.ftblibrary.ui.Widget; import dev.ftb.mods.ftblibrary.ui.input.MouseButton; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; @@ -17,26 +16,23 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import uk.sijbers.bnstoolkit.client.ClientBnsState; import uk.sijbers.bnstoolkit.data.SellCatalogue; +import uk.sijbers.bnstoolkit.data.SpurBalance; import uk.sijbers.bnstoolkit.network.NetSend; -import java.util.List; - /** * The Counting House — wealth exchange screen. * - * Not a general shop. Players bring diamonds / netherite / ancient - * debris and convert them to spurs, credited straight to their bank - * account. Iron / gold / coal / etc. are NOT here — they belong on - * player-run Numismatics Vendor blocks at market prices. + * Players bring diamonds / netherite / ancient debris and convert them + * to spurs credited directly to their bank. Reached via the Counting + * House Clerk NPC at spawn (not openable remotely by default). * - * Right pane shows current effective price for the selected wealth - * token after the player's tier fee + DR. Quick-exchange buttons cover - * 1 / 16 / 64. - * - * Reached via the Counting House Clerk NPC at spawn — not openable from - * anywhere via keybind. The sell action sends a {@code RunBnsCommand} - * packet which calls Java-side {@code /bns sell}; that handler pulls - * items, computes payout, and deposits to the Numismatics bank. + *

Left grid: 4 wealth-token icons. Click to select. + *

Right pane: selected item's name, list price, lifetime sales, + * effective fee%, payout per unit, AND how many of that + * item the player has in their inventory right now. + *

Quick-exchange buttons: 1 / 16 / 64. + *

Bottom-right: Back (returns to Hub if opened from there) / + * Close (NPC-opened path). */ public final class CountingHouseScreen extends BaseBnsScreen { public CountingHouseScreen() { @@ -47,27 +43,27 @@ public final class CountingHouseScreen extends BaseBnsScreen { @Override public void addWidgets() { + // Pre-size sub-panels so refreshWidgets recursion sees correct dims. + // Panel height = screen height - 50 so there's room below for the + // Back/Close action row without overlapping internal buttons. ItemGrid grid = new ItemGrid(this); grid.setPos(8, contentTop()); - grid.setSize(170, getHeight() - 30); + grid.setSize(170, getHeight() - 50); add(grid); SellDetail detail = new SellDetail(this); detail.setPos(186, contentTop()); - detail.setSize(getWidth() - 194, getHeight() - 30); + detail.setSize(getWidth() - 194, getHeight() - 50); add(detail); - add(SimpleTextButton.create(this, - Component.literal("Refresh"), - Icons.REFRESH, - btn -> NetSend.requestSnapshot("SELL"))); + add(BaseBnsScreen.makeBackOrClose(this)); } @Override public void alignWidgets() { - Widget rf = getWidgets().get(2); - rf.setSize(60, 16); - rf.setPos(getWidth() - 68, getHeight() - 22); + Widget close = getWidgets().get(2); + close.setSize(72, 16); + close.setPos(getWidth() - 80, getHeight() - 22); } // ─── Item grid ─────────────────────────────────────────────────── @@ -78,7 +74,7 @@ public final class CountingHouseScreen extends BaseBnsScreen { for (ResourceLocation id : SellCatalogue.PRICES.keySet()) add(new ItemCell(this, id)); } @Override public void alignWidgets() { - int cols = 5, cell = 32, gap = 2; + int cols = 4, cell = 36, gap = 4; int i = 0; for (Widget w : getWidgets()) { int col = i % cols; @@ -104,10 +100,15 @@ public final class CountingHouseScreen extends BaseBnsScreen { Color4I bg = isSelected ? Color4I.rgba(0x80FFD700) : isMouseOver ? Color4I.rgba(0x40FFFFFF) : Color4I.rgba(0x40000000); bg.draw(gfx, x, y, w, h); - theme.drawString(gfx, Component.empty(), x, y, Color4I.WHITE, 0); - // Render the item icon centered if (!stack.isEmpty()) { - gfx.renderItem(stack, x + 8, y + 8); + gfx.renderItem(stack, x + (w - 16) / 2, y + (h - 16) / 2); + } + // Inventory count badge bottom-right of the cell + int count = localInventoryCount(itemId); + if (count > 0) { + String label = String.valueOf(count); + theme.drawString(gfx, Component.literal("§f" + label), x + w - 4 - theme.getFont().width(label), + y + h - 10, Color4I.WHITE, Theme.SHADOW); } } @Override public boolean mousePressed(MouseButton button) { @@ -130,21 +131,30 @@ public final class CountingHouseScreen extends BaseBnsScreen { long sold = ClientBnsState.lifetimeSoldOf(selected); int feePct = ClientBnsState.effectiveFeePct; long perUnit = SellCatalogue.singleUnitPriceDisplay(selected, sold, feePct); + int onHand = localInventoryCount(selected); - add(new LabelRow(this, "§e" + selected.toString() + "§r")); + add(new LabelRow(this, "§e" + displayName(selected) + "§r")); + add(new LabelRow(this, "§7" + selected + "§r")); add(new LabelRow(this, "")); - add(new LabelRow(this, "List price: §6" + base + "§r")); - add(new LabelRow(this, "Sold lifetime: §7" + sold + "§r")); - add(new LabelRow(this, "Effective fee: §c" + feePct + "%§r")); - add(new LabelRow(this, "You get: §a" + perUnit + " spurs / unit§r")); + add(new LabelRow(this, "On hand: §f" + onHand + "§r")); + add(new LabelRow(this, "List price: §6" + base + "§r")); + add(new LabelRow(this, "Lifetime sold: §7" + sold + "§r")); + add(new LabelRow(this, "Effective fee: §c" + feePct + "%§r")); + add(new LabelRow(this, "You get: §a" + perUnit + " sp/unit§r")); add(new LabelRow(this, "")); for (int n : new int[]{1, 16, 64}) { final int count = n; + boolean haveEnough = onHand >= count; + Component label = Component.literal((haveEnough ? "§a" : "§8") + "Sell " + count); add(SimpleTextButton.create(this, - Component.literal("Sell " + count), + label, Icon.empty(), btn -> { + if (!haveEnough) { + TierUpgradeScreen.playClick(); + return; + } NetSend.runBns("sell " + selected + " " + count); TierUpgradeScreen.playClick(); })); @@ -177,4 +187,24 @@ public final class CountingHouseScreen extends BaseBnsScreen { theme.drawString(gfx, Component.literal(text), x, y + 2, Color4I.WHITE, Theme.SHADOW); } } + + // ─── helpers ──────────────────────────────────────────────────── + + private static int localInventoryCount(ResourceLocation itemId) { + Minecraft mc = Minecraft.getInstance(); + if (mc == null || mc.player == null) return 0; + return SpurBalance.countItem(mc.player, itemId); + } + + private static String displayName(ResourceLocation id) { + String[] parts = id.getPath().split("_"); + StringBuilder out = new StringBuilder(); + for (int i = 0; i < parts.length; i++) { + if (parts[i].isEmpty()) continue; + out.append(Character.toUpperCase(parts[i].charAt(0))); + if (parts[i].length() > 1) out.append(parts[i].substring(1)); + if (i + 1 < parts.length) out.append(' '); + } + return out.toString(); + } } diff --git a/src/main/java/uk/sijbers/bnstoolkit/client/screens/PlotPurchaseScreen.java b/src/main/java/uk/sijbers/bnstoolkit/client/screens/PlotPurchaseScreen.java index 86e3b83..7b9b0de 100644 --- a/src/main/java/uk/sijbers/bnstoolkit/client/screens/PlotPurchaseScreen.java +++ b/src/main/java/uk/sijbers/bnstoolkit/client/screens/PlotPurchaseScreen.java @@ -35,25 +35,22 @@ public final class PlotPurchaseScreen extends BaseBnsScreen { public void addWidgets() { PlotList list = new PlotList(this); list.setPos(8, contentTop()); - list.setSize(170, getHeight() - 30); + list.setSize(170, getHeight() - 50); add(list); PlotDetail detail = new PlotDetail(this); detail.setPos(186, contentTop()); - detail.setSize(getWidth() - 194, getHeight() - 30); + detail.setSize(getWidth() - 194, getHeight() - 50); add(detail); - add(SimpleTextButton.create(this, - Component.literal("Refresh"), - Icons.REFRESH, - btn -> NetSend.requestSnapshot("PLOT"))); + add(BaseBnsScreen.makeBackOrClose(this)); } @Override public void alignWidgets() { - Widget rf = getWidgets().get(2); - rf.setSize(60, 16); - rf.setPos(getWidth() - 68, getHeight() - 22); + Widget close = getWidgets().get(2); + close.setSize(72, 16); + close.setPos(getWidth() - 80, getHeight() - 22); } private static final class PlotList extends Panel { diff --git a/src/main/java/uk/sijbers/bnstoolkit/client/screens/QuestLogScreen.java b/src/main/java/uk/sijbers/bnstoolkit/client/screens/QuestLogScreen.java index 57a9b26..6efe333 100644 --- a/src/main/java/uk/sijbers/bnstoolkit/client/screens/QuestLogScreen.java +++ b/src/main/java/uk/sijbers/bnstoolkit/client/screens/QuestLogScreen.java @@ -44,25 +44,19 @@ public final class QuestLogScreen extends BaseBnsScreen { @Override public void addWidgets() { - // Pre-size the content panel so its children get correct - // dimensions during the recursive refreshWidgets. ContentPanel content = new ContentPanel(this); content.setPos(8, contentTop()); - content.setSize(getWidth() - 16, getHeight() - 32); + content.setSize(getWidth() - 16, getHeight() - 50); add(content); - add(SimpleTextButton.create(this, Component.literal("Refresh"), Icons.REFRESH, - btn -> NetSend.requestSnapshot("ALL"))); add(BaseBnsScreen.makeBackOrClose(this)); } @Override public void alignWidgets() { - int btnY = getHeight() - 22; - Widget refresh = getWidgets().get(1); - refresh.setSize(60, 16); refresh.setPos(8, btnY); - Widget close = getWidgets().get(2); - close.setSize(60, 16); close.setPos(getWidth() - 68, btnY); + Widget close = getWidgets().get(1); + close.setSize(72, 16); + close.setPos(getWidth() - 80, getHeight() - 22); } /** Three-section journal body. */ diff --git a/src/main/java/uk/sijbers/bnstoolkit/client/screens/TierUpgradeScreen.java b/src/main/java/uk/sijbers/bnstoolkit/client/screens/TierUpgradeScreen.java index ecced32..5380160 100644 --- a/src/main/java/uk/sijbers/bnstoolkit/client/screens/TierUpgradeScreen.java +++ b/src/main/java/uk/sijbers/bnstoolkit/client/screens/TierUpgradeScreen.java @@ -37,12 +37,9 @@ public final class TierUpgradeScreen extends BaseBnsScreen { @Override public void addWidgets() { - // Pre-size sub-panels so their addWidgets/alignWidgets (called - // via the recursive Panel.refreshWidgets BEFORE our own - // alignWidgets) see the correct dimensions. LadderPanel ladder = new LadderPanel(this); ladder.setPos(8, contentTop()); - ladder.setSize(180, getHeight() - 28); + ladder.setSize(180, getHeight() - 50); add(ladder); DetailPanel detail = new DetailPanel(this); @@ -50,18 +47,14 @@ public final class TierUpgradeScreen extends BaseBnsScreen { detail.setSize(getWidth() - 204, getHeight() - 50); add(detail); - add(SimpleTextButton.create(this, - Component.literal("Refresh"), - Icons.REFRESH, - btn -> NetSend.requestSnapshot("TIER"))); + add(BaseBnsScreen.makeBackOrClose(this)); } @Override public void alignWidgets() { - // Sub-panels are sized in addWidgets; only position the refresh button here. - Widget rf = getWidgets().get(2); - rf.setSize(60, 16); - rf.setPos(getWidth() - 68, getHeight() - 22); + Widget close = getWidgets().get(2); + close.setSize(72, 16); + close.setPos(getWidth() - 80, getHeight() - 22); } // ─── Sub-panels ────────────────────────────────────────────────── diff --git a/src/main/java/uk/sijbers/bnstoolkit/server/BnsServerCommands.java b/src/main/java/uk/sijbers/bnstoolkit/server/BnsServerCommands.java index dd99261..fb836c1 100644 --- a/src/main/java/uk/sijbers/bnstoolkit/server/BnsServerCommands.java +++ b/src/main/java/uk/sijbers/bnstoolkit/server/BnsServerCommands.java @@ -35,7 +35,7 @@ public final class BnsServerCommands { private BnsServerCommands() {} private static final String[] SCREEN_NAMES = { - "hub", "tier", "bounty", "plot", "counthouse", "shop", "questlog" + "hub", "tier", "bounty", "plot", "counthouse", "journal" }; @SubscribeEvent @@ -74,7 +74,7 @@ public final class BnsServerCommands { for (String s : SCREEN_NAMES) if (s.equals(which)) { ok = true; break; } if (!ok) { src.sendFailure(Component.literal("Unknown screen: " + which - + ". Options: hub, tier, bounty, plot, shop, questlog")); + + ". Options: hub, tier, bounty, plot, counthouse, journal")); return 0; } ServerEconomyBridge.openScreen(sp, which); diff --git a/src/main/resources/assets/bnstoolkit/lang/en_us.json b/src/main/resources/assets/bnstoolkit/lang/en_us.json index e28e4ad..37a5c5e 100644 --- a/src/main/resources/assets/bnstoolkit/lang/en_us.json +++ b/src/main/resources/assets/bnstoolkit/lang/en_us.json @@ -5,6 +5,7 @@ "key.bnstoolkit.bounties": "Open Bounty Board (direct)", "key.bnstoolkit.plots": "Open Plot Office (direct)", "key.bnstoolkit.shop": "Open Counting House (direct)", + "key.bnstoolkit.journal": "Open Adventurer's Journal (direct)", "key.bnstoolkit.questlog": "Open Quest Log (direct)", "screen.bnstoolkit.hub": "Brass and Sigil", @@ -12,6 +13,5 @@ "screen.bnstoolkit.bounty_board": "Bounty Board", "screen.bnstoolkit.quest_log": "Adventurer's Journal", "screen.bnstoolkit.plot_purchase": "Plot Office", - "screen.bnstoolkit.shop_browser": "Counting House", "screen.bnstoolkit.counting_house": "Counting House" }