tutorial:transfer-api_fluid_implementation
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
tutorial:transfer-api_fluid_implementation [2022/02/02 20:07] – technici4n | tutorial:transfer-api_fluid_implementation [2022/02/02 20:28] (current) – [Internal tanks] technici4n | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Fabric Transfer API: How to implement Storage< | + | ====== Fabric Transfer API: How to implement Storage< |
//This article is part of a series on the Fabric Transfer API. [[tutorial: | //This article is part of a series on the Fabric Transfer API. [[tutorial: | ||
Line 5: | Line 5: | ||
It's possible to implement directly by implementing the interface and filling the methods, but Fabric API already provides many implementations that you can use and combine for almost any task. | It's possible to implement directly by implementing the interface and filling the methods, but Fabric API already provides many implementations that you can use and combine for almost any task. | ||
- | ==== Overview of the base implementations ==== | + | ===== Overview of the base implementations |
- | === SingleVariantStorage === | + | ==== SingleVariantStorage |
[[https:// | [[https:// | ||
Line 41: | Line 41: | ||
</ | </ | ||
- | === FilteringStorage === | + | ==== FilteringStorage |
[[https:// | [[https:// | ||
Line 58: | Line 58: | ||
Subclassing '' | Subclassing '' | ||
- | === CombinedStorage === | + | ==== CombinedStorage |
[[https:// | [[https:// | ||
Line 70: | Line 70: | ||
- | ==== A more involved example ==== | + | ===== A more involved example |
To better understand how these classes can be combined together, let's write a machine that converts water to lava. Here are our requirements: | To better understand how these classes can be combined together, let's write a machine that converts water to lava. Here are our requirements: | ||
* The machine will have two internal " | * The machine will have two internal " | ||
Line 76: | Line 76: | ||
* External pipes will only be allowed to insert into the water tank (no extraction), | * External pipes will only be allowed to insert into the water tank (no extraction), | ||
* The water tank will only be accessible from the top and the sides of the machine. The lava tank will only be accessible from the bottom and the sides of the machine. In other words: top can only access water, bottom can only access lava, and sides can access both. | * The water tank will only be accessible from the top and the sides of the machine. The lava tank will only be accessible from the bottom and the sides of the machine. In other words: top can only access water, bottom can only access lava, and sides can access both. | ||
+ | |||
+ | For the internal tanks, we can just use '' | ||
+ | What we will do instead is use '' | ||
+ | Finally, we will use '' | ||
+ | |||
+ | ==== Internal tanks ==== | ||
+ | First, let's add the internal tanks to the block entity: | ||
+ | <code java> | ||
+ | import static net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants.BUCKET; | ||
+ | |||
+ | public class MachineBlockEntity extends BlockEntity { | ||
+ | // Useful constants. | ||
+ | private static final FluidVariant WATER = FluidVariant.of(Fluids.WATER); | ||
+ | private static final FluidVariant LAVA = FluidVariant.of(Fluids.LAVA); | ||
+ | |||
+ | // A helper function to create a single tank that can store 4 buckets, and is restricted to a single variant. | ||
+ | private SingleVariantStorage< | ||
+ | return new SingleVariantStorage<> | ||
+ | @Override | ||
+ | protected FluidVariant getBlankVariant() { | ||
+ | return FluidVariant.blank(); | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | protected long getCapacity(FluidVariant variant) { | ||
+ | return 4 * BUCKET; | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | protected boolean canInsert(FluidVariant variant) { | ||
+ | // Only allow the specified variant. | ||
+ | return variant.equals(allowedVariant); | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | protected void onFinalCommit() { | ||
+ | markDirty(); | ||
+ | } | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | // Our two internal tanks. | ||
+ | private final SingleVariantStorage< | ||
+ | private final SingleVariantStorage< | ||
+ | |||
+ | // Don't forget to implement toNbt and fromNbt to save the data of the tanks. | ||
+ | |||
+ | // ... [other code omitted] | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Conversion logic ==== | ||
+ | The conversion logic is straightforward: | ||
+ | <code java> | ||
+ | public class MachineBlockEntity extends BlockEntity { | ||
+ | // ... [other code] | ||
+ | |||
+ | // Call this on server tick: | ||
+ | public void doConversion() { | ||
+ | try (Transaction transaction = Transaction.openOuter()) { | ||
+ | long lavaInserted = lavaTank.insert(LAVA, | ||
+ | waterTank.extract(WATER, | ||
+ | transaction.commit(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Exposing the tanks to external pipes ==== | ||
+ | We can use the filtering and combined storages to ensure that pipes can only do what we want them to do: | ||
+ | <code java> | ||
+ | public class MachineBlockEntity extends BlockEntity { | ||
+ | // ... [other code] | ||
+ | |||
+ | // Wrapper around the internal tanks that restrict operations to what we want to allow. | ||
+ | public final Storage< | ||
+ | public final Storage< | ||
+ | // Wrapper around both, for side access | ||
+ | public final Storage< | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Finally, let's not forget to register our block entity to '' | ||
+ | <code java> | ||
+ | BlockEntityType< | ||
+ | FluidStorage.SIDED.registerForBlockEntity((machine, | ||
+ | // Only expose the water tank from the top side. | ||
+ | case UP -> machine.exposedWaterTank; | ||
+ | // Only expose the lava tank from the bottom side. | ||
+ | case DOWN -> machine.exposedLavaTank; | ||
+ | // Expose both otherwise (access from one of the 4 sides). | ||
+ | default -> machine.exposedTanks; | ||
+ | }, MACHINE); | ||
+ | </ |
tutorial/transfer-api_fluid_implementation.1643832459.txt.gz · Last modified: 2022/02/02 20:07 by technici4n