For my plugin BattleNight I am adding a method which will split items into the correct stack size. The code shown below is what I have created so far. Can you please check over my maths for errors and suggest any ways this can be improved/optimised. Code:Java private List<ItemStack> splitIntoStacks(ItemStack item, int amount) { List<ItemStack> items = new ArrayList<ItemStack>(); final int maxSize = item.getMaxStackSize(); final double remainder = amount % maxSize; final int fullStacks = (int) ((amount / item.getMaxStackSize()) - remainder); ItemStack fullStack = item; ItemStack finalStack = item; fullStack.setAmount(maxSize); finalStack.setAmount((int) (remainder * maxSize)); for (int i=0; i<fullStacks; i++) { items.add(fullStack); } items.add(finalStack); return items;}
First of all, 'a % b' is 'a modulo b' and returns the remainder of the integer division a/b, i.e. an integer such that ((int)(a/b))*b + a%b = a. This means that you should not subtract the remainder in this line: Code:Java final int fullStacks = (int) ((amount / item.getMaxStackSize()) - remainder); And you don't have to multiply it with maxSize in this line: Code:Java finalStack.setAmount((int) (remainder * maxSize)); Also you have to clone the stack to have two stacks of different sizes: Code:Java ItemStack fullStack = item.clone();ItemStack finalStack = item.clone(); I also suggest to use an array instead of an ArrayList as you know it's exact size. This is the code with all changes applied: Code:Java private ItemStack[] splitIntoStacks(ItemStack item, int amount) { final int maxSize = item.getMaxStackSize();final int remainder = amount % maxSize;final int fullStacks = (int) Math.floor(amount / item.getMaxStackSize()); ItemStack fullStack = item.clone();ItemStack finalStack = item.clone();fullStack.setAmount(maxSize);finalStack.setAmount(remainder); ItemStack[] items = new ItemStack[fullStacks+1]; for (int i=0; i<fullStacks; i++) {items[i] = fullStack;}items[items.length - 1] = finalStack; return items;}[/i]
Thanks for your help! Can anyone else improve this further? EDIT by Moderator: merged posts, please use the edit button instead of double posting.
I don't think it's possible to improve it any further, as it should get it's job done Just for reference here's my method to add an ItemStack to an array of ItemStacks (also useful for adding itemstacks to an inventory): Code:java private static boolean addTo(final ItemStack is, final ItemStack[] buf) { if (is == null || is.getTypeId() == 0) return true; int added = 0; for (int i = 0; i < buf.length; i++) { if (Utils.itemStacksEqual(is, buf[i])) { final int toAdd = Math.min(buf[i].getMaxStackSize() - buf[i].getAmount(), is.getAmount() - added); added += toAdd; buf[i].setAmount(buf[i].getAmount() + toAdd); if (added == is.getAmount()) return true; } } for (int i = 0; i < buf.length; i++) { if (buf[i] == null) { final int toAdd = Math.min(is.getMaxStackSize(), is.getAmount() - added); added += toAdd; buf[i] = is.clone(); buf[i].setAmount(toAdd); if (added == is.getAmount()) return true; } } return false; }[/i][/i][/i][/i][/i][/i][/i][/i] And the function Utils.itemStacksEqual: Code:java public static boolean itemStacksEqual(final ItemStack is1, final ItemStack is2) { if (is1 == null || is2 == null) return is1 == is2; return is1.getTypeId() == is2.getTypeId() && is1.getDurability() == is2.getDurability(); }