@@ -41,12 +41,13 @@ public class QuakeMovementHandler {
4141 private static final double GROUND_ACCELERATE = 15.0 ;
4242 private static final double AIR_ACCELERATE = 200.0 ;
4343 private static final double AIR_WISH_SPEED = 0.25 ;
44- private static final double BHOP_BOOST = 1.18 ;
44+ private static final double BHOP_BOOST = 1.12 ;
4545 private static final double HARD_CAP_SPEED = 1.25 ; // 25 b/s
4646 private static final double BHOP_SOFT_CAP = 0.5 ; // 10 b/s - pure bhop caps here
4747 private static final double SOFT_CAP_SPEED = 1.0 ; // 20 b/s
4848 private static final double SOFT_CAP_DEGEN = 0.7 ;
4949 private static final double MIN_BHOP_SPEED = 0.10 ;
50+ private static final int MIN_BHOP_AIRTIME = 5 ;
5051 private static final double TRIMP_MULTIPLIER = 1.6 ;
5152
5253 // Debug
@@ -124,17 +125,20 @@ public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
124125 wasJumping .put (uuid , false );
125126 }
126127
127- // Bhop on landing
128+ // Bhop on landing (requires minimum airtime to filter stair/step spam)
128129 if (onGround && !wasGrounded && horizontalSpeed > MIN_BHOP_SPEED ) {
129- double oldSpeed = horizontalSpeed ;
130- motion = applyBunnyHop (player , motion , horizontalSpeed );
131- player .setDeltaMovement (motion );
132- double newSpeed = getHorizontalSpeed (motion );
133- horizontalSpeed = newSpeed ;
130+ int air = airTime .getOrDefault (uuid , 0 );
131+ if (air >= MIN_BHOP_AIRTIME ) {
132+ double oldSpeed = horizontalSpeed ;
133+ motion = applyBunnyHop (player , motion , horizontalSpeed );
134+ player .setDeltaMovement (motion );
135+ double newSpeed = getHorizontalSpeed (motion );
136+ horizontalSpeed = newSpeed ;
134137
135- if (newSpeed > oldSpeed ) {
136- spawnBhopParticles (player , 4 );
137- if (DEBUG_MODE ) lastBhopTick = player .tickCount ;
138+ if (newSpeed > oldSpeed ) {
139+ spawnBhopParticles (player , 4 );
140+ if (DEBUG_MODE ) lastBhopTick = player .tickCount ;
141+ }
138142 }
139143 }
140144
@@ -176,7 +180,9 @@ private static Vec3 applyBunnyHop(Player player, Vec3 motion, double currentSpee
176180 double targetSpeed = currentSpeed ;
177181
178182 if (currentSpeed < SOFT_CAP_SPEED ) {
179- double boostedSpeed = currentSpeed * BHOP_BOOST ;
183+ double speedRatio = Math .min (currentSpeed / BHOP_SOFT_CAP , 1.0 );
184+ double dynamicMultiplier = 1.0 + (BHOP_BOOST - 1.0 ) * (1.0 - speedRatio * speedRatio );
185+ double boostedSpeed = currentSpeed * dynamicMultiplier ;
180186 if (boostedSpeed > SOFT_CAP_SPEED ) {
181187 double excess = boostedSpeed - SOFT_CAP_SPEED ;
182188 boostedSpeed = SOFT_CAP_SPEED + excess * SOFT_CAP_DEGEN ;
0 commit comments