From: divverent Date: Sat, 30 Jan 2010 08:10:29 +0000 (+0000) Subject: speed clamping: sideways friction < 0 clamps against minimum possible backwards speed... X-Git-Tag: xonotic-v0.1.0preview~230^2~582 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=088192ab8f869a3ee045b1938b83181e31268d1a speed clamping: sideways friction < 0 clamps against minimum possible backwards speed, airaccel_qw clamps against maximum possible forward speed, can behave like CPMA but with no strafejump bug git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9887 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_input.c b/cl_input.c index f6d90d4f..28339a43 100644 --- a/cl_input.c +++ b/cl_input.c @@ -438,8 +438,8 @@ cvar_t cl_movement_accelerate = {0, "cl_movement_accelerate", "10", "how fast yo cvar_t cl_movement_airaccelerate = {0, "cl_movement_airaccelerate", "-1", "how fast you accelerate while in the air (should match sv_airaccelerate), if less than 0 the cl_movement_accelerate variable is used instead"}; cvar_t cl_movement_wateraccelerate = {0, "cl_movement_wateraccelerate", "-1", "how fast you accelerate while in water (should match sv_wateraccelerate), if less than 0 the cl_movement_accelerate variable is used instead"}; cvar_t cl_movement_jumpvelocity = {0, "cl_movement_jumpvelocity", "270", "how fast you move upward when you begin a jump (should match the quakec code)"}; -cvar_t cl_movement_airaccel_qw = {0, "cl_movement_airaccel_qw", "1", "ratio of QW-style air control as opposed to simple acceleration (should match sv_airaccel_qw)"}; -cvar_t cl_movement_airaccel_sideways_friction = {0, "cl_movement_airaccel_sideways_friction", "0", "anti-sideways movement stabilization (should match sv_airaccel_sideways_friction)"}; +cvar_t cl_movement_airaccel_qw = {0, "cl_movement_airaccel_qw", "1", "ratio of QW-style air control as opposed to simple acceleration (reduces speed gain when zigzagging) (should match sv_airaccel_qw); when < 0, the speed is clamped against the maximum allowed forward speed after the move"}; +cvar_t cl_movement_airaccel_sideways_friction = {0, "cl_movement_airaccel_sideways_friction", "0", "anti-sideways movement stabilization (should match sv_airaccel_sideways_friction); when < 0, only so much friction is applied that braking (by accelerating backwards) cannot be stronger"}; cvar_t in_pitch_min = {0, "in_pitch_min", "-90", "how far downward you can aim (quake used -70"}; cvar_t in_pitch_max = {0, "in_pitch_max", "90", "how far upward you can aim (quake used 80"}; @@ -1104,31 +1104,41 @@ void CL_ClientMovement_Physics_CPM_PM_Aircontrol(cl_clientmovement_state_t *s, v void CL_ClientMovement_Physics_PM_Accelerate(cl_clientmovement_state_t *s, vec3_t wishdir, vec_t wishspeed, vec_t wishspeed0, vec_t accel, vec_t accelqw, vec_t sidefric) { - vec_t vel_straight, vel_z; + vec_t vel_straight; + vec_t vel_z; vec3_t vel_perpend; - vec_t addspeed; - vec_t savespeed; + vec_t step; + vec3_t vel_xy; + vec_t vel_xy_current; + vec_t vel_xy_backward, vel_xy_forward; + qboolean speedclamp; + + speedclamp = (accelqw < 0); + if(speedclamp) + accelqw = -accelqw; if(cl.moveflags & MOVEFLAG_Q2AIRACCELERATE) wishspeed0 = wishspeed; // don't need to emulate this Q1 bug - savespeed = VectorLength2(s->velocity); - vel_straight = DotProduct(s->velocity, wishdir); vel_z = s->velocity[2]; - VectorMA(s->velocity, -vel_straight, wishdir, vel_perpend); vel_perpend[2] -= vel_z; + VectorCopy(s->velocity, vel_xy); vel_xy[2] -= vel_z; + VectorMA(vel_xy, -vel_straight, wishdir, vel_perpend); + + step = accel * s->cmd.frametime * wishspeed0; + + vel_xy_current = VectorLength(vel_xy); + vel_xy_forward = vel_xy_current + bound(0, wishspeed - vel_xy_current, step) * accelqw + step * (1 - accelqw); + vel_xy_backward = vel_xy_current - bound(0, wishspeed + vel_xy_current, step) * accelqw - step * (1 - accelqw); + + vel_straight = vel_straight + bound(0, wishspeed - vel_straight, step) * accelqw + step * (1 - accelqw); - addspeed = wishspeed - vel_straight; - if(addspeed > 0) - vel_straight = vel_straight + min(addspeed, accel * s->cmd.frametime * wishspeed0) * accelqw; - if(wishspeed > 0) - vel_straight = vel_straight + min(wishspeed, accel * s->cmd.frametime * wishspeed0) * (1 - accelqw); - if(sidefric < 0 && VectorLength2(vel_perpend)) + // negative: only apply so much sideways friction to stay below the speed you could get by "braking" { vec_t f, fmin; f = 1 - s->cmd.frametime * wishspeed * sidefric; - fmin = (savespeed - vel_straight*vel_straight) / VectorLength2(vel_perpend); + fmin = (vel_xy_backward*vel_xy_backward - vel_straight*vel_straight) / VectorLength2(vel_perpend); if(fmin <= 0) VectorScale(vel_perpend, f, vel_perpend); else @@ -1138,6 +1148,17 @@ void CL_ClientMovement_Physics_PM_Accelerate(cl_clientmovement_state_t *s, vec3_ VectorScale(vel_perpend, 1 - s->cmd.frametime * wishspeed * sidefric, vel_perpend); VectorMA(vel_perpend, vel_straight, wishdir, s->velocity); + + if(speedclamp) + { + vel_xy_current = min(VectorLength(s->velocity), vel_xy_forward); + if(vel_xy_current > 0) // prevent division by zero + { + VectorNormalize(s->velocity); + VectorScale(s->velocity, vel_xy_current, s->velocity); + } + } + s->velocity[2] += vel_z; } diff --git a/sv_main.c b/sv_main.c index 379a8ce1..6c650243 100644 --- a/sv_main.c +++ b/sv_main.c @@ -47,8 +47,8 @@ cvar_t slowmo = {0, "slowmo", "1.0", "controls game speed, 0.5 is half speed, 2 cvar_t sv_accelerate = {0, "sv_accelerate", "10", "rate at which a player accelerates to sv_maxspeed"}; cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2", "maximum cosine angle for quake's vertical autoaim, a value above 1 completely disables the autoaim, quake used 0.93"}; -cvar_t sv_airaccel_qw = {0, "sv_airaccel_qw", "1", "ratio of QW-style air control as opposed to simple acceleration"}; -cvar_t sv_airaccel_sideways_friction = {0, "sv_airaccel_sideways_friction", "", "anti-sideways movement stabilization (reduces speed gain when zigzagging)"}; +cvar_t sv_airaccel_qw = {0, "sv_airaccel_qw", "1", "ratio of QW-style air control as opposed to simple acceleration; when < 0, the speed is clamped against the maximum allowed forward speed after the move"}; +cvar_t sv_airaccel_sideways_friction = {0, "sv_airaccel_sideways_friction", "", "anti-sideways movement stabilization (reduces speed gain when zigzagging); when < 0, only so much friction is applied that braking (by accelerating backwards) cannot be stronger"}; cvar_t sv_airaccelerate = {0, "sv_airaccelerate", "-1", "rate at which a player accelerates to sv_maxairspeed while in the air, if less than 0 the sv_accelerate variable is used instead"}; cvar_t sv_airstopaccelerate = {0, "sv_airstopaccelerate", "0", "when set, replacement for sv_airaccelerate when moving backwards"}; cvar_t sv_airstrafeaccelerate = {0, "sv_airstrafeaccelerate", "0", "when set, replacement for sv_airaccelerate when just strafing"};