bound(0.000001, 1 - (1 - fabs(accelqw)) * factor, 1);
}
-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 speedlimit)
+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 stretchfactor, vec_t sidefric, vec_t speedlimit)
{
vec_t vel_straight;
vec_t vel_z;
vec3_t vel_xy;
vec_t vel_xy_current;
vec_t vel_xy_backward, vel_xy_forward;
- qboolean speedclamp;
+ vec_t speedclamp;
- speedclamp = (accelqw < 0);
- if(speedclamp)
+ if(stretchfactor > 0)
+ speedclamp = stretchfactor;
+ else if(accelqw < 0)
+ speedclamp = 1;
+ else
+ speedclamp = -1; // no clamping
+
+ if(accelqw < 0)
accelqw = -accelqw;
if(cl.moveflags & MOVEFLAG_Q2AIRACCELERATE)
VectorMA(vel_perpend, vel_straight, wishdir, s->velocity);
- if(speedclamp)
+ if(speedclamp >= 0)
{
- vel_xy_current = min(VectorLength(s->velocity), vel_xy_forward);
- if(vel_xy_current > 0) // prevent division by zero
+ vec_t vel_xy_preclamp;
+ vel_xy_preclamp = VectorLength(s->velocity);
+ if(vel_xy_preclamp > 0) // prevent division by zero
{
- VectorNormalize(s->velocity);
- VectorScale(s->velocity, vel_xy_current, s->velocity);
+ vel_xy_current += (vel_xy_forward - vel_xy_current) * speedclamp;
+ if(vel_xy_current < vel_xy_preclamp)
+ VectorScale(s->velocity, (vel_xy_current / vel_xy_preclamp), s->velocity);
}
}
if(cl.movevars_warsowbunny_turnaccel && accelerating && s->cmd.sidemove == 0 && s->cmd.forwardmove != 0)
CL_ClientMovement_Physics_PM_AirAccelerate(s, wishdir, wishspeed2);
else
- CL_ClientMovement_Physics_PM_Accelerate(s, wishdir, wishspeed, wishspeed0, accel, accelqw, cl.movevars_airaccel_sideways_friction / cl.movevars_maxairspeed, cl.movevars_airspeedlimit_nonqw);
+ CL_ClientMovement_Physics_PM_Accelerate(s, wishdir, wishspeed, wishspeed0, accel, accelqw, cl.movevars_airaccel_qw_stretchfactor, cl.movevars_airaccel_sideways_friction / cl.movevars_maxairspeed, cl.movevars_airspeedlimit_nonqw);
if(cl.movevars_aircontrol)
CL_ClientMovement_Physics_CPM_PM_Aircontrol(s, wishdir, wishspeed2);
cl.movevars_maxairspeed = cl.statsf[STAT_MOVEVARS_MAXAIRSPEED];
cl.movevars_stepheight = cl.statsf[STAT_MOVEVARS_STEPHEIGHT];
cl.movevars_airaccel_qw = cl.statsf[STAT_MOVEVARS_AIRACCEL_QW];
+ cl.movevars_airaccel_qw_stretchfactor = cl.statsf[STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR];
cl.movevars_airaccel_sideways_friction = cl.statsf[STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION];
cl.movevars_friction = cl.statsf[STAT_MOVEVARS_FRICTION];
cl.movevars_wallfriction = cl.statsf[STAT_MOVEVARS_WALLFRICTION];
cl.movevars_maxairspeed = cl_movement_maxairspeed.value;
cl.movevars_stepheight = cl_movement_stepheight.value;
cl.movevars_airaccel_qw = cl_movement_airaccel_qw.value;
+ cl.movevars_airaccel_qw_stretchfactor = 0;
cl.movevars_airaccel_sideways_friction = cl_movement_airaccel_sideways_friction.value;
cl.movevars_airstopaccelerate = 0;
cl.movevars_airstrafeaccelerate = 0;
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; when < 0, the speed is clamped against the maximum allowed forward speed after the move"};
+cvar_t sv_airaccel_qw_stretchfactor = {0, "sv_airaccel_qw_stretchfactor", "0", "when set, the maximum acceleration increase the player may get compared to forward-acceleration when strafejumping"};
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_RegisterVariable (&sv_accelerate);
Cvar_RegisterVariable (&sv_aim);
Cvar_RegisterVariable (&sv_airaccel_qw);
+ Cvar_RegisterVariable (&sv_airaccel_qw_stretchfactor);
Cvar_RegisterVariable (&sv_airaccel_sideways_friction);
Cvar_RegisterVariable (&sv_airaccelerate);
Cvar_RegisterVariable (&sv_airstopaccelerate);
statsf[STAT_MOVEVARS_MAXAIRSPEED] = sv_maxairspeed.value;
statsf[STAT_MOVEVARS_STEPHEIGHT] = sv_stepheight.value;
statsf[STAT_MOVEVARS_AIRACCEL_QW] = sv_airaccel_qw.value;
+ statsf[STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR] = sv_airaccel_qw_stretchfactor.value;
statsf[STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION] = sv_airaccel_sideways_friction.value;
statsf[STAT_MOVEVARS_FRICTION] = sv_friction.value;
statsf[STAT_MOVEVARS_WATERFRICTION] = sv_waterfriction.value >= 0 ? sv_waterfriction.value : sv_friction.value;