diff --git a/src/main/java/com/lambda/mixin/accessor/network/AccessorNetHandlerPlayClient.java b/src/main/java/com/lambda/mixin/accessor/network/AccessorNetHandlerPlayClient.java new file mode 100644 index 000000000..a389283c8 --- /dev/null +++ b/src/main/java/com/lambda/mixin/accessor/network/AccessorNetHandlerPlayClient.java @@ -0,0 +1,15 @@ +package com.lambda.mixin.accessor.network; + +import net.minecraft.client.network.NetHandlerPlayClient; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(value = NetHandlerPlayClient.class) +public interface AccessorNetHandlerPlayClient { + + @Accessor(value = "doneLoadingTerrain") + boolean isDoneLoadingTerrain(); + + @Accessor(value = "doneLoadingTerrain") + void setDoneLoadingTerrain(boolean loaded); +} diff --git a/src/main/kotlin/com/lambda/client/module/modules/movement/ElytraFlight2b2t.kt b/src/main/kotlin/com/lambda/client/module/modules/movement/ElytraFlight2b2t.kt new file mode 100644 index 000000000..cede1611f --- /dev/null +++ b/src/main/kotlin/com/lambda/client/module/modules/movement/ElytraFlight2b2t.kt @@ -0,0 +1,383 @@ +package com.lambda.client.module.modules.movement + +import baritone.api.pathing.goals.GoalXZ +import com.lambda.client.event.SafeClientEvent +import com.lambda.client.event.events.ConnectionEvent +import com.lambda.client.event.events.PacketEvent +import com.lambda.client.event.events.PlayerMoveEvent +import com.lambda.client.event.events.PlayerTravelEvent +import com.lambda.client.manager.managers.PlayerPacketManager.sendPlayerPacket +import com.lambda.client.manager.managers.TimerManager.modifyTimer +import com.lambda.client.manager.managers.TimerManager.resetTimer +import com.lambda.client.module.Category +import com.lambda.client.module.Module +import com.lambda.client.module.modules.player.ViewLock +import com.lambda.client.util.BaritoneUtils +import com.lambda.client.util.MovementUtils.setSpeed +import com.lambda.client.util.TickTimer +import com.lambda.client.util.TimeUnit +import com.lambda.client.util.text.MessageSendHelper +import com.lambda.client.util.threads.defaultScope +import com.lambda.client.util.threads.safeListener +import com.lambda.client.util.world.getGroundPos +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import net.minecraft.init.Items +import net.minecraft.network.play.client.CPacketEntityAction +import net.minecraft.network.play.client.CPacketPlayer +import net.minecraft.network.play.server.SPacketPlayerPosLook +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Vec2f +import net.minecraft.util.math.Vec3d +import net.minecraftforge.client.event.InputUpdateEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import kotlin.math.max +import kotlin.math.min + +object ElytraFlight2b2t : Module( + name = "ElytraFlight2b2t", + description = "Go very fast on 2b2t", + category = Category.MOVEMENT, + modulePriority = 1000 +) { + private val takeoffTimerSpeed by setting("Takeoff Timer Tick Length", 395.0f, 100.0f..1000.0f, 5.0f, + description = "How long each timer tick is during redeploy (ms). Lower length = faster timer. " + + "Try increasing this if experiencing elytra timeout or rubberbands. This value is multiplied by 2 when setting timer", unit = "ms") + private val baritoneBlockagePathing by setting("Baritone Blockage Pathing", true, + description = "Use baritone to path around blockages on the highway.") + private val baritonePathForwardBlocks by setting("Baritone Path Distance", 20, 1..50, 1, + visibility = { baritoneBlockagePathing }) + private val baritoneEndDelayMs by setting("Baritone End Pathing Delay", 500, 0..2000, 50, + visibility = { baritoneBlockagePathing }, unit = "ms") + private val baritoneStartDelayMs by setting("Baritone Start Delay", 500, 0..2000, 50, + visibility = { baritoneBlockagePathing }, unit = "ms") + private val midairFallFly by setting("Mid-flight Packet Deploy", true, + description = "Uses packets to redeploy when mid-flight.") + private val autoFlyForward by setting("Auto Fly Forward", true, + description = "Automatically move forward when flying.") + private val rubberBandDetectionTime by setting("Rubberband Detection Time", 1110, 0..2000, 10, + description = "Time period (ms) between which to detect rubberband teleports. Lower period = more sensitive.", unit = "ms") + private val enableBoost by setting("Enable Boost", true, + description = "Enable boost during mid-air flight.") + private val boostDelayTicks by setting("Boost Delay", 11, 1..200, 1, + visibility = { enableBoost }, unit = "ticks", + description = "Number of ticks to wait before beginning boost") + private val boostSpeedIncrease by setting("Boost Speed Increase", 0.65, 0.0..2.0, 0.01, + visibility = { enableBoost }, + description = "Boost speed increase per tick (blocks per second / 2)") + private val initialFlightSpeed by setting("Initial Flight Speed", 39.5, 35.0..80.0, 0.01, + description = "Speed to start at for first successful deployment (blocks per second / 2).") + private val speedMax by setting("Speed Max", 100.0, 40.0..100.0, 0.1, + description = "Max flight speed (blocks per second / 2).") + private val redeploySpeedDecreaseFactor by setting("Redeploy Speed Dec Factor", 1.1, 1.0..2.0, 0.01, + description = "Decreases speed by a set factor during redeploys. Value is a divisor on current speed.") + private val avoidUnloaded by setting("Avoid Unloaded", true, + description = "Preserves speed while flying into unloaded chunks") + private val autoViewLockManage by setting("Auto ViewLock Manage", true, + description = "Automatically configures and toggles viewlock for straight flight on highways.") + + private const val TAKE_OFF_Y_VELOCITY = -0.16976 // magic number - do not question + private const val MAGIC_PITCH = -2.52f + private const val JUMP_DELAY = 10 + + private var currentState = State.PAUSED + private var isFlying = false + private var isBaritoning = false + + private var timer = TickTimer(TimeUnit.TICKS) + private var lastSPacketPlayerPosLook = Long.MIN_VALUE + private var lastRubberband = Long.MIN_VALUE + private var baritoneStartTime = 0L + private var baritoneEndPathingTime = 0L + + private var shouldStartBoosting = false + private var elytraIsEquipped = false + private var wasInLiquid = false + private var isStandingStill = false + private var startedFlying = false + private var stoppedFlying = false + private var nextBlockMoveLoaded = true + + private var elytraDurability = 0 + private var flyTickCount = 0 + private var flyBlockedTickCount = 0 + private var currentFlightSpeed = 40.2 + + private var flyPlayerLastPos = Vec3d.ZERO + private var beforePathingPlayerPitchYaw = Vec2f.ZERO + private var motionPrev = Vec2f(0.0f, 0.0f) + + private var scheduleBaritoneJob: Job? = null + + enum class State { + FLYING, TAKEOFF, PAUSED, WALKING + } + + override fun getHudInfo() = currentState.name + + init { + onEnable { + currentState = State.PAUSED + timer.reset() + shouldStartBoosting = false + lastRubberband = Long.MIN_VALUE + if (autoViewLockManage) configureViewLock() + } + + onDisable { + currentState = State.PAUSED + resetFlightSpeed() + BaritoneUtils.cancelEverything() + shouldStartBoosting = false + resetTimer() + wasInLiquid = false + isFlying = false + if (autoViewLockManage) ViewLock.disable() + } + + safeListener { + disable() + } + + safeListener(priority = 9999) { + if (it.phase != TickEvent.Phase.END) return@safeListener + when (currentState) { + State.PAUSED -> { + val armorSlot = player.inventory.armorInventory[2] + elytraIsEquipped = armorSlot.item == Items.ELYTRA + if (!elytraIsEquipped) { + MessageSendHelper.sendChatMessage("No Elytra equipped") + disable() + return@safeListener + } + if (armorSlot.maxDamage <= 1) { + MessageSendHelper.sendChatMessage("Equipped Elytra broken or almost broken") + disable() + return@safeListener + } + currentState = State.TAKEOFF + } + State.WALKING -> { + if (autoViewLockManage && ViewLock.isEnabled) ViewLock.disable() + if (scheduleBaritoneJob?.isActive == true) return@safeListener + if (BaritoneUtils.isActive) { + isBaritoning = true + return@safeListener + } + // delay takeoff if we were pathing + if (isBaritoning) { + baritoneEndPathingTime = System.currentTimeMillis() + player.rotationPitch = beforePathingPlayerPitchYaw.x + player.rotationYaw = beforePathingPlayerPitchYaw.y + isBaritoning = false + return@safeListener + } + if (System.currentTimeMillis() - baritoneEndPathingTime < baritoneEndDelayMs) return@safeListener + currentState = State.TAKEOFF + } + State.TAKEOFF -> { + if (autoViewLockManage && ViewLock.isDisabled) ViewLock.enable() + resetTimer() + shouldStartBoosting = false + resetFlightSpeed() + if (baritoneBlockagePathing && player.onGround && timer.tick(JUMP_DELAY.toLong())) player.jump() + if ((withinRange(player.motionY)) && !player.isElytraFlying) { + timer.reset() + currentState = State.FLYING + } else if (midairFallFly && player.isElytraFlying) { + connection.sendPacket(CPacketPlayer(true)) + } + } + State.FLYING -> { + if (autoViewLockManage && ViewLock.isDisabled) ViewLock.enable() + if (!player.isElytraFlying && flyTickCount++ > 30) { + pathForward() + currentState = State.WALKING + } else flyTickCount = 0 + val playerCurrentPos = player.positionVector + if (!avoidUnloaded || (avoidUnloaded && nextBlockMoveLoaded)) { + if (playerCurrentPos.distanceTo(flyPlayerLastPos) < 2.0) { + if (flyBlockedTickCount++ > 20) { + pathForward() + currentState = State.WALKING + } + } else flyBlockedTickCount = 0 + } + flyPlayerLastPos = playerCurrentPos + if (!enableBoost) return@safeListener + if (shouldStartBoosting) { + if (avoidUnloaded) { + if (nextBlockMoveLoaded && isFlying) { + setFlightSpeed(currentFlightSpeed + boostSpeedIncrease) + } + } else setFlightSpeed(currentFlightSpeed + boostSpeedIncrease) + } else if (timer.tick(boostDelayTicks, true)) shouldStartBoosting = true + } + } + } + + safeListener { + if (it.packet !is SPacketPlayerPosLook || currentState != State.FLYING) return@safeListener + timer.reset() + if (System.currentTimeMillis() - lastSPacketPlayerPosLook < rubberBandDetectionTime.toLong()) { + resetFlightSpeed() + shouldStartBoosting = false + resetTimer() + wasInLiquid = false + isFlying = false + currentState = if (baritoneBlockagePathing) { + pathForward() + State.WALKING + } else State.TAKEOFF + lastRubberband = System.currentTimeMillis() + } + lastSPacketPlayerPosLook = System.currentTimeMillis() + } + + safeListener { + if (avoidUnloaded && !nextBlockMoveLoaded && it.packet is CPacketPlayer) it.cancel() + } + + safeListener { + stateUpdate() + if (currentState == State.FLYING && elytraIsEquipped && elytraDurability > 1) { + if (stoppedFlying) setFlightSpeed(currentFlightSpeed / redeploySpeedDecreaseFactor) + if (isFlying) { + resetTimer() + player.isSprinting = false + } else takeoff(it) + } + // rotation spoof also kicks us out of elytra during glide takeoffs due to rotation not matching flight speed + spoofRotation() + } + + safeListener { + if (currentState == State.FLYING) { + if (avoidUnloaded) { + if (nextBlockMoveLoaded && !world.isBlockLoaded(BlockPos(player.posX + it.x, player.posY, player.posZ + it.z), false)) { + nextBlockMoveLoaded = false + motionPrev = Vec2f(it.x.toFloat(), it.z.toFloat()) + setSpeed(0.0) + player.motionY = 0.0 + return@safeListener + } else if (!nextBlockMoveLoaded) { + if (!world.isBlockLoaded(BlockPos(player.posX + motionPrev.x, 1.0, player.posZ + motionPrev.y), false)) { + setSpeed(0.0) + player.motionY = 0.0 + return@safeListener + } + } + } + setSpeed(currentFlightSpeed / 10.0) + player.motionY = 0.0 + } + nextBlockMoveLoaded = true + } + + safeListener { + if (autoFlyForward && (currentState == State.FLYING || currentState == State.TAKEOFF) && !player.onGround) { + it.movementInput.moveStrafe = 0.0f + it.movementInput.moveForward = 1.0f + } + } + } + + private fun withinRange(motion: Double) = motion >= TAKE_OFF_Y_VELOCITY - 0.05 && motion <= TAKE_OFF_Y_VELOCITY + 0.05 + + private fun resetFlightSpeed() { + setFlightSpeed(initialFlightSpeed) + } + + private fun setFlightSpeed(speed: Double) { + currentFlightSpeed = max(initialFlightSpeed, min(speed, speedMax)) + } + + private fun SafeClientEvent.stateUpdate() { + /* Elytra Check */ + val armorSlot = player.inventory.armorInventory[2] + elytraIsEquipped = armorSlot.item == Items.ELYTRA + + /* Elytra Durability Check */ + elytraDurability = if (elytraIsEquipped) { + armorSlot.maxDamage - armorSlot.itemDamage + } else 0 + + /* wasInLiquid check */ + if (player.isInWater || player.isInLava) { + wasInLiquid = true + } else if (player.onGround || isFlying) { + wasInLiquid = false + } + + /* Elytra flying status check */ + startedFlying = !isFlying && player.isElytraFlying + stoppedFlying = isFlying && !player.isElytraFlying + isFlying = player.isElytraFlying + + /* Movement input check */ + val isStandingStillH = player.movementInput.moveForward == 0f && player.movementInput.moveStrafe == 0f + isStandingStill = isStandingStillH && !player.movementInput.jump && !player.movementInput.sneak + } + + private fun SafeClientEvent.takeoff(event: PlayerTravelEvent) { + val timerSpeed = takeoffTimerSpeed + val height = 0.1 + val closeToGround = player.posY <= world.getGroundPos(player).y + height && !wasInLiquid && !mc.isSingleplayer + + if (player.motionY >= -0.02) return + if (closeToGround) { + resetTimer() + return + } + if (!wasInLiquid && !mc.isSingleplayer) { + event.cancel() + player.setVelocity(0.0, -0.02, 0.0) + } + + if (!mc.isSingleplayer) modifyTimer(timerSpeed * 2.0f) + connection.sendPacket(CPacketEntityAction(player, CPacketEntityAction.Action.START_FALL_FLYING)) + } + + private fun SafeClientEvent.spoofRotation() { + if (player.isSpectator || !elytraIsEquipped || elytraDurability <= 1 || !isFlying) return + var rotation = com.lambda.client.util.math.Vec2f(player) + if (!isStandingStill) rotation = com.lambda.client.util.math.Vec2f(rotation.x, MAGIC_PITCH) + /* Cancels rotation packets if player is not moving and not clicking */ + val cancelRotation = isStandingStill + && ((!mc.gameSettings.keyBindUseItem.isKeyDown && !mc.gameSettings.keyBindAttack.isKeyDown)) + sendPlayerPacket { + if (cancelRotation) { + cancelRotate() + } else { + rotate(rotation) + } + } + } + + private fun SafeClientEvent.pathForward() { + beforePathingPlayerPitchYaw = player.pitchYaw + if (scheduleBaritoneJob?.isActive == true) return + baritoneStartTime = System.currentTimeMillis() + scheduleBaritoneJob = defaultScope.launch { + delay(baritoneStartDelayMs.toLong()) + BaritoneUtils.primary?.playerContext?.let { + BaritoneUtils.primary?.customGoalProcess?.setGoalAndPath(GoalXZ.fromDirection( + it.playerFeetAsVec(), + it.player().rotationYawHead, + baritonePathForwardBlocks.toDouble() + )) + } + } + } + + private fun configureViewLock() { + ViewLock.mode.value = ViewLock.Mode.TRADITIONAL + ViewLock.yaw.value = true + ViewLock.autoYaw.value = true + ViewLock.hardAutoYaw.value = true + ViewLock.disableMouseYaw.value = true + ViewLock.yawSlice.value = 8 + ViewLock.pitch.value = false + } +} diff --git a/src/main/kotlin/com/lambda/client/module/modules/player/AntiForceLook.kt b/src/main/kotlin/com/lambda/client/module/modules/player/AntiForceLook.kt index 15447139b..133f3c3a6 100644 --- a/src/main/kotlin/com/lambda/client/module/modules/player/AntiForceLook.kt +++ b/src/main/kotlin/com/lambda/client/module/modules/player/AntiForceLook.kt @@ -1,11 +1,13 @@ package com.lambda.client.module.modules.player +import com.lambda.client.event.SafeClientEvent import com.lambda.client.event.events.PacketEvent -import com.lambda.client.mixin.extension.playerPosLookPitch -import com.lambda.client.mixin.extension.playerPosLookYaw import com.lambda.client.module.Category import com.lambda.client.module.Module import com.lambda.client.util.threads.safeListener +import com.lambda.mixin.accessor.network.AccessorNetHandlerPlayClient +import net.minecraft.network.play.client.CPacketConfirmTeleport +import net.minecraft.network.play.client.CPacketPlayer import net.minecraft.network.play.server.SPacketPlayerPosLook object AntiForceLook : Module( @@ -13,11 +15,56 @@ object AntiForceLook : Module( description = "Stops server packets from turning your head", category = Category.PLAYER ) { + init { - safeListener { - if (it.packet !is SPacketPlayerPosLook) return@safeListener - it.packet.playerPosLookYaw = player.rotationYaw - it.packet.playerPosLookPitch = player.rotationPitch + safeListener(priority = -5) { + if (it.packet is SPacketPlayerPosLook) { + it.cancel() + mc.addScheduledTask { handlePosLook(it.packet) } + } + } + } + + private fun SafeClientEvent.handlePosLook(packet: SPacketPlayerPosLook) { + /** {@see NetHandlerPlayClient#handlePlayerPosLook} **/ + var x = packet.x + var y = packet.y + var z = packet.z + var yaw = packet.yaw + var pitch = packet.pitch + + if (packet.flags.contains(SPacketPlayerPosLook.EnumFlags.X)) x += player.posX else player.motionX = 0.0 + if (packet.flags.contains(SPacketPlayerPosLook.EnumFlags.Y)) y += player.posY else player.motionY = 0.0 + if (packet.flags.contains(SPacketPlayerPosLook.EnumFlags.Z)) z += player.posZ else player.motionZ = 0.0 + if (packet.flags.contains(SPacketPlayerPosLook.EnumFlags.X_ROT)) pitch += player.rotationPitch + if (packet.flags.contains(SPacketPlayerPosLook.EnumFlags.Y_ROT)) yaw += player.rotationYaw + + player.setPositionAndRotation(x, y, z, + // retain current yaw and pitch client-side + player.rotationYaw, + player.rotationPitch + ) + + // spoof to server that we are using its rotation + connection.sendPacket(CPacketConfirmTeleport(packet.teleportId)) + + connection.sendPacket(CPacketPlayer.PositionRotation( + player.posX, + player.entityBoundingBox.minY, + player.posZ, + yaw, + pitch, + false) + ) + + val connection = (player.connection as? AccessorNetHandlerPlayClient) ?: return + + if (!connection.isDoneLoadingTerrain) { + player.prevPosX = player.posX + player.prevPosY = player.posY + player.prevPosZ = player.posZ + connection.isDoneLoadingTerrain = true + mc.displayGuiScreen(null) } } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/client/module/modules/player/ViewLock.kt b/src/main/kotlin/com/lambda/client/module/modules/player/ViewLock.kt index cc22fec95..29f970d8f 100644 --- a/src/main/kotlin/com/lambda/client/module/modules/player/ViewLock.kt +++ b/src/main/kotlin/com/lambda/client/module/modules/player/ViewLock.kt @@ -21,30 +21,34 @@ object ViewLock : Module( category = Category.PLAYER, alias = arrayOf("YawLock", "PitchLock") ) { - private val mode by setting("Mode", Mode.TRADITIONAL) - private val page by setting("Page", Page.YAW, { mode == Mode.TRADITIONAL }) - - private val yaw by setting("Yaw", true, { mode == Mode.TRADITIONAL && page == Page.YAW }) - private val autoYaw = setting("Auto Yaw", true, { mode == Mode.TRADITIONAL && page == Page.YAW && yaw }) - private val disableMouseYaw by setting("Disable Mouse Yaw", false, { mode == Mode.TRADITIONAL && page == Page.YAW && yaw && yaw }) - private val specificYaw by setting("Specific Yaw", 180.0f, -180.0f..180.0f, 1.0f, { mode == Mode.TRADITIONAL && page == Page.YAW && !autoYaw.value && yaw }) - private val yawSlice = setting("Yaw Slice", 8, 2..32, 1, { mode == Mode.TRADITIONAL && page == Page.YAW && autoYaw.value && yaw }) - - private val pitch by setting("Pitch", true, { mode == Mode.TRADITIONAL && page == Page.PITCH }) - private val autoPitch = setting("Auto Pitch", true, { mode == Mode.TRADITIONAL && page == Page.PITCH && pitch }) - private val disableMousePitch by setting("Disable Mouse Pitch", false, { mode == Mode.TRADITIONAL && page == Page.PITCH && pitch && pitch }) - private val specificPitch by setting("Specific Pitch", 0.0f, -90.0f..90.0f, 1.0f, { mode == Mode.TRADITIONAL && page == Page.PITCH && !autoPitch.value && pitch }) - private val pitchSlice = setting("Pitch Slice", 5, 2..32, 1, { mode == Mode.TRADITIONAL && page == Page.PITCH && autoPitch.value && pitch }) - - private val xCoord by setting("X coordinate", "", { mode == Mode.COORDS }) - private val yCoord by setting("Y coordinate", "", { mode == Mode.COORDS }) - private val zCoord by setting("Z coordinate", "", { mode == Mode.COORDS }) + val mode = setting("Mode", Mode.TRADITIONAL) + private val page by setting("Page", Page.YAW, { mode.value == Mode.TRADITIONAL }) + + val yaw = setting("Yaw", true, { page == Page.YAW && mode.value == Mode.TRADITIONAL }) + val autoYaw = setting("Auto Yaw", true, { page == Page.YAW && yaw.value && mode.value == Mode.TRADITIONAL }) + val hardAutoYaw = setting("Hard Auto Yaw", true, { page == Page.YAW && yaw.value && autoYaw.value && mode.value == Mode.TRADITIONAL }, + description = "Disables mouse movement snapping") + val disableMouseYaw = setting("Disable Mouse Yaw", true, { page == Page.YAW && yaw.value && mode.value == Mode.TRADITIONAL }) + private val specificYaw by setting("Specific Yaw", 180.0f, -180.0f..180.0f, 1.0f, { page == Page.YAW && !autoYaw.value && yaw.value && mode.value == Mode.TRADITIONAL }) + val yawSlice = setting("Yaw Slice", 8, 2..32, 1, { page == Page.YAW && autoYaw.value && yaw.value && mode.value == Mode.TRADITIONAL }) + + val pitch = setting("Pitch", true, { page == Page.PITCH && mode.value == Mode.TRADITIONAL }) + private val autoPitch = setting("Auto Pitch", true, { page == Page.PITCH && pitch.value && mode.value == Mode.TRADITIONAL }) + private val hardAutoPitch by setting("Hard Auto Pitch", true, { page == Page.PITCH && pitch.value && autoPitch.value && mode.value == Mode.TRADITIONAL }, + description = "Disables mouse movement snapping") + private val disableMousePitch by setting("Disable Mouse Pitch", true, { page == Page.PITCH && pitch.value && mode.value == Mode.TRADITIONAL }) + private val specificPitch by setting("Specific Pitch", 0.0f, -90.0f..90.0f, 1.0f, { page == Page.PITCH && !autoPitch.value && pitch.value && mode.value == Mode.TRADITIONAL }) + private val pitchSlice = setting("Pitch Slice", 5, 2..32, 1, { page == Page.PITCH && autoPitch.value && pitch.value && mode.value == Mode.TRADITIONAL }) + + private val xCoord by setting("X coordinate", "", { mode.value == Mode.COORDS }) + private val yCoord by setting("Y coordinate", "", { mode.value == Mode.COORDS }) + private val zCoord by setting("Z coordinate", "", { mode.value == Mode.COORDS }) private enum class Page { YAW, PITCH } - - private enum class Mode { + + enum class Mode { TRADITIONAL, COORDS } @@ -64,8 +68,8 @@ object ViewLock : Module( safeListener { if (it.phase != TickEvent.Phase.END) return@safeListener - - if (mode == Mode.COORDS) { + + if (mode.value == Mode.COORDS) { val x = xCoord.toDoubleOrNull() val y = yCoord.toDoubleOrNull() val z = zCoord.toDoubleOrNull() @@ -74,7 +78,7 @@ object ViewLock : Module( disable() return@safeListener } - + val rotation = getRotationTo(Vec3d(x, y, z)) player.rotationYaw = rotation.x player.rotationPitch = rotation.y @@ -85,11 +89,11 @@ object ViewLock : Module( snapToSlice() } - if (yaw && !autoYaw.value) { + if (yaw.value && !autoYaw.value) { player.rotationYaw = specificYaw } - if (pitch && !autoPitch.value) { + if (pitch.value && !autoPitch.value) { player.rotationPitch = specificPitch } } @@ -97,15 +101,15 @@ object ViewLock : Module( @JvmStatic fun handleTurn(entity: Entity, deltaX: Float, deltaY: Float, ci: CallbackInfo) { - if (isDisabled || mode == Mode.COORDS) return + if (isDisabled || mode.value == Mode.COORDS) return val player = mc.player ?: return if (entity != player) return val multipliedX = deltaX * 0.15f val multipliedY = deltaY * -0.15f - val yawChange = if (yaw && autoYaw.value) handleDelta(multipliedX, deltaXQueue, yawSliceAngle) else 0 - val pitchChange = if (pitch && autoPitch.value) handleDelta(multipliedY, deltaYQueue, pitchSliceAngle) else 0 + val yawChange = if (yaw.value && autoYaw.value && !hardAutoYaw.value) handleDelta(multipliedX, deltaXQueue, yawSliceAngle) else 0 + val pitchChange = if (pitch.value && autoPitch.value && !hardAutoPitch) handleDelta(multipliedY, deltaYQueue, pitchSliceAngle) else 0 turn(player, multipliedX, multipliedY) changeDirection(yawChange, pitchChange) @@ -115,12 +119,12 @@ object ViewLock : Module( } private fun turn(player: EntityPlayerSP, deltaX: Float, deltaY: Float) { - if (!yaw || !disableMouseYaw) { + if (!yaw.value || !disableMouseYaw.value) { player.prevRotationYaw += deltaX player.rotationYaw += deltaX } - if (!pitch || !disableMousePitch) { + if (!pitch.value || !disableMousePitch) { player.prevRotationPitch += deltaY player.rotationPitch += deltaY player.rotationPitch = player.rotationPitch.coerceIn(-90.0f, 90.0f) @@ -159,11 +163,11 @@ object ViewLock : Module( private fun snapToSlice() { mc.player?.let { player -> - if (yaw && autoYaw.value) { + if (yaw.value && autoYaw.value) { player.rotationYaw = (yawSnap * yawSliceAngle).coerceIn(0f, 360f) player.ridingEntity?.let { it.rotationYaw = player.rotationYaw } } - if (pitch && autoPitch.value) { + if (pitch.value && autoPitch.value) { player.rotationPitch = (pitchSnap * pitchSliceAngle - 90).coerceIn(-90f, 90f) } } diff --git a/src/main/resources/mixins.lambda.json b/src/main/resources/mixins.lambda.json index d92b2be59..f35f7716d 100644 --- a/src/main/resources/mixins.lambda.json +++ b/src/main/resources/mixins.lambda.json @@ -24,6 +24,7 @@ "accessor.network.AccessorCPacketPlayer", "accessor.network.AccessorCPacketUseEntity", "accessor.network.AccessorCPacketVehicleMove", + "accessor.network.AccessorNetHandlerPlayClient", "accessor.network.AccessorSPacketChat", "accessor.network.AccessorSPacketEntity", "accessor.network.AccessorSPacketEntityHeadLook",