From 248c252086cc847aa271f015ebd5d7a734181e59 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Wed, 28 Jan 2026 18:39:40 +0000 Subject: [PATCH] expose lambdas rotations at the start of player tick --- .../mixin/entity/ClientPlayerEntityMixin.java | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java b/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java index 2f9fefe31..7f31ad578 100644 --- a/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java +++ b/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java @@ -23,7 +23,6 @@ import com.lambda.event.events.PlayerEvent; import com.lambda.event.events.PlayerPacketEvent; import com.lambda.event.events.TickEvent; -import com.lambda.interaction.managers.rotating.Rotation; import com.lambda.interaction.managers.rotating.RotationManager; import com.lambda.module.modules.movement.ElytraFly; import com.lambda.module.modules.movement.NoJumpCooldown; @@ -37,6 +36,8 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; import com.mojang.authlib.GameProfile; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.input.Input; @@ -46,7 +47,9 @@ import net.minecraft.entity.MovementType; import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; import net.minecraft.util.Hand; +import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec3d; +import org.joml.Vector2i; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -54,16 +57,11 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.util.Objects; @Mixin(value = ClientPlayerEntity.class, priority = Integer.MAX_VALUE) public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity { - @Shadow - private float lastYawClient; - @Shadow - private float lastPitchClient; @Unique private PlayerPacketEvent.Pre moveEvent; @@ -71,6 +69,14 @@ public ClientPlayerEntityMixin(ClientWorld world, GameProfile profile) { super(world, profile); } + @Inject(method = "tick", at = @At("HEAD")) + private void injectTick(CallbackInfo ci, @Share(namespace = "shared_rotations", value = "target_rotation") final LocalRef targetRotation) { + moveEvent = EventFlow.post(new PlayerPacketEvent.Pre(pos, RotationManager.getActiveRotation(), isOnGround(), isSprinting(), horizontalCollision)); + if (RotationManager.getRequests().stream().anyMatch(Objects::nonNull)) { + targetRotation.set(new Vec2f(moveEvent.getRotation().getYawF(), moveEvent.getRotation().getPitchF())); + } + } + @WrapOperation(method = "move", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V")) private void wrapMove(ClientPlayerEntity instance, MovementType movementType, Vec3d vec3d, Operation original) { EventFlow.post(new MovementEvent.Player.Pre(movementType, vec3d)); @@ -91,28 +97,21 @@ private void injectTickMovement(CallbackInfo ci) { if (NoJumpCooldown.INSTANCE.isEnabled() || (ElytraFly.INSTANCE.isEnabled() && ElytraFly.getMode() == ElytraFly.FlyMode.Bounce)) jumpingCooldown = 0; } - @Inject(method = "sendMovementPackets", at = @At("HEAD")) - private void injectSendMovementPacketsHead(CallbackInfo ci) { - moveEvent = EventFlow.post(new PlayerPacketEvent.Pre(pos, RotationManager.getActiveRotation(), isOnGround(), isSprinting(), horizontalCollision)); - } - - @Definition(id = "g", local = @Local(type = double.class, ordinal = 3)) - @Expression("g != 0.0") - @ModifyExpressionValue(method = "sendMovementPackets", at = @At("MIXINEXTRAS:EXPRESSION")) - private boolean modifyHasRotated(boolean original) { - return !RotationManager.getActiveRotation().equalFloat(RotationManager.getServerRotation()) || original; + @ModifyExpressionValue(method = "sendMovementPackets", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getYaw()F")) + private float modifyGetYaw(float original) { + final var yaw = RotationManager.getHeadYaw(); + return yaw != null ? yaw : original; } - @Inject(method = "sendMovementPackets", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILEXCEPTION) - private void injectSendPacket(CallbackInfo ci, double d, double e, double f, double g, double h, boolean bl, boolean bl2) { - if (RotationManager.getRequests().stream().allMatch(Objects::isNull)) { - moveEvent.setRotation(new Rotation(g + lastYawClient, h + lastPitchClient)); - } + @ModifyExpressionValue(method = "sendMovementPackets", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getPitch()F")) + private float modifyGetPitch(float original) { + final var pitch = RotationManager.getHeadPitch(); + return pitch != null ? pitch : original; } @WrapOperation(method = "sendMovementPackets", at = @At(value = "NEW", target = "net/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket$Full")) private PlayerMoveC2SPacket.Full wrapFullPacket(Vec3d pos, float yaw, float pitch, boolean onGround, boolean horizontalCollision, Operation original) { - return original.call(moveEvent.getPosition(), moveEvent.getRotation().getYawF(), moveEvent.getRotation().getPitchF(), moveEvent.getOnGround(), moveEvent.isCollidingHorizontally()); + return original.call(moveEvent.getPosition(), yaw, pitch, moveEvent.getOnGround(), moveEvent.isCollidingHorizontally()); } @WrapOperation(method = "sendMovementPackets", at = @At(value = "NEW", target = "net/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket$PositionAndOnGround")) @@ -122,7 +121,7 @@ private PlayerMoveC2SPacket.PositionAndOnGround wrapPositionAndOnGround(Vec3d po @WrapOperation(method = "sendMovementPackets", at = @At(value = "NEW", target = "net/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket$LookAndOnGround")) private PlayerMoveC2SPacket.LookAndOnGround wrapLookAndOnGround(float yaw, float pitch, boolean onGround, boolean horizontalCollision, Operation original) { - return original.call(moveEvent.getRotation().getYawF(), moveEvent.getRotation().getPitchF(), moveEvent.getOnGround(), moveEvent.isCollidingHorizontally()); + return original.call(yaw, pitch, moveEvent.getOnGround(), moveEvent.isCollidingHorizontally()); } @WrapOperation(method = "sendMovementPackets", at = @At(value = "NEW", target = "net/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket$OnGroundOnly"))