use of com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour in project Create by Creators-of-Create.
the class AbstractChuteBlock method updateEntityAfterFallOn.
@Override
public void updateEntityAfterFallOn(BlockGetter worldIn, Entity entityIn) {
super.updateEntityAfterFallOn(worldIn, entityIn);
if (!(entityIn instanceof ItemEntity))
return;
if (entityIn.level.isClientSide)
return;
if (!entityIn.isAlive())
return;
DirectBeltInputBehaviour input = TileEntityBehaviour.get(entityIn.level, new BlockPos(entityIn.position().add(0, 0.5f, 0)).below(), DirectBeltInputBehaviour.TYPE);
if (input == null)
return;
if (!input.canInsertFromSide(Direction.UP))
return;
ItemEntity itemEntity = (ItemEntity) entityIn;
ItemStack toInsert = itemEntity.getItem();
ItemStack remainder = input.handleInsertion(toInsert, Direction.UP, false);
if (remainder.isEmpty())
itemEntity.discard();
if (remainder.getCount() < toInsert.getCount())
itemEntity.setItem(remainder);
}
use of com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour in project Create by Creators-of-Create.
the class FunnelTileEntity method activateExtractingBeltFunnel.
private void activateExtractingBeltFunnel() {
BlockState blockState = getBlockState();
Direction facing = blockState.getValue(BeltFunnelBlock.HORIZONTAL_FACING);
DirectBeltInputBehaviour inputBehaviour = TileEntityBehaviour.get(level, worldPosition.below(), DirectBeltInputBehaviour.TYPE);
if (inputBehaviour == null)
return;
if (!inputBehaviour.canInsertFromSide(facing))
return;
int amountToExtract = getAmountToExtract();
ItemStack stack = invManipulation.extract(amountToExtract, s -> inputBehaviour.handleInsertion(s, facing, true).isEmpty());
if (stack.isEmpty())
return;
flap(false);
onTransfer(stack);
inputBehaviour.handleInsertion(stack, facing, false);
startCooldown();
}
use of com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour in project Create by Creators-of-Create.
the class BeltFunnelBlock method isOnValidBelt.
public static boolean isOnValidBelt(BlockState state, LevelReader world, BlockPos pos) {
BlockState stateBelow = world.getBlockState(pos.below());
if ((stateBelow.getBlock() instanceof BeltBlock))
return BeltBlock.canTransportObjects(stateBelow);
DirectBeltInputBehaviour directBeltInputBehaviour = TileEntityBehaviour.get(world, pos.below(), DirectBeltInputBehaviour.TYPE);
if (directBeltInputBehaviour == null)
return false;
return directBeltInputBehaviour.canSupportBeltFunnels();
}
use of com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour in project Create by Creators-of-Create.
the class BeltInventory method tick.
public void tick() {
// Added/Removed items from previous cycle
if (!toInsert.isEmpty() || !toRemove.isEmpty()) {
toInsert.forEach(this::insert);
toInsert.clear();
items.removeAll(toRemove);
toRemove.clear();
belt.setChanged();
belt.sendData();
}
if (belt.getSpeed() == 0)
return;
// Reverse item collection if belt just reversed
if (beltMovementPositive != belt.getDirectionAwareBeltMovementSpeed() > 0) {
beltMovementPositive = !beltMovementPositive;
Collections.reverse(items);
belt.setChanged();
belt.sendData();
}
// Assuming the first entry is furthest on the belt
TransportedItemStack stackInFront = null;
TransportedItemStack currentItem = null;
Iterator<TransportedItemStack> iterator = items.iterator();
// Useful stuff
float beltSpeed = belt.getDirectionAwareBeltMovementSpeed();
Direction movementFacing = belt.getMovementFacing();
boolean horizontal = belt.getBlockState().getValue(BeltBlock.SLOPE) == BeltSlope.HORIZONTAL;
float spacing = 1;
Level world = belt.getLevel();
boolean onClient = world.isClientSide && !belt.isVirtual();
// resolve ending only when items will reach it this tick
Ending ending = Ending.UNRESOLVED;
// Loop over items
while (iterator.hasNext()) {
stackInFront = currentItem;
currentItem = iterator.next();
currentItem.prevBeltPosition = currentItem.beltPosition;
currentItem.prevSideOffset = currentItem.sideOffset;
if (currentItem.stack.isEmpty()) {
iterator.remove();
currentItem = null;
continue;
}
float movement = beltSpeed;
if (onClient)
movement *= ServerSpeedProvider.get();
// Don't move if held by processing (client)
if (world.isClientSide && currentItem.locked)
continue;
// Don't move if held by external components
if (currentItem.lockedExternally) {
currentItem.lockedExternally = false;
continue;
}
// Don't move if other items are waiting in front
boolean noMovement = false;
float currentPos = currentItem.beltPosition;
if (stackInFront != null) {
float diff = stackInFront.beltPosition - currentPos;
if (Math.abs(diff) <= spacing)
noMovement = true;
movement = beltMovementPositive ? Math.min(movement, diff - spacing) : Math.max(movement, diff + spacing);
}
// Don't move beyond the edge
float diffToEnd = beltMovementPositive ? belt.beltLength - currentPos : -currentPos;
if (Math.abs(diffToEnd) < Math.abs(movement) + 1) {
if (ending == Ending.UNRESOLVED)
ending = resolveEnding();
diffToEnd += beltMovementPositive ? -ending.margin : ending.margin;
}
float limitedMovement = beltMovementPositive ? Math.min(movement, diffToEnd) : Math.max(movement, diffToEnd);
float nextOffset = currentItem.beltPosition + limitedMovement;
// Belt item processing
if (!onClient && horizontal) {
ItemStack item = currentItem.stack;
if (handleBeltProcessingAndCheckIfRemoved(currentItem, nextOffset, noMovement)) {
iterator.remove();
belt.sendData();
continue;
}
if (item != currentItem.stack)
belt.sendData();
if (currentItem.locked)
continue;
}
// Belt Funnels
if (BeltFunnelInteractionHandler.checkForFunnels(this, currentItem, nextOffset))
continue;
if (noMovement)
continue;
// Belt Tunnels
if (BeltTunnelInteractionHandler.flapTunnelsAndCheckIfStuck(this, currentItem, nextOffset))
continue;
// Horizontal Crushing Wheels
if (BeltCrusherInteractionHandler.checkForCrushers(this, currentItem, nextOffset))
continue;
// Apply Movement
currentItem.beltPosition += limitedMovement;
currentItem.sideOffset += (currentItem.getTargetSideOffset() - currentItem.sideOffset) * Math.abs(limitedMovement) * 2f;
currentPos = currentItem.beltPosition;
// Movement successful
if (limitedMovement == movement || onClient)
continue;
// End reached
int lastOffset = beltMovementPositive ? belt.beltLength - 1 : 0;
BlockPos nextPosition = BeltHelper.getPositionForOffset(belt, beltMovementPositive ? belt.beltLength : -1);
if (ending == Ending.FUNNEL)
continue;
if (ending == Ending.INSERT) {
DirectBeltInputBehaviour inputBehaviour = TileEntityBehaviour.get(world, nextPosition, DirectBeltInputBehaviour.TYPE);
if (inputBehaviour == null)
continue;
if (!inputBehaviour.canInsertFromSide(movementFacing))
continue;
ItemStack remainder = inputBehaviour.handleInsertion(currentItem, movementFacing, false);
if (remainder.equals(currentItem.stack, false))
continue;
currentItem.stack = remainder;
if (remainder.isEmpty())
iterator.remove();
flapTunnel(this, lastOffset, movementFacing, false);
belt.sendData();
continue;
}
if (ending == Ending.BLOCKED)
continue;
if (ending == Ending.EJECT) {
eject(currentItem);
iterator.remove();
flapTunnel(this, lastOffset, movementFacing, false);
belt.sendData();
continue;
}
}
}
use of com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour in project Create by Creators-of-Create.
the class BeltInventory method resolveEnding.
private Ending resolveEnding() {
Level world = belt.getLevel();
BlockPos nextPosition = BeltHelper.getPositionForOffset(belt, beltMovementPositive ? belt.beltLength : -1);
// if (AllBlocks.BRASS_BELT_FUNNEL.has(world.getBlockState(lastPosition.up())))
// return Ending.FUNNEL;
DirectBeltInputBehaviour inputBehaviour = TileEntityBehaviour.get(world, nextPosition, DirectBeltInputBehaviour.TYPE);
if (inputBehaviour != null)
return Ending.INSERT;
if (BlockHelper.hasBlockSolidSide(world.getBlockState(nextPosition), world, nextPosition, belt.getMovementFacing().getOpposite()))
return Ending.BLOCKED;
return Ending.EJECT;
}
Aggregations