Revert "Apply the FE tunnel behaviour to the fluid tunnel (#4545)" (#4549)

This reverts commit 22f552217f.
This commit is contained in:
yueh
2020-08-04 08:45:10 +02:00
committed by GitHub
parent 22f552217f
commit 39959145a3
@@ -18,10 +18,15 @@
package appeng.parts.p2p;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nonnull;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
@@ -32,18 +37,18 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import appeng.api.config.PowerUnits;
import appeng.api.parts.IPartModel;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> {
public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implements IFluidHandler {
private static final P2PModels MODELS = new P2PModels("part/p2p/p2p_tunnel_fluids");
private static final IFluidHandler NULL_FLUID_HANDLER = new NullFluidHandler();
private final IFluidHandler inputHandler = new InputFluidHandler();
private final IFluidHandler outputHandler = new OutputFluidHandler();
private static final ThreadLocal<Deque<FluidP2PTunnelPart>> DEPTH = new ThreadLocal<>();;
private LazyOptional<IFluidHandler> cachedTank;
private int tmpUsed;
public FluidP2PTunnelPart(final ItemStack is) {
super(is);
@@ -60,10 +65,13 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> {
@Override
public void onTunnelNetworkChange() {
this.cachedTank = null;
}
@Override
public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) {
this.cachedTank = null;
if (this.isOutput()) {
final FluidP2PTunnelPart in = this.getInput();
if (in != null) {
@@ -76,10 +84,7 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> {
@Override
public <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) {
if (capabilityClass == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if (this.isOutput()) {
return (LazyOptional<T>) LazyOptional.of(() -> this.outputHandler);
}
return (LazyOptional<T>) LazyOptional.of(() -> this.inputHandler);
return (LazyOptional<T>) LazyOptional.of(() -> this);
}
return super.getCapability(capabilityClass);
@@ -90,191 +95,168 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> {
return MODELS.getModel(this.isPowered(), this.isActive());
}
private IFluidHandler getAttachedFluidHandler() {
LazyOptional<IFluidHandler> fluidHandler = LazyOptional.empty();
if (this.isActive()) {
final TileEntity self = this.getTile();
final TileEntity te = self.getWorld().getTileEntity(self.getPos().offset(this.getSide().getFacing()));
@Override
public int getTanks() {
return 0;
}
if (te != null) {
fluidHandler = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
this.getSide().getOpposite().getFacing());
@Override
@Nonnull
public FluidStack getFluidInTank(int tank) {
return FluidStack.EMPTY;
}
@Override
public int getTankCapacity(int tank) {
return 1000;
}
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return false;
}
@Override
public int fill(FluidStack resource, FluidAction action) {
final Deque<FluidP2PTunnelPart> stack = this.getDepth();
for (final FluidP2PTunnelPart t : stack) {
if (t == this) {
return 0;
}
}
return fluidHandler.orElse(NULL_FLUID_HANDLER);
}
private class InputFluidHandler implements IFluidHandler {
stack.push(this);
@Override
public int getTanks() {
return 1;
}
final List<FluidP2PTunnelPart> list = this.getOutputs(resource.getFluid());
int requestTotal = 0;
@Override
@Nonnull
public FluidStack getFluidInTank(int tank) {
return FluidStack.EMPTY;
}
Iterator<FluidP2PTunnelPart> i = list.iterator();
@Override
public int getTankCapacity(int tank) {
return Integer.MAX_VALUE;
}
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return true;
}
@Override
public int fill(FluidStack resource, FluidAction action) {
int total = 0;
try {
final int outputTunnels = FluidP2PTunnelPart.this.getOutputs().size();
final int amount = resource.getAmount();
if (outputTunnels == 0 || amount == 0) {
return 0;
}
final int amountPerOutput = Math.max(1, amount / outputTunnels);
int overflow = amountPerOutput == 0 ? amount : amount % amountPerOutput;
for (FluidP2PTunnelPart target : FluidP2PTunnelPart.this.getOutputs()) {
final IFluidHandler output = target.getAttachedFluidHandler();
final int toSend = amountPerOutput + overflow;
final FluidStack fillWithFluidStack = resource.copy();
fillWithFluidStack.setAmount(toSend);
final int received = output.fill(fillWithFluidStack, action);
overflow = toSend - received;
total += received;
}
// Make a second pass, to distribute any leftover overflow in case
// a later output did not completely consume its allotment
if (overflow > 0) {
for (FluidP2PTunnelPart target : FluidP2PTunnelPart.this.getOutputs()) {
final IFluidHandler output = target.getAttachedFluidHandler();
final FluidStack fillWithFluidStack = resource.copy();
fillWithFluidStack.setAmount(overflow);
final int received = output.fill(fillWithFluidStack, action);
overflow -= received;
total += received;
if (overflow <= 0) {
break; // don't continue if nothing is left
}
}
}
if (action == FluidAction.EXECUTE) {
FluidP2PTunnelPart.this.queueTunnelDrain(PowerUnits.RF, total);
}
} catch (GridAccessException ignored) {
while (i.hasNext()) {
final FluidP2PTunnelPart l = i.next();
final IFluidHandler tank = l.getTarget().orElse(null);
if (tank != null) {
l.tmpUsed = tank.fill(resource.copy(), FluidAction.SIMULATE);
} else {
l.tmpUsed = 0;
}
return total;
if (l.tmpUsed <= 0) {
i.remove();
} else {
requestTotal += l.tmpUsed;
}
}
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
if (requestTotal <= 0) {
if (stack.pop() != this) {
throw new IllegalStateException("Invalid Recursion detected.");
}
return 0;
}
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
if (action != FluidAction.EXECUTE) {
if (stack.pop() != this) {
throw new IllegalStateException("Invalid Recursion detected.");
}
return Math.min(resource.getAmount(), requestTotal);
}
int available = resource.getAmount();
i = list.iterator();
int used = 0;
while (i.hasNext() && available > 0) {
final FluidP2PTunnelPart l = i.next();
final FluidStack insert = resource.copy();
insert.setAmount((int) Math.ceil(insert.getAmount() * ((double) l.tmpUsed / (double) requestTotal)));
if (insert.getAmount() > available) {
insert.setAmount(available);
}
final IFluidHandler tank = l.getTarget().orElse(null);
if (tank != null) {
l.tmpUsed = tank.fill(insert.copy(), action);
} else {
l.tmpUsed = 0;
}
available -= insert.getAmount();
used += l.tmpUsed;
}
if (stack.pop() != this) {
throw new IllegalStateException("Invalid Recursion detected.");
}
return used;
}
private class OutputFluidHandler implements IFluidHandler {
@Override
public int getTanks() {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().getTanks();
}
@Override
@Nonnull
public FluidStack getFluidInTank(int tank) {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().getFluidInTank(tank);
}
@Override
public int getTankCapacity(int tank) {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().getTankCapacity(tank);
}
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().isFluidValid(tank, stack);
}
@Override
public int fill(FluidStack resource, FluidAction action) {
return 0;
}
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().drain(resource, action);
}
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().drain(maxDrain, action);
}
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
}
private static class NullFluidHandler implements IFluidHandler {
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
}
@Override
public int getTanks() {
return 0;
private Deque<FluidP2PTunnelPart> getDepth() {
Deque<FluidP2PTunnelPart> s = DEPTH.get();
if (s == null) {
DEPTH.set(s = new ArrayDeque<>());
}
@Override
@Nonnull
public FluidStack getFluidInTank(int tank) {
return FluidStack.EMPTY;
return s;
}
private List<FluidP2PTunnelPart> getOutputs(final Fluid input) {
final List<FluidP2PTunnelPart> outs = new ArrayList<>();
try {
for (final FluidP2PTunnelPart l : this.getOutputs()) {
final IFluidHandler handler = l.getTarget().orElse(null);
if (handler != null) {
outs.add(l);
}
}
} catch (final GridAccessException e) {
// :P
}
@Override
public int getTankCapacity(int tank) {
return 0;
return outs;
}
private LazyOptional<IFluidHandler> getTarget() {
if (!this.getProxy().isActive()) {
return null;
}
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return false;
if (this.cachedTank != null) {
return this.cachedTank;
}
@Override
public int fill(FluidStack resource, FluidAction action) {
return 0;
final TileEntity te = this.getTile().getWorld()
.getTileEntity(this.getTile().getPos().offset(this.getSide().getFacing()));
if (te != null && te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
this.getSide().getFacing().getOpposite()).isPresent()) {
return this.cachedTank = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
this.getSide().getFacing().getOpposite());
}
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
}
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
}
return null;
}
}