Search in sources :

Example 1 with AbstractChassisBlock

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();
}
Also used : SeatBlock(com.simibubi.create.content.contraptions.components.actors.SeatBlock) BlockState(net.minecraft.world.level.block.state.BlockState) SuperGlueEntity(com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity) MechanicalPistonBlock(com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock) AbstractChassisBlock(com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock) BlockPos(net.minecraft.core.BlockPos) Direction(net.minecraft.core.Direction) PulleyBlock(com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock)

Example 2 with AbstractChassisBlock

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;
}
Also used : FaceAttachedHorizontalDirectionalBlock(net.minecraft.world.level.block.FaceAttachedHorizontalDirectionalBlock) AttachFace(net.minecraft.world.level.block.state.properties.AttachFace) BellBlock(net.minecraft.world.level.block.BellBlock) AbstractChassisBlock(com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock) BeltBlock(com.simibubi.create.content.contraptions.relays.belt.BeltBlock) SlabBlock(net.minecraft.world.level.block.SlabBlock) BellBlock(net.minecraft.world.level.block.BellBlock) AbstractChassisBlock(com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock) FaceAttachedHorizontalDirectionalBlock(net.minecraft.world.level.block.FaceAttachedHorizontalDirectionalBlock) DirectionalAxisKineticBlock(com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock) Block(net.minecraft.world.level.block.Block) StairBlock(net.minecraft.world.level.block.StairBlock) StairBlock(net.minecraft.world.level.block.StairBlock) DirectionProperty(net.minecraft.world.level.block.state.properties.DirectionProperty) Direction(net.minecraft.core.Direction) AxisDirection(net.minecraft.core.Direction.AxisDirection)

Example 3 with AbstractChassisBlock

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;
}
Also used : BlockState(net.minecraft.world.level.block.state.BlockState) BooleanProperty(net.minecraft.world.level.block.state.properties.BooleanProperty) AbstractChassisBlock(com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock) Direction(net.minecraft.core.Direction) AxisDirection(net.minecraft.core.Direction.AxisDirection)

Aggregations

AbstractChassisBlock (com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock)3 Direction (net.minecraft.core.Direction)3 AxisDirection (net.minecraft.core.Direction.AxisDirection)2 BlockState (net.minecraft.world.level.block.state.BlockState)2 DirectionalAxisKineticBlock (com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock)1 SeatBlock (com.simibubi.create.content.contraptions.components.actors.SeatBlock)1 SuperGlueEntity (com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity)1 MechanicalPistonBlock (com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock)1 PulleyBlock (com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock)1 BeltBlock (com.simibubi.create.content.contraptions.relays.belt.BeltBlock)1 BlockPos (net.minecraft.core.BlockPos)1 BellBlock (net.minecraft.world.level.block.BellBlock)1 Block (net.minecraft.world.level.block.Block)1 FaceAttachedHorizontalDirectionalBlock (net.minecraft.world.level.block.FaceAttachedHorizontalDirectionalBlock)1 SlabBlock (net.minecraft.world.level.block.SlabBlock)1 StairBlock (net.minecraft.world.level.block.StairBlock)1 AttachFace (net.minecraft.world.level.block.state.properties.AttachFace)1 BooleanProperty (net.minecraft.world.level.block.state.properties.BooleanProperty)1 DirectionProperty (net.minecraft.world.level.block.state.properties.DirectionProperty)1