Transforming the bugs away
- Fix arm interaction point client-side deserialization and initialization issues - Fix sequenced gearshift structure rotation - Fix encased cogwheel rotation, mirroring, and structure transformation - Add ITransformableBlock to allow custom handling of StructureTransforms - Remove DirectionHelper - Add jarJarRelease Gradle task for building a jarJar without a classifier
This commit is contained in:
parent
82be76d893
commit
d9c6418fbf
15 changed files with 368 additions and 259 deletions
|
@ -209,6 +209,15 @@ jar {
|
|||
}
|
||||
}
|
||||
|
||||
task jarJarRelease {
|
||||
doLast {
|
||||
tasks.jarJar {
|
||||
classifier = ''
|
||||
}
|
||||
}
|
||||
finalizedBy tasks.jarJar
|
||||
}
|
||||
|
||||
java {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.api.behaviour;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
|
@ -14,7 +15,7 @@ import net.minecraftforge.fluids.FluidStack;
|
|||
|
||||
public abstract class BlockSpoutingBehaviour {
|
||||
|
||||
private static final HashMap<ResourceLocation, BlockSpoutingBehaviour> BLOCK_SPOUTING_BEHAVIOURS = new HashMap<>();
|
||||
private static final Map<ResourceLocation, BlockSpoutingBehaviour> BLOCK_SPOUTING_BEHAVIOURS = new HashMap<>();
|
||||
|
||||
public static void addCustomSpoutInteraction(ResourceLocation resourceLocation,
|
||||
BlockSpoutingBehaviour movementBehaviour) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.base;
|
||||
|
||||
import com.simibubi.create.foundation.utility.DirectionHelper;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlock;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -15,7 +16,7 @@ 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.BooleanProperty;
|
||||
|
||||
public abstract class DirectionalAxisKineticBlock extends DirectionalKineticBlock {
|
||||
public abstract class DirectionalAxisKineticBlock extends DirectionalKineticBlock implements ITransformableBlock {
|
||||
|
||||
public static final BooleanProperty AXIS_ALONG_FIRST_COORDINATE = BooleanProperty.create("axis_along_first");
|
||||
|
||||
|
@ -53,7 +54,7 @@ public abstract class DirectionalAxisKineticBlock extends DirectionalKineticBloc
|
|||
|
||||
if (faceAxis.isHorizontal()) {
|
||||
alongFirst = faceAxis == Axis.Z;
|
||||
Direction positivePerpendicular = DirectionHelper.getPositivePerpendicular(faceAxis);
|
||||
Direction positivePerpendicular = faceAxis == Axis.X ? Direction.SOUTH : Direction.EAST;
|
||||
|
||||
boolean shaftAbove = prefersConnectionTo(world, pos, Direction.UP, true);
|
||||
boolean shaftBelow = prefersConnectionTo(world, pos, Direction.DOWN, true);
|
||||
|
@ -121,6 +122,23 @@ public abstract class DirectionalAxisKineticBlock extends DirectionalKineticBloc
|
|||
return super.rotate(state, rot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState transform(BlockState state, StructureTransform transform) {
|
||||
if (transform.mirror != null) {
|
||||
state = mirror(state, transform.mirror);
|
||||
}
|
||||
|
||||
if (transform.rotationAxis == Direction.Axis.Y) {
|
||||
return rotate(state, transform.rotation);
|
||||
}
|
||||
|
||||
Direction newFacing = transform.rotateFacing(state.getValue(FACING));
|
||||
if (transform.rotationAxis == newFacing.getAxis() && transform.rotation.ordinal() % 2 == 1) {
|
||||
state = state.cycle(AXIS_ALONG_FIRST_COORDINATE);
|
||||
}
|
||||
return state.setValue(FACING, newFacing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) {
|
||||
return face.getAxis() == getRotationAxis(state);
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public interface ITransformableBlock {
|
||||
BlockState transform(BlockState state, StructureTransform transform);
|
||||
}
|
|
@ -4,13 +4,6 @@ import static net.minecraft.world.level.block.state.properties.BlockStatePropert
|
|||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.FACING;
|
||||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltSlope;
|
||||
import com.simibubi.create.foundation.utility.DirectionHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -30,7 +23,6 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
import net.minecraft.world.level.block.state.properties.AttachFace;
|
||||
import net.minecraft.world.level.block.state.properties.BellAttachType;
|
||||
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.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.block.state.properties.Half;
|
||||
|
@ -55,7 +47,7 @@ public class StructureTransform {
|
|||
}
|
||||
|
||||
public StructureTransform(BlockPos offset, Axis axis, Rotation rotation, Mirror mirror) {
|
||||
this(offset, rotation == Rotation.NONE ? 0 : (4 - rotation.ordinal())*90, axis, rotation, mirror);
|
||||
this(offset, rotation == Rotation.NONE ? 0 : (4 - rotation.ordinal()) * 90, axis, rotation, mirror);
|
||||
}
|
||||
|
||||
public StructureTransform(BlockPos offset, float xRotation, float yRotation, float zRotation) {
|
||||
|
@ -96,7 +88,7 @@ public class StructureTransform {
|
|||
vec = VecHelper.rotate(vec, angle, rotationAxis);
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
public Vec3 applyWithoutOffset(Vec3 localVec) {
|
||||
Vec3 vec = localVec;
|
||||
if (mirror != null)
|
||||
|
@ -124,16 +116,18 @@ public class StructureTransform {
|
|||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Vanilla does not support block state rotation around axes other than Y. Add
|
||||
* specific cases here for vanilla block states so that they can react to rotations
|
||||
* around horizontal axes. For Create blocks, implement ITransformableBlock.
|
||||
*/
|
||||
public BlockState apply(BlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (block instanceof ITransformableBlock transformable)
|
||||
return transformable.transform(state, this);
|
||||
|
||||
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)
|
||||
|
@ -141,12 +135,10 @@ public class StructureTransform {
|
|||
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;
|
||||
|
@ -185,30 +177,11 @@ public class StructureTransform {
|
|||
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);
|
||||
|
||||
state = state.setValue(FACING, rotateFacing(state.getValue(FACING)));
|
||||
} else if (state.hasProperty(AXIS)) {
|
||||
state = state.setValue(AXIS, transformAxis(state.getValue(AXIS)));
|
||||
|
||||
state = state.setValue(AXIS, rotateAxis(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)
|
||||
|
@ -216,6 +189,7 @@ public class StructureTransform {
|
|||
}
|
||||
|
||||
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);
|
||||
|
@ -244,125 +218,21 @@ public class StructureTransform {
|
|||
return state;
|
||||
}
|
||||
|
||||
protected BlockState transformBelt(BlockState state, boolean halfTurn) {
|
||||
Direction initialDirection = state.getValue(BeltBlock.HORIZONTAL_FACING);
|
||||
boolean diagonal =
|
||||
state.getValue(BeltBlock.SLOPE) == BeltSlope.DOWNWARD || state.getValue(BeltBlock.SLOPE) == BeltSlope.UPWARD;
|
||||
|
||||
if (!diagonal) {
|
||||
for (int i = 0; i < rotation.ordinal(); i++) {
|
||||
Direction direction = state.getValue(BeltBlock.HORIZONTAL_FACING);
|
||||
BeltSlope slope = state.getValue(BeltBlock.SLOPE);
|
||||
boolean vertical = slope == BeltSlope.VERTICAL;
|
||||
boolean horizontal = slope == BeltSlope.HORIZONTAL;
|
||||
boolean sideways = slope == BeltSlope.SIDEWAYS;
|
||||
|
||||
Direction newDirection = direction.getOpposite();
|
||||
BeltSlope newSlope = BeltSlope.VERTICAL;
|
||||
|
||||
if (vertical) {
|
||||
if (direction.getAxis() == rotationAxis) {
|
||||
newDirection = direction.getCounterClockWise();
|
||||
newSlope = BeltSlope.SIDEWAYS;
|
||||
} else {
|
||||
newSlope = BeltSlope.HORIZONTAL;
|
||||
newDirection = direction;
|
||||
if (direction.getAxis() == Axis.Z)
|
||||
newDirection = direction.getOpposite();
|
||||
}
|
||||
}
|
||||
|
||||
if (sideways) {
|
||||
newDirection = direction;
|
||||
if (direction.getAxis() == rotationAxis)
|
||||
newSlope = BeltSlope.HORIZONTAL;
|
||||
else
|
||||
newDirection = direction.getCounterClockWise();
|
||||
}
|
||||
|
||||
if (horizontal) {
|
||||
newDirection = direction;
|
||||
if (direction.getAxis() == rotationAxis)
|
||||
newSlope = BeltSlope.SIDEWAYS;
|
||||
else if (direction.getAxis() != Axis.Z)
|
||||
newDirection = direction.getOpposite();
|
||||
}
|
||||
|
||||
state = state.setValue(BeltBlock.HORIZONTAL_FACING, newDirection);
|
||||
state = state.setValue(BeltBlock.SLOPE, newSlope);
|
||||
}
|
||||
|
||||
} else if (initialDirection.getAxis() != rotationAxis) {
|
||||
for (int i = 0; i < rotation.ordinal(); i++) {
|
||||
Direction direction = state.getValue(BeltBlock.HORIZONTAL_FACING);
|
||||
Direction newDirection = direction.getOpposite();
|
||||
BeltSlope slope = state.getValue(BeltBlock.SLOPE);
|
||||
boolean upward = slope == BeltSlope.UPWARD;
|
||||
boolean downward = slope == BeltSlope.DOWNWARD;
|
||||
|
||||
// Rotate diagonal
|
||||
if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ downward ^ direction.getAxis() == Axis.Z) {
|
||||
state = state.setValue(BeltBlock.SLOPE, upward ? BeltSlope.DOWNWARD : BeltSlope.UPWARD);
|
||||
} else {
|
||||
state = state.setValue(BeltBlock.HORIZONTAL_FACING, newDirection);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (halfTurn) {
|
||||
Direction direction = state.getValue(BeltBlock.HORIZONTAL_FACING);
|
||||
Direction newDirection = direction.getOpposite();
|
||||
BeltSlope slope = state.getValue(BeltBlock.SLOPE);
|
||||
boolean vertical = slope == BeltSlope.VERTICAL;
|
||||
|
||||
if (diagonal) {
|
||||
state = state.setValue(BeltBlock.SLOPE, slope == BeltSlope.UPWARD ? BeltSlope.DOWNWARD
|
||||
: slope == BeltSlope.DOWNWARD ? BeltSlope.UPWARD : slope);
|
||||
} else if (vertical) {
|
||||
state = state.setValue(BeltBlock.HORIZONTAL_FACING, newDirection);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public Axis transformAxis(Axis axisIn) {
|
||||
Direction facing = Direction.get(AxisDirection.POSITIVE, axisIn);
|
||||
facing = transformFacing(facing);
|
||||
Axis axis = facing.getAxis();
|
||||
return axis;
|
||||
}
|
||||
|
||||
public Direction transformFacing(Direction facing) {
|
||||
public Direction mirrorFacing(Direction facing) {
|
||||
if (mirror != null)
|
||||
facing = mirror.mirror(facing);
|
||||
for (int i = 0; i < rotation.ordinal(); i++)
|
||||
facing = DirectionHelper.rotateAround(facing, rotationAxis);
|
||||
return mirror.mirror(facing);
|
||||
return facing;
|
||||
}
|
||||
|
||||
private BlockState rotateChassis(BlockState state) {
|
||||
if (rotation == Rotation.NONE)
|
||||
return state;
|
||||
public Axis rotateAxis(Axis axis) {
|
||||
Direction facing = Direction.get(AxisDirection.POSITIVE, axis);
|
||||
return rotateFacing(facing).getAxis();
|
||||
}
|
||||
|
||||
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;
|
||||
public Direction rotateFacing(Direction facing) {
|
||||
for (int i = 0; i < rotation.ordinal(); i++)
|
||||
facing = facing.getClockWise(rotationAxis);
|
||||
return facing;
|
||||
}
|
||||
|
||||
public static StructureTransform fromBuffer(FriendlyByteBuf buffer) {
|
||||
|
|
|
@ -3,6 +3,8 @@ package com.simibubi.create.content.contraptions.components.structureMovement.ch
|
|||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlock;
|
||||
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
@ -26,7 +28,7 @@ import net.minecraft.world.phys.BlockHitResult;
|
|||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.common.Tags;
|
||||
|
||||
public abstract class AbstractChassisBlock extends RotatedPillarBlock implements IWrenchable, ITE<ChassisTileEntity> {
|
||||
public abstract class AbstractChassisBlock extends RotatedPillarBlock implements IWrenchable, ITE<ChassisTileEntity>, ITransformableBlock {
|
||||
|
||||
public AbstractChassisBlock(Properties properties) {
|
||||
super(properties);
|
||||
|
@ -132,6 +134,44 @@ public abstract class AbstractChassisBlock extends RotatedPillarBlock implements
|
|||
return mirrored;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState transform(BlockState state, StructureTransform transform) {
|
||||
if (transform.mirror != null) {
|
||||
state = mirror(state, transform.mirror);
|
||||
}
|
||||
|
||||
if (transform.rotationAxis == Direction.Axis.Y) {
|
||||
return rotate(state, transform.rotation);
|
||||
}
|
||||
return transformInner(state, transform);
|
||||
}
|
||||
|
||||
protected BlockState transformInner(BlockState state, StructureTransform transform) {
|
||||
if (transform.rotation == Rotation.NONE)
|
||||
return state;
|
||||
|
||||
BlockState rotated = state.setValue(AXIS, transform.rotateAxis(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 = transform.rotateFacing(face);
|
||||
BooleanProperty rotatedGlueableSide = block.getGlueableSide(rotated, rotatedFacing);
|
||||
if (rotatedGlueableSide != null)
|
||||
rotated = rotated.setValue(rotatedGlueableSide, true);
|
||||
}
|
||||
|
||||
return rotated;
|
||||
}
|
||||
|
||||
public abstract BooleanProperty getGlueableSide(BlockState state, Direction face);
|
||||
|
||||
protected boolean glueAllowedOnSide(BlockGetter world, BlockPos pos, BlockState state, Direction side) {
|
||||
|
|
|
@ -7,6 +7,8 @@ import com.simibubi.create.AllTileEntities;
|
|||
import com.simibubi.create.content.contraptions.base.HorizontalAxisKineticBlock;
|
||||
import com.simibubi.create.content.contraptions.base.KineticBlock;
|
||||
import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlock;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
|
||||
|
@ -35,7 +37,7 @@ import net.minecraftforge.api.distmarker.Dist;
|
|||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implements ITE<SequencedGearshiftTileEntity> {
|
||||
public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implements ITE<SequencedGearshiftTileEntity>, ITransformableBlock {
|
||||
|
||||
public static final BooleanProperty VERTICAL = BooleanProperty.create("vertical");
|
||||
public static final IntegerProperty STATE = IntegerProperty.create("state", 0, 5);
|
||||
|
@ -166,4 +168,24 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implemen
|
|||
.intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState transform(BlockState state, StructureTransform transform) {
|
||||
if (transform.mirror != null) {
|
||||
state = mirror(state, transform.mirror);
|
||||
}
|
||||
|
||||
if (transform.rotationAxis == Direction.Axis.Y) {
|
||||
return rotate(state, transform.rotation);
|
||||
}
|
||||
|
||||
if (transform.rotation.ordinal() % 2 == 1) {
|
||||
if (transform.rotationAxis != state.getValue(HORIZONTAL_AXIS)) {
|
||||
return state.cycle(VERTICAL);
|
||||
} else if (state.getValue(VERTICAL)) {
|
||||
return state.cycle(VERTICAL).cycle(HORIZONTAL_AXIS);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import com.simibubi.create.AllTileEntities;
|
|||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlock;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||
import com.simibubi.create.content.contraptions.processing.EmptyingByBasin;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltSlicer.Feedback;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity.CasingType;
|
||||
|
@ -82,7 +84,7 @@ import net.minecraftforge.common.Tags;
|
|||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEntity>, ISpecialBlockItemRequirement {
|
||||
public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEntity>, ISpecialBlockItemRequirement, ITransformableBlock {
|
||||
|
||||
public static final Property<BeltSlope> SLOPE = EnumProperty.create("slope", BeltSlope.class);
|
||||
public static final Property<BeltPart> PART = EnumProperty.create("part", BeltPart.class);
|
||||
|
@ -594,6 +596,100 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
|||
return rotate;
|
||||
}
|
||||
|
||||
public BlockState transform(BlockState state, StructureTransform transform) {
|
||||
if (transform.mirror != null) {
|
||||
state = mirror(state, transform.mirror);
|
||||
}
|
||||
|
||||
if (transform.rotationAxis == Direction.Axis.Y) {
|
||||
return rotate(state, transform.rotation);
|
||||
}
|
||||
return transformInner(state, transform);
|
||||
}
|
||||
|
||||
protected BlockState transformInner(BlockState state, StructureTransform transform) {
|
||||
boolean halfTurn = transform.rotation == Rotation.CLOCKWISE_180;
|
||||
|
||||
Direction initialDirection = state.getValue(HORIZONTAL_FACING);
|
||||
boolean diagonal =
|
||||
state.getValue(SLOPE) == BeltSlope.DOWNWARD || state.getValue(SLOPE) == BeltSlope.UPWARD;
|
||||
|
||||
if (!diagonal) {
|
||||
for (int i = 0; i < transform.rotation.ordinal(); i++) {
|
||||
Direction direction = state.getValue(HORIZONTAL_FACING);
|
||||
BeltSlope slope = state.getValue(SLOPE);
|
||||
boolean vertical = slope == BeltSlope.VERTICAL;
|
||||
boolean horizontal = slope == BeltSlope.HORIZONTAL;
|
||||
boolean sideways = slope == BeltSlope.SIDEWAYS;
|
||||
|
||||
Direction newDirection = direction.getOpposite();
|
||||
BeltSlope newSlope = BeltSlope.VERTICAL;
|
||||
|
||||
if (vertical) {
|
||||
if (direction.getAxis() == transform.rotationAxis) {
|
||||
newDirection = direction.getCounterClockWise();
|
||||
newSlope = BeltSlope.SIDEWAYS;
|
||||
} else {
|
||||
newSlope = BeltSlope.HORIZONTAL;
|
||||
newDirection = direction;
|
||||
if (direction.getAxis() == Axis.Z)
|
||||
newDirection = direction.getOpposite();
|
||||
}
|
||||
}
|
||||
|
||||
if (sideways) {
|
||||
newDirection = direction;
|
||||
if (direction.getAxis() == transform.rotationAxis)
|
||||
newSlope = BeltSlope.HORIZONTAL;
|
||||
else
|
||||
newDirection = direction.getCounterClockWise();
|
||||
}
|
||||
|
||||
if (horizontal) {
|
||||
newDirection = direction;
|
||||
if (direction.getAxis() == transform.rotationAxis)
|
||||
newSlope = BeltSlope.SIDEWAYS;
|
||||
else if (direction.getAxis() != Axis.Z)
|
||||
newDirection = direction.getOpposite();
|
||||
}
|
||||
|
||||
state = state.setValue(HORIZONTAL_FACING, newDirection);
|
||||
state = state.setValue(SLOPE, newSlope);
|
||||
}
|
||||
|
||||
} else if (initialDirection.getAxis() != transform.rotationAxis) {
|
||||
for (int i = 0; i < transform.rotation.ordinal(); i++) {
|
||||
Direction direction = state.getValue(HORIZONTAL_FACING);
|
||||
Direction newDirection = direction.getOpposite();
|
||||
BeltSlope slope = state.getValue(SLOPE);
|
||||
boolean upward = slope == BeltSlope.UPWARD;
|
||||
boolean downward = slope == BeltSlope.DOWNWARD;
|
||||
|
||||
// Rotate diagonal
|
||||
if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ downward ^ direction.getAxis() == Axis.Z) {
|
||||
state = state.setValue(SLOPE, upward ? BeltSlope.DOWNWARD : BeltSlope.UPWARD);
|
||||
} else {
|
||||
state = state.setValue(HORIZONTAL_FACING, newDirection);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (halfTurn) {
|
||||
Direction direction = state.getValue(HORIZONTAL_FACING);
|
||||
Direction newDirection = direction.getOpposite();
|
||||
BeltSlope slope = state.getValue(SLOPE);
|
||||
boolean vertical = slope == BeltSlope.VERTICAL;
|
||||
|
||||
if (diagonal) {
|
||||
state = state.setValue(SLOPE, slope == BeltSlope.UPWARD ? BeltSlope.DOWNWARD
|
||||
: slope == BeltSlope.DOWNWARD ? BeltSlope.UPWARD : slope);
|
||||
} else if (vertical) {
|
||||
state = state.setValue(HORIZONTAL_FACING, newDirection);
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) {
|
||||
return false;
|
||||
|
|
|
@ -6,12 +6,15 @@ import com.simibubi.create.content.contraptions.base.CasingBlock;
|
|||
import com.simibubi.create.content.contraptions.base.IRotate;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlock;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||
import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock;
|
||||
import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel;
|
||||
import com.simibubi.create.content.contraptions.relays.elementary.SimpleKineticTileEntity;
|
||||
import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement;
|
||||
import com.simibubi.create.content.schematics.ItemRequirement;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.utility.VoxelShaper;
|
||||
import com.tterrag.registrate.util.entry.BlockEntry;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -29,6 +32,8 @@ import net.minecraft.world.level.BlockGetter;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -38,7 +43,7 @@ import net.minecraft.world.phys.BlockHitResult;
|
|||
import net.minecraft.world.phys.HitResult;
|
||||
|
||||
public class EncasedCogwheelBlock extends RotatedPillarKineticBlock
|
||||
implements ICogWheel, ITE<SimpleKineticTileEntity>, ISpecialBlockItemRequirement {
|
||||
implements ICogWheel, ITE<SimpleKineticTileEntity>, ISpecialBlockItemRequirement, ITransformableBlock {
|
||||
|
||||
public static final BooleanProperty TOP_SHAFT = BooleanProperty.create("top_shaft");
|
||||
public static final BooleanProperty BOTTOM_SHAFT = BooleanProperty.create("bottom_shaft");
|
||||
|
@ -120,6 +125,16 @@ public class EncasedCogwheelBlock extends RotatedPillarKineticBlock
|
|||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getRotatedBlockState(BlockState originalState, Direction targetedFace) {
|
||||
originalState = swapShaftsForRotation(originalState, Rotation.CLOCKWISE_90, targetedFace.getAxis());
|
||||
return originalState.setValue(RotatedPillarKineticBlock.AXIS,
|
||||
VoxelShaper
|
||||
.axisAsFace(originalState.getValue(RotatedPillarKineticBlock.AXIS))
|
||||
.getClockWise(targetedFace.getAxis())
|
||||
.getAxis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult onSneakWrenched(BlockState state, UseOnContext context) {
|
||||
if (context.getLevel().isClientSide)
|
||||
|
@ -170,6 +185,81 @@ public class EncasedCogwheelBlock extends RotatedPillarKineticBlock
|
|||
return state.getValue(AXIS);
|
||||
}
|
||||
|
||||
public BlockState swapShafts(BlockState state) {
|
||||
boolean bottom = state.getValue(BOTTOM_SHAFT);
|
||||
boolean top = state.getValue(TOP_SHAFT);
|
||||
state = state.setValue(BOTTOM_SHAFT, top);
|
||||
state = state.setValue(TOP_SHAFT, bottom);
|
||||
return state;
|
||||
}
|
||||
|
||||
public BlockState swapShaftsForRotation(BlockState state, Rotation rotation, Direction.Axis rotationAxis) {
|
||||
if (rotation == Rotation.NONE) {
|
||||
return state;
|
||||
}
|
||||
|
||||
Direction.Axis axis = state.getValue(AXIS);
|
||||
if (axis == rotationAxis) {
|
||||
return state;
|
||||
}
|
||||
|
||||
if (rotation == Rotation.CLOCKWISE_180) {
|
||||
return swapShafts(state);
|
||||
}
|
||||
|
||||
boolean clockwise = rotation == Rotation.CLOCKWISE_90;
|
||||
|
||||
if (rotationAxis == Direction.Axis.X) {
|
||||
if ( axis == Direction.Axis.Z && !clockwise
|
||||
|| axis == Direction.Axis.Y && clockwise) {
|
||||
return swapShafts(state);
|
||||
}
|
||||
} else if (rotationAxis == Direction.Axis.Y) {
|
||||
if ( axis == Direction.Axis.X && !clockwise
|
||||
|| axis == Direction.Axis.Z && clockwise) {
|
||||
return swapShafts(state);
|
||||
}
|
||||
} else if (rotationAxis == Direction.Axis.Z) {
|
||||
if ( axis == Direction.Axis.Y && !clockwise
|
||||
|| axis == Direction.Axis.X && clockwise) {
|
||||
return swapShafts(state);
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState mirror(BlockState state, Mirror mirror) {
|
||||
Direction.Axis axis = state.getValue(AXIS);
|
||||
if (axis == Direction.Axis.X && mirror == Mirror.FRONT_BACK
|
||||
|| axis == Direction.Axis.Z && mirror == Mirror.LEFT_RIGHT) {
|
||||
return swapShafts(state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState state, Rotation rotation) {
|
||||
state = swapShaftsForRotation(state, rotation, Direction.Axis.Y);
|
||||
return super.rotate(state, rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState transform(BlockState state, StructureTransform transform) {
|
||||
if (transform.mirror != null) {
|
||||
state = mirror(state, transform.mirror);
|
||||
}
|
||||
|
||||
if (transform.rotationAxis == Direction.Axis.Y) {
|
||||
return rotate(state, transform.rotation);
|
||||
}
|
||||
|
||||
state = swapShaftsForRotation(state, transform.rotation, transform.rotationAxis);
|
||||
state = state.setValue(AXIS, transform.rotateAxis(state.getValue(AXIS)));
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemRequirement getRequiredItems(BlockState state, BlockEntity te) {
|
||||
return ItemRequirement
|
||||
|
|
|
@ -9,7 +9,6 @@ import com.simibubi.create.content.contraptions.base.HorizontalAxisKineticBlock;
|
|||
import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock;
|
||||
import com.simibubi.create.foundation.utility.DirectionHelper;
|
||||
import com.simibubi.create.foundation.utility.VoxelShaper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -81,20 +80,20 @@ public interface IWrenchable {
|
|||
|
||||
if (targetedFace.getAxis() == Direction.Axis.Y) {
|
||||
if (originalState.hasProperty(HorizontalAxisKineticBlock.HORIZONTAL_AXIS))
|
||||
return originalState.setValue(HorizontalAxisKineticBlock.HORIZONTAL_AXIS, DirectionHelper
|
||||
.rotateAround(VoxelShaper.axisAsFace(originalState.getValue(HorizontalAxisKineticBlock.HORIZONTAL_AXIS)),
|
||||
targetedFace.getAxis())
|
||||
return originalState.setValue(HorizontalAxisKineticBlock.HORIZONTAL_AXIS, VoxelShaper
|
||||
.axisAsFace(originalState.getValue(HorizontalAxisKineticBlock.HORIZONTAL_AXIS))
|
||||
.getClockWise(targetedFace.getAxis())
|
||||
.getAxis());
|
||||
if (originalState.hasProperty(HorizontalKineticBlock.HORIZONTAL_FACING))
|
||||
return originalState.setValue(HorizontalKineticBlock.HORIZONTAL_FACING, DirectionHelper
|
||||
.rotateAround(originalState.getValue(HorizontalKineticBlock.HORIZONTAL_FACING), targetedFace.getAxis()));
|
||||
return originalState.setValue(HorizontalKineticBlock.HORIZONTAL_FACING, originalState
|
||||
.getValue(HorizontalKineticBlock.HORIZONTAL_FACING).getClockWise(targetedFace.getAxis()));
|
||||
}
|
||||
|
||||
if (originalState.hasProperty(RotatedPillarKineticBlock.AXIS))
|
||||
return originalState.setValue(RotatedPillarKineticBlock.AXIS,
|
||||
DirectionHelper
|
||||
.rotateAround(VoxelShaper.axisAsFace(originalState.getValue(RotatedPillarKineticBlock.AXIS)),
|
||||
targetedFace.getAxis())
|
||||
VoxelShaper
|
||||
.axisAsFace(originalState.getValue(RotatedPillarKineticBlock.AXIS))
|
||||
.getClockWise(targetedFace.getAxis())
|
||||
.getAxis());
|
||||
|
||||
if (!originalState.hasProperty(DirectionalKineticBlock.FACING))
|
||||
|
@ -111,7 +110,7 @@ public interface IWrenchable {
|
|||
} else {
|
||||
do {
|
||||
newState = newState.setValue(DirectionalKineticBlock.FACING,
|
||||
DirectionHelper.rotateAround(newState.getValue(DirectionalKineticBlock.FACING), targetedFace.getAxis()));
|
||||
newState.getValue(DirectionalKineticBlock.FACING).getClockWise(targetedFace.getAxis()));
|
||||
if (targetedFace.getAxis() == Direction.Axis.Y
|
||||
&& newState.hasProperty(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE))
|
||||
newState = newState.cycle(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE);
|
||||
|
|
|
@ -151,7 +151,10 @@ public class ArmInteractionPoint {
|
|||
if (type == null)
|
||||
return null;
|
||||
BlockPos pos = NbtUtils.readBlockPos(nbt.getCompound("Pos")).offset(anchor);
|
||||
ArmInteractionPoint point = type.createPoint(level, pos, level.getBlockState(pos));
|
||||
BlockState state = level.getBlockState(pos);
|
||||
if (!type.canCreatePoint(level, pos, state))
|
||||
return null;
|
||||
ArmInteractionPoint point = type.createPoint(level, pos, state);
|
||||
if (point == null)
|
||||
return null;
|
||||
point.deserialize(nbt, anchor);
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
|||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
@ -39,6 +40,7 @@ import net.minecraft.world.level.Level;
|
|||
import net.minecraft.world.level.block.JukeboxBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkSource;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
|
@ -410,10 +412,45 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
notifyUpdate();
|
||||
}
|
||||
|
||||
// ClientLevel#hasChunk (and consequently #isAreaLoaded) always returns true,
|
||||
// so manually check the ChunkSource to avoid weird behavior on the client side
|
||||
protected boolean isAreaActuallyLoaded(BlockPos center, int range) {
|
||||
if (!level.isAreaLoaded(center, range)) {
|
||||
return false;
|
||||
}
|
||||
if (level.isClientSide) {
|
||||
int minY = center.getY() - range;
|
||||
int maxY = center.getY() + range;
|
||||
if (maxY < level.getMinBuildHeight() || minY >= level.getMaxBuildHeight()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int minX = center.getX() - range;
|
||||
int minZ = center.getZ() - range;
|
||||
int maxX = center.getX() + range;
|
||||
int maxZ = center.getZ() + range;
|
||||
|
||||
int minChunkX = SectionPos.blockToSectionCoord(minX);
|
||||
int maxChunkX = SectionPos.blockToSectionCoord(maxX);
|
||||
int minChunkZ = SectionPos.blockToSectionCoord(minZ);
|
||||
int maxChunkZ = SectionPos.blockToSectionCoord(maxZ);
|
||||
|
||||
ChunkSource chunkSource = level.getChunkSource();
|
||||
for (int chunkX = minChunkX; chunkX <= maxChunkX; ++chunkX) {
|
||||
for (int chunkZ = minChunkZ; chunkZ <= maxChunkZ; ++chunkZ) {
|
||||
if (!chunkSource.hasChunk(chunkX, chunkZ)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void initInteractionPoints() {
|
||||
if (!updateInteractionPoints || interactionPointTag == null)
|
||||
return;
|
||||
if (!level.isAreaLoaded(worldPosition, getRange() + 1))
|
||||
if (!isAreaActuallyLoaded(worldPosition, getRange() + 1))
|
||||
return;
|
||||
inputs.clear();
|
||||
outputs.clear();
|
||||
|
@ -506,7 +543,7 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
previousTarget = previousPoint == null ? ArmAngleTarget.NO_TARGET
|
||||
: previousPoint.getTargetAngles(worldPosition, ceiling);
|
||||
if (previousPoint != null)
|
||||
previousBaseAngle = previousPoint.getTargetAngles(worldPosition, ceiling).baseAngle;
|
||||
previousBaseAngle = previousTarget.baseAngle;
|
||||
|
||||
ArmInteractionPoint targetedPoint = getTargetedInteractionPoint();
|
||||
if (targetedPoint != null)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.simibubi.create.foundation.block;
|
||||
|
||||
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
||||
import com.simibubi.create.foundation.utility.DirectionHelper;
|
||||
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
|
@ -31,7 +30,7 @@ public class WrenchableDirectionalBlock extends DirectionalBlock implements IWre
|
|||
if (facing.getAxis() == targetedFace.getAxis())
|
||||
return originalState;
|
||||
|
||||
Direction newFacing = DirectionHelper.rotateAround(facing, targetedFace.getAxis());
|
||||
Direction newFacing = facing.getClockWise(targetedFace.getAxis());
|
||||
|
||||
return originalState.setValue(FACING, newFacing);
|
||||
}
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import static net.minecraft.core.Direction.DOWN;
|
||||
import static net.minecraft.core.Direction.EAST;
|
||||
import static net.minecraft.core.Direction.NORTH;
|
||||
import static net.minecraft.core.Direction.SOUTH;
|
||||
import static net.minecraft.core.Direction.UP;
|
||||
import static net.minecraft.core.Direction.WEST;
|
||||
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
|
||||
/**
|
||||
* A bunch of methods that got stripped out of Direction in 1.15
|
||||
*
|
||||
* @author Mojang
|
||||
*/
|
||||
public class DirectionHelper {
|
||||
|
||||
public static Direction rotateAround(Direction dir, Direction.Axis axis) {
|
||||
switch (axis) {
|
||||
case X:
|
||||
if (dir != WEST && dir != EAST) {
|
||||
return rotateX(dir);
|
||||
}
|
||||
|
||||
return dir;
|
||||
case Y:
|
||||
if (dir != UP && dir != DOWN) {
|
||||
return dir.getClockWise();
|
||||
}
|
||||
|
||||
return dir;
|
||||
case Z:
|
||||
if (dir != NORTH && dir != SOUTH) {
|
||||
return rotateZ(dir);
|
||||
}
|
||||
|
||||
return dir;
|
||||
default:
|
||||
throw new IllegalStateException("Unable to get CW facing for axis " + axis);
|
||||
}
|
||||
}
|
||||
|
||||
public static Direction rotateX(Direction dir) {
|
||||
switch (dir) {
|
||||
case NORTH:
|
||||
return DOWN;
|
||||
case EAST:
|
||||
case WEST:
|
||||
default:
|
||||
throw new IllegalStateException("Unable to get X-rotated facing of " + dir);
|
||||
case SOUTH:
|
||||
return UP;
|
||||
case UP:
|
||||
return NORTH;
|
||||
case DOWN:
|
||||
return SOUTH;
|
||||
}
|
||||
}
|
||||
|
||||
public static Direction rotateZ(Direction dir) {
|
||||
switch (dir) {
|
||||
case EAST:
|
||||
return DOWN;
|
||||
case SOUTH:
|
||||
default:
|
||||
throw new IllegalStateException("Unable to get Z-rotated facing of " + dir);
|
||||
case WEST:
|
||||
return UP;
|
||||
case UP:
|
||||
return EAST;
|
||||
case DOWN:
|
||||
return WEST;
|
||||
}
|
||||
}
|
||||
|
||||
public static Direction getPositivePerpendicular(Axis horizontalAxis) {
|
||||
return horizontalAxis == Axis.X ? SOUTH : EAST;
|
||||
}
|
||||
|
||||
}
|
|
@ -28,7 +28,7 @@ public enum Pointing implements StringRepresentable {
|
|||
Direction top = axis == Axis.Y ? Direction.SOUTH : Direction.UP;
|
||||
int rotations = direction.getAxisDirection() == AxisDirection.NEGATIVE ? 4 - ordinal() : ordinal();
|
||||
for (int i = 0; i < rotations; i++)
|
||||
top = DirectionHelper.rotateAround(top, axis);
|
||||
top = top.getClockWise(axis);
|
||||
return top;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue