ItemStack splitter

Discussion in 'Plugin Development' started by Aza24, Jul 17, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    Aza24

    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
    1. private List<ItemStack> splitIntoStacks(ItemStack item, int amount) {
    2. List<ItemStack> items = new ArrayList<ItemStack>();
    3.  
    4. final int maxSize = item.getMaxStackSize();
    5. final double remainder = amount % maxSize;
    6. final int fullStacks = (int) ((amount / item.getMaxStackSize()) - remainder);
    7.  
    8. ItemStack fullStack = item;
    9. ItemStack finalStack = item;
    10. fullStack.setAmount(maxSize);
    11. finalStack.setAmount((int) (remainder * maxSize));
    12.  
    13. for (int i=0; i<fullStacks; i++) {
    14. items.add(fullStack);
    15. }
    16.  
    17. items.add(finalStack);
    18.  
    19. return items;
    20. }
     
    hawkfalcon likes this.
  2. Offline

    Njol

    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
    1. final int fullStacks = (int) ((amount / item.getMaxStackSize()) - remainder);

    And you don't have to multiply it with maxSize in this line:
    Code:Java
    1. finalStack.setAmount((int) (remainder * maxSize));


    Also you have to clone the stack to have two stacks of different sizes:
    Code:Java
    1. ItemStack fullStack = item.clone();
    2. 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
    1. private ItemStack[] splitIntoStacks(ItemStack item, int amount) {
    2.  
    3. final int maxSize = item.getMaxStackSize();
    4. final int remainder = amount % maxSize;
    5. final int fullStacks = (int) Math.floor(amount / item.getMaxStackSize());
    6.  
    7. ItemStack fullStack = item.clone();
    8. ItemStack finalStack = item.clone();
    9. fullStack.setAmount(maxSize);
    10. finalStack.setAmount(remainder);
    11.  
    12.  
    13. ItemStack[] items = new ItemStack[fullStacks+1];
    14.  
    15. for (int i=0; i<fullStacks; i++) {
    16. items[i] = fullStack;
    17. }
    18. items[items.length - 1] = finalStack;
    19.  
    20. return items;
    21. }[/i]
     
    hawkfalcon likes this.
  3. Offline

    Aza24

    Thanks for your help!

    Can anyone else improve this further?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 27, 2016
  4. Offline

    Njol

    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
    1. private static boolean addTo(final ItemStack is, final ItemStack[] buf) {
    2. if (is == null || is.getTypeId() == 0)
    3. return true;
    4. int added = 0;
    5. for (int i = 0; i < buf.length; i++) {
    6. if (Utils.itemStacksEqual(is, buf[i])) {
    7. final int toAdd = Math.min(buf[i].getMaxStackSize() - buf[i].getAmount(), is.getAmount() - added);
    8. added += toAdd;
    9. buf[i].setAmount(buf[i].getAmount() + toAdd);
    10. if (added == is.getAmount())
    11. return true;
    12. }
    13. }
    14. for (int i = 0; i < buf.length; i++) {
    15. if (buf[i] == null) {
    16. final int toAdd = Math.min(is.getMaxStackSize(), is.getAmount() - added);
    17. added += toAdd;
    18. buf[i] = is.clone();
    19. buf[i].setAmount(toAdd);
    20. if (added == is.getAmount())
    21. return true;
    22. }
    23. }
    24. return false;
    25. }[/i][/i][/i][/i][/i][/i][/i][/i]

    And the function Utils.itemStacksEqual:
    Code:java
    1. public static boolean itemStacksEqual(final ItemStack is1, final ItemStack is2) {
    2. if (is1 == null || is2 == null)
    3. return is1 == is2;
    4. return is1.getTypeId() == is2.getTypeId() && is1.getDurability() == is2.getDurability();
    5. }
     
Thread Status:
Not open for further replies.

Share This Page