Search in sources :

Example 1 with TransitRequest

use of mekanism.common.lib.inventory.TransitRequest in project Mekanism by mekanism.

the class TileEntityLogisticalSorter method onUpdateServer.

@Override
protected void onUpdateServer() {
    super.onUpdateServer();
    delayTicks = Math.max(0, delayTicks - 1);
    if (delayTicks == 6) {
        setActive(false);
    }
    if (MekanismUtils.canFunction(this) && delayTicks == 0) {
        Direction direction = getDirection();
        TileEntity back = WorldUtils.getTileEntity(getLevel(), worldPosition.relative(direction.getOpposite()));
        TileEntity front = WorldUtils.getTileEntity(getLevel(), worldPosition.relative(direction));
        // If there is no tile to pull from or the push to, skip doing any checks
        if (InventoryUtils.isItemHandler(back, direction) && front != null) {
            boolean sentItems = false;
            for (SorterFilter<?> filter : filters) {
                TransitRequest request = filter.mapInventory(back, direction, singleItem);
                if (request.isEmpty()) {
                    continue;
                }
                int min = singleItem ? 1 : filter.sizeMode ? filter.min : 0;
                TransitResponse response = emitItemToTransporter(front, request, filter.color, min);
                if (!response.isEmpty()) {
                    response.useAll();
                    WorldUtils.saveChunk(back);
                    setActive(true);
                    sentItems = true;
                    break;
                }
            }
            if (!sentItems && autoEject) {
                TransitRequest request = TransitRequest.definedItem(back, direction, singleItem ? 1 : 64, strictFinder);
                TransitResponse response = emitItemToTransporter(front, request, color, 0);
                if (!response.isEmpty()) {
                    response.useAll();
                    WorldUtils.saveChunk(back);
                    setActive(true);
                }
            }
        }
        delayTicks = 10;
    }
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) TransitResponse(mekanism.common.lib.inventory.TransitRequest.TransitResponse) Direction(net.minecraft.util.Direction) TransitRequest(mekanism.common.lib.inventory.TransitRequest)

Example 2 with TransitRequest

use of mekanism.common.lib.inventory.TransitRequest in project Mekanism by mekanism.

the class LogisticalTransporterBase method tick.

public void tick() {
    if (isRemote()) {
        for (TransporterStack stack : transit.values()) {
            stack.progress = Math.min(100, stack.progress + tier.getSpeed());
        }
    } else if (getTransmitterNetwork() != null) {
        // Pull items into the transporter
        if (delay > 0) {
            // If a delay has been imposed, wait a bit
            delay--;
        } else {
            // Reset delay to 3 ticks; if nothing is available to insert OR inserted, we'll try again in 3 ticks
            delay = 3;
            // Attempt to pull
            for (Direction side : getConnections(ConnectionType.PULL)) {
                TileEntity tile = WorldUtils.getTileEntity(getTileWorld(), getTilePos().relative(side));
                if (tile != null) {
                    TransitRequest request = TransitRequest.anyItem(tile, side.getOpposite(), tier.getPullAmount());
                    // There's a stack available to insert into the network...
                    if (!request.isEmpty()) {
                        TransitResponse response = insert(tile, request, getColor(), true, 0);
                        if (response.isEmpty()) {
                            // Insert failed; increment the backoff and calculate delay. Note that we cap retries
                            // at a max of 40 ticks (2 seconds), which would be 4 consecutive retries
                            delayCount++;
                            delay = Math.min(40, (int) Math.exp(delayCount));
                        } else {
                            // If the insert succeeded, remove the inserted count and try again for another 10 ticks
                            response.useAll();
                            delay = 10;
                        }
                    }
                }
            }
        }
        if (!transit.isEmpty()) {
            InventoryNetwork network = getTransmitterNetwork();
            // Update stack positions
            IntSet deletes = new IntOpenHashSet();
            // collection to occur actually causing the tick time to go up slightly.
            for (Int2ObjectMap.Entry<TransporterStack> entry : transit.int2ObjectEntrySet()) {
                int stackId = entry.getIntKey();
                TransporterStack stack = entry.getValue();
                if (!stack.initiatedPath) {
                    if (stack.itemStack.isEmpty() || !recalculate(stackId, stack, null)) {
                        deletes.add(stackId);
                        continue;
                    }
                }
                int prevProgress = stack.progress;
                stack.progress += tier.getSpeed();
                if (stack.progress >= 100) {
                    BlockPos prevSet = null;
                    if (stack.hasPath()) {
                        int currentIndex = stack.getPath().indexOf(getTilePos());
                        if (currentIndex == 0) {
                            // Necessary for transition reasons, not sure why
                            deletes.add(stackId);
                            continue;
                        }
                        BlockPos next = stack.getPath().get(currentIndex - 1);
                        if (next != null) {
                            if (!stack.isFinal(this)) {
                                LogisticalTransporterBase transmitter = network.getTransmitter(next);
                                if (stack.canInsertToTransporter(transmitter, stack.getSide(this), this)) {
                                    transmitter.entityEntering(stack, stack.progress % 100);
                                    deletes.add(stackId);
                                    continue;
                                }
                                prevSet = next;
                            } else if (stack.getPathType() != Path.NONE) {
                                TileEntity tile = WorldUtils.getTileEntity(getTileWorld(), next);
                                if (tile != null) {
                                    TransitResponse response = TransitRequest.simple(stack.itemStack).addToInventory(tile, stack.getSide(this), 0, stack.getPathType() == Path.HOME);
                                    if (!response.isEmpty()) {
                                        // We were able to add at least part of the stack to the inventory
                                        ItemStack rejected = response.getRejected();
                                        if (rejected.isEmpty()) {
                                            // Nothing was rejected (it was all accepted); remove the stack from the prediction
                                            // tracker and schedule this stack for deletion. Continue the loop thereafter
                                            TransporterManager.remove(getTileWorld(), stack);
                                            deletes.add(stackId);
                                            continue;
                                        }
                                        // Some portion of the stack got rejected; save the remainder and
                                        // let the recalculate below sort out what to do next
                                        stack.itemStack = rejected;
                                    }
                                    // else the entire stack got rejected (Note: we don't need to update the stack to point to itself)
                                    prevSet = next;
                                }
                            }
                        }
                    }
                    if (!recalculate(stackId, stack, prevSet)) {
                        deletes.add(stackId);
                    } else if (prevSet == null) {
                        stack.progress = 50;
                    } else {
                        stack.progress = 0;
                    }
                } else if (prevProgress < 50 && stack.progress >= 50) {
                    boolean tryRecalculate;
                    if (stack.isFinal(this)) {
                        Path pathType = stack.getPathType();
                        if (pathType == Path.DEST || pathType == Path.HOME) {
                            Direction side = stack.getSide(this);
                            ConnectionType connectionType = getConnectionType(side);
                            tryRecalculate = connectionType != ConnectionType.NORMAL && connectionType != ConnectionType.PUSH || !TransporterUtils.canInsert(WorldUtils.getTileEntity(getTileWorld(), stack.getDest()), stack.color, stack.itemStack, side, pathType == Path.HOME);
                        } else {
                            tryRecalculate = pathType == Path.NONE;
                        }
                    } else {
                        LogisticalTransporterBase nextTransmitter = network.getTransmitter(stack.getNext(this));
                        if (nextTransmitter == null && stack.getPathType() == Path.NONE && stack.getPath().size() == 2) {
                            // If there is no next transmitter, and it was an idle path, assume that we are idling
                            // in a single length transmitter, in which case we only recalculate it at 50 if it won't
                            // be able to go into that connection type
                            ConnectionType connectionType = getConnectionType(stack.getSide(this));
                            tryRecalculate = connectionType != ConnectionType.NORMAL && connectionType != ConnectionType.PUSH;
                        } else {
                            tryRecalculate = !stack.canInsertToTransporter(nextTransmitter, stack.getSide(this), this);
                        }
                    }
                    if (tryRecalculate && !recalculate(stackId, stack, null)) {
                        deletes.add(stackId);
                    }
                }
            }
            if (!deletes.isEmpty() || !needsSync.isEmpty()) {
                // Notify clients, so that we send the information before we start clearing our lists
                Mekanism.packetHandler.sendToAllTracking(new PacketTransporterUpdate(this, needsSync, deletes), getTransmitterTile());
                // Now remove any entries from transit that have been deleted
                deletes.forEach((IntConsumer) (this::deleteStack));
                // Clear the pending sync packets
                needsSync.clear();
                // Finally, mark chunk for save
                WorldUtils.saveChunk(getTransmitterTile());
            }
        }
    }
}
Also used : Path(mekanism.common.content.transporter.TransporterStack.Path) ConnectionType(mekanism.common.lib.transmitter.ConnectionType) IntSet(it.unimi.dsi.fastutil.ints.IntSet) Direction(net.minecraft.util.Direction) TransitRequest(mekanism.common.lib.inventory.TransitRequest) InventoryNetwork(mekanism.common.content.network.InventoryNetwork) IntConsumer(java.util.function.IntConsumer) TileEntity(net.minecraft.tileentity.TileEntity) IntOpenHashSet(it.unimi.dsi.fastutil.ints.IntOpenHashSet) TransporterStack(mekanism.common.content.transporter.TransporterStack) PacketTransporterUpdate(mekanism.common.network.to_client.PacketTransporterUpdate) TransitResponse(mekanism.common.lib.inventory.TransitRequest.TransitResponse) BlockPos(net.minecraft.util.math.BlockPos) ItemStack(net.minecraft.item.ItemStack)

Example 3 with TransitRequest

use of mekanism.common.lib.inventory.TransitRequest in project Mekanism by mekanism.

the class TileEntityDigitalMiner method onUpdateServer.

@Override
protected void onUpdateServer() {
    super.onUpdateServer();
    closeInvalidScreens();
    if (!initCalc) {
        // reset it and start running again if needed. This happens after saving the miner to disk
        if (searcher.state == State.FINISHED) {
            boolean prevRunning = running;
            reset();
            start();
            running = prevRunning;
        }
        initCalc = true;
    }
    energySlot.fillContainerOrConvert();
    if (MekanismUtils.canFunction(this) && running && searcher.state == State.FINISHED && !oresToMine.isEmpty()) {
        FloatingLong energyPerTick = energyContainer.getEnergyPerTick();
        if (energyContainer.extract(energyPerTick, Action.SIMULATE, AutomationType.INTERNAL).equals(energyPerTick)) {
            setActive(true);
            if (delay > 0) {
                delay--;
            }
            energyContainer.extract(energyPerTick, Action.EXECUTE, AutomationType.INTERNAL);
            if (delay == 0) {
                tryMineBlock();
                delay = getDelay();
            }
        } else {
            setActive(false);
        }
    } else {
        setActive(false);
    }
    if (doEject && delayTicks == 0) {
        Direction oppositeDirection = getOppositeDirection();
        TileEntity ejectInv = WorldUtils.getTileEntity(level, getBlockPos().above().relative(oppositeDirection, 2));
        TileEntity ejectTile = WorldUtils.getTileEntity(getLevel(), getBlockPos().above().relative(oppositeDirection));
        if (ejectInv != null && ejectTile != null) {
            TransitRequest ejectMap = InventoryUtils.getEjectItemMap(ejectTile, oppositeDirection, mainSlots);
            if (!ejectMap.isEmpty()) {
                TransitResponse response;
                if (ejectInv instanceof TileEntityLogisticalTransporterBase) {
                    response = ((TileEntityLogisticalTransporterBase) ejectInv).getTransmitter().insert(ejectTile, ejectMap, null, true, 0);
                } else {
                    response = ejectMap.addToInventory(ejectInv, oppositeDirection, 0, false);
                }
                if (!response.isEmpty()) {
                    response.useAll();
                }
            }
            delayTicks = 10;
        }
    } else if (delayTicks > 0) {
        delayTicks--;
    }
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) FloatingLong(mekanism.api.math.FloatingLong) TransitResponse(mekanism.common.lib.inventory.TransitRequest.TransitResponse) Direction(net.minecraft.util.Direction) TileEntityLogisticalTransporterBase(mekanism.common.tile.transmitter.TileEntityLogisticalTransporterBase) TransitRequest(mekanism.common.lib.inventory.TransitRequest)

Aggregations

TransitRequest (mekanism.common.lib.inventory.TransitRequest)3 TransitResponse (mekanism.common.lib.inventory.TransitRequest.TransitResponse)3 TileEntity (net.minecraft.tileentity.TileEntity)3 Direction (net.minecraft.util.Direction)3 IntOpenHashSet (it.unimi.dsi.fastutil.ints.IntOpenHashSet)1 IntSet (it.unimi.dsi.fastutil.ints.IntSet)1 IntConsumer (java.util.function.IntConsumer)1 FloatingLong (mekanism.api.math.FloatingLong)1 InventoryNetwork (mekanism.common.content.network.InventoryNetwork)1 TransporterStack (mekanism.common.content.transporter.TransporterStack)1 Path (mekanism.common.content.transporter.TransporterStack.Path)1 ConnectionType (mekanism.common.lib.transmitter.ConnectionType)1 PacketTransporterUpdate (mekanism.common.network.to_client.PacketTransporterUpdate)1 TileEntityLogisticalTransporterBase (mekanism.common.tile.transmitter.TileEntityLogisticalTransporterBase)1 ItemStack (net.minecraft.item.ItemStack)1 BlockPos (net.minecraft.util.math.BlockPos)1