diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/EntityMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/EntityMixin.java index fc772cb46bd..f4d26e96d1f 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/EntityMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/EntityMixin.java @@ -23,6 +23,7 @@ import meteordevelopment.meteorclient.systems.modules.world.HighwayBuilder; import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerEntity; +import meteordevelopment.meteorclient.utils.player.Rotations; import net.minecraft.client.Camera; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.MoverType; @@ -107,6 +108,12 @@ private void onMove(MoverType moverType, Vec3 delta, CallbackInfo ci) { } } + @ModifyExpressionValue(method = "moveRelative", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;getYRot()F")) + private float moveRelativeYaw(float original) { + if ((Object) this == mc.player && Rotations.shouldCorrectPlayerInput()) return Rotations.serverYaw; + return original; + } + @ModifyExpressionValue(method = "getBlockSpeedFactor", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;getBlock()Lnet/minecraft/world/level/block/Block;")) private Block modifyBlockSpeedFactor(Block original) { if ((Object) this != mc.player) return original; diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/FireworkRocketEntityMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/FireworkRocketEntityMixin.java index 7edab1947cd..d393fca3810 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/FireworkRocketEntityMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/FireworkRocketEntityMixin.java @@ -5,17 +5,23 @@ package meteordevelopment.meteorclient.mixin; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.systems.modules.movement.ElytraBoost; +import meteordevelopment.meteorclient.utils.player.Rotations; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.projectile.FireworkRocketEntity; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import static meteordevelopment.meteorclient.MeteorClient.mc; + @Mixin(FireworkRocketEntity.class) public abstract class FireworkRocketEntityMixin { @Shadow @@ -24,6 +30,15 @@ public abstract class FireworkRocketEntityMixin { @Shadow private int lifetime; + @Shadow + private LivingEntity attachedToEntity; + + @ModifyExpressionValue(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getLookAngle()Lnet/minecraft/world/phys/Vec3;")) + private Vec3 fixRocketBoostDirection(Vec3 original) { + if (attachedToEntity == mc.player && mc.player != null && Rotations.shouldCorrectPlayerInput()) return Rotations.getServerDirection(); + return original; + } + @Inject(method = "tick", at = @At("TAIL")) private void onTick(CallbackInfo ci) { FireworkRocketEntity firework = ((FireworkRocketEntity) (Object) this); diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/ItemMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/ItemMixin.java index 31f45980051..551cf745709 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/ItemMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/ItemMixin.java @@ -5,11 +5,17 @@ package meteordevelopment.meteorclient.mixin; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.events.render.TooltipDataEvent; +import meteordevelopment.meteorclient.utils.player.Rotations; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -17,6 +23,8 @@ import java.util.Optional; +import static meteordevelopment.meteorclient.MeteorClient.mc; + @Mixin(Item.class) public abstract class ItemMixin { @Inject(method = "getTooltipImage", at = @At("HEAD"), cancellable = true) @@ -26,4 +34,10 @@ private void onTooltipData(ItemStack itemStack, CallbackInfoReturnable effect) { @ModifyExpressionValue(method = "jumpFromGround", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getYRot()F")) private float modifyGetYaw(float original) { if ((Object) this != mc.player) return original; + if (Rotations.shouldCorrectPlayerInput()) original = Rotations.serverYaw; if (!Modules.get().get(Sprint.class).rageSprint()) return original; float forward = Math.signum(mc.player.zza); @@ -141,4 +144,16 @@ private void onDropItem(ItemStack itemStack, boolean thrownFromHand, Prediction if (MeteorClient.EVENT_BUS.post(DropItemsEvent.get(itemStack)).isCancelled()) cir.setReturnValue(null); } } + + @ModifyExpressionValue(method = "updateFallFlyingMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getLookAngle()Lnet/minecraft/world/phys/Vec3;")) + private Vec3 fixFallFlyingLookAngle(Vec3 original) { + if ((Object) this == mc.player && Rotations.shouldCorrectPlayerInput()) return Rotations.getServerDirection(); + return original; + } + + @ModifyExpressionValue(method = "updateFallFlyingMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getXRot()F")) + private float fixFallFlyingPitch(float original) { + if ((Object) this == mc.player && Rotations.shouldCorrectPlayerInput()) return Rotations.serverPitch; + return original; + } } diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/LocalPlayerMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/LocalPlayerMixin.java index cebbd842957..b52722338ba 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/LocalPlayerMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/LocalPlayerMixin.java @@ -8,6 +8,8 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; import com.mojang.authlib.GameProfile; import meteordevelopment.meteorclient.MeteorClient; @@ -20,6 +22,7 @@ import meteordevelopment.meteorclient.systems.modules.player.Portals; import meteordevelopment.meteorclient.systems.modules.render.NoRender; import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerEntity; +import meteordevelopment.meteorclient.utils.player.Rotations; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.AbstractClientPlayer; @@ -103,6 +106,12 @@ private void preAiStep(CallbackInfo ci) { MeteorClient.EVENT_BUS.post(PlayerTickMovementEvent.get()); } + @WrapOperation(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/ClientInput;tick()V")) + private void wrapTick(ClientInput input, Operation original) { + original.call(input); + if (Rotations.shouldCorrectPlayerInput()) Rotations.setCorrectedPlayerInput(input); + } + @ModifyReturnValue(method = "getJumpRidingScale", at = @At("RETURN")) private float modifyJumpRidingScale(float original) { if (Modules.get().get(EntityControl.class).maxJump()) return 1f; diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/MultiPlayerGameModeMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/MultiPlayerGameModeMixin.java index c2014ac42d3..8270171a677 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/MultiPlayerGameModeMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/MultiPlayerGameModeMixin.java @@ -8,6 +8,7 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.events.entity.DropItemsEvent; import meteordevelopment.meteorclient.events.entity.player.*; @@ -15,6 +16,7 @@ import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.systems.modules.player.BreakDelay; import meteordevelopment.meteorclient.systems.modules.player.SpeedMine; +import meteordevelopment.meteorclient.utils.player.Rotations; import meteordevelopment.meteorclient.utils.world.BlockUtils; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.MultiPlayerGameMode; @@ -23,6 +25,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; +import net.minecraft.network.protocol.game.ServerboundUseItemPacket; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; @@ -153,6 +156,12 @@ private void onUseItem(Player player, InteractionHand hand, CallbackInfoReturnab if (event.toReturn != null) cir.setReturnValue(event.toReturn); } + @WrapOperation(method = "lambda$useItem$0", at = @At(value = "NEW", target = "(Lnet/minecraft/world/InteractionHand;IFF)Lnet/minecraft/network/protocol/game/ServerboundUseItemPacket;")) + private ServerboundUseItemPacket fixItemRotation(InteractionHand hand, int sequence, float yaw, float pitch, Operation original, @Local(argsOnly = true) Player player) { + if (player == mc.player && Rotations.rotating) return original.call(hand, sequence, Rotations.serverYaw, Rotations.serverPitch); + return original.call(hand, sequence, yaw, pitch); + } + @Inject(method = "stopDestroyBlock", at = @At("HEAD"), cancellable = true) private void onStopDestroyBlock(CallbackInfo ci) { if (BlockUtils.breaking) ci.cancel(); diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/PlayerMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/PlayerMixin.java index 8ac78b5cb0c..268f907288c 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/PlayerMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/PlayerMixin.java @@ -5,6 +5,7 @@ package meteordevelopment.meteorclient.mixin; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import meteordevelopment.meteorclient.MeteorClient; @@ -15,6 +16,7 @@ import meteordevelopment.meteorclient.systems.modules.movement.Sprint; import meteordevelopment.meteorclient.systems.modules.player.Reach; import meteordevelopment.meteorclient.systems.modules.player.SpeedMine; +import meteordevelopment.meteorclient.utils.player.Rotations; import meteordevelopment.meteorclient.utils.world.BlockUtils; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.EntityType; @@ -115,6 +117,12 @@ private void onGetFlyingSpeed(CallbackInfoReturnable cir) { return Modules.get().get(Sprint.class).stopSprinting(); } + @ModifyExpressionValue(method = {"causeExtraKnockback", "doSweepAttack"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;getYRot()F")) + private float fixAttackYaw(float original) { + if ((Object) this == mc.player && Rotations.shouldCorrectPlayerInput()) return Rotations.serverYaw; + return original; + } + @ModifyReturnValue(method = "blockInteractionRange", at = @At("RETURN")) private double modifyBlockInteractionRange(double original) { return Math.max(0, original + Modules.get().get(Reach.class).blockReach()); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/config/Config.java b/src/main/java/meteordevelopment/meteorclient/systems/config/Config.java index ba0d7db1543..0bef7fe70f7 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/config/Config.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/config/Config.java @@ -183,7 +183,14 @@ public class Config extends System { public final Setting rotationHoldTicks = sgMisc.add(new IntSetting.Builder() .name("rotation-hold") .description("Hold long to hold server side rotation when not sending any packets.") - .defaultValue(4) + .defaultValue(2) + .build() + ); + + public final Setting rotationMovementCorrection = sgMisc.add(new BoolSetting.Builder() + .name("rotation-movement-correction") + .description("Adjust player movement depending on server side rotation (Grim movefix).") + .defaultValue(true) .build() ); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java index 93c84ed52e8..83d6770d753 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java @@ -368,7 +368,7 @@ private void doBreak(FindItemResult glowStone) { renderBlockPos = bestBreakPos; if (rotate.get()) { - Rotations.rotate(Rotations.getYaw(bestBreakPos), Rotations.getPitch(bestBreakPos), 40, () -> doInteract(glowStone)); + Rotations.rotate(bestBreakPos, 40, () -> doInteract(glowStone)); } else { doInteract(glowStone); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AntiBed.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AntiBed.java index 21c87d083e6..1b8727675b2 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AntiBed.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AntiBed.java @@ -68,10 +68,10 @@ private void onTick(TickEvent.Pre event) { BlockPos head = mc.player.blockPosition().above(); if (mc.level.getBlockState(head).getBlock() instanceof BedBlock && !breaking) { - Rotations.rotate(Rotations.getYaw(head), Rotations.getPitch(head), 50, () -> sendMinePackets(head)); + Rotations.rotate(head, 50, () -> sendMinePackets(head)); breaking = true; } else if (breaking) { - Rotations.rotate(Rotations.getYaw(head), Rotations.getPitch(head), 50, () -> sendStopPackets(head)); + Rotations.rotate(head, 50, () -> sendStopPackets(head)); breaking = false; } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java index d7eb897d84a..cc2ecca35ba 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java @@ -27,6 +27,7 @@ import net.minecraft.world.item.BowItem; import net.minecraft.world.item.Items; import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.Vec2; import java.util.Set; @@ -126,7 +127,7 @@ private void onTick(TickEvent.Pre event) { wasPathing = true; } - aim(); + Rotations.rotate(() -> aim()); } } @@ -134,7 +135,9 @@ private boolean itemInHand() { return InvUtils.testInMainHand(Items.BOW, Items.CROSSBOW); } - private void aim() { + private Vec2 aim() { + if (target == null) return null; + // Velocity based on bow charge. float velocity = BowItem.getPowerForTime(mc.player.getTicksUsingItem()); @@ -154,9 +157,9 @@ private void aim() { // Set player rotation if (Float.isNaN(pitch)) { - Rotations.rotate(Rotations.getYaw(target), Rotations.getPitch(target)); + return new Vec2((float) Rotations.getYaw(target), (float) Rotations.getPitch(target)); } else { - Rotations.rotate(Rotations.getYaw(new Vec3(pos.x, pos.y, pos.z)), pitch); + return new Vec2((float) Rotations.getYaw(target), pitch); } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Burrow.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Burrow.java index 4ef08a7d367..67ec7ce8f91 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Burrow.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Burrow.java @@ -166,7 +166,7 @@ private void onTick(TickEvent.Pre event) { if (shouldBurrow) { if (rotate.get()) - Rotations.rotate(Rotations.getYaw(mc.player.blockPosition()), Rotations.getPitch(mc.player.blockPosition()), 50, this::burrow); + Rotations.rotate(mc.player.blockPosition(), 50, this::burrow); else burrow(); toggle(); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java index aeea4ad28f7..c6aca2fddb8 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java @@ -68,7 +68,7 @@ public class KillAura extends Module { .build() ); - private final Setting rotation = sgGeneral.add(new EnumSetting.Builder() + private final Setting rotate = sgGeneral.add(new EnumSetting.Builder() .name("rotate") .description("Determines when you should rotate towards the target.") .defaultValue(RotationMode.Always) @@ -350,14 +350,17 @@ private void onTick(TickEvent.Pre event) { } attacking = true; - if (rotation.get() == RotationMode.Always) - Rotations.rotate(Rotations.getYaw(primary), Rotations.getPitch(primary, Target.Body)); + if (pauseOnCombat.get() && PathManagers.get().isPathing() && !wasPathing) { PathManagers.get().pause(); wasPathing = true; } - if (delayCheck()) targets.forEach(this::attack); + if (rotate.get() == RotationMode.Always) { + Rotations.rotate(primary, 30, () -> attackTargets()); + } else { + attackTargets(); + } } @EventHandler @@ -456,11 +459,20 @@ private boolean delayCheck() { } else return true; } else return mc.player.getAttackStrengthScale(delay) >= 1; } + + private void attackTargets() { + if (!delayCheck()) return; - private void attack(Entity target) { - if (rotation.get() == RotationMode.OnHit) - Rotations.rotate(Rotations.getYaw(target), Rotations.getPitch(target, Target.Body)); + for (Entity target : targets) { + if (rotate.get() == RotationMode.OnHit) { + Rotations.rotate(target, 30, () -> attack(target)); + } else { + attack(target); + } + } + } + private void attack(Entity target) { mc.gameMode.attack(mc.player, target); SwingMode.Both.attackSwing(InteractionHand.MAIN_HAND); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Surround.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Surround.java index 62886fc86eb..30391b59485 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Surround.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Surround.java @@ -393,7 +393,7 @@ private boolean place(BlockPos placePos, FindItemResult block) { for (Entity crystal : mc.level.getEntities((Entity) null, box, entityPredicate)) { if (rotate.get()) { - Rotations.rotate(Rotations.getPitch(crystal), Rotations.getYaw(crystal), () -> { + Rotations.rotate(crystal, () -> { mc.player.connection.send(new ServerboundAttackPacket(crystal.getId())); }); } else { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notebot.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notebot.java index 783af50ff09..890b2ca1fa8 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notebot.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notebot.java @@ -850,7 +850,7 @@ private void tuneBlocks() { int hitsNumber = entry.getValue(); if (autoRotate.get()) { - Rotations.rotate(Rotations.getYaw(pos), Rotations.getPitch(pos), 100, () -> tuneNoteblockWithPackets(pos)); + Rotations.rotate(pos, () -> tuneNoteblockWithPackets(pos)); } else { this.tuneNoteblockWithPackets(pos); } @@ -900,7 +900,7 @@ private void onTickPlay() { BlockPos firstPos = noteBlockPositions.get(firstNote.get()); if (firstPos != null) { - Rotations.rotate(Rotations.getYaw(firstPos), Rotations.getPitch(firstPos)); + Rotations.rotate(firstPos, null); } } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/NoFall.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/NoFall.java index dad0eb93fae..bef69b347f3 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/NoFall.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/NoFall.java @@ -426,8 +426,7 @@ private void queueBucketUse(FindItemResult item, BlockHitResult hit, PlacedItem // Use reachable water before falling again, rather than waiting until after movement. boolean useNow = pickup || isWithinPlaceReach(hit.getLocation()); Vec3 aim = pickup ? Vec3.atCenterOf(hit.getBlockPos()) : hit.getLocation(); - if (rotate.get()) Rotations.rotate(Rotations.getYaw(aim), Rotations.getPitch(aim), - Integer.MAX_VALUE, true, useNow ? null : use); + if (rotate.get()) Rotations.rotate(aim, Integer.MAX_VALUE, useNow ? null : use); else if (!useNow) pendingBucketUse = use; if (useNow) use.run(); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/InstantRebreak.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/InstantRebreak.java index 80d93645f1c..5c5f1b8e54c 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/InstantRebreak.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/InstantRebreak.java @@ -106,7 +106,7 @@ private void onTick(TickEvent.Pre event) { if (shouldMine()) { if (rotate.get()) - Rotations.rotate(Rotations.getYaw(blockPos), Rotations.getPitch(blockPos), this::sendPacket); + Rotations.rotate(blockPos, this::sendPacket); else sendPacket(); mc.getConnection().send(new ServerboundPunchPacket()); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java index b397d9efb19..6664c141d37 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java @@ -244,18 +244,12 @@ private void onTick(TickEvent.Post event) { double velZ = 0; if (rotate.get()) { - BlockPos crossHairPos; - Vec3 crossHairPosition; - - if (mc.hitResult instanceof EntityHitResult ehr) { - crossHairPos = ehr.getEntity().blockPosition(); - Rotations.rotate(Rotations.getYaw(crossHairPos), Rotations.getPitch(crossHairPos), 0, null); + if (mc.hitResult instanceof EntityHitResult entityHitResult) { + Rotations.rotate(entityHitResult.getEntity(), null); } else { - crossHairPosition = mc.hitResult.getLocation(); - crossHairPos = ((BlockHitResult) mc.hitResult).getBlockPos(); - - if (!mc.level.getBlockState(crossHairPos).isAir()) { - Rotations.rotate(Rotations.getYaw(crossHairPosition), Rotations.getPitch(crossHairPosition), 0, null); + BlockPos crossHairBlockPos = ((BlockHitResult) mc.hitResult).getBlockPos(); + if (!mc.level.getBlockState(crossHairBlockPos).isAir()) { + Rotations.rotate(mc.hitResult.getLocation(), null); } } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoBreed.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoBreed.java index 4ca16461cb0..5e771625669 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoBreed.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoBreed.java @@ -101,7 +101,7 @@ private void onTick(TickEvent.Pre event) { || !animal.isFood(hand.get() == InteractionHand.MAIN_HAND ? mc.player.getMainHandItem() : mc.player.getOffhandItem())) continue; - Rotations.rotate(Rotations.getYaw(entity), Rotations.getPitch(entity), -100, () -> { + Rotations.rotate(entity, -100, () -> { EntityHitResult location = new EntityHitResult(animal, animal.getBoundingBox().getCenter()); mc.gameMode.interact(mc.player, animal, location, hand.get()); mc.player.swing(hand.get(), mc.player.getItemInHand(hand.get()).getInteractAnimation(), false); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoMount.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoMount.java index 146fac5e0e7..7d1e9b25701 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoMount.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoMount.java @@ -80,7 +80,7 @@ private void onTick(TickEvent.Pre event) { private void interact(Entity entity, boolean rotate) { if (rotate) { - Rotations.rotate(Rotations.getYaw(entity), Rotations.getPitch(entity), -100, () -> interact(entity)); + Rotations.rotate(entity, -100, () -> interact(entity)); } else { interact(entity); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java index bc73ccd6738..28b8c89ec07 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java @@ -111,7 +111,7 @@ private void onTickPre(TickEvent.Pre event) { offHand = findNametag.isOffhand(); // Interaction - if (rotate.get()) Rotations.rotate(Rotations.getYaw(target), Rotations.getPitch(target), -100, this::interact); + if (rotate.get()) Rotations.rotate(target, -100, this::interact); else interact(); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoShearer.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoShearer.java index 0f3fafe75e7..15222f2b4d1 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoShearer.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoShearer.java @@ -75,7 +75,7 @@ private void onTick(TickEvent.Pre event) { this.entity = entity; if (rotate.get()) - Rotations.rotate(Rotations.getYaw(entity), Rotations.getPitch(entity), -100, this::interact); + Rotations.rotate(entity, -100, this::interact); else interact(); return; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java index bf882888843..9e2ad6d46d2 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java @@ -1302,7 +1302,7 @@ protected void tick(HighwayBuilder b) { if (!EChestMemory.isKnown()) { BlockHitResult bhr = new BlockHitResult(Vec3.atCenterOf(bp), Direction.UP, bp, false); - if (b.rotation.get().place) Rotations.rotate(Rotations.getYaw(bp), Rotations.getPitch(bp), () -> BlockUtils.interact(bhr, InteractionHand.MAIN_HAND, true)); + if (b.rotation.get().place) Rotations.rotate(bp, () -> BlockUtils.interact(bhr, InteractionHand.MAIN_HAND, true)); else BlockUtils.interact(bhr, InteractionHand.MAIN_HAND, true); return; @@ -1339,7 +1339,7 @@ protected void tick(HighwayBuilder b) { rebreakTimer = b.rebreakTimer.get(); if (b.rotation.get().mine) { - Rotations.rotate(Rotations.getYaw(bp), Rotations.getPitch(bp), () -> + Rotations.rotate(bp, () -> b.mc.gameMode.startPrediction(b.mc.level, sequence -> new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK, bp, BlockUtils.getDirection(bp), sequence) ) @@ -1349,7 +1349,7 @@ protected void tick(HighwayBuilder b) { ); } else { if (b.rotation.get().mine) - Rotations.rotate(Rotations.getYaw(bp), Rotations.getPitch(bp), () -> BlockUtils.breakBlock(bp, true)); + Rotations.rotate(bp, () -> BlockUtils.breakBlock(bp, true)); else BlockUtils.breakBlock(bp, true); } } else { @@ -1690,13 +1690,13 @@ private void handleContainerBlock(HighwayBuilder b, BlockPos bp) { InvUtils.swap(toolSlot, false); if (b.rotation.get().mine) - Rotations.rotate(Rotations.getYaw(bp), Rotations.getPitch(bp), () -> BlockUtils.breakBlock(bp, true)); + Rotations.rotate(bp, () -> BlockUtils.breakBlock(bp, true)); else BlockUtils.breakBlock(bp, true); } else { BlockHitResult bhr = new BlockHitResult(Vec3.atCenterOf(bp), Direction.UP, bp, false); if (b.rotation.get().place) - Rotations.rotate(Rotations.getYaw(bp), Rotations.getPitch(bp), () -> BlockUtils.interact(bhr, InteractionHand.MAIN_HAND, true)); + Rotations.rotate(bp, () -> BlockUtils.interact(bhr, InteractionHand.MAIN_HAND, true)); else BlockUtils.interact(bhr, InteractionHand.MAIN_HAND, true); delayTimer = b.inventoryDelay.get(); @@ -1939,7 +1939,7 @@ protected void mine(HighwayBuilder b, MBPIterator it, boolean mineBlocksToPlace, boolean multiBreak = b.blocksPerTick.get() > 1 && BlockUtils.canInstaBreak(mcPos) && !b.rotation.get().mine; if (BlockUtils.canBreak(mcPos)) { if (b.rotation.get().mine) - Rotations.rotate(Rotations.getYaw(mcPos), Rotations.getPitch(mcPos), () -> BlockUtils.breakBlock(mcPos, true)); + Rotations.rotate(mcPos, () -> BlockUtils.breakBlock(mcPos, true)); else BlockUtils.breakBlock(mcPos, true); breaking = true; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java index 65bfa42b261..cd4a83ca158 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java @@ -490,7 +490,7 @@ else if (sortMode.get() != SortMode.None) boolean canInstaMine = BlockUtils.canInstaBreak(block); if (rotate.get()) - Rotations.rotate(Rotations.getYaw(block), Rotations.getPitch(block), () -> breakBlock(block)); + Rotations.rotate(block, () -> breakBlock(block)); else breakBlock(block); if (enableRenderBreaking.get()) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/PacketMine.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/PacketMine.java index 94af0ebcd3f..0830deee63b 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/PacketMine.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/PacketMine.java @@ -242,7 +242,7 @@ public double progress() { public void mine() { if (rotate.get()) - Rotations.rotate(Rotations.getYaw(blockPos), Rotations.getPitch(blockPos), 50, this::sendMinePackets); + Rotations.rotate(blockPos, 50, this::sendMinePackets); else sendMinePackets(); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/VeinMiner.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/VeinMiner.java index 91392b09416..7315af0aebc 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/VeinMiner.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/VeinMiner.java @@ -226,7 +226,7 @@ public void mine() { mining = true; } if (rotate.get()) - Rotations.rotate(Rotations.getYaw(blockPos), Rotations.getPitch(blockPos), 50, this::updateBlockBreakingProgress); + Rotations.rotate(blockPos, this::updateBlockBreakingProgress); else updateBlockBreakingProgress(); } diff --git a/src/main/java/meteordevelopment/meteorclient/utils/player/Rotations.java b/src/main/java/meteordevelopment/meteorclient/utils/player/Rotations.java index fd562c33c0e..15c366be2f2 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/player/Rotations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/player/Rotations.java @@ -11,31 +11,32 @@ import meteordevelopment.meteorclient.systems.config.Config; import meteordevelopment.meteorclient.utils.PreInit; import meteordevelopment.meteorclient.utils.entity.Target; -import meteordevelopment.meteorclient.utils.misc.Pool; import meteordevelopment.orbit.EventHandler; +import meteordevelopment.orbit.EventPriority; +import net.minecraft.client.player.ClientInput; import net.minecraft.core.BlockPos; import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Input; +import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import java.util.ArrayList; +import java.util.function.Supplier; import java.util.List; import static meteordevelopment.meteorclient.MeteorClient.mc; public class Rotations { - private static final Pool rotationPool = new Pool<>(Rotation::new); + private static final List queue = new ArrayList<>(); private static final List rotations = new ArrayList<>(); - public static float serverYaw; - public static float serverPitch; - public static int rotationTimer; private static float preYaw, prePitch; - private static int i = 0; + public static float serverYaw, serverPitch; private static Rotation lastRotation; private static int lastRotationTimer; - private static boolean sentLastRotation; + public static boolean rotating = false; private Rotations() { @@ -46,140 +47,189 @@ public static void init() { MeteorClient.EVENT_BUS.subscribe(Rotations.class); } - public static void rotate(double yaw, double pitch, int priority, boolean clientSide, Runnable callback) { - Rotation rotation = rotationPool.get(); - rotation.set(yaw, pitch, priority, clientSide, callback); - + // Rotation Setup + + private static void rotate(Rotation rotation) { int i = 0; - for (; i < rotations.size(); i++) { - if (priority > rotations.get(i).priority) break; + for (; i < queue.size(); i++) { + if (rotation.priority > queue.get(i).priority) break; } - rotations.add(i, rotation); + queue.add(i, rotation); + } + + @Deprecated // clientSide boolean is no longer used. + public static void rotate(double yaw, double pitch, int priority, boolean clientSide, Runnable callback) { + rotate(new Rotation(yaw, pitch, priority, callback)); } public static void rotate(double yaw, double pitch, int priority, Runnable callback) { - rotate(yaw, pitch, priority, false, callback); + rotate(new Rotation(yaw, pitch, priority, callback)); } public static void rotate(double yaw, double pitch, Runnable callback) { - rotate(yaw, pitch, 0, callback); + rotate(new Rotation(yaw, pitch, 0, callback)); } public static void rotate(double yaw, double pitch, int priority) { - rotate(yaw, pitch, priority, null); + rotate(new Rotation(yaw, pitch, priority, null)); } public static void rotate(double yaw, double pitch) { - rotate(yaw, pitch, 0, null); + rotate(new Rotation(yaw, pitch, 0, null)); } - private static void resetLastRotation() { - if (lastRotation != null) { - rotationPool.free(lastRotation); + public static void rotate(Entity entity, int priority, Runnable callback) { + rotate(new Rotation(entity, priority, callback)); + } - lastRotation = null; - lastRotationTimer = 0; - } + public static void rotate(Entity entity, Runnable callback) { + rotate(new Rotation(entity, 0, callback)); } - @EventHandler - private static void onSendMovementPacketsPre(SendMovementPacketsEvent.Pre event) { - if (mc.getCameraEntity() != mc.player) return; - sentLastRotation = false; + public static void rotate(Vec3 position, int priority, Runnable callback) { + rotate(new Rotation(position, priority, callback)); + } - if (!rotations.isEmpty()) { - rotating = true; - resetLastRotation(); + public static void rotate(Vec3 position, Runnable callback) { + rotate(new Rotation(position, 0, callback)); + } - Rotation rotation = rotations.get(i); - setupMovementPacketRotation(rotation); + public static void rotate(BlockPos blockPos, int priority, Runnable callback) { + rotate(new Rotation(Vec3.atCenterOf(blockPos), priority, callback)); + } - if (rotations.size() > 1) rotationPool.free(rotation); + public static void rotate(BlockPos blockPos, Runnable callback) { + rotate(new Rotation(Vec3.atCenterOf(blockPos), 0, callback)); + } - i++; - } else if (lastRotation != null) { - if (lastRotationTimer >= Config.get().rotationHoldTicks.get()) { - resetLastRotation(); - rotating = false; - } else { - setupMovementPacketRotation(lastRotation); - sentLastRotation = true; + public static void rotate(int priority, Supplier calculate, Runnable callback) { + rotate(new Rotation(priority, calculate, callback)); + } - lastRotationTimer++; - } - } + public static void rotate(Supplier calculate, Runnable callback) { + rotate(new Rotation(0, calculate, callback)); } - private static void setupMovementPacketRotation(Rotation rotation) { - setClientRotation(rotation); - setCamRotation(rotation.yaw, rotation.pitch); + public static void rotate(Supplier calculate) { + rotate(new Rotation(0, calculate, null)); } - private static void setClientRotation(Rotation rotation) { + // Rotation Execution + + private static void setPreRotation() { preYaw = mc.player.getYRot(); prePitch = mc.player.getXRot(); + } - mc.player.setYRot((float) rotation.yaw); - mc.player.setXRot((float) rotation.pitch); + private static void setClientRotation(float yaw, float pitch) { + mc.player.setYRot(yaw); + mc.player.setXRot(pitch); } - @EventHandler - private static void onSendMovementPacketsPost(SendMovementPacketsEvent.Post event) { - if (!rotations.isEmpty()) { - if (mc.getCameraEntity() == mc.player) { - rotations.get(i - 1).runCallback(); + private static void setServerRotation(float yaw, float pitch) { + serverYaw = yaw; + serverPitch = pitch; + } - if (rotations.size() == 1) lastRotation = rotations.get(i - 1); + @EventHandler(priority = EventPriority.LOWEST - 700) + private static void onTickPre(TickEvent.Pre event) { + rotating = false; - resetPreRotation(); + if (lastRotation != null) { + if (lastRotationTimer++ >= Config.get().rotationHoldTicks.get()) { + lastRotation = null; + lastRotationTimer = 0; + } else if (queue.isEmpty()) { + queue.add(lastRotation); } + } - for (; i < rotations.size(); i++) { - Rotation rotation = rotations.get(i); - - setCamRotation(rotation.yaw, rotation.pitch); - if (rotation.clientSide) setClientRotation(rotation); - rotation.sendPacket(); - if (rotation.clientSide) resetPreRotation(); + if (!queue.isEmpty()) { + rotating = true; - if (i == rotations.size() - 1) lastRotation = rotation; - else rotationPool.free(rotation); - } + // Set the server rotation early so movefix inputs compensate. + Rotation last = queue.get(queue.size() - 1); + setServerRotation(last.yaw, last.pitch); - rotations.clear(); - i = 0; - } else if (sentLastRotation) { - resetPreRotation(); + rotations.addAll(queue); + queue.clear(); } } - private static void resetPreRotation() { - mc.player.setYRot(preYaw); - mc.player.setXRot(prePitch); + @EventHandler + private static void onSendMovementPacketsPre(SendMovementPacketsEvent.Pre event) { + if (rotations.isEmpty()) return; + + // Recalculate yaw and pitch due to entities moving around. + if (!Config.get().rotationMovementCorrection.get()) { + rotations.forEach(Rotation::recalculate); + } + + // The first rotation is sent within our normal movement packets + Rotation first = rotations.get(0); + setPreRotation(); + setServerRotation(first.yaw, first.pitch); + setClientRotation(first.yaw, first.pitch); } @EventHandler - private static void onTick(TickEvent.Pre event) { - rotationTimer++; + private static void onSendMovementPacketsPost(SendMovementPacketsEvent.Post event) { + if (rotations.isEmpty()) return; + + // First rotation packet was already sent to server naturally. + Rotation first = rotations.get(0); + setClientRotation(first.yaw, first.pitch); + first.runCallback(); + + // All subsequent rotations require a packet sent + for (int i = 1; i < rotations.size(); i++) { + Rotation rotation = rotations.get(i); + setServerRotation(rotation.yaw, rotation.pitch); + setClientRotation(rotation.yaw, rotation.pitch); + rotation.sendPacket(); + rotation.runCallback(); + } + + setClientRotation(preYaw, prePitch); + + Rotation lastIndexRotation = rotations.get(rotations.size() - 1); + if (lastIndexRotation != lastRotation) { + lastRotation = lastIndexRotation; + lastRotation.callback = null; + lastRotationTimer = 0; + rotating = Config.get().rotationHoldTicks.get() > 0; + } + + rotations.clear(); } - public static double getYaw(Entity entity) { - return mc.player.getYRot() + Mth.wrapDegrees((float) Math.toDegrees(Math.atan2(entity.getZ() - mc.player.getZ(), entity.getX() - mc.player.getX())) - 90f - mc.player.getYRot()); + // Utilities + + public static double getYaw(double x, double z) { + return Mth.wrapDegrees((float) Math.toDegrees(Math.atan2(z - mc.player.getZ(), x - mc.player.getX())) - 90f); + } + + public static double getPitch(double x, double y, double z) { + double diffX = x - mc.player.getX(); + double diffY = y - mc.player.getEyeY(); + double diffZ = z - mc.player.getZ(); + + double diffXZ = Math.hypot(diffX, diffZ); + + return Mth.wrapDegrees((float) -Math.toDegrees(Math.atan2(diffY, diffXZ))); } public static double getYaw(Vec3 pos) { - return mc.player.getYRot() + Mth.wrapDegrees((float) Math.toDegrees(Math.atan2(pos.z() - mc.player.getZ(), pos.x() - mc.player.getX())) - 90f - mc.player.getYRot()); + return getYaw(pos.x(), pos.z()); } public static double getPitch(Vec3 pos) { - double diffX = pos.x() - mc.player.getX(); - double diffY = pos.y() - (mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose())); - double diffZ = pos.z() - mc.player.getZ(); - - double diffXZ = Math.sqrt(diffX * diffX + diffZ * diffZ); + return getPitch(pos.x(), pos.y(), pos.z()); + } - return mc.player.getXRot() + Mth.wrapDegrees((float) -Math.toDegrees(Math.atan2(diffY, diffXZ)) - mc.player.getXRot()); + public static double getYaw(Entity entity) { + return getYaw(entity.getX(), entity.getZ()); } public static double getPitch(Entity entity, Target target) { @@ -189,13 +239,7 @@ public static double getPitch(Entity entity, Target target) { case Feet -> entity.getY(); }; - double diffX = entity.getX() - mc.player.getX(); - double diffY = y - (mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose())); - double diffZ = entity.getZ() - mc.player.getZ(); - - double diffXZ = Math.sqrt(diffX * diffX + diffZ * diffZ); - - return mc.player.getXRot() + Mth.wrapDegrees((float) -Math.toDegrees(Math.atan2(diffY, diffXZ)) - mc.player.getXRot()); + return getPitch(entity.getX(), y, entity.getZ()); } public static double getPitch(Entity entity) { @@ -203,42 +247,121 @@ public static double getPitch(Entity entity) { } public static double getYaw(BlockPos pos) { - return mc.player.getYRot() + Mth.wrapDegrees((float) Math.toDegrees(Math.atan2(pos.getZ() + 0.5 - mc.player.getZ(), pos.getX() + 0.5 - mc.player.getX())) - 90f - mc.player.getYRot()); + return getYaw(pos.getX() + 0.5, pos.getZ() + 0.5); } public static double getPitch(BlockPos pos) { - double diffX = pos.getX() + 0.5 - mc.player.getX(); - double diffY = pos.getY() + 0.5 - (mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose())); - double diffZ = pos.getZ() + 0.5 - mc.player.getZ(); + return getPitch(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5); + } - double diffXZ = Math.sqrt(diffX * diffX + diffZ * diffZ); + /** + * setCorrectedPlayerInput and getInputFromRelativeYaw are derived from Lambda Client. + * @see https://github.com/lambda-client/lambda/blob/1.21.11/src/main/kotlin/com/lambda/util/player/RotationUtils.kt + * @author dinosaurwizard + * + * Implementation of Grim movefix logic. + **/ - return mc.player.getXRot() + Mth.wrapDegrees((float) -Math.toDegrees(Math.atan2(diffY, diffXZ)) - mc.player.getXRot()); + public static boolean shouldCorrectPlayerInput() { + return rotating && Config.get().rotationMovementCorrection.get(); } - public static void setCamRotation(double yaw, double pitch) { - serverYaw = (float) yaw; - serverPitch = (float) pitch; - rotationTimer = 0; + public static Vec3 getServerDirection() { + return Vec3.directionFromRotation(serverPitch, serverYaw); + } + + public static void setCorrectedPlayerInput(ClientInput input) { + input.keyPresses = getInputFromRelativeYaw(input.keyPresses); + + // The movement vector must be adjusted according to the new input. + int x = (input.keyPresses.left() ? 1 : 0) - (input.keyPresses.right() ? 1 : 0); + int y = (input.keyPresses.forward() ? 1 : 0) - (input.keyPresses.backward() ? 1 : 0); + input.moveVector = new Vec2(x, y).normalized(); + } + + private static Input getInputFromRelativeYaw(Input input) { + int strafe = (input.left() ? 1 : 0) - (input.right() ? 1 : 0); + int forward = (input.forward() ? 1 : 0) - (input.backward() ? 1 : 0); + if (strafe == 0 && forward == 0) return input; + + double deltaYawRad = Math.toRadians(mc.player.getYRot() - serverYaw); + double cos = Math.cos(deltaYawRad); + double sin = Math.sin(deltaYawRad); + double newStrafe = strafe * cos - forward * sin; + double newForward = strafe * sin + forward * cos; + double angle = Math.atan2(newStrafe, newForward); + double sector = Math.PI / 4.0; + double boundary = Math.PI / 8.0; + + boolean pressForward = false; + boolean pressBackward = false; + boolean pressLeft = false; + boolean pressRight = false; + + if (angle > -boundary && angle <= boundary) { + pressForward = true; + } else if (angle > boundary && angle <= boundary + sector) { + pressForward = true; + pressLeft = true; + } else if (angle > boundary + sector && angle <= boundary + 2 * sector) { + pressLeft = true; + } else if (angle > boundary + 2 * sector && angle <= boundary + 3 * sector) { + pressBackward = true; + pressLeft = true; + } else if (angle > boundary + 3 * sector || angle <= -(boundary + 3 * sector)) { + pressBackward = true; + } else if (angle > -(boundary + 3 * sector) && angle <= -(boundary + 2 * sector)) { + pressBackward = true; + pressRight = true; + } else if (angle > -(boundary + 2 * sector) && angle <= -(boundary + sector)) { + pressRight = true; + } else if (angle > -(boundary + sector) && angle <= -boundary) { + pressForward = true; + pressRight = true; + } + + return new Input(pressForward, pressBackward, pressLeft, pressRight, input.jump(), input.shift(), input.sprint()); } private static class Rotation { - public double yaw, pitch; + public float yaw, pitch; public int priority; - public boolean clientSide; public Runnable callback; + public Supplier calculate; - public void set(double yaw, double pitch, int priority, boolean clientSide, Runnable callback) { - this.yaw = yaw; - this.pitch = pitch; + public Rotation(double yaw, double pitch, int priority, Runnable callback) { + this.yaw = (float) yaw; + this.pitch = (float) pitch; this.priority = priority; - this.clientSide = clientSide; this.callback = callback; } + public Rotation(int priority, Supplier calculate, Runnable callback) { + this(0, 0, priority, callback); + this.calculate = calculate; + recalculate(); + } + + public Rotation(Vec3 position, int priority, Runnable callback) { + this(priority, () -> new Vec2((float) getYaw(position), (float) getPitch(position)), callback); + } + + public Rotation(Entity entity, int priority, Runnable callback) { + this(priority, () -> new Vec2((float) getYaw(entity), (float) getPitch(entity)), callback); + } + + public void recalculate() { + if (calculate != null) { + Vec2 result = calculate.get(); + if (result != null) { + this.yaw = result.x; + this.pitch = result.y; + } + } + } + public void sendPacket() { - mc.getConnection().send(new ServerboundMovePlayerPacket.Rot((float) yaw, (float) pitch, mc.player.onGround(), mc.player.horizontalCollision)); - runCallback(); + mc.getConnection().send(new ServerboundMovePlayerPacket.Rot(yaw, pitch, mc.player.onGround(), mc.player.horizontalCollision)); } public void runCallback() { diff --git a/src/main/java/meteordevelopment/meteorclient/utils/world/BlockUtils.java b/src/main/java/meteordevelopment/meteorclient/utils/world/BlockUtils.java index 44b6d3444dd..57c120f51cd 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/world/BlockUtils.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/world/BlockUtils.java @@ -111,7 +111,7 @@ public static boolean place(BlockPos blockPos, InteractionHand hand, int slot, b BlockHitResult bhr = new BlockHitResult(hitPos, side.getOpposite(), neighbour, false); if (rotate) { - Rotations.rotate(Rotations.getYaw(hitPos), Rotations.getPitch(hitPos), rotationPriority, () -> { + Rotations.rotate(hitPos, rotationPriority, () -> { InvUtils.swap(slot, swapBack); interact(bhr, hand, swingHand); diff --git a/src/main/resources/meteor-client.classtweaker b/src/main/resources/meteor-client.classtweaker index 66a57a1d0bc..890905d8af7 100644 --- a/src/main/resources/meteor-client.classtweaker +++ b/src/main/resources/meteor-client.classtweaker @@ -43,3 +43,6 @@ accessible method com/mojang/renderpearl/api/pipeline/RenderPipeline$Builder