Advanced Arm Applications

- Mechanical Arms remember their targets when placed by Schematicannon (for real this time)
- Mechanical Arms will now rotate/mirror their targets when rotated/mirrored in a schematic or contraption
This commit is contained in:
reidbhuntley 2021-07-12 22:03:22 -04:00
parent 2300e0e58a
commit f3a521121d
7 changed files with 104 additions and 16 deletions

View file

@ -1057,6 +1057,8 @@ public abstract class Contraption {
mountedStorage.addStorageToWorld(tileEntity); mountedStorage.addStorageToWorld(tileEntity);
} }
} }
transform.apply(tileEntity);
} }
} }
for (BlockInfo block : blocks.values()) { for (BlockInfo block : blocks.values()) {

View file

@ -0,0 +1,7 @@
package com.simibubi.create.content.contraptions.components.structureMovement;
public interface ITransformableTE {
void transform(StructureTransform transform);
}

View file

@ -27,9 +27,11 @@ import net.minecraft.state.properties.BellAttachment;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.state.properties.Half; import net.minecraft.state.properties.Half;
import net.minecraft.state.properties.SlabType; import net.minecraft.state.properties.SlabType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation; import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3d;
@ -41,27 +43,33 @@ public class StructureTransform {
int angle; int angle;
Axis rotationAxis; Axis rotationAxis;
BlockPos offset; 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.offset = offset;
this.angle = angle; this.angle = angle;
rotationAxis = axis; rotationAxis = axis;
this.rotation = rotation; 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) { public StructureTransform(BlockPos offset, float xRotation, float yRotation, float zRotation) {
this.offset = offset; this.offset = offset;
if (xRotation != 0) { if (xRotation != 0) {
rotationAxis = Axis.X; rotationAxis = Axis.X;
angle = (int) (Math.round(xRotation / 90) * 90); angle = Math.round(xRotation / 90) * 90;
} }
if (yRotation != 0) { if (yRotation != 0) {
rotationAxis = Axis.Y; rotationAxis = Axis.Y;
angle = (int) (Math.round(yRotation / 90) * 90); angle = Math.round(yRotation / 90) * 90;
} }
if (zRotation != 0) { if (zRotation != 0) {
rotationAxis = Axis.Z; rotationAxis = Axis.Z;
angle = (int) (Math.round(zRotation / 90) * 90); angle = Math.round(zRotation / 90) * 90;
} }
angle %= 360; angle %= 360;
@ -76,22 +84,33 @@ public class StructureTransform {
if (angle == 180) if (angle == 180)
this.rotation = Rotation.CLOCKWISE_180; this.rotation = Rotation.CLOCKWISE_180;
mirror = Mirror.NONE;
} }
public Vector3d apply(Vector3d localVec) { public Vector3d applyWithoutOffset(Vector3d localVec) {
Vector3d vec = localVec; Vector3d vec = localVec;
if (mirror != null)
vec = VecHelper.mirrorCentered(vec, mirror);
if (rotationAxis != null) if (rotationAxis != null)
vec = VecHelper.rotateCentered(vec, angle, rotationAxis); vec = VecHelper.rotateCentered(vec, angle, rotationAxis);
vec = vec.add(Vector3d.of(offset));
return vec; 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) { public BlockPos apply(BlockPos localPos) {
Vector3d vec = VecHelper.getCenterOf(localPos); return applyWithoutOffset(localPos).add(offset);
if (rotationAxis != null) }
vec = VecHelper.rotateCentered(vec, angle, rotationAxis);
localPos = new BlockPos(vec); public void apply(TileEntity te) {
return localPos.add(offset); if (te instanceof ITransformableTE)
((ITransformableTE) te).transform(this);
} }
/** /**
@ -100,6 +119,9 @@ public class StructureTransform {
* horizontal axes * horizontal axes
*/ */
public BlockState apply(BlockState state) { public BlockState apply(BlockState state) {
if (mirror != null)
state = state.mirror(mirror);
Block block = state.getBlock(); Block block = state.getBlock();
if (rotationAxis == Axis.Y) { if (rotationAxis == Axis.Y) {
@ -299,6 +321,8 @@ public class StructureTransform {
} }
public Direction transformFacing(Direction facing) { public Direction transformFacing(Direction facing) {
if (mirror != null)
facing = mirror.mirror(facing);
for (int i = 0; i < rotation.ordinal(); i++) for (int i = 0; i < rotation.ordinal(); i++)
facing = DirectionHelper.rotateAround(facing, rotationAxis); facing = DirectionHelper.rotateAround(facing, rotationAxis);
return facing; return facing;
@ -335,8 +359,10 @@ public class StructureTransform {
int readAngle = buffer.readInt(); int readAngle = buffer.readInt();
int axisIndex = buffer.readVarInt(); int axisIndex = buffer.readVarInt();
int rotationIndex = buffer.readVarInt(); int rotationIndex = buffer.readVarInt();
int mirrorIndex = buffer.readVarInt();
return new StructureTransform(readBlockPos, readAngle, axisIndex == -1 ? null : Axis.values()[axisIndex], 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) { public void writeToBuffer(PacketBuffer buffer) {
@ -344,6 +370,7 @@ public class StructureTransform {
buffer.writeInt(angle); buffer.writeInt(angle);
buffer.writeVarInt(rotationAxis == null ? -1 : rotationAxis.ordinal()); buffer.writeVarInt(rotationAxis == null ? -1 : rotationAxis.ordinal());
buffer.writeVarInt(rotation == null ? -1 : rotation.ordinal()); buffer.writeVarInt(rotation == null ? -1 : rotation.ordinal());
buffer.writeVarInt(mirror == null ? - 1 : mirror.ordinal());
} }
} }

View file

@ -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.crafter.MechanicalCrafterTileEntity;
import com.simibubi.create.content.contraptions.components.deployer.DeployerBlock; 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.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.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper; import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
@ -218,6 +219,12 @@ public abstract class ArmInteractionPoint {
return interactionPoint; 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 { public static abstract class TopFaceArmInteractionPoint extends ArmInteractionPoint {
@Override @Override

View file

@ -7,6 +7,8 @@ import javax.annotation.Nullable;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; 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.Jukebox;
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode;
import com.simibubi.create.foundation.advancement.AllTriggers; 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.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.Constants.NBT;
public class ArmTileEntity extends KineticTileEntity { public class ArmTileEntity extends KineticTileEntity implements ITransformableTE {
// Server // Server
List<ArmInteractionPoint> inputs; List<ArmInteractionPoint> inputs;
@ -384,6 +386,19 @@ public class ArmTileEntity extends KineticTileEntity {
searchForItem(); 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() { protected void initInteractionPoints() {
if (!updateInteractionPoints || interactionPointTag == null) if (!updateInteractionPoints || interactionPointTag == null)
return; return;

View file

@ -6,6 +6,7 @@ import java.util.stream.Collectors;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementChecks; 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.content.schematics.item.SchematicItem;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
@ -81,6 +82,12 @@ public class SchematicPrinter {
blockReader = new SchematicWorld(schematicAnchor, originalWorld); blockReader = new SchematicWorld(schematicAnchor, originalWorld);
activeTemplate.place(blockReader, schematicAnchor, settings, blockReader.getRandom()); 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; printingEntityIndex = -1;
printStage = PrintStage.BLOCKS; printStage = PrintStage.BLOCKS;
deferredBlocks.clear(); deferredBlocks.clear();
@ -292,7 +299,8 @@ public class SchematicPrinter {
} }
public static boolean shouldDeferBlock(BlockState state) { 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);
} }
} }

View file

@ -12,6 +12,7 @@ import net.minecraft.nbt.DoubleNBT;
import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.ListNBT;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Mirror;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Quaternion; import net.minecraft.util.math.vector.Quaternion;
@ -34,8 +35,7 @@ public class VecHelper {
public static Vector3d rotateCentered(Vector3d vec, double deg, Axis axis) { public static Vector3d rotateCentered(Vector3d vec, double deg, Axis axis) {
Vector3d shift = getCenterOf(BlockPos.ZERO); Vector3d shift = getCenterOf(BlockPos.ZERO);
return VecHelper.rotate(vec.subtract(shift), deg, axis) return VecHelper.rotate(vec.subtract(shift), deg, axis).add(shift);
.add(shift);
} }
public static Vector3d rotate(Vector3d vec, double deg, Axis axis) { public static Vector3d rotate(Vector3d vec, double deg, Axis axis) {
@ -60,6 +60,28 @@ public class VecHelper {
return vec; 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) { public static Vector3d lookAt(Vector3d vec, Vector3d fwd) {
fwd = fwd.normalize(); fwd = fwd.normalize();
Vector3d up = new Vector3d(0,1,0); Vector3d up = new Vector3d(0,1,0);