This reverts commit 22f552217f.
This commit is contained in:
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user