diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 2ffc992a1..53519a6c0 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -15,6 +15,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.bearing. import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntityRenderer; import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyRenderer; @@ -146,6 +147,7 @@ public enum AllTileEntities { SPEED_GAUGE(SpeedGaugeTileEntity::new, AllBlocks.SPEED_GAUGE), STRESS_GAUGE(StressGaugeTileEntity::new, AllBlocks.STRESS_GAUGE), ANALOG_LEVER(AnalogLeverTileEntity::new, AllBlocks.ANALOG_LEVER), + CART_ASSEMBLER(CartAssemblerTileEntity::new, AllBlocks.CART_ASSEMBLER), // Logistics REDSTONE_BRIDGE(RedstoneLinkTileEntity::new, AllBlocks.REDSTONE_BRIDGE), diff --git a/src/main/java/com/simibubi/create/ScreenResources.java b/src/main/java/com/simibubi/create/ScreenResources.java index 3270590ab..19f7f780a 100644 --- a/src/main/java/com/simibubi/create/ScreenResources.java +++ b/src/main/java/com/simibubi/create/ScreenResources.java @@ -133,6 +133,9 @@ public enum ScreenResources { I_MOVE_PLACE(9, 1), I_MOVE_PLACE_RETURNED(10, 1), I_MOVE_NEVER_PLACE(11, 1), + I_CART_ROTATE(12, 1), + I_CART_ROTATE_PAUSED(13, 1), + I_CART_ROTATE_LOCKED(14, 1), I_DONT_REPLACE(0, 2), I_REPLACE_SOLID(1, 2), diff --git a/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java index 058c23c1e..580c4d3cb 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java @@ -19,16 +19,16 @@ public class AngleHelper { public static float rad(float angle) { return (float) (angle / 180 * Math.PI); } - + public static float deg(float angle) { return (float) (angle * 180 / Math.PI); } - - public static float angleLerp(float pct, float current, float target) { + + public static float angleLerp(float pct, float current, float target) { return current + getShortestAngleDiff(current, target) * pct; } - public static float getShortestAngleDiff(double current, double target) { + public static float getShortestAngleDiff(double current, double target) { current = current % 360; target = target % 360; return (float) (((((target - current) % 360) + 540) % 360) - 180); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java index 6e4f01a95..2a0afc2a0 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java @@ -12,8 +12,11 @@ import org.apache.commons.lang3.tuple.MutablePair; import com.google.common.collect.ImmutableSet; import com.simibubi.create.AllEntities; import com.simibubi.create.AllPackets; +import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.BearingContraption; +import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity.CartMovementMode; +import com.simibubi.create.modules.contraptions.components.contraptions.mounted.MountedContraption; import com.simibubi.create.modules.contraptions.components.contraptions.piston.LinearActuatorTileEntity; import net.minecraft.block.material.PushReaction; @@ -156,6 +159,14 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } public void tickAsPassenger(Entity e) { + boolean rotationLock = false; + boolean pauseWhileRotating = false; + + if (contraption instanceof MountedContraption) { + rotationLock = ((MountedContraption) contraption).rotationMode == CartMovementMode.ROTATION_LOCKED; + pauseWhileRotating = ((MountedContraption) contraption).rotationMode == CartMovementMode.ROTATE_PAUSED; + } + Entity riding = e; while (riding.getRidingEntity() != null) riding = riding.getRidingEntity(); @@ -163,20 +174,28 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD if (riding instanceof BoatEntity) movementVector = new Vec3d(posX - prevPosX, posY - prevPosY, posZ - prevPosZ); Vec3d motion = movementVector.normalize(); + boolean rotating = false; - if (motion.length() > 0) { - targetYaw = yawFromVector(motion); - if (targetYaw < 0) - targetYaw += 360; - if (yaw < 0) - yaw += 360; + if (!rotationLock) { + if (motion.length() > 0) { + targetYaw = yawFromVector(motion); + if (targetYaw < 0) + targetYaw += 360; + if (yaw < 0) + yaw += 360; + } + + prevYaw = yaw; + yaw = angleLerp(0.4f, yaw, targetYaw); + if (Math.abs(AngleHelper.getShortestAngleDiff(yaw, targetYaw)) < 1f) + yaw = targetYaw; + else + rotating = true; } - prevYaw = yaw; - yaw = angleLerp(0.4f, yaw, targetYaw); - boolean wasStalled = isStalled(); - tickActors(movementVector); + if (!rotating || !pauseWhileRotating) + tickActors(movementVector); if (isStalled()) { if (!wasStalled) motionBeforeStall = riding.getMotion(); @@ -434,8 +453,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } @Override - protected void doWaterSplashEffect() { - } + protected void doWaterSplashEffect() {} public void preventMovedEntitiesFromGettingStuck() { Vec3d stuckTest = new Vec3d(0, -2, 0); @@ -524,8 +542,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @Override // Make sure nothing can move contraptions out of the way - public void setMotion(Vec3d motionIn) { - } + public void setMotion(Vec3d motionIn) {} @Override public PushReaction getPushReaction() { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java index d33f49619..a789eef59 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java @@ -1,10 +1,11 @@ package com.simibubi.create.modules.contraptions.components.contraptions.mounted; import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.RenderUtilityBlock; import com.simibubi.create.foundation.utility.AllShapes; -import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity.CartMovementMode; import net.minecraft.block.AbstractRailBlock; import net.minecraft.block.Block; @@ -19,6 +20,7 @@ import net.minecraft.state.IProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.RailShape; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; @@ -28,7 +30,7 @@ import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; -public class CartAssemblerBlock extends AbstractRailBlock { +public class CartAssemblerBlock extends AbstractRailBlock implements ITE { public static IProperty RAIL_SHAPE = EnumProperty.create("shape", RailShape.class, RailShape.EAST_WEST, RailShape.NORTH_SOUTH); @@ -45,6 +47,16 @@ public class CartAssemblerBlock extends AbstractRailBlock { super.fillStateContainer(builder); } + @Override + public boolean hasTileEntity(BlockState state) { + return true; + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return new CartAssemblerTileEntity(); + } + @Override public BlockState getStateForPlacement(BlockItemUseContext context) { boolean alongX = context.getPlacementHorizontalFacing().getAxis() == Axis.X; @@ -72,12 +84,15 @@ public class CartAssemblerBlock extends AbstractRailBlock { if (!cart.getPassengers().isEmpty()) return; - Contraption contraption = MountedContraption.assembleMinecart(world, pos); + MountedContraption contraption = MountedContraption.assembleMinecart(world, pos); if (contraption == null) return; if (contraption.blocks.size() == 1) return; + float initialAngle = ContraptionEntity.yawFromVector(cart.getMotion()); + + withTileEntityDo(world, pos, te -> contraption.rotationMode = CartMovementMode.values()[te.movementMode.value]); ContraptionEntity entity = ContraptionEntity.createMounted(world, contraption, initialAngle); entity.setPosition(pos.getX(), pos.getY(), pos.getZ()); world.addEntity(entity); @@ -129,7 +144,7 @@ public class CartAssemblerBlock extends AbstractRailBlock { public PushReaction getPushReaction(BlockState state) { return PushReaction.BLOCK; } - + @Override public boolean isNormalCube(BlockState state, IBlockReader worldIn, BlockPos pos) { return false; @@ -142,7 +157,7 @@ public class CartAssemblerBlock extends AbstractRailBlock { builder.add(BlockStateProperties.HORIZONTAL_AXIS); super.fillStateContainer(builder); } - + @Override public boolean isSolid(BlockState state) { return false; @@ -155,4 +170,9 @@ public class CartAssemblerBlock extends AbstractRailBlock { return AllBlocks.MINECART_ANCHOR.get().getDefaultState().with(BlockStateProperties.HORIZONTAL_AXIS, axis); } + @Override + public Class getTileEntityClass() { + return CartAssemblerTileEntity.class; + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerTileEntity.java new file mode 100644 index 000000000..89ae09aa9 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerTileEntity.java @@ -0,0 +1,65 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.mounted; + +import java.util.List; + +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.ScreenResources; +import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform; +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; +import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; +import com.simibubi.create.foundation.behaviour.scrollvalue.INamedIconOptions; +import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollOptionBehaviour; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.util.Direction; + +public class CartAssemblerTileEntity extends SmartTileEntity { + + protected ScrollOptionBehaviour movementMode; + + public CartAssemblerTileEntity() { + super(AllTileEntities.CART_ASSEMBLER.type); + } + + @Override + public void addBehaviours(List behaviours) { + movementMode = new ScrollOptionBehaviour<>(CartMovementMode.class, + Lang.translate("contraptions.cart_movement_mode"), this, getMovementModeSlot()); + movementMode.requiresWrench(); + behaviours.add(movementMode); + } + + protected ValueBoxTransform getMovementModeSlot() { + return new CenteredSideValueBoxTransform((state, d) -> d == Direction.UP); + } + + public static enum CartMovementMode implements INamedIconOptions { + + ROTATE(ScreenResources.I_CART_ROTATE), + ROTATE_PAUSED(ScreenResources.I_CART_ROTATE_PAUSED), + ROTATION_LOCKED(ScreenResources.I_CART_ROTATE_LOCKED), + + ; + + private String translationKey; + private ScreenResources icon; + + private CartMovementMode(ScreenResources icon) { + this.icon = icon; + translationKey = "contraptions.cart_movement_mode." + Lang.asId(name()); + } + + @Override + public ScreenResources getIcon() { + return icon; + } + + @Override + public String getTranslationKey() { + return translationKey; + } + + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java index fd6697d7d..0c4b56ca0 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java @@ -7,11 +7,14 @@ import java.util.List; import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.modules.contraptions.components.contraptions.AllContraptionTypes; import com.simibubi.create.modules.contraptions.components.contraptions.BlockMovementTraits; import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; +import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity.CartMovementMode; import net.minecraft.block.BlockState; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.RailShape; import net.minecraft.tileentity.TileEntity; @@ -26,12 +29,14 @@ import net.minecraft.world.gen.feature.template.Template.BlockInfo; public class MountedContraption extends Contraption { + public CartMovementMode rotationMode; + @Override protected AllContraptionTypes getType() { return AllContraptionTypes.MOUNTED; } - public static Contraption assembleMinecart(World world, BlockPos pos) { + public static MountedContraption assembleMinecart(World world, BlockPos pos) { if (isFrozen()) return null; @@ -39,7 +44,7 @@ public class MountedContraption extends Contraption { if (!state.has(RAIL_SHAPE)) return null; - Contraption contraption = new MountedContraption(); + MountedContraption contraption = new MountedContraption(); if (!contraption.searchMovedStructure(world, pos, null)) return null; @@ -83,6 +88,19 @@ public class MountedContraption extends Contraption { return pair; } + @Override + public CompoundNBT writeNBT() { + CompoundNBT writeNBT = super.writeNBT(); + writeNBT.putString("RotationMode", NBTHelper.writeEnum(rotationMode)); + return writeNBT; + } + + @Override + public void readNBT(World world, CompoundNBT nbt) { + rotationMode = NBTHelper.readEnum(nbt.getString("RotationMode"), CartMovementMode.class); + super.readNBT(world, nbt); + } + @Override public void removeBlocksFromWorld(IWorld world, BlockPos offset) { super.removeBlocksFromWorld(world, offset, (pos, state) -> pos.equals(anchor)); diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index 6bb894769..8eab4367d 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -391,6 +391,10 @@ "create.contraptions.movement_mode.rotate_place": "Always Place when Stopped", "create.contraptions.movement_mode.rotate_place_returned": "Only Place near Initial Angle", "create.contraptions.movement_mode.rotate_never_place": "Only Place when Anchor Destroyed", + "create.contraptions.cart_movement_mode": "Cart Movement Mode", + "create.contraptions.cart_movement_mode.rotate": "Always face toward motion", + "create.contraptions.cart_movement_mode.rotate_paused": "Pause actors while rotating", + "create.contraptions.cart_movement_mode.rotation_locked": "Lock rotation", "create.logistics.filter": "Filter", "create.logistics.firstFrequency": "Freq. #1", diff --git a/src/main/resources/assets/create/textures/gui/icons.png b/src/main/resources/assets/create/textures/gui/icons.png index 0b0183a2e..06aa1ce24 100644 Binary files a/src/main/resources/assets/create/textures/gui/icons.png and b/src/main/resources/assets/create/textures/gui/icons.png differ