1.14.4 When i use InventoryClickEvent it bypasses if's

Discussion in 'Spigot Plugin Development' started by FlameFOxYT, Jul 28, 2020.

  1. I've been trying to use InventoryClickEvent in order to create an edit gui for something,
    and i've created a method that detects when a player picks up an item from his inventory but,
    I save the info about the item, and after 1 tick the item inside the hashmap turns into air,
    when i add the item into the hashmap
    [pickedItem.put(player, item1);]
    when i sysout its the item,
    but after 1 tick it turns into air.
    I have no idea why that happens, I've tried many ways to fix it but no success so far,
    any of you know what can i do?

    Code (Text):

    public class issue implements Listener {

       public HashMap<Player, ItemStack> pickedItem = new HashMap<>();
       
       private Main main;
       public issue(Main main) {
           this.main = main;
       }
       
       
       @EventHandler
       public void onMove(PlayerMoveEvent e) {
           Inventory gui = Bukkit.createInventory(null, 18, "EDIT");
           e.getPlayer().openInventory(gui);
       }
       
       @EventHandler
       public void onClick(InventoryClickEvent e) {
           Player player = (Player) e.getWhoClicked();
           Inventory inv = e.getClickedInventory();
           ClickType type = e.getClick();
           ItemStack item = e.getCurrentItem();
               
           if (inv == player.getInventory()) {
               
               if (type == ClickType.RIGHT || type == ClickType.LEFT) {

                   if (item != null) {
                           
                       if (item.getType() != Material.AIR) {
                               
                           pickedItem.put(player, item);
                           System.out.println(pickedItem.get(player));
                           new BukkitRunnable() {public void run() {
                               System.out.println(pickedItem.get(player));
                           }}.runTaskLater(main, 1);
                       } else {
                           e.setCancelled(true);
                       }
                           
                   } else {
                           
                       if (pickedItem.containsKey(player)) {
                           System.out.println(pickedItem.get(player).getType());
                           pickedItem.remove(player);
                       }
                   }
                           
               } else {
                   e.setCancelled(true);
               }
           }
       }
       
    }

     
     
    #1 FlameFOxYT, Jul 28, 2020
    Last edited: Jul 28, 2020
  2. the gui size is 18
     
  3. I didn't understand much from what you said.
    One question: is the item disappearing when you click another one or the same?
     
  4. when i do this
    Code (Text):

                           System.out.println(pickedItem.get(player));
                           new BukkitRunnable() {public void run() {
                               System.out.println(pickedItem.get(player));
                           }}.runTaskLater(main, 1);
     
    the first sysout gives me the correct item,
    the second one gives me air.
     
  5. Can i see the full code?
     
  6. I updated the code at the thread
     
  7. Here's one:
    Code (Java):
    inv == player.getInventory()
    Not everything uses == to compare. You have to use .equals() in this case, and this is not how you check whether the player is clicking their own inventory or a GUI. You need to use Inventory#getType and use == and check against this enum: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/inventory/InventoryType.html
    (inv.getType() == InventoryType.PLAYER)

    Something else is
    Code (Text):
     new BukkitRunnable() {public void run() {
    Do you know how much it triggers people, it makes your code extremely messy too. Unless you are writing a huge professional plugin that you should only take on when you are very fluent with Java, then go ahead and do something like this. But still though, you should setup your IDE's Formatter to help you format your code.
    Your code is also full of "else"
    Just run the if() statement, then return when the if code has ended, after that, below the if statement, just add your e.setCancelled(true);.
    Remember, code runs from top to bottom.
    So something like this works.
    Code (Java):

    public void potatoPlayer(Player target) {
          if(target.isImmune()) {
               sender.sendMessage("Unable to potato this player, he is immune.");
               return;
          }
          // Code to potato this player
    }
     
  8. Just as a quick sidenote, comparing inventories using == is equivalent to using Object#equals(Object) since the method isn‘t overridden anywhere
     
  9. This is untrue, it's not equivalent because, although the Inventory interface doesn't specify an equals method, the implementing CraftInventory class does override the equals method. https://hub.spigotmc.org/stash/proj...craftbukkit/inventory/CraftInventory.java#520
     
  10. So net.minecraft.server.<version>.IInventory does not override equals, that is not the same as the bukkit wrapper not overriding it. You can use org.bukkit.inventory.Inventory#equals to check whether two inventories are the same inventory, which is exactly OPs use case. I didn't say you can use it to check whether the contents of two inventories are equivalent.
     
  11. What I was saying is that this is not causing a problem here. If two inventories are equal (as defined by Inventory#equals(Object), they are identical and if they are identical they are equal. Obviously equals is preferred to guard against future updates but but it won’t cause problems here.
     
  12. I had encounters in the past where there were multiple bukkitwrappers for the same nms inventory, invalidating this statement.
     
  13. #equals compares the content of the objects to determine if two difference instances of the same object are equal.
    == compares if they are the same instance.

    there will never be more than 1 playerinventory instance declared for an inventory, so using == to compare the inventory is fine. we know this, because his code is executing past this if statement.
    you guys are arguing about dumb shit lol

    @op
    okay, so under the assumption that what youre telling us is undoubtedly true, this implies we have a CraftItemStack instance which wraps the nms item object in that inventory, and after that tick, the object gets updated to air. this would imply using #getItem does not return the item, but the item in that specific slot. so if you click the slot (ie picking up the item), in the next tick, that slot will be set to air. you need to clone the item so that it is not modified again when you put it into the map