1414import net .wurstclient .events .UpdateListener ;
1515import net .wurstclient .hack .Hack ;
1616import net .wurstclient .settings .CheckboxSetting ;
17+ import net .wurstclient .settings .EnumSetting ;
1718import net .wurstclient .settings .SliderSetting ;
1819import net .wurstclient .settings .SliderSetting .ValueDisplay ;
1920
@@ -22,11 +23,16 @@ public final class SpeedHackHack extends Hack implements UpdateListener
2223{
2324 private static final double AUTO_NORMALISE_BASE_BPS = 5.6 ;
2425 private static final double AUTO_NORMALISE_WALK_BPS = 4.317 ;
25- private static final double AUTO_NORMALISE_SPRINT_BPS = 5.612 ;
26+ private static final double AUTO_NORMALISE_SPRINT_BPS = 5.6112 ;
27+ private static final double SPEED_I_WALK_BPS = 5.180 ;
28+ private static final double SPEED_I_SPRINT_BPS = 6.734 ;
29+ private static final double SPEED_II_WALK_BPS = 6.044 ;
30+ private static final double SPEED_II_SPRINT_BPS = 7.857 ;
2631 private static final double AUTO_NORMALISE_GROUND_ACCEL = 0.35 ;
2732 private static final double AUTO_NORMALISE_AIR_ACCEL = 0.02 ;
2833 private static final double AUTO_NORMALISE_SIDEWAYS_DAMPING = 0.15 ;
2934 private static final double AUTO_NORMALISE_MAX_BOOST = 2.0 ;
35+ private static final double POTION_MODE_MAX_BOOST = 4.0 ;
3036 private static final double AUTO_NORMALISE_STEP_UP = 0.05 ;
3137 private static final double AUTO_NORMALISE_STEP_DOWN = 0.02 ;
3238
@@ -51,6 +57,10 @@ public final class SpeedHackHack extends Hack implements UpdateListener
5157 "Auto normalise" ,
5258 "Overrides regular SpeedHack tuning and automatically compensates persistent non-environmental slowdown to maintain a normal walking speed." ,
5359 false );
60+ private final EnumSetting <PotionMode > potionMode =
61+ new EnumSetting <>("Potion mode" ,
62+ "Vanilla-like Speed effect presets with slowdown compensation." ,
63+ PotionMode .values (), PotionMode .OFF );
5464 private final CheckboxSetting renderSpeed =
5565 new CheckboxSetting ("Show speed in HackList" , true );
5666
@@ -66,6 +76,7 @@ public SpeedHackHack()
6676 addSetting (sidewaysDamping );
6777 addSetting (autoSprint );
6878 addSetting (autoNormalise );
79+ addSetting (potionMode );
6980 addSetting (renderSpeed );
7081 }
7182
@@ -81,8 +92,7 @@ public String getRenderName()
8192
8293 Vec3 velocity = player .getDeltaMovement ();
8394 long blocksPerSecond = Math .round (velocity .length () * 20.0 );
84- String speedSetting =
85- autoNormalise .isChecked () ? "vanilla" : maxSpeed .getValueString ();
95+ String speedSetting = getModeLabel ();
8696 return getName () + " [" + blocksPerSecond + "b/s | " + speedSetting
8797 + "]" ;
8898 }
@@ -119,9 +129,15 @@ public void onUpdate()
119129 || MC .player .isInLava ())
120130 return ;
121131
132+ boolean potionPresetEnabled =
133+ potionMode .getSelected () != PotionMode .OFF ;
134+ if (potionPresetEnabled )
135+ MC .player .stuckSpeedMultiplier = Vec3 .ZERO ;
136+
122137 // activate sprint if walking forward
123- if (!autoNormalise .isChecked () && autoSprint .isChecked ()
124- && MC .player .zza > 0 && !MC .player .horizontalCollision )
138+ boolean vanillaProfile = isVanillaProfileMode ();
139+ if (!vanillaProfile && autoSprint .isChecked () && MC .player .zza > 0
140+ && !MC .player .horizontalCollision )
125141 MC .player .setSprinting (true );
126142
127143 // New approach: set a *target* horizontal velocity based on input +
@@ -139,28 +155,27 @@ public void onUpdate()
139155 Vec3 velH = new Vec3 (v .x , 0 , v .z );
140156 double currentHorizontalSpeed =
141157 Math .sqrt (velH .x * velH .x + velH .z * velH .z );
142- boolean useAutoNormalise = autoNormalise .isChecked ();
143158
144159 // Dampen sideways inertia so turning doesn't feel like ice.
145160 double alongSpeed = velH .dot (dir );
146161 Vec3 along = dir .scale (alongSpeed );
147162 Vec3 side = velH .subtract (along );
148- double damping = useAutoNormalise ? AUTO_NORMALISE_SIDEWAYS_DAMPING
163+ double damping = vanillaProfile ? AUTO_NORMALISE_SIDEWAYS_DAMPING
149164 : sidewaysDamping .getValue ();
150165 velH = along .add (side .scale (damping ));
151166
152167 // Accelerate towards target speed (strong on ground, weak in air).
153168 double accel = MC .player .onGround ()
154- ? (useAutoNormalise ? AUTO_NORMALISE_GROUND_ACCEL
169+ ? (vanillaProfile ? AUTO_NORMALISE_GROUND_ACCEL
155170 : groundAccel .getValue ())
156- : (useAutoNormalise ? AUTO_NORMALISE_AIR_ACCEL
157- : airAccel .getValue ());
158- double maxSpeedValue = useAutoNormalise
159- ? getAutoNormaliseBaseSpeedPerTick () : maxSpeed .getValue ();
171+ : (vanillaProfile ? AUTO_NORMALISE_AIR_ACCEL : airAccel .getValue ());
172+ double maxSpeedValue = vanillaProfile
173+ ? getVanillaProfileBaseSpeedPerTick () : maxSpeed .getValue ();
160174 double compensatedTargetSpeed = maxSpeedValue ;
161- if (useAutoNormalise )
162- compensatedTargetSpeed =
163- updateNormaliseTarget (maxSpeedValue , currentHorizontalSpeed );
175+ if (vanillaProfile )
176+ compensatedTargetSpeed = updateCompensatedTarget (maxSpeedValue ,
177+ currentHorizontalSpeed , potionPresetEnabled
178+ ? POTION_MODE_MAX_BOOST : AUTO_NORMALISE_MAX_BOOST );
164179 else
165180 currentNormaliseBoost = 1.0 ;
166181 Vec3 targetH = dir .scale (compensatedTargetSpeed );
@@ -213,8 +228,8 @@ private Vec3 getMoveDir(float forward, float strafe)
213228 return new Vec3 (x / len , 0 , z / len );
214229 }
215230
216- private double updateNormaliseTarget (double baseTargetSpeed ,
217- double currentHorizontalSpeed )
231+ private double updateCompensatedTarget (double baseTargetSpeed ,
232+ double currentHorizontalSpeed , double maxBoost )
218233 {
219234 // Only push compensation while we should have stable ground movement.
220235 boolean candidate = MC .player != null && MC .player .onGround ()
@@ -228,7 +243,7 @@ private double updateNormaliseTarget(double baseTargetSpeed,
228243 if (candidate && currentHorizontalSpeed > 0.08
229244 && currentHorizontalSpeed < underperformThreshold )
230245 {
231- double cap = AUTO_NORMALISE_MAX_BOOST ;
246+ double cap = Math . max ( 1.0 , maxBoost ) ;
232247 currentNormaliseBoost =
233248 Math .min (cap , currentNormaliseBoost + AUTO_NORMALISE_STEP_UP );
234249 }else if (currentNormaliseBoost > 1.0 )
@@ -243,16 +258,68 @@ private double updateNormaliseTarget(double baseTargetSpeed,
243258 return baseTargetSpeed * currentNormaliseBoost ;
244259 }
245260
246- private double getAutoNormaliseBaseSpeedPerTick ()
261+ private boolean isVanillaProfileMode ()
262+ {
263+ return autoNormalise .isChecked ()
264+ || potionMode .getSelected () != PotionMode .OFF ;
265+ }
266+
267+ private String getModeLabel ()
268+ {
269+ PotionMode preset = potionMode .getSelected ();
270+ if (preset != PotionMode .OFF )
271+ return preset .toString ();
272+
273+ return autoNormalise .isChecked () ? "vanilla"
274+ : maxSpeed .getValueString ();
275+ }
276+
277+ private double getVanillaProfileBaseSpeedPerTick ()
247278 {
248279 if (MC .player == null )
249280 return AUTO_NORMALISE_WALK_BPS / 20.0 ;
250281
251282 boolean movingForward = MC .player .zza > 0 ;
252283 boolean sprintRequested = movingForward
253284 && (MC .options .keySprint .isDown () || MC .player .isSprinting ());
254- double bps = sprintRequested ? AUTO_NORMALISE_SPRINT_BPS
255- : AUTO_NORMALISE_WALK_BPS ;
285+ double bps = getBpsForCurrentMode (sprintRequested );
256286 return bps / 20.0 ;
257287 }
288+
289+ private double getBpsForCurrentMode (boolean sprinting )
290+ {
291+ return switch (potionMode .getSelected ())
292+ {
293+ case SPEED_I -> sprinting ? SPEED_I_SPRINT_BPS : SPEED_I_WALK_BPS ;
294+ case SPEED_II -> sprinting ? SPEED_II_SPRINT_BPS
295+ : SPEED_II_WALK_BPS ;
296+ case OFF -> sprinting ? AUTO_NORMALISE_SPRINT_BPS
297+ : AUTO_NORMALISE_WALK_BPS ;
298+ };
299+ }
300+
301+ public boolean shouldIgnoreSlowdownsForPotionMode ()
302+ {
303+ return isEnabled () && potionMode .getSelected () != PotionMode .OFF ;
304+ }
305+
306+ private enum PotionMode
307+ {
308+ OFF ("Off" ),
309+ SPEED_I ("Speed I" ),
310+ SPEED_II ("Speed II" );
311+
312+ private final String name ;
313+
314+ private PotionMode (String name )
315+ {
316+ this .name = name ;
317+ }
318+
319+ @ Override
320+ public String toString ()
321+ {
322+ return name ;
323+ }
324+ }
258325}
0 commit comments