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; 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 java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; 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.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler;
import appeng.api.config.PowerUnits;
import appeng.api.parts.IPartModel; import appeng.api.parts.IPartModel;
import appeng.items.parts.PartModels; import appeng.items.parts.PartModels;
import appeng.me.GridAccessException; 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 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 static final ThreadLocal<Deque<FluidP2PTunnelPart>> DEPTH = new ThreadLocal<>();;
private final IFluidHandler outputHandler = new OutputFluidHandler();
private LazyOptional<IFluidHandler> cachedTank;
private int tmpUsed;
public FluidP2PTunnelPart(final ItemStack is) { public FluidP2PTunnelPart(final ItemStack is) {
super(is); super(is);
@@ -60,10 +65,13 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> {
@Override @Override
public void onTunnelNetworkChange() { public void onTunnelNetworkChange() {
this.cachedTank = null;
} }
@Override @Override
public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) { public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) {
this.cachedTank = null;
if (this.isOutput()) { if (this.isOutput()) {
final FluidP2PTunnelPart in = this.getInput(); final FluidP2PTunnelPart in = this.getInput();
if (in != null) { if (in != null) {
@@ -76,10 +84,7 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> {
@Override @Override
public <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) { public <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) {
if (capabilityClass == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { if (capabilityClass == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if (this.isOutput()) { return (LazyOptional<T>) LazyOptional.of(() -> this);
return (LazyOptional<T>) LazyOptional.of(() -> this.outputHandler);
}
return (LazyOptional<T>) LazyOptional.of(() -> this.inputHandler);
} }
return super.getCapability(capabilityClass); return super.getCapability(capabilityClass);
@@ -90,191 +95,168 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> {
return MODELS.getModel(this.isPowered(), this.isActive()); return MODELS.getModel(this.isPowered(), this.isActive());
} }
private IFluidHandler getAttachedFluidHandler() { @Override
LazyOptional<IFluidHandler> fluidHandler = LazyOptional.empty(); public int getTanks() {
if (this.isActive()) { return 0;
final TileEntity self = this.getTile(); }
final TileEntity te = self.getWorld().getTileEntity(self.getPos().offset(this.getSide().getFacing()));
if (te != null) { @Override
fluidHandler = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, @Nonnull
this.getSide().getOpposite().getFacing()); 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 final List<FluidP2PTunnelPart> list = this.getOutputs(resource.getFluid());
public int getTanks() { int requestTotal = 0;
return 1;
}
@Override Iterator<FluidP2PTunnelPart> i = list.iterator();
@Nonnull
public FluidStack getFluidInTank(int tank) {
return FluidStack.EMPTY;
}
@Override while (i.hasNext()) {
public int getTankCapacity(int tank) { final FluidP2PTunnelPart l = i.next();
return Integer.MAX_VALUE; final IFluidHandler tank = l.getTarget().orElse(null);
} if (tank != null) {
l.tmpUsed = tank.fill(resource.copy(), FluidAction.SIMULATE);
@Override } else {
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { l.tmpUsed = 0;
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) {
} }
return total; if (l.tmpUsed <= 0) {
i.remove();
} else {
requestTotal += l.tmpUsed;
}
} }
@Override if (requestTotal <= 0) {
@Nonnull if (stack.pop() != this) {
public FluidStack drain(FluidStack resource, FluidAction action) { throw new IllegalStateException("Invalid Recursion detected.");
return FluidStack.EMPTY; }
return 0;
} }
@Override if (action != FluidAction.EXECUTE) {
@Nonnull if (stack.pop() != this) {
public FluidStack drain(int maxDrain, FluidAction action) { throw new IllegalStateException("Invalid Recursion detected.");
return FluidStack.EMPTY; }
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
@Nonnull
@Override public FluidStack drain(FluidStack resource, FluidAction action) {
public int getTanks() { return FluidStack.EMPTY;
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);
}
} }
private static class NullFluidHandler implements IFluidHandler { @Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
}
@Override private Deque<FluidP2PTunnelPart> getDepth() {
public int getTanks() { Deque<FluidP2PTunnelPart> s = DEPTH.get();
return 0;
if (s == null) {
DEPTH.set(s = new ArrayDeque<>());
} }
@Override return s;
@Nonnull }
public FluidStack getFluidInTank(int tank) {
return FluidStack.EMPTY; 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 return outs;
public int getTankCapacity(int tank) { }
return 0;
private LazyOptional<IFluidHandler> getTarget() {
if (!this.getProxy().isActive()) {
return null;
} }
@Override if (this.cachedTank != null) {
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return this.cachedTank;
return false;
} }
@Override final TileEntity te = this.getTile().getWorld()
public int fill(FluidStack resource, FluidAction action) { .getTileEntity(this.getTile().getPos().offset(this.getSide().getFacing()));
return 0;
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 return null;
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
}
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
}
} }
} }