Problem with removing item from Player Inventory

Discussion in 'Plugin Development' started by kev3200, Apr 1, 2015.

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

    kev3200

    Hi there,

    Just had a quick problem that I think should work.. but doesn't for some reason.

    Code:
        @EventHandler
        public void onInventoryClick(InventoryClickEvent e) {
            Player p = (Player) e.getWhoClicked();
            Material clicked = e.getCurrentItem().getType();
            Inventory inv = p.getInventory();
            World w = p.getWorld();
    
            if (e.getInventory().equals(smelt)) {
                e.setCancelled(true);
                if (clicked.equals(Material.CLAY_BRICK)) {
                    if (inv.contains(Material.REDSTONE_ORE, 1) && inv.contains(Material.CLAY, 1)) {
                        inv.removeItem(new ItemStack(Material.REDSTONE_ORE, 1));
                        inv.removeItem(new ItemStack(Material.CLAY, 1));
                        inv.addItem(makeItem(Material.CLAY_BRICK, "Bronze Bar", "A bar of bronze", 1));
                        p.updateInventory();
                        w.playSound(p.getLocation(), Sound.FIZZ, 10, 1);
                    }
                    else {
                        p.closeInventory();
                        p.sendMessage(GOLD + "You don't have enough materials to make that!\n" +
                                      RED + "Required: " + WHITE + "1 Tin, 1 Copper");
                    }
                }
            }
        }
    This should (when the player is in the inventory called smelt) test whether a player clicks on the clay_brick. If so, it will see if Player has at least 1 Redstone ore and 1 clay block. If that is true, it should remove those two items, give the player a clay_brick (using a custom method called makeItem(Material, String, String, int) which returns an ItemStack), and then play the Fizz sound.

    Everything works except the removeItem part. When I click on the Clay_brick, a "Bronze Bar" appears in my inventory but the redstone_ore and clay are not removed. Which means I can just spam the clay_brick to get as many "Bronze Bar" as I want.
     
  2. Offline

    CheesyFreezy

    Heey, in the first if statement you're checking if the e.getInventory() is equal to the inventory smelt. What you want to do is check if the name of the inventory is equal to Smelt

    Code:
    if(e.getInventory().getName().equalsIgnoreCase("Smelt")) {
       //Do stuff here
    }
     
    sgavster likes this.
  3. Offline

    kev3200

    Ok thanks. Any idea why the rest isn't working then?

    Anyone else know the answer to this? Some help would be greatly appreciated! :)
     
    Last edited by a moderator: Apr 1, 2015
  4. Offline

    kev3200

    It's been a while and I'm still looking for a solution. Any help out there?!
     
  5. Offline

    caderape

    @kev3200
    if(inv.contains(Material.REDSTONE_ORE, 1)&& inv.contains(Material.CLAY, 1))

    You're checking if the inventory contains just one redstone for example. So if the player has two redstone stacked, it will not work.
    Try #containsatleast
     
  6. Offline

    kev3200

    That's actually not the problem I'm having. But good to know for the future. My problem is that the redstone_ore has a custom display name and isn't being recognized by its base material.
     
  7. Offline

    Msrules123

    Then get the original ItemStack, check if the type is redstone_ore and if the item has ItemMeta.
     
  8. Offline

    caderape

    @kev3200 Loops the contents of the inventory and check the type and the data so
     
  9. Offline

    kev3200

    Ok. that sounds like what I need to do... How would I do that? Code example would be appreciated. (not specific please, I want to figure out details for myself, if you know what I mean.) Thanks btw.
     
  10. Offline

    Msrules123

    You already have the ItemStack defined in line #4, just remove the #getMaterial.

    You can check if an ItemStack is the Material type of Redstone_Ore and has ItemMeta with #hasItemMeta. Then if it does have the ItemMeta, make sure it is the ItemMeta you want by checking the display name and the lore, depending on what you need.

    Try to figure that out first, and if you can't, open this spoiler. (It is a vague piece of code, you'll have to customize it and fill in the blanks).

    Code (open)

    Code:
    ItemStack item = e.getCurrentItem();
            if(*Blank*.hasItemMeta() && item.getType() == *Blank*) {
                if(item.getItemMeta().equals(*Your ItemMeta*)) {
                    // Do something
                }
            }
     
  11. Offline

    kev3200

    Alright that works. However, having another issue now. My checkItem method works well. I am getting the "You have the right stuff!" in-game but the Redstone_Ore item is not being removed.

    Code:
        @EventHandler
        public void onInventoryClick(InventoryClickEvent e) {
            Player p = (Player) e.getWhoClicked();
            Material clicked = e.getCurrentItem().getType();
            Inventory inv = p.getInventory();
            World w = p.getWorld();
    
            if (e.getInventory().equals(smelt)) {
                e.setCancelled(true);
                if (clicked.equals(Material.CLAY_BRICK)) {
                   
                    if (checkItem(inv, Material.REDSTONE_ORE) && checkItem(inv, Material.CLAY)) {
                        p.sendMessage("You have the right stuff!");
                        inv.remove(new ItemStack(Material.REDSTONE_ORE, 1));
                        //inv.removeItem(new ItemStack(Material.REDSTONE_ORE));
                        //inv.removeItem(new ItemStack(Material.CLAY));
                        inv.addItem(makeItem(Material.CLAY_BRICK, "Bronze Bar",    "A bar of bronze", 1));
                        p.updateInventory();
                        w.playSound(p.getLocation(), Sound.FIZZ, 10, 1);
                    }
                    else {
                        p.closeInventory();
                        p.sendMessage(GOLD + "You don't have enough materials to make that!\n" + RED + "Required: " + WHITE + "1 Tin, 1 Copper");
                    }
                }
            }
        }
    
        public boolean checkItem(Inventory inv, Material m) {
            for (int i = 0; i < inv.getSize(); i++) {
                ItemStack item = new ItemStack(inv.getItem(i));
                if (item != null) {
                    if (item.getType().equals(m)) {
                      return true;
                    }
                }
            }
            return false;
        }
     
  12. Offline

    Zombie_Striker

    Use == instead of .equals with dealing with Enums.

    If you know that the only redstone ore that will be in that players inventory will be that one, you can make a While loop that checks while the player's inventory.contains redstoneore, will remove any redstone ore from their inventory.

    The while loop will stop once the player no long has redstone ore in their inventory.
     
  13. Offline

    BrickBoy55

    @Zombie_Striker

    I always use .equals for enums and it doesn't throw an error for me?
     
  14. Offline

    Zombie_Striker

    @BrickBoy55
    Its not that it doesn't work, Its that using == for Enums is the official and proper way of testing if something equals something else ( If you plan on making anything professional or going into the coding field, Its better to get into the habit of doing it now compared to after doing it the wrong way for years.)
     
  15. Offline

    kev3200

    Actually, in java == only compares references to objects. .equals() refers to the actual contents. (CIS201 java class) Not saying one is better, but it really depends on what you use it for. Neither one is "better" than the other.

    Ok and about the while loop, not quite what I'm looking for. The Redstone_ore is more like ingredients. When I click on the clay_brick in the inventory, I want 1 redstone_ore and 1 clay to be removed from the player's inventory, and then stop. Sort of like a shop. If they click on the clay_brick again, 1 redstone_ore and 1 clay will be removed again. If they don't have the proper amount of ingredients, a message will pop up telling them that they don't have enough.

    My problem then is that the redstone_ore and clay are not being removed at all. (keep in mind that both of these have custom display names, not sure if that effects their removal process)

    Sorry, was that a little bit clearer? I realize just plain code can be confusing sometimes, my bad.
     
    Last edited: Apr 11, 2015
  16. Offline

    kev3200

    Any idea why the code isn't working? Enum conventions are nice but don't solve my problem :) I'm not looking to remove all the redstone ore. Only 1 every time the player clicks.
     
Thread Status:
Not open for further replies.

Share This Page