1
1
package com.lambda.client.module.modules.movement
2
2
3
+ import com.lambda.client.commons.interfaces.DisplayEnum
3
4
import com.lambda.client.event.SafeClientEvent
5
+ import com.lambda.client.event.events.PacketEvent
4
6
import com.lambda.client.event.events.PlayerMoveEvent
5
7
import com.lambda.client.event.events.PlayerTravelEvent
6
8
import com.lambda.client.manager.managers.TimerManager.modifyTimer
7
9
import com.lambda.client.manager.managers.TimerManager.resetTimer
8
10
import com.lambda.client.mixin.extension.isInWeb
11
+ import com.lambda.client.mixin.extension.playerY
9
12
import com.lambda.client.module.Category
10
13
import com.lambda.client.module.Module
11
- import com.lambda.client.module.modules.player.AutoEat
12
14
import com.lambda.client.util.BaritoneUtils
13
- import com.lambda.client.util.EntityUtils.flooredPosition
14
15
import com.lambda.client.util.EntityUtils.isInOrAboveLiquid
15
16
import com.lambda.client.util.MovementUtils
16
17
import com.lambda.client.util.MovementUtils.applySpeedPotionEffects
17
18
import com.lambda.client.util.MovementUtils.calcMoveYaw
18
- import com.lambda.client.util.MovementUtils.isMoving
19
19
import com.lambda.client.util.MovementUtils.setSpeed
20
20
import com.lambda.client.util.MovementUtils.speed
21
21
import com.lambda.client.util.TickTimer
22
22
import com.lambda.client.util.TimeUnit
23
23
import com.lambda.client.util.threads.runSafe
24
24
import com.lambda.client.util.threads.safeListener
25
25
import net.minecraft.client.settings.KeyBinding
26
+ import net.minecraft.network.play.client.CPacketPlayer
27
+ import net.minecraft.network.play.server.SPacketPlayerPosLook
26
28
import net.minecraftforge.fml.common.gameevent.TickEvent
27
29
import java.lang.Double.max
30
+ import java.lang.Double.min
28
31
import kotlin.math.cos
32
+ import kotlin.math.hypot
29
33
import kotlin.math.sin
30
34
35
+
31
36
object Speed : Module(
32
37
name = " Speed" ,
33
38
description = " Move faster" ,
34
39
category = Category .MOVEMENT ,
35
40
modulePriority = 100
36
41
) {
37
42
// General settings
38
- val mode by setting(" Mode" , SpeedMode .STRAFE )
39
-
40
- // strafe settings
41
- private val strafeAirSpeedBoost by setting(" Air Speed Boost" , 0.029f , 0.01f .. 0.04f , 0.001f , { mode == SpeedMode .STRAFE })
42
- private val strafeTimerBoost by setting(" Timer Boost" , true , { mode == SpeedMode .STRAFE })
43
- private val strafeAutoJump by setting(" Auto Jump" , true , { mode == SpeedMode .STRAFE })
44
- private val strafeOnHoldingSprint by setting(" On Holding Sprint" , false , { mode == SpeedMode .STRAFE })
45
- private val strafeCancelInertia by setting(" Cancel Inertia" , false , { mode == SpeedMode .STRAFE })
46
-
47
- // onGround settings
48
- private val onGroundTimer by setting(" Timer" , true , { mode == SpeedMode .ONGROUND })
49
- private val onGroundTimerSpeed by setting(" Timer Speed" , 1.29f , 1.0f .. 2.0f , 0.01f , { mode == SpeedMode .ONGROUND && onGroundTimer })
50
- private val onGroundSpeed by setting(" Speed" , 1.31f , 1.0f .. 2.0f , 0.01f , { mode == SpeedMode .ONGROUND })
51
- private val onGroundSprint by setting(" Sprint" , true , { mode == SpeedMode .ONGROUND })
52
- private val onGroundCheckAbove by setting(" Smart Mode" , true , { mode == SpeedMode .ONGROUND })
43
+ val mode = setting(" Mode" , SpeedMode .STRAFE )
44
+
45
+ // Strafe settings
46
+ private val strafeAirSpeedBoost by setting(" Air Speed Boost" , 0.028f , 0.01f .. 0.04f , 0.001f , { mode.value == SpeedMode .STRAFE })
47
+ private val strafeTimerBoost by setting(" Timer Boost" , true , { mode.value == SpeedMode .STRAFE })
48
+ private val strafeAutoJump by setting(" Auto Jump" , true , { mode.value == SpeedMode .STRAFE }, description = " WARNING: Food intensive!" )
49
+ private val strafeOnlyOverhead by setting(" Only strafe on overhead" , false , { mode.value == SpeedMode .STRAFE && strafeAutoJump })
50
+ private val strafeOnHoldingSprint by setting(" On Holding Sprint" , false , { mode.value == SpeedMode .STRAFE })
51
+ private val strafeCancelInertia by setting(" Cancel Inertia" , false , { mode.value == SpeedMode .STRAFE })
52
+
53
+ // YPort settings
54
+ private val yPortAccelerate by setting(" Accelerate" , true , { mode.value == SpeedMode .YPORT })
55
+ private val yPortStrict by setting(" Head Strict" , false , { mode.value == SpeedMode .YPORT }, description = " Only allow YPort when you are under a block" )
56
+ private val yPortAirStrict by setting(" Air Strict" , false , { mode.value == SpeedMode .YPORT }, description = " Force YPort to handle Y movement differently, slows this down A LOT" )
57
+ private val yPortMaxSpeed by setting(" Maximum Speed" , 0.0 , 0.0 .. 2.0 , 0.001 , { mode.value == SpeedMode .YPORT })
58
+ private val yPortAcceleration by setting(" Acceleration Speed" , 2.149 , 1.0 .. 5.0 , 0.001 , { mode.value == SpeedMode .YPORT })
59
+ private val yPortDecay by setting(" Decay Amount" , 0.66 , 0.0 .. 1.0 , 0.001 , { mode.value == SpeedMode .YPORT })
60
+
61
+ private const val TIMER_SPEED = 45.955883f
53
62
54
63
// Strafe Mode
55
64
private var jumpTicks = 0
56
65
private val strafeTimer = TickTimer (TimeUnit .TICKS )
57
66
58
- // onGround Mode
59
- private var wasSprintEnabled = Sprint .isEnabled
67
+ // yport stuff
68
+ private var currentSpeed = .2873
69
+ private var currentY = 0.0
70
+ private var phase: YPortPhase = YPortPhase .WALKING
71
+ private var prevPhase: YPortPhase = YPortPhase .WALKING
72
+ private var goUp = false
73
+ private var lastDistance = 0.0
60
74
61
- private var currentMode = mode
75
+ private enum class YPortPhase {
76
+ // to help with bypassing right after setback
77
+ WAITING ,
78
+ // to get some speed initially
79
+ WALKING ,
80
+ // to jump and accelerate
81
+ ACCELERATING ,
82
+ // to fall to the ground
83
+ SLOWDOWN ,
84
+ // to slowly fall to the ground
85
+ FALLING
86
+ }
62
87
63
- enum class SpeedMode {
64
- STRAFE , ONGROUND
88
+ enum class SpeedMode (override val displayName : String ) : DisplayEnum {
89
+ STRAFE (" Strafe" ),
90
+ YPORT (" YPort" )
65
91
}
66
92
67
93
init {
68
94
onEnable {
69
- wasSprintEnabled = Sprint .isEnabled
95
+ currentSpeed = .2873
96
+ phase = YPortPhase .WALKING
97
+ prevPhase = YPortPhase .WALKING
98
+ goUp = false
99
+ currentY = 0.0
70
100
}
71
101
72
102
onDisable {
73
- if (! wasSprintEnabled && mode == SpeedMode .ONGROUND ) Sprint .disable()
74
103
runSafe {
75
104
reset()
76
105
}
77
106
}
78
107
79
108
safeListener<TickEvent .ClientTickEvent > {
80
- if (mode != currentMode) {
81
- currentMode = mode
82
- reset()
83
- }
84
-
85
- if (mode == SpeedMode .ONGROUND && Sprint .isDisabled && onGroundSprint) Sprint .enable()
86
- }
87
-
88
- safeListener<PlayerTravelEvent > {
89
- if (mode == SpeedMode .STRAFE && shouldStrafe()) strafe()
109
+ lastDistance = hypot(player.posX - player.prevPosX, player.posZ - player.prevPosZ)
110
+ if (mode.value == SpeedMode .STRAFE
111
+ && shouldStrafe()
112
+ ) strafe()
90
113
}
91
114
92
115
safeListener<PlayerMoveEvent > {
93
- when (mode) {
116
+ when (mode.value ) {
94
117
SpeedMode .STRAFE -> {
95
- if (shouldStrafe()) setSpeed(max(player.speed, applySpeedPotionEffects(0.2873 )))
96
- else {
118
+ if (shouldStrafe()) {
119
+ setSpeed(max(player.speed, applySpeedPotionEffects(0.2873 )))
120
+ } else {
97
121
reset()
98
122
if (strafeCancelInertia && ! strafeTimer.tick(2L , false )) {
99
123
player.motionX = 0.0
100
124
player.motionZ = 0.0
101
125
}
102
126
}
103
127
}
104
- SpeedMode .ONGROUND -> {
105
- if (shouldOnGround()) onGround()
106
- else resetTimer()
128
+
129
+ SpeedMode .YPORT -> {
130
+ handleBoost(it)
131
+ }
132
+ }
133
+ }
134
+
135
+ safeListener<PacketEvent .Send > {
136
+ if (mode.value != SpeedMode .YPORT
137
+ || it.packet !is CPacketPlayer
138
+ || ! goUp
139
+ ) return @safeListener
140
+
141
+ var offset = .42
142
+
143
+ // .015625 is the largest number that block heights are always divisible
144
+ while (world.collidesWithAnyBlock(player.entityBoundingBox.offset(.0 , offset, .0 ))) {
145
+ if (offset <= 0 )
146
+ break
147
+
148
+ offset - = .015625
149
+ }
150
+
151
+ val unModOffset = offset
152
+
153
+ if (currentY + unModOffset > 0 )
154
+ offset + = currentY
155
+ else if (yPortAirStrict && phase == YPortPhase .FALLING && prevPhase == YPortPhase .FALLING ) {
156
+
157
+ var predictedY = currentY
158
+ predictedY - = 0.08
159
+ predictedY * = 0.9800000190734863 // 0.333200006 vs 0.341599999
160
+
161
+ if (predictedY + player.posY <= player.posY) {
162
+ phase = YPortPhase .WAITING
107
163
}
108
164
}
165
+
166
+ it.packet.playerY = (offset + player.posY)
167
+
168
+ currentY = offset - unModOffset
169
+ }
170
+
171
+ safeListener<PacketEvent .Receive > {
172
+ if (mode.value != SpeedMode .YPORT || it.packet !is SPacketPlayerPosLook ) return @safeListener
173
+
174
+ currentSpeed = 0.0
175
+ currentY = 0.0
176
+ goUp = false
177
+ // 3 extra ticks at base speed
178
+ phase = YPortPhase .WAITING
179
+ }
180
+
181
+ mode.listeners.add {
182
+ runSafe { reset() }
109
183
}
110
184
}
111
185
112
186
private fun SafeClientEvent.strafe () {
113
187
player.jumpMovementFactor = strafeAirSpeedBoost
114
- if (strafeTimerBoost) modifyTimer( 45.87156f )
115
- if (( Step .isDisabled || ! player.collidedHorizontally) && strafeAutoJump) jump( )
188
+ // slightly slower timer speed bypasses better (1.088 )
189
+ if (strafeTimerBoost) modifyTimer( TIMER_SPEED )
116
190
117
- strafeTimer.reset()
118
- }
191
+ if ((Step .isDisabled || player.onGround) && strafeAutoJump) jump()
119
192
120
- private fun SafeClientEvent.onGround () {
121
- if (onGroundTimer) modifyTimer(50.0f / onGroundTimerSpeed)
122
- else resetTimer()
123
-
124
- player.motionX * = onGroundSpeed
125
- player.motionZ * = onGroundSpeed
193
+ strafeTimer.reset()
126
194
}
127
195
128
196
private fun SafeClientEvent.shouldStrafe (): Boolean =
129
- ( ! player.capabilities.isFlying
197
+ ! player.capabilities.isFlying
130
198
&& ! player.isElytraFlying
131
199
&& ! mc.gameSettings.keyBindSneak.isKeyDown
132
200
&& (! strafeOnHoldingSprint || mc.gameSettings.keyBindSprint.isKeyDown)
133
201
&& ! BaritoneUtils .isPathing
134
202
&& MovementUtils .isInputting
135
- && ! (player.isInOrAboveLiquid || player.isInWeb))
136
-
137
- private fun SafeClientEvent.shouldOnGround (): Boolean =
138
- (world.getBlockState(player.flooredPosition.add(0.0 , 2.0 , 0.0 )).material.isSolid || ! onGroundCheckAbove)
139
- && ! AutoEat .eating
140
- && player.isMoving
141
- && MovementUtils .isInputting
142
- && ! player.movementInput.sneak
143
- && player.onGround
144
203
&& ! (player.isInOrAboveLiquid || player.isInWeb)
145
- && ! player.capabilities.isFlying
146
- && ! player.isElytraFlying
147
- && ! mc.gameSettings.keyBindSneak.isKeyDown
204
+ && (! strafeOnlyOverhead || world.collidesWithAnyBlock(player.entityBoundingBox.offset(.0 ,.42 ,.0 )))
148
205
149
206
private fun SafeClientEvent.reset () {
150
207
player.jumpMovementFactor = 0.02f
@@ -168,4 +225,77 @@ object Speed : Module(
168
225
169
226
jumpTicks--
170
227
}
171
- }
228
+
229
+ private fun SafeClientEvent.handleBoost (event : PlayerMoveEvent ) {
230
+ if (player.movementInput.moveForward == 0f && player.movementInput.moveStrafe == 0f
231
+ || player.isInOrAboveLiquid
232
+ || mc.gameSettings.keyBindJump.isKeyDown
233
+ || ! player.onGround
234
+ || ! world.collidesWithAnyBlock(player.entityBoundingBox.offset(0.0 , 0.42 , 0.0 )) && yPortStrict
235
+ ) {
236
+ resetTimer()
237
+ currentSpeed = .2873
238
+ return
239
+ }
240
+
241
+ modifyTimer(TIMER_SPEED )
242
+
243
+ prevPhase = phase
244
+
245
+ when (phase) {
246
+ YPortPhase .ACCELERATING -> {
247
+ // NCP says hDistance < 2.15 * hDistanceBaseRef
248
+ currentSpeed * = yPortAcceleration
249
+ phase = if (yPortAirStrict) YPortPhase .FALLING else YPortPhase .SLOWDOWN
250
+ goUp = true
251
+ currentY = 0.0
252
+ }
253
+
254
+ YPortPhase .SLOWDOWN -> {
255
+ // NCP says hDistDiff >= 0.66 * (lastMove.hDistance - hDistanceBaseRef)
256
+ currentSpeed = if (yPortAccelerate) {
257
+ lastDistance - yPortDecay * (lastDistance - .2873 )
258
+ } else {
259
+ .2873
260
+ }
261
+ phase = YPortPhase .ACCELERATING
262
+ goUp = false
263
+ }
264
+
265
+ YPortPhase .FALLING -> {
266
+ if (prevPhase == YPortPhase .WALKING ) {
267
+ currentSpeed = if (yPortAccelerate) {
268
+ lastDistance - yPortDecay * (lastDistance - .2873 )
269
+ } else {
270
+ .2873
271
+ }
272
+ }
273
+
274
+ goUp = true
275
+
276
+ currentSpeed - = currentSpeed / 159
277
+
278
+ currentY - = 0.08
279
+ currentY * = 0.9800000190734863
280
+ }
281
+
282
+ else -> {
283
+ currentSpeed = max(currentSpeed, .2873 )
284
+ phase = YPortPhase .values()[phase.ordinal + 1 % YPortPhase .values().size]
285
+ goUp = false
286
+ }
287
+ }
288
+
289
+ val yaw = calcMoveYaw()
290
+
291
+ if (yPortMaxSpeed != 0.0 ) {
292
+ currentSpeed = currentSpeed.coerceAtMost(yPortMaxSpeed)
293
+ }
294
+
295
+ event.x = - sin(yaw) * currentSpeed
296
+ event.y = min(0.0 , event.y)
297
+ event.z = cos(yaw) * currentSpeed
298
+
299
+ player.setVelocity(event.x, event.y, event.z)
300
+ }
301
+ }
0 commit comments