use of com.simibubi.create.content.contraptions.fluids.PipeConnection.Flow in project Create by Creators-of-Create.
the class FluidNetwork method tick.
public void tick() {
if (pauseBeforePropagation > 0) {
pauseBeforePropagation--;
return;
}
for (int cycle = 0; cycle < CYCLES_PER_TICK; cycle++) {
boolean shouldContinue = false;
for (Iterator<BlockFace> iterator = queued.iterator(); iterator.hasNext(); ) {
BlockFace blockFace = iterator.next();
if (!isPresent(blockFace))
continue;
PipeConnection pipeConnection = get(blockFace);
if (pipeConnection != null) {
if (blockFace.equals(start))
transferSpeed = (int) Math.max(1, pipeConnection.pressure.get(true) / 2f);
frontier.add(Pair.of(blockFace, pipeConnection));
}
iterator.remove();
}
for (Iterator<Pair<BlockFace, PipeConnection>> iterator = frontier.iterator(); iterator.hasNext(); ) {
Pair<BlockFace, PipeConnection> pair = iterator.next();
BlockFace blockFace = pair.getFirst();
PipeConnection pipeConnection = pair.getSecond();
if (!pipeConnection.hasFlow())
continue;
Flow flow = pipeConnection.flow.get();
if (!fluid.isEmpty() && !flow.fluid.isFluidEqual(fluid)) {
iterator.remove();
continue;
}
if (!flow.inbound) {
if (pipeConnection.comparePressure() >= 0)
iterator.remove();
continue;
}
if (!flow.complete)
continue;
if (fluid.isEmpty())
fluid = flow.fluid;
boolean canRemove = true;
for (Direction side : Iterate.directions) {
if (side == blockFace.getFace())
continue;
BlockFace adjacentLocation = new BlockFace(blockFace.getPos(), side);
PipeConnection adjacent = get(adjacentLocation);
if (adjacent == null)
continue;
if (!adjacent.hasFlow()) {
// Branch could potentially still appear
if (adjacent.hasPressure() && adjacent.pressure.getSecond() > 0)
canRemove = false;
continue;
}
Flow outFlow = adjacent.flow.get();
if (outFlow.inbound) {
if (adjacent.comparePressure() > 0)
canRemove = false;
continue;
}
if (!outFlow.complete) {
canRemove = false;
continue;
}
// Give pipe end a chance to init connections
if (!adjacent.source.isPresent() && !adjacent.determineSource(world, blockFace.getPos())) {
canRemove = false;
continue;
}
if (adjacent.source.isPresent() && adjacent.source.get().isEndpoint()) {
targets.add(Pair.of(adjacentLocation, adjacent.source.get().provideHandler()));
continue;
}
if (visited.add(adjacentLocation.getConnectedPos())) {
queued.add(adjacentLocation.getOpposite());
shouldContinue = true;
}
}
if (canRemove)
iterator.remove();
}
if (!shouldContinue)
break;
}
if (!source.isPresent())
source = sourceSupplier.get();
if (!source.isPresent())
return;
keepPortableFluidInterfaceEngaged();
if (targets.isEmpty())
return;
for (Pair<BlockFace, LazyOptional<IFluidHandler>> pair : targets) {
if (pair.getSecond().isPresent() && world.getGameTime() % 40 != 0)
continue;
PipeConnection pipeConnection = get(pair.getFirst());
if (pipeConnection == null)
continue;
pipeConnection.source.ifPresent(fs -> {
if (fs.isEndpoint())
pair.setSecond(fs.provideHandler());
});
}
int flowSpeed = transferSpeed;
for (boolean simulate : Iterate.trueAndFalse) {
FluidAction action = simulate ? FluidAction.SIMULATE : FluidAction.EXECUTE;
IFluidHandler handler = source.orElse(null);
if (handler == null)
return;
FluidStack transfer = FluidStack.EMPTY;
for (int i = 0; i < handler.getTanks(); i++) {
FluidStack contained = handler.getFluidInTank(i);
if (contained.isEmpty())
continue;
if (!contained.isFluidEqual(fluid))
continue;
FluidStack toExtract = FluidHelper.copyStackWithAmount(contained, flowSpeed);
transfer = handler.drain(toExtract, action);
}
if (transfer.isEmpty()) {
FluidStack genericExtract = handler.drain(flowSpeed, action);
if (!genericExtract.isEmpty() && genericExtract.isFluidEqual(fluid))
transfer = genericExtract;
}
if (transfer.isEmpty())
return;
if (simulate)
flowSpeed = transfer.getAmount();
List<Pair<BlockFace, LazyOptional<IFluidHandler>>> availableOutputs = new ArrayList<>(targets);
while (!availableOutputs.isEmpty() && transfer.getAmount() > 0) {
int dividedTransfer = transfer.getAmount() / availableOutputs.size();
int remainder = transfer.getAmount() % availableOutputs.size();
for (Iterator<Pair<BlockFace, LazyOptional<IFluidHandler>>> iterator = availableOutputs.iterator(); iterator.hasNext(); ) {
Pair<BlockFace, LazyOptional<IFluidHandler>> pair = iterator.next();
int toTransfer = dividedTransfer;
if (remainder > 0) {
toTransfer++;
remainder--;
}
if (transfer.isEmpty())
break;
IFluidHandler targetHandler = pair.getSecond().orElse(null);
if (targetHandler == null) {
iterator.remove();
continue;
}
FluidStack divided = transfer.copy();
divided.setAmount(toTransfer);
int fill = targetHandler.fill(divided, action);
transfer.setAmount(transfer.getAmount() - fill);
if (fill < toTransfer)
iterator.remove();
}
}
flowSpeed -= transfer.getAmount();
transfer = FluidStack.EMPTY;
}
}
use of com.simibubi.create.content.contraptions.fluids.PipeConnection.Flow in project Create by Creators-of-Create.
the class TransparentStraightPipeRenderer method renderSafe.
@Override
protected void renderSafe(StraightPipeTileEntity te, float partialTicks, PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
FluidTransportBehaviour pipe = te.getBehaviour(FluidTransportBehaviour.TYPE);
if (pipe == null)
return;
for (Direction side : Iterate.directions) {
Flow flow = pipe.getFlow(side);
if (flow == null)
continue;
FluidStack fluidStack = flow.fluid;
if (fluidStack.isEmpty())
continue;
LerpedFloat progress = flow.progress;
if (progress == null)
continue;
float value = progress.getValue(partialTicks);
boolean inbound = flow.inbound;
if (value == 1) {
if (inbound) {
Flow opposite = pipe.getFlow(side.getOpposite());
if (opposite == null)
value -= 1e-6f;
} else {
FluidTransportBehaviour adjacent = TileEntityBehaviour.get(te.getLevel(), te.getBlockPos().relative(side), FluidTransportBehaviour.TYPE);
if (adjacent == null)
value -= 1e-6f;
else {
Flow other = adjacent.getFlow(side.getOpposite());
if (other == null || !other.inbound && !other.complete)
value -= 1e-6f;
}
}
}
FluidRenderer.renderFluidStream(fluidStack, side, 3 / 16f, value, inbound, buffer, ms, light);
}
}
use of com.simibubi.create.content.contraptions.fluids.PipeConnection.Flow in project Create by Creators-of-Create.
the class ContentObserverTileEntity method tick.
@Override
public void tick() {
super.tick();
BlockState state = getBlockState();
if (turnOffTicks > 0) {
turnOffTicks--;
if (turnOffTicks == 0)
level.scheduleTick(worldPosition, state.getBlock(), 1);
}
if (!isActive())
return;
Direction facing = state.getValue(ContentObserverBlock.FACING);
BlockPos targetPos = worldPosition.relative(facing);
// Detect items on belt
TransportedItemStackHandlerBehaviour behaviour = TileEntityBehaviour.get(level, targetPos, TransportedItemStackHandlerBehaviour.TYPE);
if (behaviour != null) {
behaviour.handleCenteredProcessingOnAllItems(.45f, stack -> {
if (!filtering.test(stack.stack) || turnOffTicks == 6)
return TransportedResult.doNothing();
activate();
return TransportedResult.doNothing();
});
return;
}
// Detect fluids in pipe
FluidTransportBehaviour fluidBehaviour = TileEntityBehaviour.get(level, targetPos, FluidTransportBehaviour.TYPE);
if (fluidBehaviour != null) {
for (Direction side : Iterate.directions) {
Flow flow = fluidBehaviour.getFlow(side);
if (flow == null || !flow.inbound || !flow.complete)
continue;
if (!filtering.test(flow.fluid))
continue;
activate();
return;
}
return;
}
if (!observedInventory.simulate().extract().isEmpty()) {
activate();
return;
}
if (!observedTank.simulate().extractAny().isEmpty()) {
activate();
return;
}
}
use of com.simibubi.create.content.contraptions.fluids.PipeConnection.Flow in project Create by Creators-of-Create.
the class FluidPropagator method resetAffectedFluidNetworks.
public static void resetAffectedFluidNetworks(Level world, BlockPos start, Direction side) {
List<BlockPos> frontier = new ArrayList<>();
Set<BlockPos> visited = new HashSet<>();
frontier.add(start);
while (!frontier.isEmpty()) {
BlockPos pos = frontier.remove(0);
if (visited.contains(pos))
continue;
visited.add(pos);
FluidTransportBehaviour pipe = getPipe(world, pos);
if (pipe == null)
continue;
for (Direction d : Iterate.directions) {
if (pos.equals(start) && d != side)
continue;
BlockPos target = pos.relative(d);
if (visited.contains(target))
continue;
PipeConnection connection = pipe.getConnection(d);
if (connection == null)
continue;
if (!connection.hasFlow())
continue;
Flow flow = connection.flow.get();
if (!flow.inbound)
continue;
connection.resetNetwork();
frontier.add(target);
}
}
}
Aggregations