diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 2ec56b1a4..3ab2a068b 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -742,10 +742,21 @@ public final class Settings { public final Setting elytraFreeLook = new Setting<>(false); /** - * Forces the client-sided rotations to an average of the last 10 ticks of server-sided rotations. + * Forces the client-sided yaw rotation to an average of the last {@link #smoothLookTicks} of server-sided rotations. * Requires {@link #freeLook}. */ - public final Setting smoothLook = new Setting<>(false); + public final Setting smoothLookYaw = new Setting<>(false); + + /** + * Forces the client-sided pitch rotation to an average of the last {@link #smoothLookTicks} of server-sided rotations. + * Requires {@link #freeLook}. + */ + public final Setting smoothLookPitch = new Setting<>(false); + + /** + * The number of ticks to average across for {@link #smoothLookYaw} and {@link #smoothLookPitch}; + */ + public final Setting smoothLookTicks = new Setting<>(10); /** * When true, the player will remain with its existing look direction as often as possible. diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index d93607644..5f6421d08 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -26,9 +26,10 @@ import baritone.api.event.events.*; import baritone.api.utils.IPlayerContext; import baritone.api.utils.Rotation; import baritone.behavior.look.ForkableRandom; -import com.google.common.collect.EvictingQueue; import net.minecraft.network.play.client.CPacketPlayer; +import java.util.ArrayDeque; +import java.util.Deque; import java.util.Optional; public final class LookBehavior extends Behavior implements ILookBehavior { @@ -52,12 +53,14 @@ public final class LookBehavior extends Behavior implements ILookBehavior { private final AimProcessor processor; - private final EvictingQueue smoothYawBuffer; + private final Deque smoothYawBuffer; + private final Deque smoothPitchBuffer; public LookBehavior(Baritone baritone) { super(baritone); this.processor = new AimProcessor(baritone.getPlayerContext()); - this.smoothYawBuffer = EvictingQueue.create(10); + this.smoothYawBuffer = new ArrayDeque<>(); + this.smoothPitchBuffer = new ArrayDeque<>(); } @Override @@ -100,15 +103,22 @@ public final class LookBehavior extends Behavior implements ILookBehavior { case POST: { // Reset the player's rotations back to their original values if (this.prevRotation != null) { - if (Baritone.settings().smoothLook.value) { - this.smoothYawBuffer.add(this.target.rotation.getYaw()); - ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream() - .mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw); - ctx.player().rotationPitch = this.prevRotation.getPitch(); - } else { - ctx.player().rotationYaw = this.prevRotation.getYaw(); - ctx.player().rotationPitch = this.prevRotation.getPitch(); + this.smoothYawBuffer.add(this.target.rotation.getYaw()); + while (this.smoothYawBuffer.size() > Baritone.settings().smoothLookTicks.value) { + this.smoothYawBuffer.pop(); } + this.smoothPitchBuffer.add(this.target.rotation.getPitch()); + while (this.smoothPitchBuffer.size() > Baritone.settings().smoothLookTicks.value) { + this.smoothPitchBuffer.pop(); + } + + ctx.player().rotationYaw = Baritone.settings().smoothLookYaw.value + ? (float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw) + : this.prevRotation.getYaw(); + ctx.player().rotationPitch = Baritone.settings().smoothLookPitch.value + ? (float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getPitch) + : this.prevRotation.getPitch(); + this.prevRotation = null; } // The target is done being used for this game tick, so it can be invalidated