added .float disableclientprediction field for qc to use to disable prediction intent...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 27 Mar 2007 19:48:09 +0000 (19:48 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 27 Mar 2007 19:48:09 +0000 (19:48 +0000)
added .movetype check to disable prediction whenever movetype is not MOVETYPE_WALK, this fixes unwanted prediction issues in all known cases
moved prediction disabling code from SV_ReadClientMove to SV_ExecuteClientMoves as a minor cleanup

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

progsvm.h
prvm_edict.c
sv_main.c
sv_user.c

index cb46759..87806d7 100644 (file)
--- a/progsvm.h
+++ b/progsvm.h
@@ -162,6 +162,7 @@ typedef struct prvm_prog_fieldoffsets_s
        int customizeentityforclient; // ssqc
        int dimension_hit; // ssqc / csqc
        int dimension_solid; // ssqc / csqc
+       int disableclientprediction; // ssqc
        int dphitcontentsmask; // ssqc / csqc
        int drawonlytoclient; // ssqc
        int effects; // ssqc / csqc
index 81dd581..302f09b 100644 (file)
@@ -1271,6 +1271,7 @@ void PRVM_FindOffsets(void)
        prog->fieldoffsets.customizeentityforclient       = PRVM_ED_FindFieldOffset("customizeentityforclient");
        prog->fieldoffsets.dimension_hit                  = PRVM_ED_FindFieldOffset("dimension_hit");
        prog->fieldoffsets.dimension_solid                = PRVM_ED_FindFieldOffset("dimension_solid");
+       prog->fieldoffsets.disableclientprediction        = PRVM_ED_FindFieldOffset("disableclientprediction");
        prog->fieldoffsets.dphitcontentsmask              = PRVM_ED_FindFieldOffset("dphitcontentsmask");
        prog->fieldoffsets.drawonlytoclient               = PRVM_ED_FindFieldOffset("drawonlytoclient");
        prog->fieldoffsets.exteriormodeltoclient          = PRVM_ED_FindFieldOffset("exteriormodeltoclient");
index ced0a71..e3234ab 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -2541,6 +2541,7 @@ prvm_required_field_t reqfields[] =
        {ev_float, "buttonuse"},
        {ev_float, "clientcolors"},
        {ev_float, "cursor_active"},
+       {ev_float, "disableclientprediction"},
        {ev_float, "fullbright"},
        {ev_float, "glow_color"},
        {ev_float, "glow_size"},
index ff49513..f6bc1f1 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -530,12 +530,6 @@ void SV_ReadClientMove (void)
                move->buttons |= host_client->cmd.buttons;
        }
 
-       // disable clientside movement prediction in some cases
-       if (ceil(max(move->receivetime - move->time, 0) * 1000.0) < sv_clmovement_minping.integer)
-               host_client->clmovement_disabletimeout = realtime + sv_clmovement_minping_disabletime.value / 1000.0;
-       if (!sv_clmovement_enable.integer || host_client->clmovement_disabletimeout > realtime)
-               move->sequence = 0;
-
        // now store this move for later execution
        // (we have to buffer the moves because of old ones being repeated)
        if (sv_numreadmoves < CL_MAX_USERCMDS)
@@ -551,6 +545,7 @@ void SV_ExecuteClientMoves(void)
 #ifdef NUM_PING_TIMES
        double total;
 #endif
+       prvm_eval_t *val;
        if (sv_numreadmoves < 1)
                return;
        // only start accepting input once the player is spawned
@@ -559,7 +554,11 @@ void SV_ExecuteClientMoves(void)
 #if DEBUGMOVES
        Con_Printf("SV_ExecuteClientMoves: read %i moves at sv.time %f\n", sv_numreadmoves, (float)sv.time);
 #endif
-       if (sv_readmoves[sv_numreadmoves-1].sequence && sv_clmovement_enable.integer && sv_clmovement_waitforinput.integer > 0)
+       // disable clientside movement prediction in some cases
+       if (ceil(max(sv_readmoves[sv_numreadmoves-1].receivetime - sv_readmoves[sv_numreadmoves-1].time, 0) * 1000.0) < sv_clmovement_minping.integer)
+               host_client->clmovement_disabletimeout = realtime + sv_clmovement_minping_disabletime.value / 1000.0;
+       // several conditions govern whether clientside movement prediction is allowed
+       if (sv_readmoves[sv_numreadmoves-1].sequence && sv_clmovement_enable.integer && sv_clmovement_waitforinput.integer > 0 && host_client->clmovement_disabletimeout <= realtime && host_client->edict->fields.server->movetype == MOVETYPE_WALK && (!(val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.disableclientprediction)) || !val->_float))
        {
                // process the moves in order and ignore old ones
                // but always trust the latest move
@@ -569,7 +568,7 @@ void SV_ExecuteClientMoves(void)
                for (moveindex = 0;moveindex < sv_numreadmoves;moveindex++)
                {
                        usercmd_t *move = sv_readmoves + moveindex;
-                       if (host_client->cmd.sequence < move->sequence || moveindex == sv_numreadmoves - 1)
+                       if (host_client->movesequence < move->sequence || moveindex == sv_numreadmoves - 1)
                        {
 #if DEBUGMOVES
                                Con_Printf("%smove #%i %ims (%ims) %i %i '%i %i %i' '%i %i %i'\n", (move->time - host_client->cmd.time) > sv.frametime ? "^1" : "^2", move->sequence, (int)floor((move->time - host_client->cmd.time) * 1000.0 + 0.5), (int)floor(move->time * 1000.0 + 0.5), move->impulse, move->buttons, (int)move->viewangles[0], (int)move->viewangles[1], (int)move->viewangles[2], (int)move->forwardmove, (int)move->sidemove, (int)move->upmove);
@@ -623,8 +622,8 @@ void SV_ExecuteClientMoves(void)
                }
                // now copy the new move
                host_client->cmd = sv_readmoves[sv_numreadmoves-1];
+               host_client->movesequence = 0;
        }
-       host_client->movesequence = host_client->cmd.sequence;
 
        // calculate average ping time
        host_client->ping = host_client->cmd.receivetime - host_client->cmd.time;