From 4cb0ff292ee05fa9813ba3ce153b9af46bbe7f9a Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Mon, 21 Apr 2025 16:02:18 +0200 Subject: [PATCH] Add support for player inventory integration in UI system --- .../src/de/steamwar/core/Core.java | 2 + .../inventory/ui/StatefulUIInventory.java | 6 +++ .../de/steamwar/inventory/ui/UIInventory.java | 46 +++++++++++++++++-- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java index 4e7b7576..da2e627d 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java @@ -24,6 +24,7 @@ import de.steamwar.Reflection; import de.steamwar.command.*; import de.steamwar.core.authlib.AuthlibInjector; import de.steamwar.core.events.*; +import de.steamwar.inventory.ui.test.TestInvCommand; import de.steamwar.message.Message; import de.steamwar.network.NetworkReceiver; import de.steamwar.network.handlers.ServerDataHandler; @@ -67,6 +68,7 @@ public class Core extends JavaPlugin{ @Override public void onEnable() { + new TestInvCommand(); errorHandler = new ErrorHandler(); crashDetector = new CrashDetector(); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/ui/StatefulUIInventory.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/ui/StatefulUIInventory.java index 4dbb2fa8..c67e318f 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/ui/StatefulUIInventory.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/ui/StatefulUIInventory.java @@ -31,7 +31,13 @@ public abstract class StatefulUIInventory extends UIInventory implements Upda protected abstract UIComponent render(T state); protected abstract void update(T state); + public StatefulUIInventory(UpdateStream stateObservable, int playerSlots) { + super(playerSlots); + this.stream = stateObservable; + } + public StatefulUIInventory(UpdateStream stateObservable) { + super(); this.stream = stateObservable; } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/ui/UIInventory.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/ui/UIInventory.java index 1a828cab..a86c680c 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/ui/UIInventory.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/ui/UIInventory.java @@ -27,7 +27,6 @@ import de.steamwar.inventory.ui.util.Size; import de.steamwar.message.Message; import lombok.AllArgsConstructor; import lombok.Setter; -import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -38,17 +37,25 @@ import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.ItemStack; import java.util.*; -import java.util.function.Consumer; import java.util.function.Function; -import java.util.function.Supplier; import java.util.stream.Collectors; public abstract class UIInventory { protected final List viewers = new ArrayList<>(); private final Map callbacks = new HashMap<>(); + private final Map originalItems = new HashMap<>(); private UIInventory parent; private Player currentRender; + private final int playerSlots; + + protected UIInventory() { + this(0); + } + + protected UIInventory(int playerSlots) { + this.playerSlots = playerSlots; + } public abstract UIComponent render(); public abstract Inventory createInventory(Player player); @@ -65,6 +72,9 @@ public abstract class UIInventory { } private void openInventory(Player player) { + if (playerSlots > 0) { + originalItems.put(player, player.getInventory().getContents()); + } Inventory inventory = createInventory(player); renderPlayer(player, inventory); InventoryView view = player.openInventory(inventory); @@ -73,7 +83,13 @@ public abstract class UIInventory { private void renderPlayer(Player player, Inventory inventory) { int width = Math.min(inventory.getSize(), 9); - int height = Math.max(inventory.getSize() / 9, 1); + if (width < 9 && playerSlots > 0) { + throw new IllegalArgumentException("Player Inventory is only supported in Chests"); + } + + int inventoryHeight = Math.max(inventory.getSize() / 9, 1); + int height = inventoryHeight + playerSlots; + int invSize = inventoryHeight * width; currentRender = player; ComponentRender render = render().render(new RenderContext(new Size(width, height), new Size(width, height), this)); @@ -86,10 +102,27 @@ public abstract class UIInventory { Message message = getMessages(); ItemStack[] itemStacks = new ItemStack[inventory.getSize()]; + ItemStack[] playerStacks = new ItemStack[playerSlots > 0 ? 4 * 9 : 0]; - render.getItems().forEach(item -> itemStacks[item.getX() + item.getY() * 9] = item.getItemStack().message(message).build(player)); + for (RenderItem item : render.getItems()) { + int slot = item.getX() + item.getY() * 9; + if (slot < invSize) { + itemStacks[item.getX() + item.getY() * 9] = item.getItemStack().message(message).build(player); + } else { + playerStacks[(item.getX() + item.getY() * 9) - invSize] = item.getItemStack().message(message).build(player); + } + } inventory.setContents(itemStacks); + if (playerSlots > 0) { + ItemStack[] lastRow = new ItemStack[9]; + System.arraycopy(playerStacks, playerStacks.length - 9, lastRow, 0, 9); + System.arraycopy(playerStacks, 0, playerStacks, 9, playerStacks.length - 9); + System.arraycopy(lastRow, 0, playerStacks, 0, 9); + + // TODO: Update to Client-Side Only Update + player.getInventory().setContents(playerStacks); + } Map> clickEventMap = render.getItems().stream() .filter(item -> item.getClickEvent() != null) @@ -159,6 +192,9 @@ public abstract class UIInventory { viewers.remove(player); UIInventory.this.callbacks.remove(player); + if (playerSlots > 0) { + player.getInventory().setContents(originalItems.remove(player)); + } onClose(); }