Inventories 
Minestom has an improved inventory system! This includes vanilla accurate click behaviour (except in cases like crafting), an improved inventory event API, and a few other changes.
Usage 
In order to create an inventory, you can simply call its constructor by specifying an InventoryType and the title.
// Create the inventory
ContainerInventory inventory = new ContainerInventory(InventoryType.CHEST_1_ROW, Component.text("Title"));
// Open the inventory for the player
// (Opening the same inventory for multiple players would result in a shared interface)
player.openInventory(inventory);
// Close the current player inventory
player.closeInventory();Adding callbacks are as simple as registering a listener to an EventNode
EventNode.type("click", EventFilter.INVENTORY, (event, inv) -> inventory == inv)
.addListener(InventoryClickEvent.class, event -> {
	event.getPlayer().sendMessage("Clicked!");
})Recent Changes 
- Inventory classes have been renamed. - AbstractInventoryis now- Inventory, and what was- Inventoryis now- ContainerInventory. This makes the hierarchy a bit clearer. To be clear,- ContainerInventoryrepresents all named inventories (e.g. chest inventories, anvil inventories, crafting inventories).
- Click events with - #getClickedItem(),- #getClickType(),- #getSlot(), etc. have been replaced with the- Click.Infotype. This is an interface permitting a bunch of subclasses, including- Left,- Right,- RightShift, etc., each storing the relevant slots. When listening to an event, you can simply check the click type:- if (event.getClickInfo() instanceof Click.Info.Left left) { /* logic */ }
- Inventory click events have been refactored to the following structure: - InventoryPreClickEvent - Allows modification of the raw information about the click (e.g. clicked slots, click type, which button was used, etc.) via event.getClickInfo().
- This occurs before the click is processed.
 
- Allows modification of the raw information about the click (e.g. clicked slots, click type, which button was used, etc.) via 
- InventoryClickEvent - Allows modification of the slot changes and side effects that occur as result of the click via event.getChanges()instead of just the click info.
- This occurs before the click is processed.
 
- Allows modification of the slot changes and side effects that occur as result of the click via 
- InventoryPostClickEvent - Allows viewing the click info and results for the click, but cannot modify them.
- This occurs after the click is processed.
 
 
- InventoryPreClickEvent 
- When the player clicks while their own inventory is open, the - event.getInventory()in each event is now the player's inventory. Previously, it was- null.
- InventorySwapItemEventis now considered a click, so you can listen to click events that have- event.getClickInfo() instanceof OffhandSwap.
- InventoryCloseEventno longer has- #setNewInventory(Inventory). Instead, use- event.getPlayer().openInventoryor- event.setCancelled(true)when needed.
- PlayerInventoryItemChangeEventis now under- InventoryItemChangeEvent. Filter the event if you want only- PlayerInventoryinstances.
- InventoryClickEventhas been renamed to- InventoryPostClickEvent
- InventoryConditionhas been converted into an event.Java- // Old inventory.addInventoryCondition((player, slot, clickType, inventoryConditionResult) -> { player.sendMessage("Clicked!"); }); // New EventNode.type("click", EventFilter.INVENTORY, (event, inv) -> inventory == inv) .addListener(InventoryClickEvent.class, event -> { event.getPlayer().sendMessage("Clicked!"); })
Click.Info 
Click slots in Click.Info are stored in an unintuitive manner. The slot IDs represent both clicked inventory slots and player inventory slots. To get an item from a slot ID, you can use this code:
Inventory inventory = event.getInventory();
if (slot < inventory.getSize()) {
    return inventory.getItemStack(slot);
} else {
    int converted = PlayerInventoryUtils.protocolToMinestom(slot, inventory.getSize());
    return event.getPlayerInventory().getItemStack(converted);
}Let @GoldenStack know if you have a better idea for handling this.
