diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 960759fa2..5ec5b6ed4 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -58,6 +58,7 @@ public final class Settings { public final Setting renderHitboxRaytraces = new Setting<>(false); public final Setting renderElytraSimulation = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); + public final Setting smoothLook = new Setting<>(false); // Experimental Elytra Settings public final Setting experimentalTakeoff = new Setting<>(false); diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 9dd379771..f59d1be83 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -26,6 +26,7 @@ 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.Optional; @@ -51,9 +52,12 @@ public final class LookBehavior extends Behavior implements ILookBehavior { private final AimProcessor processor; + private final EvictingQueue smoothYawBuffer; + public LookBehavior(Baritone baritone) { super(baritone); this.processor = new AimProcessor(baritone.getPlayerContext()); + this.smoothYawBuffer = EvictingQueue.create(10); } @Override @@ -96,8 +100,14 @@ public final class LookBehavior extends Behavior implements ILookBehavior { case POST: { // Reset the player's rotations back to their original values if (this.prevRotation != null) { - ctx.player().rotationYaw = this.prevRotation.getYaw(); - ctx.player().rotationPitch = this.prevRotation.getPitch(); + if (Baritone.settings().smoothLook.value) { + 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.prevRotation = null; } // The target is done being used for this game tick, so it can be invalidated