Skip to content

Commit a2c913a

Browse files
authored
Fix #1105: Fix extractions from configurable chest if the first fluid cannot be inserted (#1122)
1 parent 57f8639 commit a2c913a

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

src/main/java/aztech/modern_industrialization/inventory/MIInventory.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import net.minecraft.world.level.Level;
3838
import net.neoforged.neoforge.capabilities.BlockCapabilityCache;
3939
import net.neoforged.neoforge.capabilities.Capabilities;
40-
import net.neoforged.neoforge.fluids.FluidUtil;
4140
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
4241
import net.neoforged.neoforge.items.IItemHandler;
4342
import org.jetbrains.annotations.Nullable;
@@ -105,7 +104,7 @@ public void autoExtractFluids(Level world, BlockPos pos, Direction direction) {
105104
IFluidHandler target = world.getCapability(Capabilities.FluidHandler.BLOCK, pos.relative(direction), direction.getOpposite());
106105

107106
if (target != null) {
108-
FluidUtil.tryFluidTransfer(target, fluidStorage.fluidHandler, Integer.MAX_VALUE, true);
107+
TransferHelper.tryFluidTransfer(target, fluidStorage.fluidHandler, Integer.MAX_VALUE, true);
109108
}
110109
}
111110

@@ -121,7 +120,7 @@ public void autoInsertFluids(Level world, BlockPos pos, Direction direction) {
121120
IFluidHandler target = world.getCapability(Capabilities.FluidHandler.BLOCK, pos.relative(direction), direction.getOpposite());
122121

123122
if (target != null) {
124-
FluidUtil.tryFluidTransfer(fluidStorage.fluidHandler, target, Integer.MAX_VALUE, true);
123+
TransferHelper.tryFluidTransfer(fluidStorage.fluidHandler, target, Integer.MAX_VALUE, true);
125124
}
126125
}
127126

src/main/java/aztech/modern_industrialization/util/TransferHelper.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import net.minecraft.world.entity.player.Inventory;
2929
import net.minecraft.world.item.ItemStack;
3030
import net.neoforged.neoforge.capabilities.Capabilities;
31+
import net.neoforged.neoforge.fluids.FluidStack;
32+
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
3133
import net.neoforged.neoforge.items.IItemHandler;
3234
import net.neoforged.neoforge.items.ItemHandlerHelper;
3335
import net.neoforged.neoforge.items.wrapper.PlayerInvWrapper;
@@ -128,4 +130,45 @@ public static ItemStack extractMatching(IItemHandler src, Predicate<ItemStack> p
128130

129131
return ret;
130132
}
133+
134+
/**
135+
* Fixed version of NeoForge's FluidUtil method. This one correctly handles multi-tank to multi-tank transfer.
136+
*
137+
* <p>
138+
* Fill a destination fluid handler from a source fluid handler with a max amount.
139+
* To transfer as much as possible, use {@link Integer#MAX_VALUE} for maxAmount.
140+
*
141+
* @param fluidDestination The fluid handler to be filled.
142+
* @param fluidSource The fluid handler to be drained.
143+
* @param maxAmount The largest amount of fluid that should be transferred.
144+
* @param doTransfer True if the transfer should actually be done, false if it should be simulated.
145+
* @return the fluidStack that was transferred from the source to the destination. null on failure.
146+
*/
147+
public static FluidStack tryFluidTransfer(IFluidHandler fluidDestination, IFluidHandler fluidSource, int maxAmount, boolean doTransfer) {
148+
int tanks = fluidSource.getTanks();
149+
for (int i = 0; i < tanks; ++i) {
150+
FluidStack toTry = fluidSource.getFluidInTank(i).copy();
151+
if (toTry.getAmount() > maxAmount) {
152+
toTry.setAmount(maxAmount);
153+
}
154+
FluidStack drainable = fluidSource.drain(toTry, IFluidHandler.FluidAction.SIMULATE);
155+
if (drainable.isEmpty()) {
156+
continue;
157+
}
158+
int fillableAmount = fluidDestination.fill(drainable, IFluidHandler.FluidAction.SIMULATE);
159+
if (fillableAmount > 0) {
160+
drainable.setAmount(fillableAmount);
161+
if (doTransfer) {
162+
FluidStack drained = fluidSource.drain(drainable, IFluidHandler.FluidAction.EXECUTE);
163+
if (!drained.isEmpty()) {
164+
drained.setAmount(fluidDestination.fill(drained, IFluidHandler.FluidAction.EXECUTE));
165+
return drained;
166+
}
167+
} else {
168+
return drainable;
169+
}
170+
}
171+
}
172+
return FluidStack.EMPTY;
173+
}
131174
}

0 commit comments

Comments
 (0)