Inventory
The xyz.xenondevs.invui.inventory.Inventory
is a type of inventory that can be embedded in GUIs.
It provides several utility methods to easily add and remove items from the inventory, as well as an advanced event
system allowing to listen for and affect changes in the inventory.
The general contracts of Inventory
and all implementations are:
- There are no
ItemStacks
of typeMaterial.AIR
orItemStack.getAmount() == 0
.
EmptyItemStacks
are represented bynull
. - Unless otherwise specified, all methods will return a clone of the actual backing
ItemStack
.
Changes to returnedItemStacks
will never affect theInventory
. - Unless otherwise specified, all methods accepting
ItemStacks
will always clone them before
putting them in the backing array / inventory.
Changes to the passedItemStacks
after calling a method will never affect theInventory
.
Types of Inventories
Virtual Inventory
Like normal inventories, virtual inventories can store a predefined amount of ItemStacks
, but unlike
Minecraft's inventories, they do not have a defined width or height, just a size.
To create a VirtualInventory
, you can do one of three things:
- Call the
VirtualInventory
constructor directly - Deserialize a
VirtualInventory
from anInputStream
orbyte[]
usingVirtualInventory#deserialize
- Use the
VirtualInventoryManager
to get a previously serializedVirtualInventory
from a file. ThisVirtualInventory
will then get written into the file again when the plugin gets disabled.
Custom Stack Sizes
Virtual inventories also allow customizing the stack sizes of every slot.
You can change them by providing a maxStackSizes
array in the constructor, or set them later using
VirtualInventory#setMaxStackSizes
or VirtualInventory#setMaxStackSize
.
If you're creating a plugin that modifies maximum stack sizes of items, change the
StackSizeProvider
in InventoryUtils#stackSizeProvider
to a custom one you've created.
This will make InvUI respect your maximum stack sizes.
Stack sizes higher than what is normally allowed in vanilla Minecraft are not possible!
Serialization
You can either directly (de)serialize a VirtualInventory
to/from a stream or byte[] using VirtualInventory#serialize
and VirtualInventory#deserialize
, or use the VirtualInventoryManager
to automatically do that for you.
Only the UUID
and ItemStack[]
are serialized!
Using the VirtualInventoryManager
, inventories obtained with createNew
, getByUUID
and getOrCreate
will be automatically serialized when the plugin gets disabled. These inventories are stored under
plugins/InvUI/VirtualInventory/<Name of your plugin>/
.
Info
The uuid
parameter is only required for serialization with the VirtualInventoryManager
.
You can set it to null, if you're not planning to serialize your inventory this way.
ReferencingInventory
The ReferencingInventory
is an Inventory
that is backed by a Bukkit inventory. Changes in this inventory are
applied in the referenced inventory and changes in the bukkit inventory are visible in this inventory.
Window Updating
Changes done using the methods provided by InvUI inventory will cause displaying Windows
to be notified, but
changes done directly in the bukkit inventory will not. Therefore, if embedded in a GUI, it is necessary to call
Inventory#notifyWindows
manually in order for changes to be displayed.
CompositeInventory
The CompositeInventory
is a composite of multiple inventories. Those can be VirtualInventories
, ReferencingInventories
,
or any other custom implementation of Inventory
.
Inventory Events
You can also register update handlers to your Inventory
. There are two different types of events:
Event type | Registered with | Description | Use-case |
---|---|---|---|
ItemPreUpdateEvent |
Inventory.setPreUpdateHandler |
Called before changes were fully processed. Cancelling this event or changing the amount of items that were added/removed will affect the source of the change (which is the player most of the time). | Restricting which or how many items can be put into an inventory or a specific slot. Example 1: A player tries to put a full stack of 64 items into the inventory, but the amount gets changed to 32 in the event, so the remaining 32 items stay on the player's cursor. Example 2: A player shift-clicks a dirt block into the inventory, but the event is cancelled in such a way that only diamonds can be placed on slot 1, and everything else can be placed on slot 2, so the dirt is put on slot 2. |
ItemPostUpdateEvent |
Inventory.setPostUpdateHandler |
After changes were fully processed. This event cannot be cancelled and changes done to the inventory during this event will not affect the source of the change. | Removing or editing items after they've been added to the inventory. Example: A trash can inventory that immediately removes all items that have been put into it. |
Inventories in GUIs
Adding an Inventory
to a GUI can be done the same way as adding Items.
You can either:
- Define an ingredient for the
Inventory
inStructure
or the delegatingGui.Builder
method. - Use the filling methods in
Gui
. - Create a
SlotElement.InventorySlotElement
which links to the specific slot.
GUI priority
If you have multiple virtual inventories in one GUI, you might want to change the order of
which items are added to them with shift-clicks or collected using double clicks.
This can be done by setting the guiPriority
in Inventory
. The inventory with the highest priority will be used first.
Background
If you want your inventory slots to have a background ItemProvider
(which is an item that is technically in the slot,
but will be ignored by all click actions) you can set the background
parameter in
Structure.addIngredient(char key, Inventory inventory, ItemProvider background)
or in the delegating Gui.Builder
method for it.
Alternatively, you can also create the SlotElement.InventorySlotElement
yourself.