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 nowInventory, and what wasInventoryis nowContainerInventory. 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 theClick.Infotype. This is an interface permitting a bunch of subclasses, includingLeft,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 wasnull.InventorySwapItemEventis now considered a click, so you can listen to click events that haveevent.getClickInfo() instanceof OffhandSwap.InventoryCloseEventno longer has#setNewInventory(Inventory). Instead, useevent.getPlayer().openInventoryorevent.setCancelled(true)when needed.PlayerInventoryItemChangeEventis now underInventoryItemChangeEvent. Filter the event if you want onlyPlayerInventoryinstances.InventoryClickEventhas been renamed toInventoryPostClickEventInventoryConditionhas 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.
