public static void SV_UserFriction() { float speed = Mathlib.LengthXY(ref sv_player.v.velocity); if (speed == 0) { return; } // if the leading edge is over a dropoff, increase friction Vector3 start, stop; start.X = stop.X = sv_player.v.origin.x + sv_player.v.velocity.x / speed * 16; start.Y = stop.Y = sv_player.v.origin.y + sv_player.v.velocity.y / speed * 16; start.Z = sv_player.v.origin.z + sv_player.v.mins.z; stop.Z = start.Z - 34; trace_t trace = SV_Move(ref start, ref q_shared.ZeroVector, ref q_shared.ZeroVector, ref stop, 1, sv_player); float friction = sv_friction.value; if (trace.fraction == 1.0) { friction *= edgefriction.value; } // apply friction float control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed; float newspeed = (float)(speed - host_framtime * control * friction); if (newspeed < 0) { newspeed = 0; } newspeed /= speed; Mathlib.VectorScale(ref sv_player.v.velocity, newspeed, out sv_player.v.velocity); }