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.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<Integer, ItemStack> leftovers = inventory.removeItem(item);
if (!leftovers.isEmpty()) {
for (Iterator<ItemStack> 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<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);
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);
}

View File

@ -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;
}