Modern Warfare 2 - Bouncing

Some general info

Bouncing is possible via a combination of PM_ProjectVelocity and PM_StepSlideMove. The latter function is needed for stairs and little elevations on the ground so the player doesn’t stop at every brush that is 1 unit heigher than the plane he is walking on. It basically lifts the player up if the brush he walks against is lower or equal the height thats set with the jump_stepSize dvar.

Fun Fact: CoD2 did not include PM_ProjectVelocity and used PM_ClipVelocity in its place. Hooking the call to PM_ClipVelocity and instead calling your own version of PM_ProjectVelocity will enable bouncing just like it is in CoD4.

Bouncing in Modern Warfare 2

The Bouncefix that was first introduced in Modern Warfare 2 is just one check on a variable called jumping right were it decides if PM_StepSlideMove should return early or try to further clip/project the players origin/velocity. The jumping variable was also set in CoD4’s PM_StepSlideMove but not used at that location.

This snippet shows where jumping is set for both games:

​Part of PM_StepSlideMove - same for cod4 / mw2

if ( ps->pm_flags & 0x4000 && ps->pm_time )
    Jump_ClearState(ps);
    
if ( iBumps && ps->pm_flags & 0x4000 && Jump_GetStepHeight(ps, start_o, &fStepSize) )
{
    if ( fStepSize < 1.0 )
        return;

    jumping = 1;
}

Here you can see the change that prevents bouncing on MW2:

Part of MW2's PM_StepSlideMove

if ( trace.fraction >= 1.0 )
{
    if ( fStepAmount != 0.0 )
        ps->origin[2] = ps->origin[2] - fStepAmount;
}
else
{
    if ( !trace.walkable && (jumping || trace.normal[2] < 0.30000001) ) // was :: if ( !trace.walkable && trace.normal[2] < 0.30000001 ) in cod4
    {
        ps->origin[0] = down_o[0];
        ps->origin[1] = down_o[1];
        ps->origin[2] = down_o[2];
        ps->velocity[0] = down_v[0];
        ps->velocity[1] = down_v[1];
        ps->velocity[2] = down_v[2];
        return;
    }

    Vec3Lerp(ps->origin, &in, trace.fraction, ps->origin);
    PM_ProjectVelocity(ps->velocity, trace.normal, ps->velocity);
}

So removing that check re-enables bouncing like it was back in Call of Duty 4 :)