1.8.8 Inventory Interact and Drag Event problems

Discussion in 'Spigot Plugin Development' started by Gustavo_kio, Jan 22, 2020.

  1. So, I'm creating a custom gui and I'm having some problems preventing players to add items to the inventory.

    What do i wanna achive:

    - I want players to use their own inventory even with the custom gui opened.
    - I want players to grab and drag certain items from the custom gui to his inventory (done with the onClick method bellow)
    - I don't want players to add items to empty (air) slots in the custom inventory.

    What is happening:


    My code:

    Code (Java):
    @EventHandler
        public void onClick(InventoryClickEvent event) {
            if (!(event.getWhoClicked() instanceof Player) || event.getCurrentItem() == null) {
                return;
            }

            if (event.getClickedInventory().getHolder() != null &&
                    event.getClickedInventory().getHolder() instanceof InventoryGUI) {
                event.setCancelled(true);

                final InventoryGUI inventoryGUI = (InventoryGUI) event.getClickedInventory().getHolder();
                inventoryGUI.onClick(event);
            }
        }
    The onClick method just handle which thing got clicked, he does not take care of empty (air/null) slots.

    What did i tried:
    - Canceling drag event (It works, but if a player pick up an item he can't put it back, because you can't check which inventory was clicked in drag event. At least i didn't find any documentation about it.)
    - Canceling ClickEvent (that's what i'm doing, but if you spam click it will consider as a Drag and then it got added to the inv).
    - I tried in 1.8.8 and 1.12 (I thought it was a Spigot bug in the beginning)

    I'm here because I'm trying stuff for almost 5 hours and couldn't figure out a fixed for that.

    Thank you.
     
  2. I would take an approach based on how the player clicked:
    1) The player clicks one of ClickTypes.(LEFT, RIGHT, CONTROL_DROP, DROP, NUMBER_KEY) -> Check the Inventory, if it's the GUI, cancel
    2) The player clicks one of SHIFT_LEFT, SHIFT_RIGHT or DOUBLE_CLICK: either cancel completely while in the GUI-Inventory or mimic the Minecraft-methods by your own logic.
    3) I would cancel any other click types just to be sure
     
  3. I would use the InventoryInteractEvent and then access the separate inventories through the InventoryView, this is where you can just disable the player being able to do anything in the top gui, drop items, etc.
     
  4. I'm currently cancelling all clicks related to my custom inventory, the problem is that the click event is not fired at all when dragging.

    Can you show me an example? Because InventoryView.getTopInventory() == my inventory will always be true, even if the clicked on the botton one. That's my problem, i need to check where did the dragged the item to.
     
  5. But when placing the item (after dragging) to your GUI, won't the click event be fired?
     
  6. Yes, but even with me cancelling it sometimes it bugs.
     
  7. that is crazy is it a gui???
     
  8. You could also fill up the empty slots in the top inventory with another block, like glass pane and sent its displayname to ""
     
  9. It is.

    That's a fix, yes. But i wanted to let it empty.

    I guess that's a Spigot (or nms) limitation, because hypixel uses Glass panes to block the slots. Very light ones
     
  10. Light gray glass panes are invisible inside inventories
     
  11. After your InventoryHolder check, use something like this:
    Code (Text):
    Inventory inv = event.getInventory()
    Inventory clickedInv = event.getInventory()
    if inv equals clickedInv {
        if inv.getType() == InventoryType.PLAYER {
            return
        }
        ItemStack currItem = event.getCurrentItem()
        ItemStack cursorItem = event.getCursor()
        if currItem.getType() == Material.AIR && cursorItem != null {
            cancel event
        }
    }
    First you're making sure you click the top inventory. If that's true, then you check if the player already has something in their cursor and they're trying to put it in an empty slot. If so, then the event gets cancelled.
     
    #12 Escad, Jan 23, 2020
    Last edited: Jan 23, 2020