Skip to content

Commit 9ccbc3a

Browse files
committed
Fix movement input correction
1 parent 63a9377 commit 9ccbc3a

File tree

4 files changed

+104
-82
lines changed

4 files changed

+104
-82
lines changed

src/main/java/com/lambda/mixin/baritone/MixinLookBehavior.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void onTargetUpdate(Rotation rotation, boolean blockInteract, CallbackInfo ci) {
3636
LookBehavior instance = ((LookBehavior) (Object) this);
3737
if (instance.baritone != BaritoneUtils.getPrimary()) return;
3838

39-
RotationManager.BaritoneProcessor.handleBaritoneRotation(rotation.getYaw(), rotation.getPitch());
39+
RotationManager.handleBaritoneRotation(rotation.getYaw(), rotation.getPitch());
4040
ci.cancel();
4141
}
4242

src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ private void emitMovementEvents(AbstractClientPlayerEntity instance, MovementTyp
7070
void processMovement(Input input) {
7171
input.tick();
7272
RotationManager.processRotations();
73-
RotationManager.BaritoneProcessor.processInputs(input);
73+
RotationManager.redirectStrafeInputs(input);
7474
EventFlow.post(new MovementEvent.InputUpdate(input));
7575
}
7676

src/main/kotlin/com/lambda/interaction/PlayerPacketManager.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import com.lambda.event.EventFlow.post
2222
import com.lambda.event.EventFlow.postChecked
2323
import com.lambda.event.events.PlayerPacketEvent
2424
import com.lambda.interaction.request.rotating.Rotation
25+
import com.lambda.interaction.request.rotating.Rotation.Companion.rotation
2526
import com.lambda.interaction.request.rotating.RotationManager
2627
import com.lambda.threading.runSafe
2728
import com.lambda.util.collections.LimitedOrderedSet
@@ -87,7 +88,7 @@ object PlayerPacketManager {
8788
val onGround = new.onGround
8889
val isCollidingHorizontally = new.isCollidingHorizontally
8990

90-
val updatePosition = position.approximate(lastPosition, 2.0E-4) || ++sendTicks >= 20
91+
val updatePosition = position.approximate(lastPosition) || ++sendTicks >= 20
9192
val updateRotation = lastRotation.yaw != yaw || lastRotation.pitch != pitch
9293

9394
when {

src/main/kotlin/com/lambda/interaction/request/rotating/RotationManager.kt

Lines changed: 100 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import com.lambda.context.SafeContext
2222
import com.lambda.event.EventFlow.post
2323
import com.lambda.event.events.ConnectionEvent
2424
import com.lambda.event.events.PacketEvent
25-
import com.lambda.event.events.RotationEvent
2625
import com.lambda.event.events.TickEvent
2726
import com.lambda.event.events.UpdateManagerEvent
2827
import com.lambda.event.listener.SafeListener.Companion.listen
@@ -39,11 +38,13 @@ import com.lambda.util.math.MathUtils.toRadian
3938
import com.lambda.util.math.Vec2d
4039
import com.lambda.util.math.lerp
4140
import net.minecraft.client.input.Input
41+
import net.minecraft.client.input.KeyboardInput
4242
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket
43+
import net.minecraft.util.PlayerInput
4344
import net.minecraft.util.math.Vec2f
45+
import kotlin.math.PI
46+
import kotlin.math.atan2
4447
import kotlin.math.cos
45-
import kotlin.math.round
46-
import kotlin.math.sign
4748
import kotlin.math.sin
4849

4950
object RotationManager : RequestHandler<RotationRequest>(
@@ -119,6 +120,102 @@ object RotationManager : RequestHandler<RotationRequest>(
119120
}
120121
}
121122

123+
@JvmStatic
124+
fun handleBaritoneRotation(yaw: Float, pitch: Float) {
125+
lookAt(Rotation(yaw, pitch)).requestBy(Baritone.rotation)
126+
}
127+
128+
@JvmStatic
129+
fun redirectStrafeInputs(input: Input) = runSafe {
130+
val movementYaw = movementYaw ?: return@runSafe
131+
val playerYaw = player.yaw
132+
133+
if (movementYaw.minus(playerYaw).rem(360f).let { it * it } < 0.001f) return@runSafe
134+
135+
val originalStrafe = input.movementVector.x
136+
val originalForward = input.movementVector.y
137+
138+
if (originalStrafe == 0.0f && originalForward == 0.0f) return@runSafe
139+
140+
val deltaYawRad = (playerYaw - movementYaw).toRadian()
141+
142+
val cos = cos(deltaYawRad)
143+
val sin = sin(deltaYawRad)
144+
// This is the IDEAL movement vector in the server-side entity's frame of reference
145+
val newStrafe = originalStrafe * cos - originalForward * sin
146+
val newForward = originalStrafe * sin + originalForward * cos
147+
148+
// --- ANGLE SNAPPING LOGIC ---
149+
// Instead of simple thresholds, we find the closest of the 8 possible directions.
150+
151+
// Get the angle of the ideal vector. atan2 gives us an angle in radians.
152+
// Note: Minecraft input vector's +Y is forward, +X is left.
153+
val angle = atan2(newStrafe.toDouble(), newForward.toDouble())
154+
155+
// Define the boundaries for our 8 sectors (in radians). Each sector is 45 degrees (PI/4).
156+
val sector = (PI / 4.0).toFloat()
157+
val boundary = (PI / 8.0).toFloat() // The halfway point between sectors (22.5 degrees)
158+
159+
var pressForward = false
160+
var pressBackward = false
161+
var pressLeft = false
162+
var pressRight = false
163+
164+
// Determine which 45-degree sector the angle falls into and set the corresponding keys.
165+
if (angle > -boundary && angle <= boundary) {
166+
// Forward
167+
pressForward = true
168+
} else if (angle > boundary && angle <= boundary + sector) {
169+
// Forward-Left
170+
pressForward = true
171+
pressLeft = true
172+
} else if (angle > boundary + sector && angle <= boundary + 2 * sector) {
173+
// Left
174+
pressLeft = true
175+
} else if (angle > boundary + 2 * sector && angle <= boundary + 3 * sector) {
176+
// Backward-Left
177+
pressBackward = true
178+
pressLeft = true
179+
} else if (angle > boundary + 3 * sector || angle <= -(boundary + 3 * sector)) {
180+
// Backward
181+
pressBackward = true
182+
} else if (angle > -(boundary + 3 * sector) && angle <= -(boundary + 2 * sector)) {
183+
// Backward-Right
184+
pressBackward = true
185+
pressRight = true
186+
} else if (angle > -(boundary + 2 * sector) && angle <= -(boundary + sector)) {
187+
// Right
188+
pressRight = true
189+
} else if (angle > -(boundary + sector) && angle <= -boundary) {
190+
// Forward-Right
191+
pressForward = true
192+
pressRight = true
193+
}
194+
195+
// --- Update Minecraft's input objects ---
196+
input.playerInput = PlayerInput(
197+
pressForward,
198+
pressBackward,
199+
pressLeft,
200+
pressRight,
201+
input.playerInput.jump(),
202+
input.playerInput.sneak(),
203+
input.playerInput.sprint()
204+
)
205+
206+
val f = getMovementMultiplier(input.playerInput.forward(), input.playerInput.backward())
207+
val g = getMovementMultiplier(input.playerInput.left(), input.playerInput.right())
208+
input.movementVector = Vec2f(g, f).normalize()
209+
}
210+
211+
private fun getMovementMultiplier(positive: Boolean, negative: Boolean): Float {
212+
return if (positive == negative) {
213+
0.0f
214+
} else {
215+
if (positive) 1.0f else -1.0f
216+
}
217+
}
218+
122219
fun onRotationSend() {
123220
prevServerRotation = serverRotation
124221
serverRotation = activeRotation/*.fixSensitivity(prevServerRotation)*/
@@ -196,81 +293,5 @@ object RotationManager : RequestHandler<RotationRequest>(
196293
return Vec2d(rot.yaw, rot.pitch)
197294
}
198295

199-
object BaritoneProcessor {
200-
private var baritoneContext: RotationRequest? = null
201-
202-
private val movementYawList = arrayOf(
203-
0.0, 45.0,
204-
90.0, 135.0,
205-
180.0, 225.0,
206-
270.0, 315.0,
207-
)
208-
209-
@JvmStatic
210-
fun handleBaritoneRotation(yaw: Float, pitch: Float) {
211-
baritoneContext = lookAt(Rotation(yaw, pitch)).requestBy(Baritone.rotation)
212-
}
213-
214-
init {
215-
listenUnsafe<TickEvent.Pre> {
216-
baritoneContext = null
217-
}
218-
}
219-
220-
@JvmStatic
221-
fun processInputs(input: Input) = runSafe {
222-
// The yaw relative to which the movement was constructed
223-
val baritoneYaw = baritoneContext?.target?.targetRotation?.value?.yaw
224-
val baseYaw = baritoneYaw ?: player.yaw.toDouble()
225-
val strafeEvent = RotationEvent.StrafeInput(baseYaw, input)
226-
val movementYaw = strafeEvent.post().strafeYaw
227-
228-
// No changes are needed, when we don't modify the yaw used to move the player
229-
// val config = currentContext?.config ?: return@runSafe
230-
// if (config.rotationMode == RotationMode.SILENT && !input.handledByBaritone && baritoneContext == null) return@runSafe
231-
232-
// Sign it to remove previous speed modifier
233-
input.hasForwardMovement()
234-
val signForward = sign(input.movementVector.y)
235-
val signStrafe = sign(input.movementVector.x)
236-
237-
// No changes are needed when no inputs are pressed
238-
if (signForward <= 1.0E-5f && signStrafe <= 1.0E-5F) return@runSafe
239-
240-
// Actual yaw used by the physics engine
241-
var actualYaw = activeRotation.yaw
242-
243-
if (activeRequest?.rotationMode == RotationMode.Silent) {
244-
actualYaw = player.yaw.toDouble()
245-
}
246-
247-
val yawRad = (movementYaw - actualYaw).toRadian()
248-
249-
val cosDelta = cos(yawRad)
250-
val sinDelta = sin(yawRad)
251-
252-
val newX = signStrafe * cosDelta - signForward * sinDelta
253-
val newZ = signForward * cosDelta + signStrafe * sinDelta
254-
255-
// Apply new movement
256-
input.apply {
257-
movementVector = Vec2f(
258-
round(newX).toFloat(),
259-
round(newZ).toFloat(),
260-
)
261-
}
262-
263-
baritoneYaw ?: return@runSafe
264-
265-
// Makes baritone movement safe
266-
// when yaw difference is too big to compensate it by modifying keyboard input
267-
val minYawDist = movementYawList
268-
.map { activeRotation.yaw + it } // all possible movement directions (including diagonals)
269-
.minOf { Rotation.angleDifference(it, baritoneYaw) }
270-
271-
if (minYawDist > 5.0) input.movementVector = Vec2f.ZERO
272-
}
273-
}
274-
275296
override fun preEvent() = UpdateManagerEvent.Rotation.post()
276297
}

0 commit comments

Comments
 (0)