diff --git a/src/api/java/baritone/api/utils/Rotation.java b/src/api/java/baritone/api/utils/Rotation.java
index c75a9a559..a45cc32dc 100644
--- a/src/api/java/baritone/api/utils/Rotation.java
+++ b/src/api/java/baritone/api/utils/Rotation.java
@@ -159,6 +159,26 @@ public static float normalizeYaw(float yaw) {
return newYaw;
}
+ /**
+ * Gets the distance between a starting yaw and an offset yaw.
+ * Distance can be negative if the offset yaw is behind of the starting yaw.
+ *
+ * @param yaw The initial yaw
+ * @param offsetYaw The offset yaw
+ * @return The distance between the yaws
+ */
+ public static float yawDistanceFromOffset(float yaw, float offsetYaw) {
+ if ((yaw > 0 ^ offsetYaw > 0) && ((yaw > 90 || yaw < -90) ^ (offsetYaw > 90 || offsetYaw < -90))) {
+ if (yaw < 0) {
+ return 360 + (yaw - offsetYaw);
+ } else {
+ return 360 - (yaw - offsetYaw);
+ }
+ } else {
+ return yaw - offsetYaw;
+ }
+ }
+
@Override
public String toString() {
return "Yaw: " + yaw + ", Pitch: " + pitch;
diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java
index 914a806ae..c01fd40e6 100644
--- a/src/main/java/baritone/pathing/movement/MovementHelper.java
+++ b/src/main/java/baritone/pathing/movement/MovementHelper.java
@@ -31,6 +31,7 @@
import baritone.utils.ToolSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
+import net.minecraft.util.Mth;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.piston.MovingPistonBlock;
@@ -50,10 +51,9 @@
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
+import static baritone.api.utils.RotationUtils.DEG_TO_RAD_F;
import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP;
import static baritone.pathing.precompute.Ternary.*;
@@ -659,6 +659,43 @@ static void moveTowards(IPlayerContext ctx, MovementState state, BlockPos pos) {
)).setInput(Input.MOVE_FORWARD, true);
}
+ static void moveTowardsWithoutRotation(IPlayerContext ctx, MovementState state, float idealYaw) {
+ MovementOption.getOptions(
+ Mth.sin(ctx.playerRotations().getYaw() * DEG_TO_RAD_F),
+ Mth.cos(ctx.playerRotations().getYaw() * DEG_TO_RAD_F),
+ Baritone.settings().allowSprint.value
+ ).min(Comparator.comparing(option -> option.distanceToSq(
+ Mth.sin(idealYaw * DEG_TO_RAD_F),
+ Mth.cos(idealYaw * DEG_TO_RAD_F)
+ ))).ifPresent(selection -> selection.setInputs(state));
+ }
+
+ static void moveTowardsWithoutRotation(IPlayerContext ctx, MovementState state, BlockPos dest) {
+ float idealYaw = RotationUtils.calcRotationFromVec3d(
+ ctx.playerHead(),
+ VecUtils.getBlockPosCenter(dest),
+ ctx.playerRotations()
+ ).getYaw();
+ moveTowardsWithoutRotation(ctx, state, idealYaw);
+ }
+
+ static void moveTowardsWithSlightRotation(IPlayerContext ctx, MovementState state, BlockPos dest) {
+ float idealYaw = RotationUtils.calcRotationFromVec3d(
+ ctx.playerHead(),
+ VecUtils.getBlockPosCenter(dest),
+ ctx.playerRotations()
+ ).getYaw();
+ float distance = Rotation.yawDistanceFromOffset(ctx.playerRotations().getYaw(), idealYaw) % 45f;
+ float newYaw = distance > 0f ?
+ distance > 22.5f ? distance - 45f : distance :
+ distance < -22.5f ? distance + 45f : distance;
+ state.setTarget(new MovementTarget(new Rotation(
+ ctx.playerRotations().getYaw() - newYaw,
+ ctx.playerRotations().getPitch()
+ ), true));
+ moveTowardsWithoutRotation(ctx, state, idealYaw);
+ }
+
/**
* Returns whether or not the specified block is
* water, regardless of whether or not it is flowing.
@@ -778,7 +815,7 @@ static PlaceResult attemptToPlaceABlock(MovementState state, IBaritone baritone,
if (ctx.getSelectedBlock().isPresent()) {
BlockPos selectedBlock = ctx.getSelectedBlock().get();
Direction side = ((BlockHitResult) ctx.objectMouseOver()).getDirection();
- // only way for selectedBlock.equals(placeAt) to be true is if it's replacable
+ // only way for selectedBlock.equals(placeAt) to be true is if it's replaceable
if (selectedBlock.equals(placeAt) || (MovementHelper.canPlaceAgainst(ctx, selectedBlock) && selectedBlock.relative(side).equals(placeAt))) {
if (wouldSneak) {
state.setInput(Input.SNEAK, true);
diff --git a/src/main/java/baritone/pathing/movement/MovementOption.java b/src/main/java/baritone/pathing/movement/MovementOption.java
new file mode 100644
index 000000000..27dfcfd5a
--- /dev/null
+++ b/src/main/java/baritone/pathing/movement/MovementOption.java
@@ -0,0 +1,57 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.pathing.movement;
+
+import baritone.api.utils.input.Input;
+import net.minecraft.util.Mth;
+
+import java.util.stream.Stream;
+
+public record MovementOption(Input input1, Input input2, float motionX, float motionZ) {
+ private static final float SPRINT_MULTIPLIER = 1.3f;
+
+ public MovementOption(Input input1, float motionX, float motionZ) {
+ this(input1, null, motionX, motionZ);
+ }
+
+ public void setInputs(MovementState movementState) {
+ if (input1 != null) {
+ movementState.setInput(input1, true);
+ }
+ if (input2 != null) {
+ movementState.setInput(input2, true);
+ }
+ }
+
+ public float distanceToSq(float otherX, float otherZ) {
+ return Mth.abs(motionX() - otherX) + Mth.abs(motionZ() - otherZ);
+ }
+
+ public static Stream getOptions(float motionX, float motionZ, boolean canSprint) {
+ return Stream.of(
+ new MovementOption(Input.MOVE_FORWARD, canSprint ? motionX * SPRINT_MULTIPLIER : motionX, canSprint ? motionZ * SPRINT_MULTIPLIER : motionZ),
+ new MovementOption(Input.MOVE_BACK, -motionX, -motionZ),
+ new MovementOption(Input.MOVE_LEFT, -motionZ, motionX),
+ new MovementOption(Input.MOVE_RIGHT, motionZ, -motionX),
+ new MovementOption(Input.MOVE_FORWARD, Input.MOVE_LEFT, (canSprint ? motionX * SPRINT_MULTIPLIER : motionX) - motionZ, (canSprint ? motionZ * SPRINT_MULTIPLIER : motionZ) + motionX),
+ new MovementOption(Input.MOVE_FORWARD, Input.MOVE_RIGHT, (canSprint ? motionX * SPRINT_MULTIPLIER : motionX) + motionZ, (canSprint ? motionZ * SPRINT_MULTIPLIER : motionZ) - motionX),
+ new MovementOption(Input.MOVE_BACK, Input.MOVE_LEFT, -motionX - motionZ, -motionZ + motionX),
+ new MovementOption(Input.MOVE_BACK, Input.MOVE_RIGHT, -motionX + motionZ, -motionZ - motionX)
+ );
+ }
+}
diff --git a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java
index b500eb8e4..156da1adb 100644
--- a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java
+++ b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java
@@ -356,9 +356,8 @@ public MovementState updateState(MovementState state) {
}
return state;
}
- MovementHelper.moveTowards(ctx, state, positionsToBreak[0]);
+ MovementHelper.moveTowardsWithSlightRotation(ctx, state, dest);
return state;
- // TODO MovementManager.moveTowardsBlock(to); // move towards not look at because if we are bridging for a couple blocks in a row, it is faster if we dont spin around and walk forwards then spin around and place backwards for every block
}
}