use of com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity in project Create by Creators-of-Create.
the class BasinBlock method canOutputTo.
public static boolean canOutputTo(BlockGetter world, BlockPos basinPos, Direction direction) {
BlockPos neighbour = basinPos.relative(direction);
BlockPos output = neighbour.below();
BlockState blockState = world.getBlockState(neighbour);
if (FunnelBlock.isFunnel(blockState)) {
if (FunnelBlock.getFunnelFacing(blockState) == direction)
return false;
} else if (!blockState.getCollisionShape(world, neighbour).isEmpty()) {
return false;
} else {
BlockEntity tileEntity = world.getBlockEntity(output);
if (tileEntity instanceof BeltTileEntity) {
BeltTileEntity belt = (BeltTileEntity) tileEntity;
return belt.getSpeed() == 0 || belt.getMovementFacing() != direction.getOpposite();
}
}
DirectBeltInputBehaviour directBeltInputBehaviour = TileEntityBehaviour.get(world, output, DirectBeltInputBehaviour.TYPE);
if (directBeltInputBehaviour != null)
return directBeltInputBehaviour.canInsertFromSide(direction);
return false;
}
use of com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity in project Create by Creators-of-Create.
the class BrassTunnelTileEntity method tick.
@Override
public void tick() {
super.tick();
BeltTileEntity beltBelow = BeltHelper.getSegmentTE(level, worldPosition.below());
if (distributionProgress > 0)
distributionProgress--;
if (beltBelow == null || beltBelow.getSpeed() == 0)
return;
if (stackToDistribute.isEmpty() && !syncedOutputActive)
return;
if (level.isClientSide && !isVirtual())
return;
if (distributionProgress == -1) {
distributionTargets.forEach(List::clear);
distributionDistanceLeft = 0;
distributionDistanceRight = 0;
syncSet.clear();
List<Pair<BrassTunnelTileEntity, Direction>> validOutputs = gatherValidOutputs();
if (selectionMode.get() == SelectionMode.SYNCHRONIZE) {
boolean allEmpty = true;
boolean allFull = true;
for (BrassTunnelTileEntity te : syncSet) {
boolean hasStack = !te.stackToDistribute.isEmpty();
allEmpty &= !hasStack;
allFull &= hasStack;
}
final boolean notifySyncedOut = !allEmpty;
if (allFull || allEmpty)
syncSet.forEach(te -> te.syncedOutputActive = notifySyncedOut);
}
if (validOutputs == null)
return;
if (stackToDistribute.isEmpty())
return;
for (Pair<BrassTunnelTileEntity, Direction> pair : validOutputs) {
BrassTunnelTileEntity tunnel = pair.getKey();
Direction output = pair.getValue();
if (insertIntoTunnel(tunnel, output, stackToDistribute, true) == null)
continue;
distributionTargets.get(!tunnel.flapFilterEmpty(output)).add(Pair.of(tunnel.worldPosition, output));
int distance = tunnel.worldPosition.getX() + tunnel.worldPosition.getZ() - worldPosition.getX() - worldPosition.getZ();
if (distance < 0)
distributionDistanceLeft = Math.max(distributionDistanceLeft, -distance);
else
distributionDistanceRight = Math.max(distributionDistanceRight, distance);
}
if (distributionTargets.getFirst().isEmpty() && distributionTargets.getSecond().isEmpty())
return;
if (selectionMode.get() != SelectionMode.SYNCHRONIZE || syncedOutputActive) {
distributionProgress = 10;
sendData();
}
return;
}
if (distributionProgress != 0)
return;
distributionTargets.forEach(list -> {
if (stackToDistribute.isEmpty())
return;
List<Pair<BrassTunnelTileEntity, Direction>> validTargets = new ArrayList<>();
for (Pair<BlockPos, Direction> pair : list) {
BlockPos tunnelPos = pair.getKey();
Direction output = pair.getValue();
BlockEntity te = level.getBlockEntity(tunnelPos);
if (!(te instanceof BrassTunnelTileEntity))
continue;
validTargets.add(Pair.of((BrassTunnelTileEntity) te, output));
}
distribute(validTargets);
distributionProgress = -1;
});
}
use of com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity in project Create by Creators-of-Create.
the class BeltMovementHandler method transportEntity.
public static void transportEntity(BeltTileEntity beltTe, Entity entityIn, TransportedEntityInfo info) {
BlockPos pos = info.lastCollidedPos;
Level world = beltTe.getLevel();
BlockEntity te = world.getBlockEntity(pos);
BlockEntity tileEntityBelowPassenger = world.getBlockEntity(entityIn.blockPosition());
BlockState blockState = info.lastCollidedState;
Direction movementFacing = Direction.fromAxisAndDirection(blockState.getValue(BlockStateProperties.HORIZONTAL_FACING).getAxis(), beltTe.getSpeed() < 0 ? POSITIVE : NEGATIVE);
boolean collidedWithBelt = te instanceof BeltTileEntity;
boolean betweenBelts = tileEntityBelowPassenger instanceof BeltTileEntity && tileEntityBelowPassenger != te;
// Don't fight other Belts
if (!collidedWithBelt || betweenBelts) {
return;
}
// Too slow
boolean notHorizontal = beltTe.getBlockState().getValue(BeltBlock.SLOPE) != BeltSlope.HORIZONTAL;
if (Math.abs(beltTe.getSpeed()) < 1)
return;
// Not on top
if (entityIn.getY() - .25f < pos.getY())
return;
// Lock entities in place
boolean isPlayer = entityIn instanceof Player;
if (entityIn instanceof LivingEntity && !isPlayer)
((LivingEntity) entityIn).addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 10, 1, false, false));
final Direction beltFacing = blockState.getValue(BlockStateProperties.HORIZONTAL_FACING);
final BeltSlope slope = blockState.getValue(BeltBlock.SLOPE);
final Axis axis = beltFacing.getAxis();
float movementSpeed = beltTe.getBeltMovementSpeed();
final Direction movementDirection = Direction.get(axis == Axis.X ? NEGATIVE : POSITIVE, axis);
Vec3i centeringDirection = Direction.get(POSITIVE, beltFacing.getClockWise().getAxis()).getNormal();
Vec3 movement = Vec3.atLowerCornerOf(movementDirection.getNormal()).scale(movementSpeed);
double diffCenter = axis == Axis.Z ? (pos.getX() + .5f - entityIn.getX()) : (pos.getZ() + .5f - entityIn.getZ());
if (Math.abs(diffCenter) > 48 / 64f)
return;
BeltPart part = blockState.getValue(BeltBlock.PART);
float top = 13 / 16f;
boolean onSlope = notHorizontal && (part == BeltPart.MIDDLE || part == BeltPart.PULLEY || part == (slope == BeltSlope.UPWARD ? BeltPart.END : BeltPart.START) && entityIn.getY() - pos.getY() < top || part == (slope == BeltSlope.UPWARD ? BeltPart.START : BeltPart.END) && entityIn.getY() - pos.getY() > top);
boolean movingDown = onSlope && slope == (movementFacing == beltFacing ? BeltSlope.DOWNWARD : BeltSlope.UPWARD);
boolean movingUp = onSlope && slope == (movementFacing == beltFacing ? BeltSlope.UPWARD : BeltSlope.DOWNWARD);
if (beltFacing.getAxis() == Axis.Z) {
boolean b = movingDown;
movingDown = movingUp;
movingUp = b;
}
if (movingUp)
movement = movement.add(0, Math.abs(axis.choose(movement.x, movement.y, movement.z)), 0);
if (movingDown)
movement = movement.add(0, -Math.abs(axis.choose(movement.x, movement.y, movement.z)), 0);
Vec3 centering = Vec3.atLowerCornerOf(centeringDirection).scale(diffCenter * Math.min(Math.abs(movementSpeed), .1f) * 4);
if (!(entityIn instanceof LivingEntity) || ((LivingEntity) entityIn).zza == 0 && ((LivingEntity) entityIn).xxa == 0)
movement = movement.add(centering);
float step = entityIn.maxUpStep;
if (!isPlayer)
entityIn.maxUpStep = 1;
// Entity Collisions
if (Math.abs(movementSpeed) < .5f) {
Vec3 checkDistance = movement.normalize().scale(0.5);
AABB bb = entityIn.getBoundingBox();
AABB checkBB = new AABB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ);
checkBB = checkBB.move(checkDistance).inflate(-Math.abs(checkDistance.x), -Math.abs(checkDistance.y), -Math.abs(checkDistance.z));
List<Entity> list = world.getEntities(entityIn, checkBB);
list.removeIf(e -> shouldIgnoreBlocking(entityIn, e));
if (!list.isEmpty()) {
entityIn.setDeltaMovement(0, 0, 0);
info.ticksSinceLastCollision--;
return;
}
}
entityIn.fallDistance = 0;
if (movingUp) {
float minVelocity = .13f;
float yMovement = (float) -(Math.max(Math.abs(movement.y), minVelocity));
entityIn.move(SELF, new Vec3(0, yMovement, 0));
entityIn.move(SELF, movement.multiply(1, 0, 1));
} else if (movingDown) {
entityIn.move(SELF, movement.multiply(1, 0, 1));
entityIn.move(SELF, movement.multiply(0, 1, 0));
} else {
entityIn.move(SELF, movement);
}
entityIn.setOnGround(true);
if (!isPlayer)
entityIn.maxUpStep = step;
boolean movedPastEndingSlope = onSlope && (AllBlocks.BELT.has(world.getBlockState(entityIn.blockPosition())) || AllBlocks.BELT.has(world.getBlockState(entityIn.blockPosition().below())));
if (movedPastEndingSlope && !movingDown && Math.abs(movementSpeed) > 0)
entityIn.setPos(entityIn.getX(), entityIn.getY() + movement.y, entityIn.getZ());
if (movedPastEndingSlope) {
entityIn.setDeltaMovement(movement);
entityIn.hurtMarked = true;
}
}
use of com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity in project Create by Creators-of-Create.
the class SchematicannonTileEntity method launchBlockOrBelt.
protected void launchBlockOrBelt(BlockPos target, ItemStack icon, BlockState blockState, BlockEntity tile) {
if (AllBlocks.BELT.has(blockState)) {
blockState = stripBeltIfNotLast(blockState);
if (tile instanceof BeltTileEntity && AllBlocks.BELT.has(blockState))
launchBelt(target, blockState, ((BeltTileEntity) tile).beltLength);
else if (blockState != Blocks.AIR.defaultBlockState())
launchBlock(target, icon, blockState, null);
} else {
CompoundTag data = null;
if (tile != null) {
if (AllBlockTags.SAFE_NBT.matches(blockState)) {
data = tile.saveWithFullMetadata();
data = NBTProcessors.process(tile, data, true);
} else if (tile instanceof IPartialSafeNBT) {
data = new CompoundTag();
((IPartialSafeNBT) tile).writeSafe(data, false);
data = NBTProcessors.process(tile, data, true);
}
}
launchBlock(target, icon, blockState, data);
}
}
use of com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity in project Create by Creators-of-Create.
the class BeltTunnelInteractionHandler method stuckAtTunnel.
public static boolean stuckAtTunnel(BeltInventory beltInventory, int offset, ItemStack stack, Direction movementDirection) {
BeltTileEntity belt = beltInventory.belt;
BlockPos pos = BeltHelper.getPositionForOffset(belt, offset).above();
if (!(belt.getLevel().getBlockState(pos).getBlock() instanceof BrassTunnelBlock))
return false;
BlockEntity te = belt.getLevel().getBlockEntity(pos);
if (te == null || !(te instanceof BrassTunnelTileEntity))
return false;
BrassTunnelTileEntity tunnel = (BrassTunnelTileEntity) te;
return !tunnel.canInsert(movementDirection.getOpposite(), stack);
}
Aggregations