diff --git a/code/game/bg_slidemove.c b/code/game/bg_slidemove.c index 6c7b307..007a5ea 100644 --- a/code/game/bg_slidemove.c +++ b/code/game/bg_slidemove.c @@ -234,18 +234,20 @@ void PM_StepSlideMove( qboolean gravity ) { vec3_t start_o, start_v; vec3_t down_o, down_v; trace_t trace; -// float down_dist, up_dist; -// vec3_t delta, delta2; vec3_t up, down; + vec3_t projected; float stepSize; VectorCopy (pm->ps->origin, start_o); VectorCopy (pm->ps->velocity, start_v); if ( PM_SlideMove( gravity ) == 0 ) { - return; // we got exactly where we wanted to go first try + return; // we got exactly where we wanted to go first try } + // QL: compute projected position (where player would be without collision) + VectorMA( start_o, pml.frametime, start_v, projected ); + // QL pm_airSteps: allow step-ups with upward velocity. // Q3 blocked step-ups during jumps unless ground was directly below. // This prevented smooth stair traversal while bunny-hopping. @@ -289,23 +291,19 @@ void PM_StepSlideMove( qboolean gravity ) { } } -#if 0 - // if the down trace can trace back to the original position directly, don't step - pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask); - if ( trace.fraction == 1.0 ) { - // use the original move - VectorCopy (down_o, pm->ps->origin); - VectorCopy (down_v, pm->ps->velocity); - if ( pm->debugLevel ) { - Com_Printf("%i:bend\n", c_pmove); - } - } else -#endif - { - // use the step move + // QL master gate: trace from original position to final position. + // If the trace hits geometry (fraction < 1.0), a real step was crossed. + // On flat ground with micro-bumps, the trace is clear and this entire + // block is skipped — filtering out false positives. + pm->trace( &trace, start_o, pm->mins, pm->maxs, pm->ps->origin, + pm->ps->clientNum, pm->tracemask ); + + if ( trace.fraction < 1.0 ) { float delta; delta = pm->ps->origin[2] - start_o[2]; + + // step sound events if ( delta > 2 ) { if ( delta < 7 ) { PM_AddEvent( EV_STEP_4 ); @@ -317,6 +315,35 @@ void PM_StepSlideMove( qboolean gravity ) { PM_AddEvent( EV_STEP_16 ); } } + + // QL air-step friction: 3% horizontal speed penalty per airborne step-up + if ( !pml.groundPlane && delta > 0 && start_v[2] > 0 ) { + pm->ps->velocity[0] *= 0.97f; + pm->ps->velocity[1] *= 0.97f; + } + + // QL step jump gate: validate stair geometry at projected position. + // Traces DOWN at where the player would be without collision. + // Walls fail (startsolid), flat ground fails (delta<=0), stairs pass. + if ( delta > 0 && pm->ps->pm_type == PM_NORMAL + && pm->waterlevel < 2 && PM_CanJump() ) { + vec3_t stepStart, stepEnd; + trace_t stepTrace; + + VectorCopy( projected, stepStart ); + VectorCopy( projected, stepEnd ); + stepStart[2] += STEPSIZE; + stepEnd[2] -= STEPSIZE; + + pm->trace( &stepTrace, stepStart, pm->mins, pm->maxs, + stepEnd, pm->ps->clientNum, pm->tracemask ); + + if ( !stepTrace.startsolid && !stepTrace.allsolid + && stepTrace.plane.normal[2] >= MIN_WALK_NORMAL ) { + PM_Jump(); + } + } + if ( pm->debugLevel ) { Com_Printf("%i:stepped\n", c_pmove); }