]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
cl_input: movevars for "warsowbunny" mode, also implemented in Nexuiz cl_physics...
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 7 May 2009 08:24:38 +0000 (08:24 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 7 May 2009 08:24:38 +0000 (08:24 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8948 d7cf8633-e32d-0410-b094-e92efae38249

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

index cea4cab2002e8cbad23b180438a7da1f3b9e6f54..f71f586812100455137099cb5918dc5a70ad7882 100644 (file)
@@ -988,6 +988,79 @@ 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)
+{
+       vec_t vel_straight, vel_z;
+       vec3_t vel_perpend;
+       vec_t addspeed;
+
+       vel_straight = DotProduct(s->velocity, wishdir);
+       vel_z = s->velocity[2];
+       VectorMA(s->velocity, -vel_straight, wishdir, vel_perpend); vel_perpend[2] -= vel_z;
+
+       addspeed = wishspeed - vel_straight;
+       if(addspeed > 0)
+               vel_straight = vel_straight + min(addspeed, accel * s->cmd.frametime * wishspeed) * accelqw;
+       if(wishspeed > 0)
+               vel_straight = vel_straight + min(wishspeed, accel * s->cmd.frametime * wishspeed) * (1 - accelqw);
+       
+       VectorScale(vel_perpend, 1 - s->cmd.frametime * wishspeed * sidefric, vel_perpend);
+
+       VectorMA(vel_perpend, vel_straight, wishdir, s->velocity);
+       s->velocity[2] += vel_z;
+}
+
+void CL_ClientMovement_Physics_PM_AirAccelerate(cl_clientmovement_state_t *s, vec3_t wishdir, vec_t wishspeed)
+{
+    vec3_t curvel, wishvel, acceldir, curdir;
+    float addspeed, accelspeed, curspeed;
+    float dot;
+
+    float airforwardaccel = cl.movevars_warsowbunny_airforwardaccel;
+    float bunnyaccel = cl.movevars_warsowbunny_accel;
+    float bunnytopspeed = cl.movevars_warsowbunny_topspeed;
+    float turnaccel = cl.movevars_warsowbunny_turnaccel;
+    float backtosideratio = cl.movevars_warsowbunny_backtosideratio;
+
+    if( !wishspeed )
+        return;
+
+    VectorCopy( s->velocity, curvel );
+    curvel[2] = 0;
+    curspeed = VectorLength( curvel );
+
+    if( wishspeed > curspeed * 1.01f )
+    {
+        float accelspeed = curspeed + airforwardaccel * cl.movevars_maxairspeed * s->cmd.frametime;
+        if( accelspeed < wishspeed )
+            wishspeed = accelspeed;
+    }
+    else
+    {
+        float f = ( bunnytopspeed - curspeed ) / ( bunnytopspeed - cl.movevars_maxairspeed );
+        if( f < 0 )
+            f = 0;
+        wishspeed = max( curspeed, cl.movevars_maxairspeed ) + bunnyaccel * f * cl.movevars_maxairspeed * s->cmd.frametime;
+    }
+    VectorScale( wishdir, wishspeed, wishvel );
+    VectorSubtract( wishvel, curvel, acceldir );
+    addspeed = VectorNormalizeLength( acceldir );
+
+    accelspeed = turnaccel * cl.movevars_maxairspeed /* wishspeed */ * s->cmd.frametime;
+    if( accelspeed > addspeed )
+        accelspeed = addspeed;
+
+    if( backtosideratio < 1.0f )
+    {
+        VectorNormalize2( curvel, curdir );
+        dot = DotProduct( acceldir, curdir );
+        if( dot < 0 )
+            VectorMA( acceldir, -( 1.0f - backtosideratio ) * dot, curdir, acceldir );
+    }
+
+    VectorMA( s->velocity, accelspeed, acceldir, s->velocity );
+}
+
 void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
 {
        vec_t friction;
@@ -1077,61 +1150,68 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
        {
                if (s->waterjumptime <= 0)
                {
-                       vec_t f;
-                       vec_t vel_straight;
-                       vec_t vel_z;
-                       vec3_t vel_perpend;
-                       float wishspeed2, accel;
-
                        // apply air speed limit
+                       vec_t accel, wishspeed2;
                        wishspeed = min(wishspeed, cl.movevars_maxairspeed);
                        if (s->crouched)
                                wishspeed *= 0.5;
-
                        accel = cl.movevars_airaccelerate;
-                       
-                       // CPM: air control
                        wishspeed2 = wishspeed;
-                       if(cl.movevars_airstopaccelerate != 0)
-                               if(DotProduct(s->velocity, wishdir) < 0)
-                                       accel = cl.movevars_airstopaccelerate;
-                       if(s->cmd.forwardmove == 0 && s->cmd.sidemove != 0)
-                       {
-                               if(cl.movevars_maxairstrafespeed)
-                                       if(wishspeed > cl.movevars_maxairstrafespeed)
-                                               wishspeed = cl.movevars_maxairstrafespeed;
-                               if(cl.movevars_airstrafeaccelerate)
-                                       accel = cl.movevars_airstrafeaccelerate;
-                       }
-                       // !CPM
 
-                       /*
-                       addspeed = wishspeed - DotProduct(s->velocity, wishdir);
-                       if (addspeed > 0)
+                       if(cl.movevars_warsowbunny_turnaccel)
                        {
-                               accelspeed = min(cl.movevars_accelerate * s->q.frametime * wishspeed, addspeed);
-                               VectorMA(s->velocity, accelspeed, wishdir, s->velocity);
-                       }
-                       */
+                               qboolean accelerating, decelerating, aircontrol;
+                               accelerating = (DotProduct(s->velocity, wishdir) > 0);
+                               decelerating = (DotProduct(s->velocity, wishdir) < 0);
+                               aircontrol = false;
 
-                       vel_straight = DotProduct(s->velocity, wishdir);
-                       vel_z = s->velocity[2];
-                       VectorMA(s->velocity, -vel_straight, wishdir, vel_perpend);
-                       vel_perpend[2] -= vel_z;
-
-                       f = wishspeed - vel_straight;
-                       if(f > 0)
-                               vel_straight += min(f, accel * s->cmd.frametime * wishspeed) * cl.movevars_airaccel_qw;
-                       if(wishspeed > 0)
-                               vel_straight += min(wishspeed, accel * s->cmd.frametime * wishspeed) * (1 - cl.movevars_airaccel_qw);
-
-                       VectorM(1 - (s->cmd.frametime * (wishspeed / cl.movevars_maxairspeed) * cl.movevars_airaccel_sideways_friction), vel_perpend, vel_perpend);
-
-                       VectorMA(vel_perpend, vel_straight, wishdir, s->velocity);
-                       s->velocity[2] += vel_z;
+                               if(accelerating && s->cmd.sidemove == 0 && s->cmd.forwardmove != 0)
+                               {
+                                       CL_ClientMovement_Physics_PM_AirAccelerate(s, wishdir, wishspeed2);
+                               }
+                               else
+                               {
+                                       // CPM: air control
+                                       if(cl.movevars_airstopaccelerate != 0)
+                                               if(DotProduct(s->velocity, wishdir) < 0)
+                                                       accel = cl.movevars_airstopaccelerate;
+                                       if(s->cmd.forwardmove == 0 && s->cmd.sidemove != 0)
+                                       {
+                                               if(cl.movevars_maxairstrafespeed)
+                                                       if(wishspeed > cl.movevars_maxairstrafespeed)
+                                                               wishspeed = cl.movevars_maxairstrafespeed;
+                                               if(cl.movevars_airstrafeaccelerate)
+                                                       accel = cl.movevars_airstrafeaccelerate;
+                                               if(cl.movevars_aircontrol)
+                                                       aircontrol = true;
+                                       }
+                                       // !CPM
+                                       
+                                       CL_ClientMovement_Physics_PM_Accelerate(s, wishdir, wishspeed, accel, cl.movevars_airaccel_qw, cl.movevars_airaccel_sideways_friction / cl.movevars_maxairspeed);
+                                       if(aircontrol)
+                                               CL_ClientMovement_Physics_CPM_PM_Aircontrol(s, wishdir, wishspeed2);
+                               }
+                       }
+                       else
+                       {
+                               // CPM: air control
+                               if(cl.movevars_airstopaccelerate != 0)
+                                       if(DotProduct(s->velocity, wishdir) < 0)
+                                               accel = cl.movevars_airstopaccelerate;
+                               if(s->cmd.forwardmove == 0 && s->cmd.sidemove != 0)
+                               {
+                                       if(cl.movevars_maxairstrafespeed)
+                                               if(wishspeed > cl.movevars_maxairstrafespeed)
+                                                       wishspeed = cl.movevars_maxairstrafespeed;
+                                       if(cl.movevars_airstrafeaccelerate)
+                                               accel = cl.movevars_airstrafeaccelerate;
+                               }
+                               // !CPM
 
-                       if(cl.movevars_aircontrol)
-                               CL_ClientMovement_Physics_CPM_PM_Aircontrol(s, wishdir, wishspeed2);
+                               CL_ClientMovement_Physics_PM_Accelerate(s, wishdir, wishspeed, accel, cl.movevars_airaccel_qw, cl.movevars_airaccel_sideways_friction / cl.movevars_maxairspeed);
+                               if(cl.movevars_aircontrol)
+                                       CL_ClientMovement_Physics_CPM_PM_Aircontrol(s, wishdir, wishspeed2);
+                       }
                }
                s->velocity[2] -= cl.movevars_gravity * cl.movevars_entgravity * s->cmd.frametime;
                CL_ClientMovement_Move(s);
@@ -1181,6 +1261,11 @@ void CL_UpdateMoveVars(void)
                cl.movevars_airstrafeaccelerate = cl.statsf[STAT_MOVEVARS_AIRSTRAFEACCELERATE];
                cl.movevars_maxairstrafespeed = cl.statsf[STAT_MOVEVARS_MAXAIRSTRAFESPEED];
                cl.movevars_aircontrol = cl.statsf[STAT_MOVEVARS_AIRCONTROL];
+               cl.movevars_warsowbunny_airforwardaccel = cl.statsf[STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL];
+               cl.movevars_warsowbunny_accel = cl.statsf[STAT_MOVEVARS_WARSOWBUNNY_ACCEL];
+               cl.movevars_warsowbunny_topspeed = cl.statsf[STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED];
+               cl.movevars_warsowbunny_turnaccel = cl.statsf[STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL];
+               cl.movevars_warsowbunny_backtosideratio = cl.statsf[STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO];
        }
        else
        {
@@ -1206,6 +1291,11 @@ void CL_UpdateMoveVars(void)
                cl.movevars_airstrafeaccelerate = 0;
                cl.movevars_maxairstrafespeed = 0;
                cl.movevars_aircontrol = 0;
+               cl.movevars_warsowbunny_airforwardaccel = 0;
+               cl.movevars_warsowbunny_accel = 0;
+               cl.movevars_warsowbunny_topspeed = 0;
+               cl.movevars_warsowbunny_turnaccel = 0;
+               cl.movevars_warsowbunny_backtosideratio = 0;
        }
 }
 
index e470b9a5a4a8d7459bce12f2269e1fec2830b983..6b4e38fca7bc9ea45776bd33d9e83f7afdf87277 100644 (file)
--- a/client.h
+++ b/client.h
@@ -1062,6 +1062,11 @@ typedef struct client_state_s
        float movevars_airstrafeaccelerate;
        float movevars_maxairstrafespeed;
        float movevars_aircontrol;
+       float movevars_warsowbunny_airforwardaccel;
+       float movevars_warsowbunny_accel;
+       float movevars_warsowbunny_topspeed;
+       float movevars_warsowbunny_turnaccel;
+       float movevars_warsowbunny_backtosideratio;
 
        // models used by qw protocol
        int qw_modelindex_spike;
index 74ccc6d8538ad88050d8414fec9badafe728121b..3f6043052271057edd7cfd984cd89cebd4418198 100644 (file)
@@ -103,6 +103,11 @@ extern char engineversion[128];
 //#define STAT_TIME                    17 // FTE
 //#define STAT_VIEW2           20 // FTE
 #define STAT_VIEWZOOM          21 // DP
+#define STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL      226 // DP
+#define STAT_MOVEVARS_WARSOWBUNNY_ACCEL                                227 // DP
+#define STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED                     228 // DP
+#define STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL                    229 // DP
+#define STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO      230 // DP
 #define STAT_MOVEVARS_AIRSTOPACCELERATE                                231 // DP
 #define STAT_MOVEVARS_AIRSTRAFEACCELERATE                      232 // DP
 #define STAT_MOVEVARS_MAXAIRSTRAFESPEED                                233 // DP
index 1bff09322e614cb87682c411c58aedba10187d66..606872e5ec0702243fd4c03a8cb2951f08642350 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -122,6 +122,11 @@ cvar_t sv_stopspeed = {CVAR_NOTIFY, "sv_stopspeed","100", "how fast you come to
 cvar_t sv_wallfriction = {CVAR_NOTIFY, "sv_wallfriction", "1", "how much you slow down when sliding along a wall"};
 cvar_t sv_wateraccelerate = {0, "sv_wateraccelerate", "-1", "rate at which a player accelerates to sv_maxspeed while in the air, if less than 0 the sv_accelerate variable is used instead"};
 cvar_t sv_waterfriction = {CVAR_NOTIFY, "sv_waterfriction","-1", "how fast you slow down, if less than 0 the sv_friction variable is used instead"};
+cvar_t sv_warsowbunny_airforwardaccel = {0, "sv_warsowbunny_airforwardaccel", "1.00001", "how fast you accelerate until you reach sv_maxspeed"};
+cvar_t sv_warsowbunny_accel = {0, "sv_warsowbunny_accel", "0.1585", "how fast you accelerate until after reaching sv_maxspeed (it gets harder as you near sv_warsowbunny_topspeed)"};
+cvar_t sv_warsowbunny_topspeed = {0, "sv_warsowbunny_topspeed", "925", "soft speed limit (can get faster with rjs and on ramps)"};
+cvar_t sv_warsowbunny_turnaccel = {0, "sv_warsowbunny_turnaccel", "9", "max sharpness of turns (also master switch for the sv_warsowbunny_* mode)"};
+cvar_t sv_warsowbunny_backtosideratio = {0, "sv_warsowbunny_backtosideratio", "0.8", "lower values make it easier to change direction without losing speed; the drawback is \"understeering\" in sharp turns"};
 cvar_t sys_ticrate = {CVAR_SAVE, "sys_ticrate","0.0138889", "how long a server frame is in seconds, 0.05 is 20fps server rate, 0.1 is 10fps (can not be set higher than 0.1), 0 runs as many server frames as possible (makes games against bots a little smoother, overwhelms network players), 0.0138889 matches QuakeWorld physics"};
 cvar_t teamplay = {CVAR_NOTIFY, "teamplay","0", "teamplay mode, values depend on mod but typically 0 = no teams, 1 = no team damage no self damage, 2 = team damage and self damage, some mods support 3 = no team damage but can damage self"};
 cvar_t timelimit = {CVAR_NOTIFY, "timelimit","0", "ends level at this time (in minutes)"};
@@ -405,6 +410,11 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_wallfriction);
        Cvar_RegisterVariable (&sv_wateraccelerate);
        Cvar_RegisterVariable (&sv_waterfriction);
+       Cvar_RegisterVariable (&sv_warsowbunny_airforwardaccel);
+       Cvar_RegisterVariable (&sv_warsowbunny_accel);
+       Cvar_RegisterVariable (&sv_warsowbunny_topspeed);
+       Cvar_RegisterVariable (&sv_warsowbunny_turnaccel);
+       Cvar_RegisterVariable (&sv_warsowbunny_backtosideratio);
        Cvar_RegisterVariable (&sys_ticrate);
        Cvar_RegisterVariable (&teamplay);
        Cvar_RegisterVariable (&timelimit);
@@ -1668,6 +1678,11 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
        statsf[STAT_MOVEVARS_AIRSTRAFEACCELERATE] = sv_airstrafeaccelerate.value;
        statsf[STAT_MOVEVARS_MAXAIRSTRAFESPEED] = sv_maxairstrafespeed.value;
        statsf[STAT_MOVEVARS_AIRCONTROL] = sv_aircontrol.value;
+       statsf[STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL] = sv_warsowbunny_airforwardaccel.value;
+       statsf[STAT_MOVEVARS_WARSOWBUNNY_ACCEL] = sv_warsowbunny_accel.value;
+       statsf[STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED] = sv_warsowbunny_topspeed.value;
+       statsf[STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL] = sv_warsowbunny_turnaccel.value;
+       statsf[STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO] = sv_warsowbunny_backtosideratio.value;
        statsf[STAT_FRAGLIMIT] = fraglimit.value;
        statsf[STAT_TIMELIMIT] = timelimit.value;