Removing items from inventory

Discussion in 'Plugin Development' started by Pink__Slime, Jun 8, 2013.

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

    Pink__Slime

    Hey community,
    I've been looking for a way to remove items from players inventories and I have come up short.
    I have been using this method but it doesn't work for multiple stacks.
    Code:java
    1. public static int remove(Inventory inventory, Material mat, int amount, short damage)
    2. {
    3. ItemStack[] contents = inventory.getContents();
    4. int removed = 0;
    5. for (int i = 0; i < contents.length; i++) {
    6. ItemStack item = contents[i];
    7.  
    8. if (item == null || !item.getType().equals(mat)) {
    9. continue;
    10. }
    11.  
    12. if (damage != (short) -1 && item.getDurability() != damage) {
    13. continue;
    14. }
    15.  
    16. int remove = item.getAmount() - amount - removed;
    17.  
    18. if (removed > 0) {
    19. removed = 0;
    20. }
    21.  
    22. if (remove <= 0) {
    23. removed += Math.abs(remove);
    24. contents[i] = null;
    25. } else {
    26. item.setAmount(remove);
    27. }
    28. }
    29. return removed;
    30. }[/i][/i]


    Also, this method breaks and stops working when there is only 1 item left.
    This is what I did before but there is no way to check when it's not in the player's hand that I'm aware of.
    Code:java
    1. if(p.getInventory().getItemInHand().getAmount() > 1){
    2. InventoryMethods.remove(p.getInventory(), Material.SLIME_BALL, 1, (short)0);
    3. }else{
    4. p.getInventory().remove(Material.SLIME_BALL);
    5. }


    Basically, what I want to do is simulate a flamethrower. Your ammunition for it will be in your inventory (5-6 stacks of coal) and when you right click it removes 1. Instead, it removes 1 from each stack until there is one left and I can't do anything.

    Code:java
    1. }else if(p.getItemInHand() != null && p.getItemInHand().getType().equals(Material.FLINT_AND_STEEL)){
    2. if(Main.playFlamethrower.containsKey(p.getName())){
    3. if(p.getInventory().contains(Material.COAL)){
    4. FallingBlock fire = p.getWorld().spawnFallingBlock(p.getEyeLocation().add(p.getLocation().getDirection().normalize()), Material.FIRE, (byte)0);
    5. fire.setVelocity(p.getLocation().getDirection().multiply(2));
    6. Debug.tryDebug(p.getName() + " shot fire as Flamethrower");
    7. if(p.getInventory().contains(Material.COAL, 1)){
    8. InventoryMethods.remove(p.getInventory(), Material.COAL, 1, (short)0);
    9. }
    10. }
    11. }
    12. }
     
  2. Offline

    Technius

    Pink__Slime
    Since the items retrieved from the inventory are usually copies, you'll have to set the items in the slots back to the ItemStack you used. All you have to do is add
    Code:
    inventory.setItem(i, item);
    
    after you set the item amount.
     
  3. Offline

    Pink__Slime

    Technius
    Doesn't change anything to what I have sadly.
     
  4. Offline

    Technius

    Pink__Slime
    Here's an improved version of your remove method.
    Code:
    //Untested
    public static int removeItems(Inventory inv, Material mat, int amount, short damage)
    {
        ItemStack[] contents = inv.getContents();
        int removed = 0;
        final short negone = (short)-1;
        for(int i = 0; i < contents.length; i ++)
        {
            if(removed >= amount)break;
            ItemStack is = contents[i];
            if(is == null)continue;
            if(is.getType() != mat)continue;
            if(damage != negone && item.getDurability() != damage)continue;
            int a = is.getAmount();
            int r;
            if(removed + a > amount)
            {
                r = removed + a - amount;
            }
            else r = a;
            int t = a - r;
            removed += t;
            inv.setItem(i, t);
        }
        return removed;
    }
    
    Edit: Updated code
    Edit 2: Updated code again. Might work now.
     
  5. Offline

    Pink__Slime

    Technius
    inv.setItem(i, t) isn't applicable for int, int.
     
  6. Offline

    afistofirony

    Pink__Slime what exactly are you trying to do with your code? From what I see, it looks like you're basically excluding what you find from being removed... if I'm wrong, please explain the code to me.

    Here's how I would do it.

    Code:
    public static int removeItems(Inventory inv, Material mat, int amount, short damage) {
        int removed = 0;
        for (int i = 0; i < 36; i++) {
            ItemStack is = inv.getItem(i);
            int old = is.getAmount();
            if (is.getType() == mat && is.getDurability() == damage) {
                int finalAmt = old - amount;
                ItemStack stack = new ItemStack(is.getType(), finalAmt, is.getDurability());
                inv.setItem(i, (finalAmt > 0 ? stack : null));
                removed += (finalAmt > 0 ? old - finalAmt : old);
            }
      } return removed;
    }
     
  7. Offline

    Pink__Slime

    afistofirony
    Basically, when a player right clicks flint n steel, it shoots a falling fire block and takes 1 coal from his/her inventory. Except, it takes 1 from each stack when it's only meant to take it from 1 stack.
     
  8. Offline

    afistofirony

    Pink__Slime Oh, okay, I see now. Just add a break statement :p

    Code:
    public static int removeItems(Inventory inv, Material mat, int amount, short damage) {
        int removed = 0;
        for (int i = 0; i < 36; i++) {
            ItemStack is = inv.getItem(i);
            int old = is.getAmount();
            if (is.getType() == mat && is.getDurability() == damage) {
                int finalAmt = old - amount;
                ItemStack stack = new ItemStack(is.getType(), finalAmt, is.getDurability());
                inv.setItem(i, (finalAmt > 0 ? stack : null));
                removed += (finalAmt > 0 ? old - finalAmt : old);
                if (removed >= amount) break; // Stop if the quota of removals has been met
            }
      } return removed;
    }
     
  9. Offline

    Pink__Slime

    afistofirony
    Slight problem.
    This works PERFECTLY for the first stack. Then for the remaining stacks absolutely nothing happens.
     
    kevc45 likes this.
  10. Offline

    afistofirony

    Wait, I thought that's what you wanted :confused:
     
  11. Offline

    Pink__Slime

    afistofirony
    Ok I'll try and explain a bit :p
    Player right clicks flint n steel. Falling fire block is spawned. 1 coal gets removed from the first stack.
    If one stack is empty, then continue with the second one. When that's finished, go to the third and so on.
     
  12. Offline

    Technius

    Pink__Slime
    Oops, forgot something. Try this. Sorry for the mistakes, it was late at night.
    Code:
    //Untested
    public static int removeItems(Inventory inv, Material mat, int amount, short damage)
    {
        ItemStack[] contents = inv.getContents();
        int removed = 0;
        final short negone = (short)-1;
        for(int i = 0; i < contents.length; i ++)
        {
            if(removed >= amount)break;
            ItemStack is = contents[i];
            if(is == null)continue;
            if(is.getType() != mat)continue;
            if(damage != negone && item.getDurability() != damage)continue;
            int a = is.getAmount();
            int r;
            if(removed + a > amount)
            {
                r = removed + a - amount;
            }
            else r = a;
            int t = a - r;
            removed += t;
            is.setAmount(t);
            inv.setItem(i, is);
        }
        return removed;
    }
    
     
  13. Offline

    Pink__Slime

    Technius
    Is:
    if(damage != negone && item.getDurability() != damage)continue;
    meant to be:
    if(damage != negone && is.getDurability() != damage) continue;
     
  14. Offline

    Technius

  15. Offline

    Pink__Slime

    Technius
    Hehe your method works but in a very wrong way xD
    I have 7 stacks in my inventory. When I trigger it once, it removes all but one in that stack. When I trigger it again, it removes that one and leaves the next stack with one.
     
  16. Offline

    Technius

    Pink__Slime
    Do you have an extra item not in a stack somewhere in your inventory?
     
  17. Offline

    Pink__Slime

    Technius
    7 full, complete stacks of coal.
     
Thread Status:
Not open for further replies.

Share This Page