Issue with Cancelling an Event / Method Being Called But Not Working

Discussion in 'Spigot Plugin Development' started by liv_golden, Sep 30, 2018.

Thread Status:
Not open for further replies.
  1. I'm trying to cancel an event and setting it cancelled seems to not be working.

    No console errors, heres my code

    Code (Java):
        }
        public void click(final InventoryClickEvent e) {
            e.setCancelled(true);
            Player p123 = (Player) e.getWhoClicked();
            p123.updateInventory();
            int slot = e.getSlot();
            switch(slot) {
                case 0: tradeShards(e);
                    break;
                case 1: tradeStones(e);
                    break;
                default: break;
            }
        }
     
  2. You forgot to include @EventHandler:

    Code (Text):
    @EventHandler
    public void onClick(InventoryClickEvent event) {

    }
     
  3. just added it and no difference :/

    Im also not sure if the method is getting called because the other parts tradeShards and tradeStones aren't getting called either
     
  4. What exactly are you trying to achieve? Also make sure that you implement Listener in your class.
     
  5. im making a gui where when you click specific items it trades items from your inventory into different items, a currency exchange in essence. Ive made a similar one that is working and based this one off of that, and this is the only method that is different.
     
  6. So what exactly is not working and why do you have to cancel the event?
     
  7. I want the event to cancel so that they aren't taking items out of the gui, and the other methods that aren't being called switch out the items in the players inventory for the new ones.
     
  8. Its probably that your not registering the even properly on not implementing listener properly. Can you show me the full class the event is in and your main class.

    Side note:
    Why is the player variable p123? just use generally a good practice is to use "player" (or "p" if you really want something short) cause then anyone updating or depending on your code knows what the hell your talking about and just generally makes things easier.
     
  9. Code (Java):
        public void onEnable() {
            this.guiHandler = new GUIHandler();
            Bukkit.getPluginManager().registerEvents((Listener)this.guiHandler, (Plugin)this);
     
  10. Just fyi casting this.guiHandler to Listener is completely redundant same with casting this to Plugin.
    other than that that code seems fine can you show me the FULL class your listeners in.
     
  11. Sounds goods. You need to check these things:
    • Check if the inventory is equal to the inventory that you are trading in.
      • You can approach this by checking if the name of the player's inventory is the same as the inventory of the event. (player.getInventory().getDisplayName().equals(event.getInventory().getDisplayName()))
      • Or c heck if the event of the inventory equals the inventory of the event (event.getInventory().equals(player.getInventory())
      • It does not matter which way you check this the player or events inventory can come first.
    • You also need to check if there is an item in the slot that the player wants to click on before cancelling the event.
    • Then when all these conditions are met and checked successfully then you take action and cancel the event.

    If this is not working write some debug messages inside the event to check if things are actually run in the first place.
     
  12. Just adding onto this, also check that inventory is your custom trading inventory easiest way to do that is to give the custom inventory a unique name "token trader" for example then get the inventory from the even and check if it has that name otherwise it will cancel the event even if your just say click in a chest.
     

  13. New Code:

    Code (Java):
        @EventHandler
        public void click(final InventoryClickEvent e) {
            if(e.getClickedInventory().getTitle().contains("Blacksmith")) {
                if(e.getCursor() != null) {
                    e.getWhoClicked().sendMessage("click event has been called");
                    e.setCancelled(true);
                    Player p123 = (Player) e.getWhoClicked();
                    p123.updateInventory();
                    int slot = e.getSlot();
                    switch(slot) {
                        case 0: tradeShards(e);
                            break;
                        case 1: tradeStones(e);
                            break;
                        default: break;
                    }
                }  
            }
        }
    Code that calls the broken method:
    Code (Java):
    public class GUIHandler implements Listener {
        private Map<UUID, GUI> guiMap;
       
        public GUIHandler() {
            this.guiMap = new HashMap<UUID, GUI>();
        }
       
        public void createGUI(final Player player) {
            this.guiMap.put(player.getUniqueId(), new GUI(player));
        }
       
        @EventHandler
        public void onInventoryClick(final InventoryClickEvent e) {
            if (e.getWhoClicked() instanceof Player) {
                final Player player = (Player)e.getWhoClicked();
                if (e.getCurrentItem() != null && ChatColor.stripColor(e.getView().getTopInventory().getTitle()).equals(ChatColor.BOLD.toString() + "Asteran Blacksmith") && this.guiMap.containsKey(player.getUniqueId())) {
                    this.guiMap.get(player.getUniqueId()).click(e);
                }
            }
        }
       
        @EventHandler
        public void onInventoryClose(final InventoryCloseEvent e) {
            if (e.getPlayer() instanceof Player) {
                final Player player = (Player)e.getPlayer();
                if (ChatColor.stripColor(e.getView().getTopInventory().getTitle()).equals(ChatColor.BOLD.toString() + "Asteran Blacksmith")) {
                    this.guiMap.get(player.getUniqueId()).dropItems();
                    this.guiMap.remove(player.getUniqueId());
                }
            }
        }
    }
     
    Message doesn't show up and event still not cancelled
     
    #13 liv_golden, Sep 30, 2018
    Last edited: Sep 30, 2018
  14. RandomHashTags

    Supporter

    "ChatColor.stripColor(e.getView().getTopInventory().getTitle()).equals(ChatColor.BOLD.toString() + "Asteran Blacksmith""
    • Correct me if I am wrong, but you're essentially removing all chat colors from the top inventory's title, and you're seeing if it equals a string with chat colors
    • If that is the case, you would just need to remove the "ChatColor.BOLD.toString() +" and it would call the other method, given that your top inventory's title is "Asteran Blacksmith", even if it is chat colored
     
    • Agree Agree x 1
  15. This worked perfectly, thank you so so much!
     
  16. Now my issue is that the method called by the event is getting called (used a debug message to check) but its not trading the items properly

    Code (Text):
        private void tradeStones(InventoryClickEvent e) {
            int totalStones = 0;
            for (int i = 0; i < e.getWhoClicked().getInventory().getSize(); ++i) {
                ItemStack item = e.getWhoClicked().getInventory().getItem(i);
                if (item.equals(asShard)) {
                    totalStones +=item.getAmount();
                }
                int jewelsToGive = Math.floorDiv(totalStones, 14);
                int stonesToRemove = (14*jewelsToGive);
                ItemStack newJewels = new ItemStack(asJewel);
                newJewels.setAmount(jewelsToGive);
                ItemStack oldStones = new ItemStack(asStone);
                oldStones.setAmount(stonesToRemove);
                if (e.getWhoClicked().getInventory().firstEmpty() != -1) {
                    e.getWhoClicked().getInventory().addItem(newJewels);
                    e.getWhoClicked().getInventory().removeItem(oldStones);
                } else {
                    e.getWhoClicked().getWorld().dropItemNaturally(e.getWhoClicked().getLocation(), newJewels);
                    e.getWhoClicked().getInventory().removeItem(oldStones);
                }
            }
        }
     
  17. RandomHashTags

    Supporter

    Any errors when this method is called? It looks like it should send an error.

    Also you should move all the code after the if statement within the brackets to prevent errors.
     
  18. no errors, but debug messages showed me that its the for statement that isn't getting run, trying to move code into the if statement now
     
  19. You sure that you have @EventHandler above?
    Try to check if the event isn't cancelled already
    Make sure to check if the Inventory open is the inventory you want
     
  20. EventHandler is above the click event but the 2 methods it calls don't, do they need it?

    Update: added the 2 @EventHandler things and the debug message is working, however the two lines that take out the item and replace it with another aren't trading

    Current Code:
    Code (Text):
        @EventHandler
        private void tradeStones(InventoryClickEvent e) {
            int totalStones = 0;
            for (int i = 0; i < e.getWhoClicked().getInventory().getSize(); ++i) {
                ItemStack item = e.getWhoClicked().getInventory().getItem(i);
                if (item != null && item.getType() != Material.AIR && item.equals(asShard)) {
                    totalStones += item.getAmount();
                }
                int jewelsToGive = Math.floorDiv(totalStones, 14);
                int stonesToRemove = (14 * jewelsToGive);
                ItemStack newJewels = new ItemStack(asJewel);
                newJewels.setAmount(jewelsToGive);
                ItemStack oldStones = new ItemStack(asStone);
                oldStones.setAmount(stonesToRemove);
                if (e.getWhoClicked().getInventory().firstEmpty() != -1) {
                    e.getWhoClicked().getInventory().addItem(newJewels);
                    e.getWhoClicked().getInventory().removeItem(oldStones);
                } else {
                    e.getWhoClicked().getWorld().dropItemNaturally(e.getWhoClicked().getLocation(), newJewels);
                    e.getWhoClicked().getInventory().removeItem(oldStones);
                }
            }
        }
    Also I know its going through the items in the correct inventory because of this:
    @ImIllusion

    https://hastebin.com/ebotobibah.md
     
    #20 liv_golden, Sep 30, 2018
    Last edited: Oct 1, 2018
Thread Status:
Not open for further replies.