mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-06-02 10:49:31 +02:00
219 lines
8 KiB
Java
219 lines
8 KiB
Java
package com.simibubi.create.content.contraptions.relays.encased;
|
|
|
|
import com.simibubi.create.AllTileEntities;
|
|
import com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock;
|
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
|
import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock;
|
|
import com.simibubi.create.content.contraptions.solver.AllConnections;
|
|
import com.simibubi.create.content.contraptions.solver.ConnectionsBuilder;
|
|
import com.simibubi.create.foundation.block.ITE;
|
|
import com.simibubi.create.foundation.utility.Iterate;
|
|
import com.simibubi.create.foundation.utility.Lang;
|
|
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.core.Direction.Axis;
|
|
import net.minecraft.core.Direction.AxisDirection;
|
|
import net.minecraft.util.StringRepresentable;
|
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
|
import net.minecraft.world.item.context.UseOnContext;
|
|
import net.minecraft.world.level.LevelAccessor;
|
|
import net.minecraft.world.level.LevelReader;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
|
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
|
import net.minecraft.world.level.block.state.properties.Property;
|
|
import net.minecraft.world.level.material.PushReaction;
|
|
|
|
public class EncasedBeltBlock extends RotatedPillarKineticBlock implements ITE<KineticTileEntity> {
|
|
|
|
public static final Property<Part> PART = EnumProperty.create("part", Part.class);
|
|
public static final BooleanProperty CONNECTED_ALONG_FIRST_COORDINATE =
|
|
DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE;
|
|
|
|
public EncasedBeltBlock(Properties properties) {
|
|
super(properties);
|
|
registerDefaultState(defaultBlockState().setValue(PART, Part.NONE));
|
|
}
|
|
|
|
@Override
|
|
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public PushReaction getPistonPushReaction(BlockState state) {
|
|
return PushReaction.NORMAL;
|
|
}
|
|
|
|
@Override
|
|
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
|
|
super.createBlockStateDefinition(builder.add(PART, CONNECTED_ALONG_FIRST_COORDINATE));
|
|
}
|
|
|
|
@Override
|
|
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
|
Axis placedAxis = context.getNearestLookingDirection()
|
|
.getAxis();
|
|
Axis axis = context.getPlayer() != null && context.getPlayer()
|
|
.isShiftKeyDown() ? placedAxis : getPreferredAxis(context);
|
|
if (axis == null)
|
|
axis = placedAxis;
|
|
|
|
BlockState state = defaultBlockState().setValue(AXIS, axis);
|
|
for (Direction facing : Iterate.directions) {
|
|
if (facing.getAxis() == axis)
|
|
continue;
|
|
BlockPos pos = context.getClickedPos();
|
|
BlockPos offset = pos.relative(facing);
|
|
state = updateShape(state, facing, context.getLevel()
|
|
.getBlockState(offset), context.getLevel(), pos, offset);
|
|
}
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
public BlockState updateShape(BlockState stateIn, Direction face, BlockState neighbour, LevelAccessor worldIn,
|
|
BlockPos currentPos, BlockPos facingPos) {
|
|
Part part = stateIn.getValue(PART);
|
|
Axis axis = stateIn.getValue(AXIS);
|
|
boolean connectionAlongFirst = stateIn.getValue(CONNECTED_ALONG_FIRST_COORDINATE);
|
|
Axis connectionAxis =
|
|
connectionAlongFirst ? (axis == Axis.X ? Axis.Y : Axis.X) : (axis == Axis.Z ? Axis.Y : Axis.Z);
|
|
|
|
Axis faceAxis = face.getAxis();
|
|
boolean facingAlongFirst = axis == Axis.X ? faceAxis.isVertical() : faceAxis == Axis.X;
|
|
boolean positive = face.getAxisDirection() == AxisDirection.POSITIVE;
|
|
|
|
if (axis == faceAxis)
|
|
return stateIn;
|
|
|
|
if (!(neighbour.getBlock() instanceof EncasedBeltBlock)) {
|
|
if (facingAlongFirst != connectionAlongFirst || part == Part.NONE)
|
|
return stateIn;
|
|
if (part == Part.MIDDLE)
|
|
return stateIn.setValue(PART, positive ? Part.END : Part.START);
|
|
if ((part == Part.START) == positive)
|
|
return stateIn.setValue(PART, Part.NONE);
|
|
return stateIn;
|
|
}
|
|
|
|
Part otherPart = neighbour.getValue(PART);
|
|
Axis otherAxis = neighbour.getValue(AXIS);
|
|
boolean otherConnection = neighbour.getValue(CONNECTED_ALONG_FIRST_COORDINATE);
|
|
Axis otherConnectionAxis =
|
|
otherConnection ? (otherAxis == Axis.X ? Axis.Y : Axis.X) : (otherAxis == Axis.Z ? Axis.Y : Axis.Z);
|
|
|
|
if (neighbour.getValue(AXIS) == faceAxis)
|
|
return stateIn;
|
|
if (otherPart != Part.NONE && otherConnectionAxis != faceAxis)
|
|
return stateIn;
|
|
|
|
if (part == Part.NONE) {
|
|
part = positive ? Part.START : Part.END;
|
|
connectionAlongFirst = axis == Axis.X ? faceAxis.isVertical() : faceAxis == Axis.X;
|
|
} else if (connectionAxis != faceAxis) {
|
|
return stateIn;
|
|
}
|
|
|
|
if ((part == Part.START) != positive)
|
|
part = Part.MIDDLE;
|
|
|
|
BlockState newState = stateIn.setValue(PART, part)
|
|
.setValue(CONNECTED_ALONG_FIRST_COORDINATE, connectionAlongFirst);
|
|
|
|
withTileEntityDo(worldIn, currentPos, kte -> kte.updateInitialConnections(newState));
|
|
|
|
return newState;
|
|
}
|
|
|
|
@Override
|
|
public BlockState getRotatedBlockState(BlockState originalState, Direction targetedFace) {
|
|
if (originalState.getValue(PART) == Part.NONE)
|
|
return super.getRotatedBlockState(originalState, targetedFace);
|
|
return super.getRotatedBlockState(originalState,
|
|
Direction.get(AxisDirection.POSITIVE, getConnectionAxis(originalState)));
|
|
}
|
|
|
|
@Override
|
|
public BlockState updateAfterWrenched(BlockState newState, UseOnContext context) {
|
|
// Blocks.AIR.getDefaultState()
|
|
// .updateNeighbors(context.getWorld(), context.getPos(), 1);
|
|
Axis axis = newState.getValue(AXIS);
|
|
newState = defaultBlockState().setValue(AXIS, axis);
|
|
if (newState.hasProperty(BlockStateProperties.POWERED))
|
|
newState = newState.setValue(BlockStateProperties.POWERED, context.getLevel()
|
|
.hasNeighborSignal(context.getClickedPos()));
|
|
for (Direction facing : Iterate.directions) {
|
|
if (facing.getAxis() == axis)
|
|
continue;
|
|
BlockPos pos = context.getClickedPos();
|
|
BlockPos offset = pos.relative(facing);
|
|
newState = updateShape(newState, facing, context.getLevel()
|
|
.getBlockState(offset), context.getLevel(), pos, offset);
|
|
}
|
|
// newState.updateNeighbors(context.getWorld(), context.getPos(), 1 | 2);
|
|
return newState;
|
|
}
|
|
|
|
@Override
|
|
public boolean hasShaftTowards(BlockState state, Direction face) {
|
|
return face.getAxis() == state.getValue(AXIS);
|
|
}
|
|
|
|
@Override
|
|
public Axis getRotationAxis(BlockState state) {
|
|
return state.getValue(AXIS);
|
|
}
|
|
|
|
public static ConnectionsBuilder encasedBeltConnections(BlockState state, float mod) {
|
|
Part part = state.getValue(PART);
|
|
Axis shaftAxis = state.getValue(AXIS);
|
|
Axis connectionAxis = getConnectionAxis(state);
|
|
|
|
ConnectionsBuilder builder = ConnectionsBuilder.builder().withFullShaft(shaftAxis);
|
|
|
|
if (part == Part.START || part == Part.MIDDLE)
|
|
builder.withDirectional(AllConnections.Directional.ENCASED_BELT, AllConnections.pos(connectionAxis), mod);
|
|
if (part == Part.MIDDLE || part == Part.END)
|
|
builder.withDirectional(AllConnections.Directional.ENCASED_BELT, AllConnections.neg(connectionAxis), mod);
|
|
|
|
return builder;
|
|
}
|
|
|
|
@Override
|
|
public ConnectionsBuilder buildInitialConnections(ConnectionsBuilder builder, BlockState state) {
|
|
return encasedBeltConnections(state, 1);
|
|
}
|
|
|
|
protected static Axis getConnectionAxis(BlockState state) {
|
|
Axis axis = state.getValue(AXIS);
|
|
boolean alongFirst = state.getValue(CONNECTED_ALONG_FIRST_COORDINATE);
|
|
return alongFirst ? (axis == Axis.X ? Axis.Y : Axis.X) : (axis == Axis.Z ? Axis.Y : Axis.Z);
|
|
}
|
|
|
|
public enum Part implements StringRepresentable {
|
|
START, MIDDLE, END, NONE;
|
|
|
|
@Override
|
|
public String getSerializedName() {
|
|
return Lang.asId(name());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Class<KineticTileEntity> getTileEntityClass() {
|
|
return KineticTileEntity.class;
|
|
}
|
|
|
|
@Override
|
|
public BlockEntityType<? extends KineticTileEntity> getTileEntityType() {
|
|
return AllTileEntities.ENCASED_SHAFT.get();
|
|
}
|
|
|
|
}
|