Skip to content

Commit f49b739

Browse files
committed
Rotation, Speed refactor
1 parent e5bbeaa commit f49b739

File tree

9 files changed

+166
-114
lines changed

9 files changed

+166
-114
lines changed

common/src/main/kotlin/com/lambda/config/groups/IRotationConfig.kt

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import com.lambda.interaction.rotation.RotationMode
44

55
interface IRotationConfig {
66
/**
7-
* - [RotationMode.NONE] No rotation.
87
* - [RotationMode.SILENT] Spoofing server-side rotation.
98
* - [RotationMode.SYNC] Spoofing server-side rotation and adjusting client-side movement based on reported rotation (for Grim).
109
* - [RotationMode.LOCK] Locks the camera client-side.
@@ -26,20 +25,9 @@ interface IRotationConfig {
2625
*/
2726
val resetTicks: Int
2827

29-
/**
30-
* If true, rotation will be instant without any transition. If false, rotation will transition over time.
31-
*/
32-
val instant: Boolean
33-
34-
/**
35-
* The mean (average) value for the Gaussian distribution used to calculate rotation speed.
36-
* This value represents the center of the distribution.
37-
*/
38-
val mean: Double
39-
40-
/**
41-
* The standard deviation for the Gaussian distribution used to calculate rotation speed.
42-
* This value represents the spread or dispersion of the distribution.
43-
*/
44-
val derivation: Double
28+
interface Instant : IRotationConfig {
29+
override val turnSpeed get() = 360.0
30+
override val keepTicks get() = 1
31+
override val resetTicks get() = 1
32+
}
4533
}

common/src/main/kotlin/com/lambda/config/groups/RotationSettings.kt

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,59 @@ class RotationSettings(
99
c: Configurable,
1010
vis: () -> Boolean = { true },
1111
) : IRotationConfig {
12-
override var rotationMode by c.setting("Mode", RotationMode.SYNC, "SILENT - server-side rotation, SYNC - server-side rotation; client-side movement, LOCK - Lock camera", vis)
12+
override var rotationMode by c.setting(
13+
"Mode",
14+
RotationMode.SYNC,
15+
"SILENT - server-side rotation, SYNC - server-side rotation; client-side movement, LOCK - Lock camera",
16+
vis
17+
)
18+
1319
override val keepTicks by c.setting("Keep Rotation", 3, 1..10, 1, "Ticks to keep rotation", " ticks", vis)
1420
override val resetTicks by c.setting("Reset Rotation", 3, 1..10, 1, "Ticks before rotation is reset", " ticks", vis)
15-
override var instant by c.setting("Instant Rotation", true, "Instantly rotate", vis)
16-
override var mean by c.setting("Mean", 20.0, 1.0..80.0, 0.1, "Average rotation speed", unit = "°") { vis() && !instant }
17-
override var derivation by c.setting("Standard Deviation", 5.0, 0.0..20.0, 0.1, "Spread of rotation speeds", unit = "°") { vis() && !instant }
1821

19-
override val turnSpeed get() = if (instant) 360.0 else abs(nextGaussian(mean, derivation))
22+
/**
23+
* If true, rotation will be instant without any transition. If false, rotation will transition over time.
24+
*/
25+
private var instant by c.setting("Instant Rotation", true, "Instantly rotate", vis)
26+
27+
/**
28+
* The mean (average/base) value used to calculate rotation speed.
29+
* This value represents the center of the distribution.
30+
*/
31+
private var mean by c.setting(
32+
"Mean",
33+
40.0,
34+
1.0..120.0,
35+
0.1,
36+
"Average rotation speed",
37+
unit = "°"
38+
) { vis() && !instant }
39+
40+
/**
41+
* The standard deviation for the Gaussian distribution used to calculate rotation speed.
42+
* This value represents the spread of rotation speed.
43+
*/
44+
private var spread by c.setting(
45+
"Spread",
46+
10.0,
47+
0.0..60.0,
48+
0.1,
49+
"Spread of rotation speeds",
50+
unit = "°"
51+
) { vis() && !instant }
52+
53+
/**
54+
* We always have to pass turn speed to the interpolator, because player's yaw could be out of -180..180 range and
55+
* Thus we cant simply assign new angles to the player's rotation without getting flagged by Grim's AimModulo360 check
56+
*/
57+
override val turnSpeed get() = if (instant) 180.0 else abs(mean + spread * nextRandom())
2058

2159
var speedMultiplier = 1.0
2260

23-
private fun nextGaussian(
24-
mean: Double = 0.0,
25-
deviation: Double = 1.0
26-
): Double {
61+
private fun nextRandom(): Double {
2762
val u1 = Random.nextDouble()
2863
val u2 = Random.nextDouble()
2964

30-
val randStdNormal = sqrt(-2.0 * ln(u1)) * cos(2.0 * PI * u2)
31-
return mean + deviation * randStdNormal
65+
return sqrt(-2.0 * ln(u1)) * cos(2.0 * PI * u2)
3266
}
3367
}

common/src/main/kotlin/com/lambda/gui/impl/clickgui/buttons/setting/EnumSlider.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import com.lambda.gui.impl.clickgui.buttons.ModuleButton
77
import com.lambda.gui.impl.clickgui.buttons.SettingButton
88
import com.lambda.module.modules.client.ClickGui
99
import com.lambda.util.math.ColorUtils.setAlpha
10+
import com.lambda.util.math.MathUtils.floorToInt
1011
import com.lambda.util.math.MathUtils.lerp
1112
import com.lambda.util.math.Vec2d
1213
import com.lambda.util.math.transform
1314
import com.lambda.util.primitives.extension.displayValue
1415
import java.awt.Color
15-
import kotlin.math.floor
1616

1717
class EnumSlider<T : Enum<T>>(
1818
setting: EnumSetting<T>,
@@ -43,7 +43,7 @@ class EnumSlider<T : Enum<T>>(
4343
}
4444

4545
override fun setValueByProgress(progress: Double) {
46-
val entryIndex = floor(progress * enumSize).toInt().coerceIn(0, enumSize - 1)
46+
val entryIndex = (progress * enumSize).floorToInt().coerceIn(0, enumSize - 1)
4747
value = values[entryIndex]
4848
valueSetByDrag = true
4949
}

common/src/main/kotlin/com/lambda/interaction/rotation/RotationMode.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
package com.lambda.interaction.rotation
22

33
/**
4-
* @property NONE No rotation.
54
* @property SILENT Spoofing server-side rotation.
65
* @property SYNC Spoofing server-side rotation and adjusting client-side movement based on reported rotation (for Grim).
76
* @property LOCK Locks the camera client-side.
87
*/
98
enum class RotationMode {
10-
NONE,
119
SILENT,
1210
SYNC,
1311
LOCK

common/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,37 @@ import com.lambda.event.events.ClientEvent
66
import com.lambda.event.events.MovementEvent
77
import com.lambda.event.events.RotationEvent
88
import com.lambda.event.listener.SafeListener.Companion.listener
9+
import com.lambda.interaction.RotationManager
910
import com.lambda.interaction.rotation.Rotation
1011
import com.lambda.interaction.rotation.RotationContext
1112
import com.lambda.interaction.rotation.RotationMode
1213
import com.lambda.module.Module
1314
import com.lambda.module.tag.ModuleTag
15+
import com.lambda.util.Nameable
1416
import com.lambda.util.player.MovementUtils.addSpeed
17+
import com.lambda.util.player.MovementUtils.calcMoveYaw
1518
import com.lambda.util.player.MovementUtils.isInputting
1619
import com.lambda.util.player.MovementUtils.motionY
1720
import com.lambda.util.player.MovementUtils.moveDelta
21+
import com.lambda.util.player.MovementUtils.newMovementInput
22+
import com.lambda.util.player.MovementUtils.roundedForward
23+
import com.lambda.util.player.MovementUtils.roundedStrafing
1824
import com.lambda.util.player.MovementUtils.setSpeed
1925
import com.lambda.util.primitives.extension.contains
2026
import com.lambda.util.world.WorldUtils.getFastEntities
2127
import net.minecraft.entity.LivingEntity
2228
import net.minecraft.entity.vehicle.BoatEntity
23-
import kotlin.math.atan2
2429

2530
object Speed : Module(
2631
name = "Speed",
2732
description = "Accelerates your walking speed",
2833
defaultTags = setOf(ModuleTag.MOVEMENT)
2934
) {
30-
@JvmStatic val mode by setting("Mode", Mode.GRIM_STRAFE)
35+
@JvmStatic val mode by setting("Mode", Mode.GRIM_STRAFE).apply {
36+
onValueChange { _, _ ->
37+
reset()
38+
}
39+
}
3140

3241
// Grim
3342
private val grimEntityBoost by setting("Entity Boost", 1.0, 0.0..2.0, 0.01) { mode == Mode.GRIM_STRAFE }
@@ -41,28 +50,21 @@ object Speed : Module(
4150
private val ncpTimerBoost by setting("Timer Boost", 1.08, 1.0..1.1, 0.01) { mode == Mode.NCP_STRAFE }
4251

4352
// Grim
44-
private var desiredRotation: Rotation? = null
45-
private val rotationConfig = object : IRotationConfig {
53+
private val rotationConfig = object : IRotationConfig.Instant {
4654
override val rotationMode = RotationMode.SYNC
47-
override val turnSpeed = 360.0
48-
override val keepTicks = 1
49-
override val resetTicks = 1
50-
override val instant = true
51-
override val mean = 180.0
52-
override val derivation = 1.0
5355
}
5456

5557
// NCP
5658
private const val NCP_BASE_SPEED = 0.2873
5759
private const val NCP_AIR_DECAY = 0.9937
5860

59-
private var ncpPhase = NCPPhase.JUMP
61+
private var ncpPhase = NCPPhase.SLOWDOWN
6062
private var ncpSpeed = NCP_BASE_SPEED
6163
private var lastDistance = 0.0
6264

63-
enum class Mode {
64-
GRIM_STRAFE,
65-
NCP_STRAFE,
65+
enum class Mode(override val displayName: String) : Nameable.NamedEnum {
66+
GRIM_STRAFE("Grim Strafe"),
67+
NCP_STRAFE("NCP Strafe"),
6668
}
6769

6870
private enum class NCPPhase {
@@ -72,33 +74,9 @@ object Speed : Module(
7274
}
7375

7476
init {
75-
listener<MovementEvent.InputUpdate> {
76-
it.input.let { input ->
77-
val dx = if (input.pressingForward) 1 else if (input.pressingBack) -1 else 0
78-
val dy = if (input.pressingRight) 1 else if (input.pressingLeft) -1 else 0
79-
80-
desiredRotation = if (dx != 0 || dy != 0) {
81-
val angle = Math.toDegrees(atan2(dy.toDouble(), dx.toDouble()))
82-
Rotation(player.yaw + angle.toFloat(), player.pitch)
83-
} else null
84-
}
85-
}
86-
87-
listener<RotationEvent.Pre> { event ->
88-
if (!shouldWork()) return@listener
89-
if (mode != Mode.GRIM_STRAFE) return@listener
90-
91-
desiredRotation?.let { rot ->
92-
event.context = RotationContext(
93-
rot,
94-
rotationConfig
95-
)
96-
}
97-
}
98-
9977
listener<MovementEvent.Pre> {
10078
if (!shouldWork()) {
101-
ncpSpeed = NCP_BASE_SPEED
79+
reset()
10280
return@listener
10381
}
10482

@@ -113,8 +91,8 @@ object Speed : Module(
11391
}
11492

11593
listener<ClientEvent.Timer> {
116-
if (!shouldWork() || !isInputting) return@listener
11794
if (mode != Mode.NCP_STRAFE) return@listener
95+
if (!shouldWork() || !isInputting) return@listener
11896
it.speed = ncpTimerBoost
11997
}
12098

@@ -127,9 +105,20 @@ object Speed : Module(
127105
}
128106
}
129107

108+
listener<RotationEvent.Update> { event ->
109+
if (mode != Mode.GRIM_STRAFE) return@listener
110+
if (!shouldWork() || !isInputting) return@listener
111+
112+
val input = newMovementInput()
113+
val moveYaw = RotationManager.BaritoneProcessor.baritoneContext?.rotation?.yawF ?: player.yaw
114+
val yaw = calcMoveYaw(moveYaw, input.roundedForward, input.roundedStrafing)
115+
val rotation = Rotation(yaw, event.context?.rotation?.pitch ?: player.pitch.toDouble())
116+
117+
event.context = RotationContext(rotation, rotationConfig)
118+
}
119+
130120
onEnable {
131-
ncpPhase = NCPPhase.SLOWDOWN
132-
ncpSpeed = NCP_BASE_SPEED
121+
reset()
133122
}
134123
}
135124

@@ -208,4 +197,9 @@ object Speed : Module(
208197
&& !player.input.sneaking
209198
&& !player.isTouchingWater
210199
&& !player.isInLava
200+
201+
private fun reset() {
202+
ncpPhase = NCPPhase.SLOWDOWN
203+
ncpSpeed = NCP_BASE_SPEED
204+
}
211205
}

common/src/main/kotlin/com/lambda/module/modules/player/Replay.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package com.lambda.module.modules.player
22

33
import com.google.gson.*
44
import com.lambda.brigadier.CommandResult
5-
import com.lambda.config.groups.RotationSettings
5+
import com.lambda.config.groups.IRotationConfig
66
import com.lambda.context.SafeContext
77
import com.lambda.core.TimerManager
88
import com.lambda.event.EventFlow.lambdaScope
@@ -60,10 +60,10 @@ object Replay : Module(
6060
private val velocityCheck by setting("Velocity check", true, description = "Check if the player is moving before starting a recording.")
6161
private val cancelOnDeviation by setting("Cancel on deviation", true)
6262
private val deviationThreshold by setting("Deviation threshold", 0.1, 0.1..5.0, 0.1, description = "The threshold for the deviation to cancel the replay.") { cancelOnDeviation }
63+
private val lockCamera by setting("Lock Camera", true)
6364

64-
private val rotationConfig = RotationSettings(this).apply {
65-
rotationMode = RotationMode.LOCK
66-
instant = true
65+
private val rotationConfig = object : IRotationConfig.Instant {
66+
override val rotationMode = if (lockCamera) RotationMode.LOCK else RotationMode.SYNC
6767
}
6868

6969
enum class State {
@@ -140,7 +140,7 @@ object Replay : Module(
140140
}
141141
}
142142

143-
listener<RotationEvent.Pre> { event ->
143+
listener<RotationEvent.Update> { event ->
144144
when (state) {
145145
State.RECORDING -> {
146146
buffer?.rotation?.add(player.rotation)

common/src/main/kotlin/com/lambda/util/Nameable.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,8 @@ package com.lambda.util
55
*/
66
interface Nameable {
77
val name: String
8+
9+
interface NamedEnum {
10+
val displayName: String
11+
}
812
}

0 commit comments

Comments
 (0)