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 } }