diff --git a/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java b/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java index f9a6bf5a3..c8bd52b47 100644 --- a/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java +++ b/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java @@ -90,9 +90,12 @@ private void onOpenEditSignScreen(SignBlockEntity sign, boolean front, CallbackI @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)); + MovementEvent.Player.Pre preEvent = new MovementEvent.Player.Pre(movementType, vec3d); + EventFlow.post(preEvent); + vec3d = preEvent.getMovement(); original.call(instance, movementType, vec3d); - EventFlow.post(new MovementEvent.Player.Post(movementType, vec3d)); + MovementEvent.Player.Post postEvent = new MovementEvent.Player.Post(movementType, vec3d); + EventFlow.post(postEvent); } @WrapOperation(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/input/Input;tick()V")) diff --git a/src/main/java/com/lambda/mixin/input/KeyBindingMixin.java b/src/main/java/com/lambda/mixin/input/KeyBindingMixin.java index 02569e68b..24954cb22 100644 --- a/src/main/java/com/lambda/mixin/input/KeyBindingMixin.java +++ b/src/main/java/com/lambda/mixin/input/KeyBindingMixin.java @@ -36,7 +36,6 @@ boolean modifyIsPressed(boolean original) { if (Sprint.INSTANCE.isEnabled()) return true; if (Speed.INSTANCE.isEnabled() && Speed.getMode() == Speed.Mode.GrimStrafe) return true; - if (TargetStrafe.INSTANCE.isEnabled() && TargetStrafe.isActive()) return true; return original; } } diff --git a/src/main/kotlin/com/lambda/event/events/MovementEvent.kt b/src/main/kotlin/com/lambda/event/events/MovementEvent.kt index 98c72d532..7a0d6c6e8 100644 --- a/src/main/kotlin/com/lambda/event/events/MovementEvent.kt +++ b/src/main/kotlin/com/lambda/event/events/MovementEvent.kt @@ -37,18 +37,18 @@ sealed class MovementEvent { /** * Event triggered before player movement. * - * @property movementType The type of movement. + * @property movement Type The type of movement. * @property movement The movement vector. */ data class Pre( override val movementType: MovementType, - override val movement: Vec3d, + override var movement: Vec3d, ) : Player(), ICancellable by Cancellable() /** * Event triggered after player movement. * - * @property movementType The type of movement. + * @property movement Type The type of movement. * @property movement The movement vector. */ data class Post( diff --git a/src/main/kotlin/com/lambda/gui/components/ModuleEntry.kt b/src/main/kotlin/com/lambda/gui/components/ModuleEntry.kt index da2c8d712..7c73ae9ab 100644 --- a/src/main/kotlin/com/lambda/gui/components/ModuleEntry.kt +++ b/src/main/kotlin/com/lambda/gui/components/ModuleEntry.kt @@ -43,7 +43,7 @@ class ModuleEntry(val module: Module): Layout { if (isMouseReleased() && suppressedEntryId == entryId) suppressedEntryId = null ImGui.setNextWindowSizeConstraints(0f, 0f, Float.MAX_VALUE, io.displaySize.y * 0.5f) - popupContextItem(popupId, ImGuiPopupFlags.None) { + popupContextItem(popupId, ImGuiPopupFlags.MouseButtonRight) { buildConfigSettingsContext(module) } } diff --git a/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt b/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt index 57ece652e..116e68521 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt @@ -17,80 +17,134 @@ package com.lambda.module.modules.movement -import com.lambda.event.events.RotationEvent +import com.lambda.config.ConfigEditor.forEachSetting +import com.lambda.config.ConfigEditor.hideAllExcept +import com.lambda.config.blocks.WorldLineSettings +import com.lambda.config.withEdits +import com.lambda.context.SafeContext +import com.lambda.event.events.MovementEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo import com.lambda.module.Module import com.lambda.module.modules.combat.KillAura import com.lambda.module.tag.ModuleTag -import com.lambda.util.math.distSq -import com.lambda.util.player.MovementUtils.update -import kotlin.math.pow +import net.minecraft.entity.effect.StatusEffects +import net.minecraft.util.math.Vec3d +import java.awt.Color +import kotlin.math.cos +import kotlin.math.sin +import kotlin.math.sqrt object TargetStrafe : Module( name = "TargetStrafe", - description = "Automatically strafes around entities", + description = "Strafes around a target in a circle. The default settings work great for old NCP.", tag = ModuleTag.MOVEMENT, ) { - private val targetDistance by setting("Strafe Distance", 1.0, 0.0..5.0, 0.1) - private val jitterCompensation by setting("Jitter Compensation", 0.0, 0.0..1.0, 0.1) - private val stabilize by setting("Stabilize", StabilizationMode.Normal) - - enum class StabilizationMode { - None, - Weak, - Normal, - Strong - } + private val autoJump by setting("AutoJump", true) + private val distanceSetting by setting("PreferredDistance", 1f, 0f..6f, 0.1f) + private val maxDistance by setting("MaxDistance", 10f, 1f..32f, 0.5f) + private val turnAmount by setting("TurnAmount", 5f, 1f..90f, 0.5f) + private val hSpeed by setting("HSpeed", 0.2873f, 0.001f..10.0f, 0.0001f) + + private val needsAura by setting("NeedsAura", true) + private val antiStuck by setting("AntiStuck", true) + + private val renderCircle by setting("RenderCircle", true) + private val renderCircleColor by setting("RenderCircleColor", Color(255, 255, 255, 100)) { renderCircle } + private val renderThickness by configBlock(WorldLineSettings(this)) + .withEdits { + hideAllExcept( + ::distanceScaling, + ::worldWidthSetting, + ::screenWidthSetting + ) + forEachSetting { + visibility { old -> { old() && renderCircle } } + } + } + + private var direction = 1 - private var forwardDirection = 1.0 - private var strafeDirection = 1.0 + private var currentDistance = 0.0 + private var currentTargetVec: Vec3d? = null - @JvmStatic - val isActive get() = isEnabled && KillAura.isEnabled && KillAura.target != null + private var strafing = false init { listen { - if (player.horizontalCollision) strafeDirection *= -1 + if (strafing && autoJump && player.isOnGround) { + player.jump() + } + } + + listen { event -> + if (player.horizontalCollision && antiStuck) { + switchDirection() + } + if (canStrafe()) { + val rotations = KillAura.target?.let { it1 -> player.eyePos?.rotationTo(it1.pos) } ?: return@listen + KillAura.target?.let { it1 -> doStrafeAtSpeed(event, rotations.yawF, it1.pos) } + currentTargetVec = KillAura.target?.pos - if (KillAura.target == null) { - forwardDirection = 1.0 - strafeDirection = 1.0 + strafing = true + } else { + strafing = false } } - listen { event -> - KillAura.target?.let { target -> - event.strafeYaw = player.eyePos.rotationTo(target.boundingBox.center).yaw + immediateRenderer("TargetStrafe immediate renderer") { + if (strafing && renderCircle) { + circleLine( + currentTargetVec ?: return@immediateRenderer, + distanceSetting.toDouble(), + renderCircleColor, + renderThickness.width, + segments = 64 + ) + } + } + } - val distSq = player.pos distSq target.pos - val keepRange = 0.5 * jitterCompensation + private fun SafeContext.doStrafeAtSpeed(event: MovementEvent.Player.Pre, rotation: Float, target: Vec3d): Boolean { + var playerSpeed = hSpeed + var rotationYaw = rotation + (90f * direction) - forwardDirection = when { - distSq > (targetDistance + keepRange).pow(2) -> 1.0 - distSq < (targetDistance - keepRange).pow(2) -> -1.0 - else -> forwardDirection - } - // Premium code, do not touch it bites - var shouldStabilize = when (stabilize) { - StabilizationMode.None -> false - StabilizationMode.Weak -> player.age % 4 == 0 // 1/4 - StabilizationMode.Normal -> player.age % 2 == 0 // 2/4 - StabilizationMode.Strong -> player.age % 4 != 0 // 3/4 - } + val disX = player.pos.x - target.x + val disZ = player.pos.z - target.z - shouldStabilize = shouldStabilize && distSq > (targetDistance + 0.5).pow(2) + val distance = sqrt(disX * disX + disZ * disZ) - val strafe = if (shouldStabilize) 0.0 else strafeDirection - event.input.update(forwardDirection, strafe, jump = true) + if (distance < maxDistance) { + if (distance > distanceSetting) { + rotationYaw -= turnAmount * direction + } else if (distance < distanceSetting) { + rotationYaw += turnAmount * direction } + } else { + rotationYaw = rotation } - onEnable { - forwardDirection = 1.0 - strafeDirection = 1.0 + currentDistance = distance + + // speed + val speed = player.getStatusEffect(StatusEffects.SPEED) + if (speed != null) { + + playerSpeed *= 1.0f + 0.2f * (speed.amplifier + 1) } + + event.movement = Vec3d(playerSpeed * cos(Math.toRadians((rotationYaw + 90.0f).toDouble())), event.movement.y, playerSpeed * sin(Math.toRadians((rotationYaw + 90.0f).toDouble()))) + return false + } + + private fun canStrafe(): Boolean { + return (KillAura.isEnabled || !needsAura) && KillAura.target != null + } + + private fun switchDirection() { + direction = -direction } }