Fix stacking issues (Fixes #74)

This also fixes some conditions under which the STACK_TO_64 option did not get applied correctly and wrong inventory space checking for items with a max stack size of less than 64
This commit is contained in:
Phoenix616 2017-09-06 14:19:34 +01:00
parent 7199acb8ef
commit 9da7d5198b
3 changed files with 43 additions and 15 deletions

View File

@ -6,9 +6,9 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.Acrobot.ChestShop.Configuration.Properties;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
/** /**
* @author Acrobot * @author Acrobot
@ -83,7 +83,8 @@ public class InventoryUtil {
* @return Does the inventory contain stock of this type? * @return Does the inventory contain stock of this type?
*/ */
public static boolean hasItems(ItemStack[] items, Inventory inventory) { 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()) { if (getAmount(item, inventory) < item.getAmount()) {
return false; return false;
} }
@ -112,7 +113,7 @@ public class InventoryUtil {
} }
if (MaterialUtil.isEmpty(iStack)) { if (MaterialUtil.isEmpty(iStack)) {
left -= item.getMaxStackSize(); left -= getMaxStackSize(item);
continue; continue;
} }
@ -120,7 +121,7 @@ public class InventoryUtil {
continue; continue;
} }
left -= (iStack.getMaxStackSize() - iStack.getAmount()); left -= (getMaxStackSize(iStack) - iStack.getAmount());
} }
return left <= 0; return left <= 0;
@ -211,12 +212,7 @@ public class InventoryUtil {
Map<Integer, ItemStack> leftovers = inventory.removeItem(item); Map<Integer, ItemStack> leftovers = inventory.removeItem(item);
if (!leftovers.isEmpty()) { if (!leftovers.isEmpty()) {
for (Iterator<ItemStack> iterator = leftovers.values().iterator(); iterator.hasNext(); ) { leftovers.values().removeIf(left -> removeManually(left, inventory) == 0);
ItemStack left = iterator.next();
if (removeManually(left, inventory) == 0) {
iterator.remove();
}
}
} }
return countItems(leftovers); return countItems(leftovers);
@ -261,7 +257,7 @@ public class InventoryUtil {
} }
} }
itemList.add(item); itemList.add(item.clone());
} }
return itemList.toArray(new ItemStack[itemList.size()]); return itemList.toArray(new ItemStack[itemList.size()]);
@ -298,4 +294,34 @@ public class InventoryUtil {
return totalLeft; 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<ItemStack> 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()]);
}
} }

View File

@ -153,7 +153,7 @@ public class PlayerInteract implements Listener {
item.setAmount(amount); item.setAmount(amount);
ItemStack[] items = {item}; ItemStack[] items = InventoryUtil.getItemsStacked(item);
TransactionType transactionType = (action == buy ? BUY : SELL); TransactionType transactionType = (action == buy ? BUY : SELL);
return new PreTransactionEvent(ownerInventory, player.getInventory(), items, price, player, owner, sign, transactionType); 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; Action buy = Properties.REVERSE_BUTTONS ? LEFT_CLICK_BLOCK : RIGHT_CLICK_BLOCK;
Inventory checkedInventory = (action == buy ? inventory : player.getInventory()); Inventory checkedInventory = (action == buy ? inventory : player.getInventory());
if (checkedInventory.containsAtLeast(item, item.getMaxStackSize())) { if (checkedInventory.containsAtLeast(item, InventoryUtil.getMaxStackSize(item))) {
return item.getMaxStackSize(); return InventoryUtil.getMaxStackSize(item);
} else { } else {
return InventoryUtil.getAmount(item, checkedInventory); return InventoryUtil.getAmount(item, checkedInventory);
} }

View File

@ -1,6 +1,7 @@
package com.Acrobot.ChestShop.Listeners.PreTransaction; package com.Acrobot.ChestShop.Listeners.PreTransaction;
import com.Acrobot.Breeze.Utils.InventoryUtil; import com.Acrobot.Breeze.Utils.InventoryUtil;
import com.Acrobot.ChestShop.Database.Item;
import com.Acrobot.ChestShop.Events.PreTransactionEvent; import com.Acrobot.ChestShop.Events.PreTransactionEvent;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -45,7 +46,8 @@ public class StockFittingChecker implements Listener {
} }
private static boolean itemsFitInInventory(ItemStack[] items, Inventory inventory) { 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)) { if (!InventoryUtil.fits(item, inventory)) {
return false; return false;
} }