User Tools

Site Tools


tutorial:transfer-api_fluid-containing-items

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tutorial:transfer-api_fluid-containing-items [2022/02/11 17:17] – [The problem] technici4ntutorial:transfer-api_fluid-containing-items [2022/02/11 18:40] (current) – external edit 127.0.0.1
Line 7: Line 7:
 ===== The problem ===== ===== The problem =====
 When we are dealing with fluid-containing items, we are interacting with fluid containers stored inside of an inventory. For example, this is the sequence of operations that must be executed to empty a water bucket: When we are dealing with fluid-containing items, we are interacting with fluid containers stored inside of an inventory. For example, this is the sequence of operations that must be executed to empty a water bucket:
-  * Check that the inventory still contains water bucket, abort otherwise+  * The first step is to remove 1 water bucket item from the current slot, that is the slot that contains the water bucket. 
-  * Ensure at least 1 bucket is being extractedabort otherwise+  * The second step is to try to add one empty bucket item to the current slotat the same position
-  * Try to replace 1 bucket of water by 1 empty bucket in the inventory, abort if it fails+  * If that fails, the third step is to add the empty bucket item somewhere else in the inventory. 
-  * Commit these operations, and return that 1 bucket was extracted.+  * The water extraction can only proceed if both step 1, and step 2 or 3, succeed.
  
 You do not need to understand this in detail, but this should give an idea of where we are headed. In code, this is what this looks like: (taken from ''FullItemFluidStorage'' with comments adjusted) You do not need to understand this in detail, but this should give an idea of where we are headed. In code, this is what this looks like: (taken from ''FullItemFluidStorage'' with comments adjusted)
Line 43: Line 43:
 } }
 </code> </code>
 +
 +===== ContainerItemContext =====
 +[[https://github.com/FabricMC/fabric/blob/1.18/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/context/ContainerItemContext.java|ContainerItemContext]] represents the inventory containing the fluid container, and it is made of the following parts:
 +  * The specific slot in the inventory that the fluid container is queried from. In the example above, this is the slot containing the water bucket, used for steps 1 and 2.
 +  * An overflow insertion function that can be used to insert items into the context's inventory when insertion into the main slot fails. In our example above, this is the function used for step 3.
 +  * The context may also contain additional slots.
 +
 +You usually don't interact with these methods directly, since ''ContainerItemContext'' has many useful default-implemented methods. Make sure to read the javadoc if you ever need to implement or use it.
 +
 +==== Obtaining instances ====
 +Fabric provides various static methods to create a ''ContainerItemContext'', depending on your use case. The most important ones are the following:
 +  * ''ContainerItemContext.ofPlayerHand(player, hand)'' creates a context for the slot of the passed hand, and with any overflow sent back to the player.
 +  * ''ContainerItemContext.ofPlayerCursor(player, screenHandler)'' creates a context for the cursor slot of the passed screen handler, and with any overflow sent back to the player.
 +
 +A word of caution: don't use ''ContainerItemContext.withInitial(stack)'' unless you know what you're doing. It **does not** mutate the stack.
 +
 +==== The API in action ====
 +An example to understand what is going on: how to query a storage for the main hand of a player, and insert 1 bucket of water into it:
 +<code java>
 +PlayerEntity player;
 +
 +// Build the ContainerItemContext.
 +ContainerItemContext handContext = ContainerItemContext.ofPlayerHand(player, Hand.MAIN_HAND);
 +// Use it to query a fluid storage.
 +Storage<FluidVariant> handStorage = handContext.find(FluidStorage.ITEM);
 +if (handStorage != null) {
 + // Use the storage: any usual Storage<FluidVariant> can be attempted.
 + try (Transaction transaction = Transaction.openOuter()) {
 + handStorage.insert(FluidVariant.of(Fluids.WATER), FluidConstants.BUCKET, transaction);
 + transaction.commit();
 + }
 +}
 +</code>
 +
 +TODO:
 +  - filling an item, example from TR
 +  - using the existing base implementations for items
tutorial/transfer-api_fluid-containing-items.1644599859.txt.gz · Last modified: 2022/02/11 17:17 by technici4n