use of com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock in project Create by Creators-of-Create.
the class Contraption method moveBlock.
/**
* move the first block in frontier queue
*/
protected boolean moveBlock(Level world, @Nullable Direction forcedDirection, Queue<BlockPos> frontier, Set<BlockPos> visited) throws AssemblyException {
BlockPos pos = frontier.poll();
if (pos == null)
return false;
visited.add(pos);
if (world.isOutsideBuildHeight(pos))
return true;
if (!world.isLoaded(pos))
throw AssemblyException.unloadedChunk(pos);
if (isAnchoringBlockAt(pos))
return true;
BlockState state = world.getBlockState(pos);
if (!BlockMovementChecks.isMovementNecessary(state, world, pos))
return true;
if (!movementAllowed(state, world, pos))
throw AssemblyException.unmovableBlock(pos, state);
if (state.getBlock() instanceof AbstractChassisBlock && !moveChassis(world, pos, forcedDirection, frontier, visited))
return false;
if (AllBlocks.BELT.has(state))
moveBelt(pos, frontier, visited, state);
if (AllBlocks.GANTRY_CARRIAGE.has(state))
moveGantryPinion(world, pos, frontier, visited, state);
if (AllBlocks.GANTRY_SHAFT.has(state))
moveGantryShaft(world, pos, frontier, visited, state);
if (AllBlocks.STICKER.has(state) && state.getValue(StickerBlock.EXTENDED)) {
Direction offset = state.getValue(StickerBlock.FACING);
BlockPos attached = pos.relative(offset);
if (!visited.contains(attached) && !BlockMovementChecks.isNotSupportive(world.getBlockState(attached), offset.getOpposite()))
frontier.add(attached);
}
// Double Chest halves stick together
if (state.hasProperty(ChestBlock.TYPE) && state.hasProperty(ChestBlock.FACING) && state.getValue(ChestBlock.TYPE) != ChestType.SINGLE) {
Direction offset = ChestBlock.getConnectedDirection(state);
BlockPos attached = pos.relative(offset);
if (!visited.contains(attached))
frontier.add(attached);
}
// Bearings potentially create stabilized sub-contraptions
if (AllBlocks.MECHANICAL_BEARING.has(state))
moveBearing(pos, frontier, visited, state);
// WM Bearings attach their structure when moved
if (AllBlocks.WINDMILL_BEARING.has(state))
moveWindmillBearing(pos, frontier, visited, state);
// Seats transfer their passenger to the contraption
if (state.getBlock() instanceof SeatBlock)
moveSeat(world, pos);
// Pulleys drag their rope and their attached structure
if (state.getBlock() instanceof PulleyBlock)
movePulley(world, pos, frontier, visited);
// Pistons drag their attaches poles and extension
if (state.getBlock() instanceof MechanicalPistonBlock)
if (!moveMechanicalPiston(world, pos, frontier, visited, state))
return false;
if (isExtensionPole(state))
movePistonPole(world, pos, frontier, visited, state);
if (isPistonHead(state))
movePistonHead(world, pos, frontier, visited, state);
// Cart assemblers attach themselves
BlockPos posDown = pos.below();
BlockState stateBelow = world.getBlockState(posDown);
if (!visited.contains(posDown) && AllBlocks.CART_ASSEMBLER.has(stateBelow))
frontier.add(posDown);
Map<Direction, SuperGlueEntity> superglue = SuperGlueHandler.gatherGlue(world, pos);
// Slime blocks and super glue drag adjacent blocks if possible
for (Direction offset : Iterate.directions) {
BlockPos offsetPos = pos.relative(offset);
BlockState blockState = world.getBlockState(offsetPos);
if (isAnchoringBlockAt(offsetPos))
continue;
if (!movementAllowed(blockState, world, offsetPos)) {
if (offset == forcedDirection)
throw AssemblyException.unmovableBlock(pos, state);
continue;
}
boolean wasVisited = visited.contains(offsetPos);
boolean faceHasGlue = superglue.containsKey(offset);
boolean blockAttachedTowardsFace = BlockMovementChecks.isBlockAttachedTowards(blockState, world, offsetPos, offset.getOpposite());
boolean brittle = BlockMovementChecks.isBrittle(blockState);
boolean canStick = !brittle && state.canStickTo(blockState) && blockState.canStickTo(state);
if (canStick) {
if (state.getPistonPushReaction() == PushReaction.PUSH_ONLY || blockState.getPistonPushReaction() == PushReaction.PUSH_ONLY) {
canStick = false;
}
if (BlockMovementChecks.isNotSupportive(state, offset)) {
canStick = false;
}
if (BlockMovementChecks.isNotSupportive(blockState, offset.getOpposite())) {
canStick = false;
}
}
if (!wasVisited && (canStick || blockAttachedTowardsFace || faceHasGlue || (offset == forcedDirection && !BlockMovementChecks.isNotSupportive(state, forcedDirection))))
frontier.add(offsetPos);
if (faceHasGlue)
addGlue(superglue.get(offset));
}
addBlock(pos, capture(world, pos));
if (blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get())
return true;
else
throw AssemblyException.structureTooLarge();
}
use of com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock in project Create by Creators-of-Create.
the class StructureTransform method apply.
/**
* Minecraft does not support blockstate rotation around axes other than y. Add
* specific cases here for blockstates, that should react to rotations around
* horizontal axes
*/
public BlockState apply(BlockState state) {
if (mirror != null)
state = state.mirror(mirror);
Block block = state.getBlock();
if (rotationAxis == Axis.Y) {
if (block instanceof BellBlock) {
if (state.getValue(BlockStateProperties.BELL_ATTACHMENT) == BellAttachType.DOUBLE_WALL)
state = state.setValue(BlockStateProperties.BELL_ATTACHMENT, BellAttachType.SINGLE_WALL);
return state.setValue(BellBlock.FACING, rotation.rotate(state.getValue(BellBlock.FACING)));
}
return state.rotate(rotation);
}
if (block instanceof AbstractChassisBlock)
return rotateChassis(state);
if (block instanceof FaceAttachedHorizontalDirectionalBlock) {
DirectionProperty facingProperty = FaceAttachedHorizontalDirectionalBlock.FACING;
EnumProperty<AttachFace> faceProperty = FaceAttachedHorizontalDirectionalBlock.FACE;
Direction stateFacing = state.getValue(facingProperty);
AttachFace stateFace = state.getValue(faceProperty);
Direction forcedAxis = rotationAxis == Axis.Z ? Direction.EAST : Direction.SOUTH;
if (stateFacing.getAxis() == rotationAxis && stateFace == AttachFace.WALL)
return state;
for (int i = 0; i < rotation.ordinal(); i++) {
stateFace = state.getValue(faceProperty);
stateFacing = state.getValue(facingProperty);
boolean b = state.getValue(faceProperty) == AttachFace.CEILING;
state = state.setValue(facingProperty, b ? forcedAxis : forcedAxis.getOpposite());
if (stateFace != AttachFace.WALL) {
state = state.setValue(faceProperty, AttachFace.WALL);
continue;
}
if (stateFacing.getAxisDirection() == AxisDirection.POSITIVE) {
state = state.setValue(faceProperty, AttachFace.FLOOR);
continue;
}
state = state.setValue(faceProperty, AttachFace.CEILING);
}
return state;
}
boolean halfTurn = rotation == Rotation.CLOCKWISE_180;
if (block instanceof StairBlock) {
state = transformStairs(state, halfTurn);
return state;
}
if (AllBlocks.BELT.has(state)) {
state = transformBelt(state, halfTurn);
return state;
}
if (state.hasProperty(FACING)) {
Direction newFacing = transformFacing(state.getValue(FACING));
if (state.hasProperty(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE)) {
if (rotationAxis == newFacing.getAxis() && rotation.ordinal() % 2 == 1)
state = state.cycle(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE);
}
state = state.setValue(FACING, newFacing);
} else if (state.hasProperty(AXIS)) {
state = state.setValue(AXIS, transformAxis(state.getValue(AXIS)));
} else if (halfTurn) {
if (state.hasProperty(FACING)) {
Direction stateFacing = state.getValue(FACING);
if (stateFacing.getAxis() == rotationAxis)
return state;
}
if (state.hasProperty(HORIZONTAL_FACING)) {
Direction stateFacing = state.getValue(HORIZONTAL_FACING);
if (stateFacing.getAxis() == rotationAxis)
return state;
}
state = state.rotate(rotation);
if (state.hasProperty(SlabBlock.TYPE) && state.getValue(SlabBlock.TYPE) != SlabType.DOUBLE)
state = state.setValue(SlabBlock.TYPE, state.getValue(SlabBlock.TYPE) == SlabType.BOTTOM ? SlabType.TOP : SlabType.BOTTOM);
}
return state;
}
use of com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock in project Create by Creators-of-Create.
the class StructureTransform method rotateChassis.
private BlockState rotateChassis(BlockState state) {
if (rotation == Rotation.NONE)
return state;
BlockState rotated = state.setValue(AXIS, transformAxis(state.getValue(AXIS)));
AbstractChassisBlock block = (AbstractChassisBlock) state.getBlock();
for (Direction face : Iterate.directions) {
BooleanProperty glueableSide = block.getGlueableSide(rotated, face);
if (glueableSide != null)
rotated = rotated.setValue(glueableSide, false);
}
for (Direction face : Iterate.directions) {
BooleanProperty glueableSide = block.getGlueableSide(state, face);
if (glueableSide == null || !state.getValue(glueableSide))
continue;
Direction rotatedFacing = transformFacing(face);
BooleanProperty rotatedGlueableSide = block.getGlueableSide(rotated, rotatedFacing);
if (rotatedGlueableSide != null)
rotated = rotated.setValue(rotatedGlueableSide, true);
}
return rotated;
}
Aggregations