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;
}
}
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());
}
}
}
}
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--;
}
}
Aggregations