Solved Removing items from inventory not working?

Discussion in 'Plugin Development' started by Moneymaster2012, Dec 27, 2016.

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

    Moneymaster2012

    I am running the 1.11.1 Bukkit api, and I just can't figure out this problem. It always prints out "You don't have enough carrots" even when I have 4/more than 4.

    Code:
        @EventHandler
        public void onPlayerInteract2(PlayerInteractEvent e) {
            Player p = e.getPlayer();
            int pay = Integer.parseInt(settings.getData().getString("players." + p.getDisplayName() + ".money"));
            if (!(e.getAction() == Action.RIGHT_CLICK_BLOCK))
                return;
            if (e.getClickedBlock().getState() instanceof Sign) {
                Sign s = (Sign) e.getClickedBlock().getState();
                if (s.getLine(1).equalsIgnoreCase("§a§l[Sell]")) {
                    ItemStack item = new ItemStack(Material.CARROT, 4);
                    if(p.getInventory().contains(Material.CARROT, 4)){
                        int finalPay = pay + 1;
                       
                        p.getInventory().removeItem(item);
                       
                        settings.getData().set("players." + p.getDisplayName() + ".money", finalPay);
                        settings.saveData();
                        p.sendMessage("§aSuccessfully sold 4 carrots for 1 coin!");
                    } else {
                        p.sendMessage("§cYou do not have enough carrots!");
                    }
                }
            }
        }
     
  2. Offline

    Zombie_Striker

    This is your problem. This method works best if you just want to know if the inventory contains the item, not checking amounts and other data.

    Instead, for loop through all the contents of the inventory. For each itemstack, check if the item is a carrot. If so, check the amount. If the amount is greater than 4, subtract 4 from the item's amount and update the stack. If it is equal to 4, remove the itemstack.
     
  3. Offline

    Moneymaster2012

    So something like this?
    Code:
    for(ItemStack item:inv){
    if(item.getType().equals(i.getType())){
    Could you please give an example?
     
  4. Offline

    ShaneCraftDev

    @Moneymaster2012

    Do not use equals for enums, use the == operator instead.
    Inventory#contains(Material material, int amount) should work, however it is better to iterate over all itemstacks until the item has been found. If the itemstack has been found, you can easily remove that stack from the inventory instance

    Code:java
    1.  
    2. Inventory inv = ...;
    3. ItemStack stackToRemove = null;
    4. for (ItemStack stack : inv.getContents()) {
    5. if (stack.getType() == Material.CARROT && stack.getAmount() == 4) {
    6. stackToRemove = stack;
    7. break;
    8. }
    9. }
    10. if (stackToRemove != null) {
    11. inv.remove(stackToRemove);
    12. }
    13.  
    14.  
     
  5. Offline

    Moneymaster2012

    is this even remotely close?
    Code:
    @EventHandler
        public void onPlayerInteract2(PlayerInteractEvent e) {
            Player p = e.getPlayer();
            int pay = Integer.parseInt(settings.getData().getString("players." + p.getDisplayName() + ".money"));
            if (!(e.getAction() == Action.RIGHT_CLICK_BLOCK))
                return;
            if (e.getClickedBlock().getState() instanceof Sign) {
                Sign s = (Sign) e.getClickedBlock().getState();
                if (s.getLine(1).equalsIgnoreCase("§a§l[Sell]")) {
                    ItemStack item = new ItemStack(Material.CARROT, 4);
                    if(p.getInventory().contains(Material.CARROT, 4)){
                        int finalPay = pay + 1;
                       
                        p.getInventory().removeItem(item);
                       
                        settings.getData().set("players." + p.getDisplayName() + ".money", finalPay);
                        settings.saveData();
                        p.sendMessage("§aSuccessfully sold 4 carrots for 1 coin!");
                    } else {
                        p.sendMessage("§cYou do not have enough carrots!");
                    }
                }
            }
        }
    oops wrong one

    EDIT: The whole forums edit thing is completely messed up. I can't edit the code.

    Code:
        @EventHandler
        public void onPlayerInteract3(PlayerInteractEvent e) {
            Player p = e.getPlayer();
            if (!(e.getAction() == Action.RIGHT_CLICK_BLOCK))
                return;
            if (e.getClickedBlock().getState() instanceof Sign) {
                Sign s = (Sign) e.getClickedBlock().getState();
                if (s.getLine(1).equalsIgnoreCase("§a§l[Sell]")) {
                  
                    Inventory inv = p.getInventory();
                    ItemStack stackToRemove = null;
                    for (ItemStack stack : inv.getContents()) {
                        if (stack.getType() == Material.CARROT && stack.getAmount() == 4) {
                            p.sendMessage("You have enough!");
                            stackToRemove = stack;
                            break;
                        } else {
                            p.sendMessage("Not enough");
                        }
                    }
                    if (stackToRemove != null) {
                        inv.remove(stackToRemove);
                    }
                  
                }
            }
        }
    Is that even remotely close?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
  6. Offline

    ShaneCraftDev

    @Moneymaster2012

    For me (using bukkit for mc 1.10) Inventory#contains(Material material, int amount) works as intended, however I have posted the a working example that does what you are trying to do. If the ItemStack "stackToRemove" is not null, that means it has found an itemstack with ONLY a size of 4. If you have more carrots on the same itemstack, it will not work. You would have to take from the itemstack if there are more then 4.
     
  7. Offline

    Moneymaster2012

    Hmm, but my code gives an error in the console whenever I right click the sign.
     
  8. Offline

    Zombie_Striker

  9. Offline

    Moneymaster2012

    Code:
    [19:53:07 ERROR]: Could not pass event PlayerInteractEvent to HarryPotter v1.0
    org.bukkit.event.EventException
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at org.bukkit.craftbukkit.v1_11_R1.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:232) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at net.minecraft.server.v1_11_R1.PlayerInteractManager.a(PlayerInteractManager.java:444) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at net.minecraft.server.v1_11_R1.PlayerConnection.a(PlayerConnection.java:904) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at net.minecraft.server.v1_11_R1.PacketPlayInUseItem.a(PacketPlayInUseItem.java:37) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at net.minecraft.server.v1_11_R1.PacketPlayInUseItem.a(PacketPlayInUseItem.java:1) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at net.minecraft.server.v1_11_R1.PlayerConnectionUtils$1.run(SourceFile:13) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_111]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_111]
        at net.minecraft.server.v1_11_R1.SystemUtils.a(SourceFile:46) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at net.minecraft.server.v1_11_R1.MinecraftServer.D(MinecraftServer.java:739) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at net.minecraft.server.v1_11_R1.DedicatedServer.D(DedicatedServer.java:399) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at net.minecraft.server.v1_11_R1.MinecraftServer.C(MinecraftServer.java:675) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at net.minecraft.server.v1_11_R1.MinecraftServer.run(MinecraftServer.java:574) [spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        at java.lang.Thread.run(Thread.java:745) [?:1.8.0_111]
    Caused by: java.lang.NullPointerException
        at com.mccalmon.hp.main.onPlayerInteract3(main.java:190) ~[?:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_111]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_111]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_111]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_111]
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:302) ~[spigot.jar:git-Spigot-9deaa4c-8ea0c87]
        ... 17 more
     
  10. Offline

    ShaneCraftDev

    @Moneymaster2012
    Inventory#getContents returns all slots, empty slots are null. Just add a null check. Another note, I just realized it is CARROT_ITEM and not CARROT for the appropriate Material instance. CARROT is the Material for blocks.
     
  11. Offline

    Zombie_Striker

    @Moneymaster2012
    First, you should not have more than 1 of an event. If you have to add "3" to the method name, that means you have atleast 3 other methods of the same event. Merge them so you only have one method for the event.

    What is line 190? Something on that line is null.
     
  12. Offline

    Moneymaster2012

    if (stack.getType() == Material.CARROT && stack.getAmount() >= 4) {

    That's the line I'm having trouble with

    THANK YOU SO MUCH! Haha I haven't thought of that. It works perfectly. No errors :)

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Dec 27, 2016
Thread Status:
Not open for further replies.

Share This Page