From e41f76937e238bb02c833a9742eab7c91265d8e6 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 23 Oct 2026 17:47:30 +0200 Subject: [PATCH] Give particle menus a shared bottom bar Back, use, add, rename, icon, particle count and delete or reset now sit in the same column of the last row in every particle menu, and columns a menu does not use show a barrier. --- .../lobby/particle/gui/BottomBar.java | 59 +++++++++++++++++++ .../lobby/particle/gui/EntryEditor.java | 12 ++-- .../steamwar/lobby/particle/gui/Pickers.java | 4 +- .../lobby/particle/gui/SlotEditor.java | 24 ++++---- .../lobby/particle/gui/ValueEditors.java | 21 ++++--- 5 files changed, 95 insertions(+), 25 deletions(-) create mode 100644 LobbySystem/src/de/steamwar/lobby/particle/gui/BottomBar.java diff --git a/LobbySystem/src/de/steamwar/lobby/particle/gui/BottomBar.java b/LobbySystem/src/de/steamwar/lobby/particle/gui/BottomBar.java new file mode 100644 index 00000000..71637ad1 --- /dev/null +++ b/LobbySystem/src/de/steamwar/lobby/particle/gui/BottomBar.java @@ -0,0 +1,59 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2026 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.lobby.particle.gui; + +import de.steamwar.inventory.SWInventory; +import de.steamwar.inventory.SWItem; +import lombok.experimental.UtilityClass; +import org.bukkit.Material; + +// Every particle menu puts the same button in the same column of its last row +@UtilityClass +class BottomBar { + + // Taken by the page arrows of list menus + final int PREVIOUS_PAGE = 0; + final int BACK = 1; + final int USE = 2; + final int ADD = 3; + final int RENAME = 4; + final int ICON = 5; + final int COST = 6; + // Delete in editors, reset in value screens; no menu has both + final int DELETE = 7; + final int RESET = 7; + final int NEXT_PAGE = 8; + + int position(int inventorySize, int column) { + return inventorySize - 9 + column; + } + + // Marks the columns this menu does not use, so the buttons it does use stay recognisable by position. + // List menus keep the outer columns free for the page arrows they add when opened. + void fillUnused(SWInventory inventory, int inventorySize, boolean listMenu) { + for (int column = listMenu ? 1 : 0; column < (listMenu ? 8 : 9); column++) { + int position = position(inventorySize, column); + if (!inventory.hasItem(position)) { + inventory.setItem(position, new SWItem(Material.BARRIER, "§8-", clickType -> { + })); + } + } + } +} diff --git a/LobbySystem/src/de/steamwar/lobby/particle/gui/EntryEditor.java b/LobbySystem/src/de/steamwar/lobby/particle/gui/EntryEditor.java index 866cf37b..59448f5c 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/gui/EntryEditor.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/gui/EntryEditor.java @@ -50,9 +50,10 @@ class EntryEditor { private final int ROW_SHAPE = 2; private final int ROW_TIMING = 3; private final int ROW_CONDITIONS = 4; - private final int BACK = 45; - private final int COST = 49; - private final int DELETE = 53; + private final int SIZE = 54; + private final int BACK = BottomBar.position(SIZE, BottomBar.BACK); + private final int COST = BottomBar.position(SIZE, BottomBar.COST); + private final int DELETE = BottomBar.position(SIZE, BottomBar.DELETE); private final Map, Material> ICONS = Map.ofEntries( Map.entry(COUNT, Material.GLOWSTONE_DUST), @@ -97,7 +98,7 @@ class EntryEditor { ParticleEntry entry = context.entry(); ParticleDesign design = entry.getDesign(); - SWInventory inventory = new SWInventory(player, 54, msg("PARTICLE_ENTRY_EDITOR", player, designName(design, player))); + SWInventory inventory = new SWInventory(player, SIZE, msg("PARTICLE_ENTRY_EDITOR", player, designName(design, player))); header(inventory, ROW_DESIGN, Material.PAINTING, "PARTICLE_SECTION_DESIGN", player); header(inventory, ROW_PARTICLE, Material.FIREWORK_STAR, "PARTICLE_SECTION_PARTICLE", player); header(inventory, ROW_SHAPE, Material.ARMOR_STAND, "PARTICLE_SECTION_SHAPE", player); @@ -128,7 +129,8 @@ class EntryEditor { SlotEditor.save(player, index, slot); SlotEditor.open(player, index); })); - SlotEditor.fill(inventory, 0, 54); + BottomBar.fillUnused(inventory, SIZE, false); + SlotEditor.fill(inventory, 0, SIZE); inventory.open(); } diff --git a/LobbySystem/src/de/steamwar/lobby/particle/gui/Pickers.java b/LobbySystem/src/de/steamwar/lobby/particle/gui/Pickers.java index 90a70a01..28ba9bf0 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/gui/Pickers.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/gui/Pickers.java @@ -39,7 +39,8 @@ import static de.steamwar.lobby.particle.gui.ParticleGuiText.*; @UtilityClass class Pickers { - private final int BACK = 49; + private final int SIZE = 54; + private final int BACK = BottomBar.position(SIZE, BottomBar.BACK); // Basic designs first, then rewards; locked rewards are shown with their requirement but cannot be picked. // The current design, if any, glows. @@ -104,6 +105,7 @@ class Pickers { if (value != null) onPick.accept(value); }); inventory.setItem(BACK, new SWItem(Material.ARROW, msg("PARTICLE_BACK", player), clickType -> onBack.run())); + BottomBar.fillUnused(inventory, SIZE, true); inventory.open(); } } diff --git a/LobbySystem/src/de/steamwar/lobby/particle/gui/SlotEditor.java b/LobbySystem/src/de/steamwar/lobby/particle/gui/SlotEditor.java index 4b672a88..a33d63aa 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/gui/SlotEditor.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/gui/SlotEditor.java @@ -43,13 +43,14 @@ import static de.steamwar.lobby.particle.gui.ParticleGuiText.*; @UtilityClass public class SlotEditor { - private final int BACK = 45; - private final int USE = 46; - private final int ADD_ENTRY = 47; - private final int RENAME = 48; - private final int ICON = 49; - private final int COST = 50; - private final int DELETE = 53; + private final int SIZE = 54; + private final int BACK = BottomBar.position(SIZE, BottomBar.BACK); + private final int USE = BottomBar.position(SIZE, BottomBar.USE); + private final int ADD_ENTRY = BottomBar.position(SIZE, BottomBar.ADD); + private final int RENAME = BottomBar.position(SIZE, BottomBar.RENAME); + private final int ICON = BottomBar.position(SIZE, BottomBar.ICON); + private final int COST = BottomBar.position(SIZE, BottomBar.COST); + private final int DELETE = BottomBar.position(SIZE, BottomBar.DELETE); public void open(Player player, int index) { LobbyPlayer lobbyPlayer = LobbyPlayer.getLobbyPlayer(player); @@ -62,7 +63,7 @@ public class SlotEditor { UnlockContext context = new UnlockContext(user); boolean editable = ParticleSlots.requirement(index).test(context); - SWInventory inventory = new SWInventory(player, 54, slotTitle(slot, user, player)); + SWInventory inventory = new SWInventory(player, SIZE, slotTitle(slot, user, player)); List entries = slot.getEntries(); for (int i = 0; i < entries.size(); i++) { ParticleEntry entry = entries.get(i); @@ -80,9 +81,10 @@ public class SlotEditor { inventory.setItem(BACK, new SWItem(Material.ARROW, msg("PARTICLE_BACK", player), clickType -> ParticleMenu.open(player))); if (!editable) { List lore = new ArrayList<>(requirement(ParticleSlots.requirement(index), player)); - inventory.setItem(ICON, new SWItem(Material.BARRIER, msg("PARTICLE_LOCKED", player), lore, false, clickType -> { + inventory.setItem(USE, new SWItem(Material.IRON_BARS, msg("PARTICLE_LOCKED", player), lore, false, clickType -> { })); - fill(inventory, 45, 54); + inventory.setItem(COST, costItem(player, user, slot)); + BottomBar.fillUnused(inventory, SIZE, false); inventory.open(); return; } @@ -138,7 +140,7 @@ public class SlotEditor { lobbyPlayer.setSlot(index, null); ParticleMenu.open(player); })); - fill(inventory, 45, 54); + BottomBar.fillUnused(inventory, SIZE, false); inventory.open(); } diff --git a/LobbySystem/src/de/steamwar/lobby/particle/gui/ValueEditors.java b/LobbySystem/src/de/steamwar/lobby/particle/gui/ValueEditors.java index b248e501..89cbda37 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/gui/ValueEditors.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/gui/ValueEditors.java @@ -41,7 +41,10 @@ import static de.steamwar.lobby.particle.gui.ParticleGuiText.*; @UtilityClass class ValueEditors { - private final int BACK = 18; + private final int SIZE = 27; + private final int BACK = BottomBar.position(SIZE, BottomBar.BACK); + private final int ADD = BottomBar.position(SIZE, BottomBar.ADD); + private final int RESET = BottomBar.position(SIZE, BottomBar.RESET); // Buttons step the value down or up; clicking the value itself lets the player type one void editNumber(Player player, String title, Supplier current, double step, double min, double max, double defaultValue, boolean integer, @@ -49,7 +52,7 @@ class ValueEditors { double value = current.get(); Runnable reopen = () -> editNumber(player, title, current, step, min, max, defaultValue, integer, apply, back); - SWInventory inventory = new SWInventory(player, 27, "§0" + strip(title)); + SWInventory inventory = new SWInventory(player, SIZE, "§0" + strip(title)); inventory.setItem(10, stepItem(player, Material.RED_CONCRETE, -10 * step, step, value, min, max, integer, apply, reopen)); inventory.setItem(11, stepItem(player, Material.RED_STAINED_GLASS_PANE, -step, step, value, min, max, integer, apply, reopen)); inventory.setItem(15, stepItem(player, Material.LIME_STAINED_GLASS_PANE, step, step, value, min, max, integer, apply, reopen)); @@ -72,11 +75,12 @@ class ValueEditors { })); inventory.setItem(BACK, new SWItem(Material.ARROW, msg("PARTICLE_BACK", player), clickType -> back.run())); - inventory.setItem(22, new SWItem(Material.STRUCTURE_VOID, msg("PARTICLE_VALUE_RESET", player, number(defaultValue)), clickType -> { + inventory.setItem(RESET, new SWItem(Material.STRUCTURE_VOID, msg("PARTICLE_VALUE_RESET", player, number(defaultValue)), clickType -> { apply.test(defaultValue); reopen.run(); })); - SlotEditor.fill(inventory, 0, 27); + BottomBar.fillUnused(inventory, SIZE, false); + SlotEditor.fill(inventory, 0, SIZE); inventory.open(); } @@ -95,7 +99,7 @@ class ValueEditors { List colors = current.get(); Runnable reopen = () -> editColors(player, current, maxColors, apply, back); - SWInventory inventory = new SWInventory(player, 27, msg("PARTICLE_COLOR_EDITOR", player)); + SWInventory inventory = new SWInventory(player, SIZE, msg("PARTICLE_COLOR_EDITOR", player)); for (int i = 0; i < colors.size() && i < 9; i++) { int position = i; Color color = colors.get(i); @@ -114,18 +118,19 @@ class ValueEditors { inventory.setItem(BACK, new SWItem(Material.ARROW, msg("PARTICLE_BACK", player), clickType -> back.run())); if (colors.size() < maxColors) { - inventory.setItem(21, new SWItem(Material.NETHER_STAR, msg("PARTICLE_COLOR_ADD", player), clickType -> Pickers.color(player, color -> { + inventory.setItem(ADD, new SWItem(Material.NETHER_STAR, msg("PARTICLE_COLOR_ADD", player), clickType -> Pickers.color(player, color -> { List next = new ArrayList<>(colors); next.add(color); apply.test(next); reopen.run(); }, reopen))); } - inventory.setItem(23, new SWItem(Material.WHITE_DYE, msg("PARTICLE_COLOR_RANDOM", player), clickType -> { + inventory.setItem(RESET, new SWItem(Material.WHITE_DYE, msg("PARTICLE_COLOR_RANDOM", player), clickType -> { apply.test(List.of()); reopen.run(); })); - SlotEditor.fill(inventory, 0, 27); + BottomBar.fillUnused(inventory, SIZE, false); + SlotEditor.fill(inventory, 0, SIZE); inventory.open(); }