]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_user.c
improved server handling of multiple packets per client physics frame (as would be...
[xonotic/darkplaces.git] / sv_user.c
index 66f26938f209347b17b11577bee84548c46aa161..2525785abb91d432e9f601a18e815d85fd633e60 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -21,12 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 
-cvar_t sv_edgefriction = {0, "edgefriction", "2"};
-cvar_t sv_deltacompress = {0, "sv_deltacompress", "1"};
-cvar_t sv_idealpitchscale = {0, "sv_idealpitchscale","0.8"};
-cvar_t sv_maxspeed = {CVAR_NOTIFY, "sv_maxspeed", "320"};
-cvar_t sv_maxairspeed = {0, "sv_maxairspeed", "30"};
-cvar_t sv_accelerate = {0, "sv_accelerate", "10"};
+cvar_t sv_edgefriction = {0, "edgefriction", "2", "how much you slow down when nearing a ledge you might fall off"};
+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_maxspeed = {CVAR_NOTIFY, "sv_maxspeed", "320", "maximum speed a player can accelerate to when on ground (can be exceeded by tricks)"};
+cvar_t sv_maxairspeed = {0, "sv_maxairspeed", "30", "maximum speed a player can accelerate to when airborn (note that it is possible to completely stop by moving the opposite direction)"};
+cvar_t sv_accelerate = {0, "sv_accelerate", "10", "rate at which a player accelerates to sv_maxspeed"};
 
 static usercmd_t cmd;
 
@@ -603,7 +602,6 @@ void SV_ClientThink(void)
 SV_ReadClientMove
 ===================
 */
-void SV_ApplyClientMove (void);
 void SV_ReadClientMove (void)
 {
        int i;
@@ -611,7 +609,6 @@ void SV_ReadClientMove (void)
        usercmd_t *move = &host_client->cmd;
 
        oldmovetime = move->time;
-       memset(move, 0, sizeof(usercmd_t));
 
        if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
 
@@ -643,10 +640,12 @@ void SV_ReadClientMove (void)
        if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
 
        // read buttons
+       // be sure to bitwise OR them into the move->buttons because we want to
+       // accumulate button presses from multiple packets per actual move
        if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
-               move->buttons = MSG_ReadByte ();
+               move->buttons |= MSG_ReadByte ();
        else
-               move->buttons = MSG_ReadLong ();
+               move->buttons |= MSG_ReadLong ();
        if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
 
        // read impulse
@@ -683,7 +682,6 @@ void SV_ReadClientMove (void)
        else
        {
                // apply the latest accepted move to the entity fields
-               SV_ApplyClientMove();
                host_client->movesequence = move->sequence;
                if (host_client->movesequence)
                {
@@ -707,6 +705,9 @@ void SV_ApplyClientMove (void)
        prvm_eval_t *val;
        usercmd_t *move = &host_client->cmd;
 
+       if (!move->receivetime)
+               return;
+
        // calculate average ping time
        host_client->ping = move->receivetime - move->time;
 #ifdef NUM_PING_TIMES
@@ -729,6 +730,14 @@ void SV_ApplyClientMove (void)
        if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button6))) val->_float = ((move->buttons >> 5) & 1);
        if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button7))) val->_float = ((move->buttons >> 6) & 1);
        if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button8))) val->_float = ((move->buttons >> 7) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button9))) val->_float = ((move->buttons >> 11) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button10))) val->_float = ((move->buttons >> 12) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button11))) val->_float = ((move->buttons >> 13) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button12))) val->_float = ((move->buttons >> 14) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button13))) val->_float = ((move->buttons >> 15) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button14))) val->_float = ((move->buttons >> 16) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button15))) val->_float = ((move->buttons >> 17) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button16))) val->_float = ((move->buttons >> 18) & 1);
        if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_buttonuse))) val->_float = ((move->buttons >> 8) & 1);
        if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_buttonchat))) val->_float = ((move->buttons >> 9) & 1);
        if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_cursor_active))) val->_float = ((move->buttons >> 10) & 1);
@@ -738,6 +747,8 @@ void SV_ApplyClientMove (void)
        if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_endpos))) VectorCopy(move->cursor_impact, val->vector);
        if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_ent))) val->edict = PRVM_EDICT_TO_PROG(PRVM_EDICT_NUM(move->cursor_entitynumber));
        if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ping))) val->_float = host_client->ping * 1000.0;
+
+       memset(move, 0, sizeof(*move));
 }
 
 void SV_FrameLost(int framenum)
@@ -850,7 +861,10 @@ void SV_ReadClientMessage(void)
                        if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
                        if (developer_networkentities.integer >= 1)
                                Con_Printf("recv clc_ackframe %i\n", num);
-                       if (host_client->latestframenum < num)
+                       // if the client hasn't progressed through signons yet,
+                       // ignore any clc_ackframes we get (they're probably from the
+                       // previous level)
+                       if (host_client->spawned && host_client->latestframenum < num)
                        {
                                int i;
                                for (i = host_client->latestframenum + 1;i < num;i++)