Issue description
Follow-up to #778 (and CyclopsMC/IntegratedTunnels#367). That issue is closed and the fix (commit 2366851, "Fix extraction fluid loss") is present in my version, but fluid is still being deleted on extraction in the same way.
Observed behaviour: when an Integrated Tunnels fluid importer pulls from an Oritech block, fluid is removed from the machine's tank but never arrives in the network.
- If the importer's rate is greater than or equal to the amount currently in the tank, the entire tank contents are deleted. Setting the rate very high (e.g.
99999999) deletes everything in one go.
- If the rate is lower than the amount, transfer works normally until the remaining amount drops to the rate, and that final chunk is deleted.
Confirmed on the Centrifuge and the Refinery. The affected code is in the shared NeoForge wrapper layer rather than in any individual block entity, so it should apply to any Oritech block exposing a fluid handler.
Expected: all fluid removed from the tank arrives in the destination.
Commit 2366851 rewrote the three drain(int maxDrain, FluidAction) overloads to go through the new drainStoredFluid helper, which works on a copy and is correct. However, drain(FluidStack, FluidAction) and getFluidInTank(int) in NeoforgeFluidApiImpl were not changed, and they still show the same pattern the fix was addressing:
getFluidInTank(int) returns FluidStackHooksForge.toForge(container.getStack(...)), which is not a copy — it hands out the container's live FluidStack object.
drain(FluidStack, FluidAction) passes that same object into container.extract(...), which shrinks it, and then builds its return value as new FluidStack(fluidStack.getFluid(), (int) extractedAmount) — reading getFluid() after the object has been zeroed. FluidStack#getFluid() returns Fluids.EMPTY when the stack is empty, so the returned stack is empty even though the extraction physically happened.
This affects all three wrapper classes (SingleSlotContainerStorageWrapper, MultiSlotStorageWrapper, DelegatingContainerStorageWrapper). It still present on branch 1.21 at f68e0c2 and in v1.2.10
Steps to reproduce
- Set up an Oritech Centrifuge (with fluid addon) or Refinery so that it has fluid in its tank (Or any machine from Oritech I believe).
- Place an Integrated Tunnels Fluid Importer on it, and a Fluid Interface on a separate fluid inventory, on the same network and channel.
- Note the amount of fluid in the Oritech block — call it X.
- Set the importer's rate to a value greater than or equal to X, then activate it.
- The Oritech tank empties, but no fluid arrives in the destination inventory — all X is deleted.
- Repeat with a rate lower than X: fluid transfers normally, except the final transfer (where the remaining amount equals the rate) is deleted.
Minecraft version
1.21.1 (Bugfixes only)
Platform
Neoforge
Loader version
21.1.247
Oritech version
1.2.9
Other relevant versions
Integrated Tunnels: 1.21.1-neoforge-1.9.4-652
Integrated Dynamics: 1.21.1-neoforge-1.33.4-1907
Integrated Crafting: 1.21.1-neoforge-1.4.6-605
CommonCapabilities: 1.21.1-neoforge-2.11.5-363
CyclopsCore: 1.21.1-neoforge-1.29.2
If a (crash)log is relevant for this issue, link it here: (It's almost always relevant)
no log is relevant, nothing is thrown; the fluid is silently discarded
Issue description
Follow-up to #778 (and CyclopsMC/IntegratedTunnels#367). That issue is closed and the fix (commit 2366851, "Fix extraction fluid loss") is present in my version, but fluid is still being deleted on extraction in the same way.
Observed behaviour: when an Integrated Tunnels fluid importer pulls from an Oritech block, fluid is removed from the machine's tank but never arrives in the network.
99999999) deletes everything in one go.Confirmed on the Centrifuge and the Refinery. The affected code is in the shared NeoForge wrapper layer rather than in any individual block entity, so it should apply to any Oritech block exposing a fluid handler.
Expected: all fluid removed from the tank arrives in the destination.
Commit 2366851 rewrote the three
drain(int maxDrain, FluidAction)overloads to go through the newdrainStoredFluidhelper, which works on a copy and is correct. However,drain(FluidStack, FluidAction)andgetFluidInTank(int)inNeoforgeFluidApiImplwere not changed, and they still show the same pattern the fix was addressing:getFluidInTank(int)returnsFluidStackHooksForge.toForge(container.getStack(...)), which is not a copy — it hands out the container's liveFluidStackobject.drain(FluidStack, FluidAction)passes that same object intocontainer.extract(...), which shrinks it, and then builds its return value asnew FluidStack(fluidStack.getFluid(), (int) extractedAmount)— readinggetFluid()after the object has been zeroed.FluidStack#getFluid()returnsFluids.EMPTYwhen the stack is empty, so the returned stack is empty even though the extraction physically happened.This affects all three wrapper classes (
SingleSlotContainerStorageWrapper,MultiSlotStorageWrapper,DelegatingContainerStorageWrapper). It still present on branch 1.21 at f68e0c2 and in v1.2.10Steps to reproduce
Minecraft version
1.21.1 (Bugfixes only)
Platform
Neoforge
Loader version
21.1.247
Oritech version
1.2.9
Other relevant versions
If a (crash)log is relevant for this issue, link it here: (It's almost always relevant)
no log is relevant, nothing is thrown; the fluid is silently discarded