diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 240096801..0454b058c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -1057,6 +1057,8 @@ public abstract class Contraption { mountedStorage.addStorageToWorld(tileEntity); } } + + transform.apply(tileEntity); } } for (BlockInfo block : blocks.values()) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ITransformableTE.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ITransformableTE.java new file mode 100644 index 000000000..64d77b497 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ITransformableTE.java @@ -0,0 +1,7 @@ +package com.simibubi.create.content.contraptions.components.structureMovement; + +public interface ITransformableTE { + + void transform(StructureTransform transform); + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java index 1d47d2554..225cbc02f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java @@ -27,9 +27,11 @@ import net.minecraft.state.properties.BellAttachment; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.Half; import net.minecraft.state.properties.SlabType; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.Mirror; import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; @@ -41,27 +43,33 @@ public class StructureTransform { int angle; Axis rotationAxis; BlockPos offset; + Mirror mirror; - private StructureTransform(BlockPos offset, int angle, Axis axis, Rotation rotation) { + private StructureTransform(BlockPos offset, int angle, Axis axis, Rotation rotation, Mirror mirror) { this.offset = offset; this.angle = angle; rotationAxis = axis; this.rotation = rotation; + this.mirror = mirror; + } + + public StructureTransform(BlockPos offset, Axis axis, Rotation rotation, Mirror mirror) { + this(offset, rotation == Rotation.NONE ? 0 : (4 - rotation.ordinal())*90, axis, rotation, mirror); } public StructureTransform(BlockPos offset, float xRotation, float yRotation, float zRotation) { this.offset = offset; if (xRotation != 0) { rotationAxis = Axis.X; - angle = (int) (Math.round(xRotation / 90) * 90); + angle = Math.round(xRotation / 90) * 90; } if (yRotation != 0) { rotationAxis = Axis.Y; - angle = (int) (Math.round(yRotation / 90) * 90); + angle = Math.round(yRotation / 90) * 90; } if (zRotation != 0) { rotationAxis = Axis.Z; - angle = (int) (Math.round(zRotation / 90) * 90); + angle = Math.round(zRotation / 90) * 90; } angle %= 360; @@ -76,22 +84,33 @@ public class StructureTransform { if (angle == 180) this.rotation = Rotation.CLOCKWISE_180; + mirror = Mirror.NONE; } - public Vector3d apply(Vector3d localVec) { + public Vector3d applyWithoutOffset(Vector3d localVec) { Vector3d vec = localVec; + if (mirror != null) + vec = VecHelper.mirrorCentered(vec, mirror); if (rotationAxis != null) vec = VecHelper.rotateCentered(vec, angle, rotationAxis); - vec = vec.add(Vector3d.of(offset)); return vec; } + public Vector3d apply(Vector3d localVec) { + return applyWithoutOffset(localVec).add(Vector3d.of(offset)); + } + + public BlockPos applyWithoutOffset(BlockPos localPos) { + return new BlockPos(applyWithoutOffset(VecHelper.getCenterOf(localPos))); + } + public BlockPos apply(BlockPos localPos) { - Vector3d vec = VecHelper.getCenterOf(localPos); - if (rotationAxis != null) - vec = VecHelper.rotateCentered(vec, angle, rotationAxis); - localPos = new BlockPos(vec); - return localPos.add(offset); + return applyWithoutOffset(localPos).add(offset); + } + + public void apply(TileEntity te) { + if (te instanceof ITransformableTE) + ((ITransformableTE) te).transform(this); } /** @@ -100,6 +119,9 @@ public class StructureTransform { * horizontal axes */ public BlockState apply(BlockState state) { + if (mirror != null) + state = state.mirror(mirror); + Block block = state.getBlock(); if (rotationAxis == Axis.Y) { @@ -299,6 +321,8 @@ public class StructureTransform { } public Direction transformFacing(Direction facing) { + if (mirror != null) + facing = mirror.mirror(facing); for (int i = 0; i < rotation.ordinal(); i++) facing = DirectionHelper.rotateAround(facing, rotationAxis); return facing; @@ -335,8 +359,10 @@ public class StructureTransform { int readAngle = buffer.readInt(); int axisIndex = buffer.readVarInt(); int rotationIndex = buffer.readVarInt(); + int mirrorIndex = buffer.readVarInt(); return new StructureTransform(readBlockPos, readAngle, axisIndex == -1 ? null : Axis.values()[axisIndex], - rotationIndex == -1 ? null : Rotation.values()[rotationIndex]); + rotationIndex == -1 ? null : Rotation.values()[rotationIndex], + mirrorIndex == -1 ? null : Mirror.values()[mirrorIndex]); } public void writeToBuffer(PacketBuffer buffer) { @@ -344,6 +370,7 @@ public class StructureTransform { buffer.writeInt(angle); buffer.writeVarInt(rotationAxis == null ? -1 : rotationAxis.ordinal()); buffer.writeVarInt(rotation == null ? -1 : rotation.ordinal()); + buffer.writeVarInt(mirror == null ? - 1 : mirror.ordinal()); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java index b3394640b..f6b40d285 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java @@ -17,6 +17,7 @@ import com.simibubi.create.content.contraptions.components.crafter.MechanicalCra import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity; import com.simibubi.create.content.contraptions.components.deployer.DeployerBlock; import com.simibubi.create.content.contraptions.components.saw.SawBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.contraptions.relays.belt.BeltHelper; import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; @@ -218,6 +219,12 @@ public abstract class ArmInteractionPoint { return interactionPoint; } + protected static void transformPos(StructureTransform transform, CompoundNBT nbt) { + BlockPos pos = NBTUtil.readBlockPos(nbt.getCompound("Pos")); + pos = transform.applyWithoutOffset(pos); + nbt.put("Pos", NBTUtil.writeBlockPos(pos)); + } + public static abstract class TopFaceArmInteractionPoint extends ArmInteractionPoint { @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java index 9db6a126a..6a9fbde49 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java @@ -7,6 +7,8 @@ import javax.annotation.Nullable; import com.simibubi.create.Create; import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE; +import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Jukebox; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode; import com.simibubi.create.foundation.advancement.AllTriggers; @@ -41,7 +43,7 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.util.Constants.NBT; -public class ArmTileEntity extends KineticTileEntity { +public class ArmTileEntity extends KineticTileEntity implements ITransformableTE { // Server List inputs; @@ -384,6 +386,19 @@ public class ArmTileEntity extends KineticTileEntity { searchForItem(); } + @Override + public void transform(StructureTransform transform) { + if (interactionPointTag == null) + return; + + for (INBT inbt : interactionPointTag) { + ArmInteractionPoint.transformPos(transform, (CompoundNBT) inbt); + } + + sendData(); + markDirty(); + } + protected void initInteractionPoints() { if (!updateInteractionPoints || interactionPointTag == null) return; diff --git a/src/main/java/com/simibubi/create/content/schematics/SchematicPrinter.java b/src/main/java/com/simibubi/create/content/schematics/SchematicPrinter.java index 50c05fb04..cc4634615 100644 --- a/src/main/java/com/simibubi/create/content/schematics/SchematicPrinter.java +++ b/src/main/java/com/simibubi/create/content/schematics/SchematicPrinter.java @@ -6,6 +6,7 @@ import java.util.stream.Collectors; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementChecks; +import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform; import com.simibubi.create.content.schematics.item.SchematicItem; import com.simibubi.create.foundation.utility.BlockHelper; @@ -81,6 +82,12 @@ public class SchematicPrinter { blockReader = new SchematicWorld(schematicAnchor, originalWorld); activeTemplate.place(blockReader, schematicAnchor, settings, blockReader.getRandom()); + StructureTransform transform = new StructureTransform(settings.getCenterOffset(), Direction.Axis.Y, + settings.getRotation(), settings.getMirror()); + for (TileEntity te : blockReader.tileEntities.values()) { + transform.apply(te); + } + printingEntityIndex = -1; printStage = PrintStage.BLOCKS; deferredBlocks.clear(); @@ -292,7 +299,8 @@ public class SchematicPrinter { } public static boolean shouldDeferBlock(BlockState state) { - return state.getBlock().is(AllBlocks.GANTRY_CARRIAGE.get()) || BlockMovementChecks.isBrittle(state); + return AllBlocks.GANTRY_CARRIAGE.has(state) || AllBlocks.MECHANICAL_ARM.has(state) + || BlockMovementChecks.isBrittle(state); } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java index a2cb48d26..676e3f7fb 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java @@ -12,6 +12,7 @@ import net.minecraft.nbt.DoubleNBT; import net.minecraft.nbt.ListNBT; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Mirror; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.vector.Quaternion; @@ -34,8 +35,7 @@ public class VecHelper { public static Vector3d rotateCentered(Vector3d vec, double deg, Axis axis) { Vector3d shift = getCenterOf(BlockPos.ZERO); - return VecHelper.rotate(vec.subtract(shift), deg, axis) - .add(shift); + return VecHelper.rotate(vec.subtract(shift), deg, axis).add(shift); } public static Vector3d rotate(Vector3d vec, double deg, Axis axis) { @@ -60,6 +60,28 @@ public class VecHelper { return vec; } + public static Vector3d mirrorCentered(Vector3d vec, Mirror mirror) { + Vector3d shift = getCenterOf(BlockPos.ZERO); + return VecHelper.mirror(vec.subtract(shift), mirror).add(shift); + } + + public static Vector3d mirror(Vector3d vec, Mirror mirror) { + if (mirror == null || mirror == Mirror.NONE) + return vec; + if (vec == Vector3d.ZERO) + return vec; + + double x = vec.x; + double y = vec.y; + double z = vec.z; + + if (mirror == Mirror.LEFT_RIGHT) + return new Vector3d(x, y, -z); + if (mirror == Mirror.FRONT_BACK) + return new Vector3d(-x, y, z); + return vec; + } + public static Vector3d lookAt(Vector3d vec, Vector3d fwd) { fwd = fwd.normalize(); Vector3d up = new Vector3d(0,1,0);