Bug when using onClose() to open another Inventory
Anvil GUI version: 1.5.3 Spigot version: 1.18.2-R0.1
Scenario: I'm trying to open the previous inventory when AnvilGUI is closed, as it's less disruptive to "go back" to the previous menu when closed.
Issue: Using builder.onClose() to open another inventory opens target inventory, but that inventory doesn't fire InventoryClickEvent, despite being called by the same method in other locations where it does work.
Steps:
- Player opens my GUI
- Clicks a nametag
- Gets AnvilGUI
- Hit ESC
- Returns to first GUI, but the new GUI doesn't respond to player clicks.
My plugin event listener calls openChestManagerGui():
@EventHandler
public void onChestOpen(PlayerInteractEvent e) {
// conditional checks
e.setCancelled(true);
GuiInteract.openChestManagerGui(e.getPlayer(), e.getClickedBlock());
}
AnvilGUI calls the same method onClose():
.onClose((player) -> {
GuiInteract.openChestManagerGui(player, Utils.getCurrentChest(player));
})
ChestManager GUI opens (all item icons are visible) but has no response to InventoryClickEvent (items can be dragged, clicking does nothing). I tested this with e.getWhoClicked().sendMessage(e.getClickedInventory().toString()); at the beginning of the InventoryClickEvent EventHandler and got no message after closing the AnvilGUI.
Complete AnvilGUI method:
new AnvilGUI.Builder()
.onClose((player) -> {
GuiInteract.openChestManagerGui(player, Utils.getCurrentChest(player));
})
.onComplete((player,text) -> {
Block chest = Utils.getCurrentChest(player);
Player newUser = Utils.getPlayerFromName(text);
if (newUser == null) {
player.sendMessage("No online player found by that name.");
return AnvilGUI.Response.text("Player not found");
}
Utils.addChestUser(player, chest, newUser);
return AnvilGUI.Response.openInventory(ChestManager.inv);
})
.text("Username")
.itemLeft(item)
.title("Add Chest User")
.plugin(ChestGuard.getPlugin(ChestGuard.class))
.open(clicker);
}
Try
new BukkitRunnable(() ->
GuiInteract.openChestManagerGui(player, Utils.getCurrentChest(player))
).runTaskLaster(plugin, 1);
with plugin being a reference to your Plugin instance.
Have same issue. Using BukkitRunable solve problem.
The best way around this is indeed using a runnable that runs your code a single tick later.
The issue that is occurring is that onClose is called before the InventoryCloseEvent is finished. As a result, your code is running while the anvil is still open, and it makes Bukkit close your inventory. Perhaps a way around this would be to add a Response-like return result for onClose, but this requires some more thought.
isnt it just better to do Player#closeInventory before opening new one?
If you don't call closeInventory, the users cursor will stay in the same position when the new inventory opens.
problem is that i want it to go back when i close anvilgui so it opens previous gui, but when player click, i want it to go forward to next gui, when player clicks it first opens next gui and then anvilgui close task is triggered and it opens previous gui
i tried doing delay, so anvilgui will close first (and open prev gui) and then task will run next gui, but now next gui gets ghost items no matter what delay there is
problem is that i want it to go back when i close anvilgui so it opens previous gui, but when player click, i want it to go forward to next gui, when player clicks it first opens next gui and then anvilgui close task is triggered and it opens previous gui
i tried doing delay, so anvilgui will close first (and open prev gui) and then task will run next gui, but now next gui gets ghost items no matter what delay there is
It sounds like a combination of two things:
a) You aren't using AnvilGUI.Response.openInventory(Inventory)
b) You have another bug in your own code