New Inventory Framework New Events The inventory framework add six new events. The biggest one is InventoryClickEvent. InventoryClickEvent is fired whenever the user clicks on a slot in any inventory window. The only exception is that in the creative window it can only detect clicks on the quickbar. It will also fire if the user clicks outside the window (for example if they want to drop the stack attached to their mouse cursor). In a click event, you can see the inventory window involved, access items through either their slot number in the window or through the inventory itself, check whether the shift key was held down and whether the click was a right-click, and change the item in the slot and the item attached to the player's mouse cursor. In order have changes to an InventoryClickEvent be kept, you need to setResult(Result.ALLOW). If you want no change to go through, not even the default change, you can setResult(Result.DENY). The default is Result.DEFAULT, which ignores changes to the event and goes through with the default reaction to the click. Other new events: InventoryOpenEvent and InventoryCloseEvent are fired when a player opens or closes an inventory, though no event is fired when they open their own inventory. PrepareItemCraftEvent is fired just before updating the result slot to reflect a change to the crafting matrix. It cannot be cancelled, but the output can be changed. CraftItemEvent is a subevent of InventoryClickEvent which fires when the clicked slot is a crafting result slot, and gives access to the recipe that was crafted. BrewEvent fires when a set of potions finishes brewing in a brewing stand. Changes to existing events: Furnace events now extend BlockEvent (getFurnace() is deprecated) Enchanting events now extend InventoryEvent Inventory Views You can get an inventory view from any inventory event, or with the getOpenInventory() method in Player. An inventory view typically represents a linkage of two inventories, usually a player's inventory and some external inventory. It also represents the visual window onscreen, more or less. It has a title and a type which you can access, and you can edit its contents directly or by modifying the two inventories that it links. An inventory view has a setItem() method just like an inventory; however, it is important to realize that the indices to this method are completely different than they are for an inventory. For the most part, slots are numbered from the top left to the bottom right, starting at zero. A crafting result slot is always slot 0, followed immediately by the crafting matrix. In a player's crafting inventory (getType() == InventoryType.CRAFTING), the crafting matrix is followed by the armour slots. Furnaces and brewing stands have their own personal convention of slot order for the non-player slots; the enchanting slot is of course slot 0. Some inventory views have additional properties that you can change. For example, you can set the progress of a furnace smelting metre, even if the inventory view you have is not backed by an actual furnace block. Or you can set the progress without actually affecting the status of the underlying furnace block. These properties are found in the InventoryView.Property enum and are set using setWindowProperty(). Inventory Holders Goodbye ContainerBlock! This interface is now deprecated, and replaced with an new interface, InventoryHolder. This serves essentially the same function, representing something that has an inventory, but no longer only applies to blocks. For example, Player and StorageMinecart implement it. Custom Inventories You can extend InventoryView yourself to create a custom inventory view that does whatever you want. It doesn't even need to link a player inventory. You control what window type it uses with the getType() method; if the return type of this method changes, the window type will automatically be updated. If you want a custom inventory, you can create one of whatever size you like using the createInventory() methods in Server... as long as it's a multiple of 9. You can even create a size 0 inventory if you really want to, or an inventory with a custom title. If you want a special type of inventory (rather than a basic chest-type inventory), you can do that too, but it won't allow you to customize the size or title. Opening and Closing Inventories You can open an inventory for a player using the openInventory() method in Player, to which you pass either an Inventory or an InventoryView. For convenience, there's also an openWorkbench() method and an openEnchanting() method which creates and opens the corresponding inventory; these are included because these inventory types are normally transient and only created on demand. General Inventory Improvements There are several new subclasses of Inventory for common inventories, providing some additional utility methods. BrewerInventory, EnchantingInventory, and FurnaceInventory offer convenience methods to get special slots by name, so that you no longer have to remember which slot in a furnace is the output slot and which is the fuel slot and so forth. DoubleChestInventory represents a double chest, allowing you to access the left and right halves separately. And last but not least, CraftingInventory gives access to the crafting matrix. The inventory class now allows you to get a list of players who are currently examining the inventory; there's also a method to get the holder of the inventory. You can also get the type and the title. In addition to all this, inventories are now iterable. That means you can use them in an enhanced for-loop. Furthermore, the iterator is a list iterator, so it's bi-directional and you can change the contents as you iterate,