sv_gameplayfix_q2airaccelerate: use Quake2/3/Nexuiz-style air acceleration (clamped...
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 18 Sep 2009 07:24:41 +0000 (07:24 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 18 Sep 2009 07:24:41 +0000 (07:24 +0000)
This is also supported by cl_movement
Mods that now experience prediction errors must set sv_gameplayfix_q2airaccelerate to 1 in their default configuration

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9210 d7cf8633-e32d-0410-b094-e92efae38249

cl_input.c
client.h
quakedef.h
sv_main.c
sv_user.c

index ae2562e..99ed255 100644 (file)
@@ -1102,13 +1102,16 @@ void CL_ClientMovement_Physics_CPM_PM_Aircontrol(cl_clientmovement_state_t *s, v
        s->velocity[2] = zspeed;
 }
 
-void CL_ClientMovement_Physics_PM_Accelerate(cl_clientmovement_state_t *s, vec3_t wishdir, vec_t wishspeed, vec_t accel, vec_t accelqw, vec_t sidefric)
+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;
        vec3_t vel_perpend;
        vec_t addspeed;
        vec_t savespeed;
 
+       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);
@@ -1117,9 +1120,9 @@ void CL_ClientMovement_Physics_PM_Accelerate(cl_clientmovement_state_t *s, vec3_
 
        addspeed = wishspeed - vel_straight;
        if(addspeed > 0)
-               vel_straight = vel_straight + min(addspeed, accel * s->cmd.frametime * wishspeed) * accelqw;
+               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 * wishspeed) * (1 - accelqw);
+               vel_straight = vel_straight + min(wishspeed, accel * s->cmd.frametime * wishspeed0) * (1 - accelqw);
        
        if(sidefric < 0 && VectorLength2(vel_perpend))
        {
@@ -1279,10 +1282,11 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
                if (s->waterjumptime <= 0)
                {
                        // apply air speed limit
-                       vec_t accel, wishspeed2, accelqw;
+                       vec_t accel, wishspeed0, wishspeed2, accelqw;
                        qboolean accelerating;
 
                        accelqw = cl.movevars_airaccel_qw;
+                       wishspeed0 = wishspeed;
                        wishspeed = min(wishspeed, cl.movevars_maxairspeed);
                        if (s->crouched)
                                wishspeed *= 0.5;
@@ -1322,7 +1326,7 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
                        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, accel, accelqw, cl.movevars_airaccel_sideways_friction / cl.movevars_maxairspeed);
+                               CL_ClientMovement_Physics_PM_Accelerate(s, wishdir, wishspeed, wishspeed0, accel, accelqw, cl.movevars_airaccel_sideways_friction / cl.movevars_maxairspeed);
 
                        if(cl.movevars_aircontrol)
                                CL_ClientMovement_Physics_CPM_PM_Aircontrol(s, wishdir, wishspeed2);
@@ -1350,9 +1354,11 @@ void CL_UpdateMoveVars(void)
 {
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
        {
+               cl.moveflags = 0;
        }
        else if (cl.stats[STAT_MOVEVARS_TICRATE])
        {
+               cl.moveflags = cl.stats[STAT_MOVEFLAGS];
                cl.movevars_ticrate = cl.statsf[STAT_MOVEVARS_TICRATE];
                cl.movevars_timescale = cl.statsf[STAT_MOVEVARS_TIMESCALE];
                cl.movevars_gravity = cl.statsf[STAT_MOVEVARS_GRAVITY];
@@ -1384,6 +1390,7 @@ void CL_UpdateMoveVars(void)
        }
        else
        {
+               cl.moveflags = 0;
                cl.movevars_ticrate = slowmo.value / bound(1.0f, cl_netfps.value, 1000.0f);
                cl.movevars_timescale = slowmo.value;
                cl.movevars_gravity = sv_gravity.value;
@@ -1413,6 +1420,12 @@ void CL_UpdateMoveVars(void)
                cl.movevars_warsowbunny_turnaccel = 0;
                cl.movevars_warsowbunny_backtosideratio = 0;
        }
+
+       if(!(cl.moveflags & MOVEFLAG_VALID))
+       {
+               if(gamemode == GAME_NEXUIZ)
+                       cl.moveflags = MOVEFLAG_Q2AIRACCELERATE;
+       }
 }
 
 void CL_ClientMovement_Replay(void)
index 82bbfae..4b84fa2 100644 (file)
--- a/client.h
+++ b/client.h
@@ -1055,6 +1055,7 @@ typedef struct client_state_s
        double lastpackettime;
 
        // movement parameters for client prediction
+       unsigned int moveflags;
        float movevars_wallfriction;
        float movevars_waterfriction;
        float movevars_friction;
index 31f2fbc..f235378 100644 (file)
@@ -104,6 +104,7 @@ extern char engineversion[128];
 //#define STAT_TIME                    17 ///< FTE
 //#define STAT_VIEW2           20 ///< FTE
 #define STAT_VIEWZOOM          21 ///< DP
+#define STAT_MOVEFLAGS                              225 ///< DP
 #define STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL      226 ///< DP
 #define STAT_MOVEVARS_WARSOWBUNNY_ACCEL                                227 ///< DP
 #define STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED                     228 ///< DP
@@ -135,6 +136,10 @@ extern char engineversion[128];
 #define STAT_MOVEVARS_AIRACCEL_QW                                      254 ///< DP
 #define STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION       255 ///< DP
 
+// moveflags values
+#define MOVEFLAG_VALID 0x80000000
+#define MOVEFLAG_Q2AIRACCELERATE 0x00000001
+
 // stock defines
 
 #define        IT_SHOTGUN                              1
index ada40db..476be28 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -100,6 +100,7 @@ cvar_t sv_gameplayfix_stepwhilejumping = {0, "sv_gameplayfix_stepwhilejumping",
 cvar_t sv_gameplayfix_swiminbmodels = {0, "sv_gameplayfix_swiminbmodels", "1", "causes pointcontents (used to determine if you are in a liquid) to check bmodel entities as well as the world model, so you can swim around in (possibly moving) water bmodel entities"};
 cvar_t sv_gameplayfix_upwardvelocityclearsongroundflag = {0, "sv_gameplayfix_upwardvelocityclearsongroundflag", "1", "prevents monsters, items, and most other objects from being stuck to the floor when pushed around by damage, and other situations in mods"};
 cvar_t sv_gameplayfix_gravityunaffectedbyticrate = {0, "sv_gameplayfix_gravityunaffectedbyticrate", "0", "fix some ticrate issues in physics."};
+cvar_t sv_gameplayfix_q2airaccelerate = {0, "sv_gameplayfix_q2airaccelerate", "0", "Quake2-style air acceleration"};
 cvar_t sv_gravity = {CVAR_NOTIFY, "sv_gravity","800", "how fast you fall (512 = roughly earth gravity)"};
 cvar_t sv_idealpitchscale = {0, "sv_idealpitchscale","0.8", "how much to look up/down slopes and stairs when not using freelook"};
 cvar_t sv_jumpstep = {CVAR_NOTIFY, "sv_jumpstep", "0", "whether you can step up while jumping (sv_gameplayfix_stepwhilejumping must also be 1)"};
@@ -388,6 +389,7 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_gameplayfix_swiminbmodels);
        Cvar_RegisterVariable (&sv_gameplayfix_upwardvelocityclearsongroundflag);
        Cvar_RegisterVariable (&sv_gameplayfix_gravityunaffectedbyticrate);
+       Cvar_RegisterVariable (&sv_gameplayfix_q2airaccelerate);
        Cvar_RegisterVariable (&sv_gravity);
        Cvar_RegisterVariable (&sv_idealpitchscale);
        Cvar_RegisterVariable (&sv_jumpstep);
@@ -483,6 +485,11 @@ void SV_Init (void)
                // rogue mission pack has a guardian boss that does not wake up if findradius returns one of the entities around its spawn area
                Cvar_SetValueQuick (&sv_gameplayfix_findradiusdistancetobox, 0);
        }
+       if (gamemode == GAME_NEXUIZ)
+       {
+               // rogue mission pack has a guardian boss that does not wake up if findradius returns one of the entities around its spawn area
+               Cvar_SetValueQuick (&sv_gameplayfix_q2airaccelerate, 1);
+       }
 
        sv_mempool = Mem_AllocPool("server", 0, NULL);
 }
@@ -1666,6 +1673,9 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
 
        // movement settings for prediction
        // note: these are not sent in protocols with lower MAX_CL_STATS limits
+       stats[STAT_MOVEFLAGS] = MOVEFLAG_VALID
+               | (sv_gameplayfix_q2airaccelerate.integer ? MOVEFLAG_Q2AIRACCELERATE : 0)
+       ;
        statsf[STAT_MOVEVARS_TICRATE] = sys_ticrate.value;
        statsf[STAT_MOVEVARS_TIMESCALE] = slowmo.value;
        statsf[STAT_MOVEVARS_GRAVITY] = sv_gravity.value;
index 4ea1916..0870147 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -165,6 +165,7 @@ void SV_Accelerate (void)
                host_client->edict->fields.server->velocity[i] += accelspeed*wishdir[i];
 }
 
+extern cvar_t sv_gameplayfix_q2airaccelerate;
 void SV_AirAccelerate (vec3_t wishveloc)
 {
        int i;
@@ -177,7 +178,7 @@ void SV_AirAccelerate (vec3_t wishveloc)
        addspeed = wishspd - currentspeed;
        if (addspeed <= 0)
                return;
-       accelspeed = (sv_airaccelerate.value < 0 ? sv_accelerate.value : sv_airaccelerate.value)*wishspeed * sv.frametime;
+       accelspeed = (sv_airaccelerate.value < 0 ? sv_accelerate.value : sv_airaccelerate.value)*(sv_gameplayfix_q2airaccelerate.integer ? wishspd : wishspeed) * sv.frametime;
        if (accelspeed > addspeed)
                accelspeed = addspeed;