From d37a03a5a92000ae80b3cccbe407090020b5f6d9 Mon Sep 17 00:00:00 2001 From: NichtStudioCode <51272202+NichtStudioCode@users.noreply.github.com> Date: Thu, 9 Jun 2022 19:05:05 +0200 Subject: [PATCH] StackSizeProvider --- .../de/studiocode/invui/gui/impl/BaseGUI.java | 4 +- .../studiocode/invui/util/InventoryUtils.java | 63 +++++++++++++++++++ .../virtualinventory/StackSizeProvider.java | 9 +++ .../virtualinventory/VirtualInventory.java | 3 +- 4 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 InvUI/src/main/java/de/studiocode/invui/virtualinventory/StackSizeProvider.java diff --git a/InvUI/src/main/java/de/studiocode/invui/gui/impl/BaseGUI.java b/InvUI/src/main/java/de/studiocode/invui/gui/impl/BaseGUI.java index 45916d5..2c57a0c 100644 --- a/InvUI/src/main/java/de/studiocode/invui/gui/impl/BaseGUI.java +++ b/InvUI/src/main/java/de/studiocode/invui/gui/impl/BaseGUI.java @@ -227,9 +227,7 @@ public abstract class BaseGUI implements GUI, Controllable { leftOverAmount = ((BaseGUI) otherGui).putIntoFirstVirtualInventory(updateReason, clicked, inventory); } else { - leftOverAmount = 0; - HashMap leftover = event.getWhoClicked().getInventory().addItem(inventory.getItemStack(slot)); - if (!leftover.isEmpty()) leftOverAmount = leftover.get(0).getAmount(); + leftOverAmount = InventoryUtils.addItemCorrectly(event.getWhoClicked().getInventory(), inventory.getItemStack(slot)); } clicked.setAmount(leftOverAmount); diff --git a/InvUI/src/main/java/de/studiocode/invui/util/InventoryUtils.java b/InvUI/src/main/java/de/studiocode/invui/util/InventoryUtils.java index 3db7764..8b7c4d2 100644 --- a/InvUI/src/main/java/de/studiocode/invui/util/InventoryUtils.java +++ b/InvUI/src/main/java/de/studiocode/invui/util/InventoryUtils.java @@ -1,6 +1,7 @@ package de.studiocode.invui.util; import de.studiocode.invui.gui.GUI; +import de.studiocode.invui.virtualinventory.StackSizeProvider; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Item; @@ -8,9 +9,71 @@ import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class InventoryUtils { + public static StackSizeProvider stackSizeProvider = ItemStack::getMaxStackSize; + + public static int addItemCorrectly(Inventory inventory, ItemStack itemStack) { + int maxStackSize = Math.min(inventory.getMaxStackSize(), stackSizeProvider.getMaxStackSize(itemStack)); + int amountLeft = itemStack.getAmount(); + + // add to partial stacks + while (amountLeft > 0) { + ItemStack partialStack = getFirstPartialStack(inventory, itemStack); + if (partialStack == null) + break; + + int partialAmount = partialStack.getAmount(); + int addableAmount = Math.max(0, Math.min(amountLeft, maxStackSize - partialAmount)); + partialStack.setAmount(partialAmount + addableAmount); + amountLeft -= addableAmount; + } + + // add to empty slots + while (amountLeft > 0) { + int emptySlot = getFirstEmptySlot(inventory); + if (emptySlot == -1) + break; + + int addableAmount = Math.min(amountLeft, maxStackSize); + + ItemStack newStack = itemStack.clone(); + newStack.setAmount(addableAmount); + inventory.setItem(emptySlot, newStack); + + amountLeft -= addableAmount; + } + + return amountLeft; + } + + @Nullable + public static ItemStack getFirstPartialStack(Inventory inventory, @NotNull ItemStack type) { + int maxStackSize = stackSizeProvider.getMaxStackSize(type); + for (ItemStack item : inventory.getStorageContents()) { + if (type.isSimilar(item)) { + int amount = item.getAmount(); + if (amount < maxStackSize) + return item; + } + } + + return null; + } + + public static int getFirstEmptySlot(Inventory inventory) { + ItemStack[] storageContents = inventory.getStorageContents(); + for (int i = 0; i < storageContents.length; i++) { + if (storageContents[i] == null) + return i; + } + + return -1; + } + public static Inventory createMatchingInventory(GUI gui, String title) { InventoryType type; diff --git a/InvUI/src/main/java/de/studiocode/invui/virtualinventory/StackSizeProvider.java b/InvUI/src/main/java/de/studiocode/invui/virtualinventory/StackSizeProvider.java new file mode 100644 index 0000000..878bbc6 --- /dev/null +++ b/InvUI/src/main/java/de/studiocode/invui/virtualinventory/StackSizeProvider.java @@ -0,0 +1,9 @@ +package de.studiocode.invui.virtualinventory; + +import org.bukkit.inventory.ItemStack; + +public interface StackSizeProvider { + + int getMaxStackSize(ItemStack itemStack); + +} diff --git a/InvUI/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java b/InvUI/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java index 20207d6..6259357 100644 --- a/InvUI/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java +++ b/InvUI/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java @@ -2,6 +2,7 @@ package de.studiocode.invui.virtualinventory; import de.studiocode.invui.gui.GUI; import de.studiocode.invui.util.ArrayUtils; +import de.studiocode.invui.util.InventoryUtils; import de.studiocode.invui.virtualinventory.event.InventoryUpdatedEvent; import de.studiocode.invui.virtualinventory.event.ItemUpdateEvent; import de.studiocode.invui.virtualinventory.event.UpdateReason; @@ -275,7 +276,7 @@ public class VirtualInventory { public int getMaxStackSize(int slot, int alternative) { ItemStack currentItem = items[slot]; int slotMaxStackSize = stackSizes == null ? 64 : stackSizes[slot]; - return min(currentItem != null ? currentItem.getMaxStackSize() : alternative != -1 ? alternative : slotMaxStackSize, slotMaxStackSize); + return min(currentItem != null ? InventoryUtils.stackSizeProvider.getMaxStackSize(currentItem) : alternative != -1 ? alternative : slotMaxStackSize, slotMaxStackSize); } /**