diff --git a/src/main/java/com/Acrobot/Breeze/Utils/InventoryUtil.java b/src/main/java/com/Acrobot/Breeze/Utils/InventoryUtil.java index 6bafcdd..0b33230 100644 --- a/src/main/java/com/Acrobot/Breeze/Utils/InventoryUtil.java +++ b/src/main/java/com/Acrobot/Breeze/Utils/InventoryUtil.java @@ -6,9 +6,9 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import com.Acrobot.ChestShop.Configuration.Properties; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BookMeta; /** * @author Acrobot @@ -83,7 +83,8 @@ public class InventoryUtil { * @return Does the inventory contain stock of this type? */ public static boolean hasItems(ItemStack[] items, Inventory inventory) { - for (ItemStack item : items) { + ItemStack[] mergedItems = mergeSimilarStacks(items); + for (ItemStack item : mergedItems) { if (getAmount(item, inventory) < item.getAmount()) { return false; } @@ -112,7 +113,7 @@ public class InventoryUtil { } if (MaterialUtil.isEmpty(iStack)) { - left -= item.getMaxStackSize(); + left -= getMaxStackSize(item); continue; } @@ -120,7 +121,7 @@ public class InventoryUtil { continue; } - left -= (iStack.getMaxStackSize() - iStack.getAmount()); + left -= (getMaxStackSize(iStack) - iStack.getAmount()); } return left <= 0; @@ -211,12 +212,7 @@ public class InventoryUtil { Map leftovers = inventory.removeItem(item); if (!leftovers.isEmpty()) { - for (Iterator iterator = leftovers.values().iterator(); iterator.hasNext(); ) { - ItemStack left = iterator.next(); - if (removeManually(left, inventory) == 0) { - iterator.remove(); - } - } + leftovers.values().removeIf(left -> removeManually(left, inventory) == 0); } return countItems(leftovers); @@ -261,7 +257,7 @@ public class InventoryUtil { } } - itemList.add(item); + itemList.add(item.clone()); } return itemList.toArray(new ItemStack[itemList.size()]); @@ -298,4 +294,34 @@ public class InventoryUtil { return totalLeft; } + + /** + * Get the max size an item stack is allowed to stack to while respecting the STACK_TO_64 config property + * @param item The item to get the max stacksize of + * @return The max stacksize of the item stack's type or 64 if STACK_TO_64 is enabled + */ + public static int getMaxStackSize(ItemStack item) { + return Properties.STACK_TO_64 ? 64 : item.getMaxStackSize(); + } + + /** + * Get an array of different item stacks that are properly stacked to their max stack size + * @param item The item to stack + * @return An array of item stacks which's amount is a maximum of the allowed stack size + */ + public static ItemStack[] getItemsStacked(ItemStack item) { + int maxStackSize = getMaxStackSize(item); + if (item.getAmount() <= maxStackSize) { + return new ItemStack[]{item}; + } + List items = new LinkedList<>(); + int left = item.getAmount(); + while (left > 0) { + ItemStack itemClone = item.clone(); + itemClone.setAmount(left > maxStackSize ? maxStackSize : left); + left -= itemClone.getAmount(); + items.add(itemClone); + } + return items.toArray(new ItemStack[items.size()]); + } } diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java b/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java index 2494c78..44e17eb 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java @@ -153,7 +153,7 @@ public class PlayerInteract implements Listener { item.setAmount(amount); - ItemStack[] items = {item}; + ItemStack[] items = InventoryUtil.getItemsStacked(item); TransactionType transactionType = (action == buy ? BUY : SELL); return new PreTransactionEvent(ownerInventory, player.getInventory(), items, price, player, owner, sign, transactionType); @@ -173,8 +173,8 @@ public class PlayerInteract implements Listener { Action buy = Properties.REVERSE_BUTTONS ? LEFT_CLICK_BLOCK : RIGHT_CLICK_BLOCK; Inventory checkedInventory = (action == buy ? inventory : player.getInventory()); - if (checkedInventory.containsAtLeast(item, item.getMaxStackSize())) { - return item.getMaxStackSize(); + if (checkedInventory.containsAtLeast(item, InventoryUtil.getMaxStackSize(item))) { + return InventoryUtil.getMaxStackSize(item); } else { return InventoryUtil.getAmount(item, checkedInventory); } diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/PreTransaction/StockFittingChecker.java b/src/main/java/com/Acrobot/ChestShop/Listeners/PreTransaction/StockFittingChecker.java index fd11551..3424467 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/PreTransaction/StockFittingChecker.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/PreTransaction/StockFittingChecker.java @@ -1,6 +1,7 @@ package com.Acrobot.ChestShop.Listeners.PreTransaction; import com.Acrobot.Breeze.Utils.InventoryUtil; +import com.Acrobot.ChestShop.Database.Item; import com.Acrobot.ChestShop.Events.PreTransactionEvent; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -45,7 +46,8 @@ public class StockFittingChecker implements Listener { } private static boolean itemsFitInInventory(ItemStack[] items, Inventory inventory) { - for (ItemStack item : items) { + ItemStack[] mergedItems = InventoryUtil.mergeSimilarStacks(items); + for (ItemStack item : mergedItems) { if (!InventoryUtil.fits(item, inventory)) { return false; }