X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcsqcmodellib%2Fcl_player.qc;h=46c312f160ec8e333bd566897cf37aabc559affd;hb=3c7ef5b449d479f9a2e24fdddf767f87208c9be6;hp=71fc2f600cd44af355f7ba015ba67165abe8b9fc;hpb=55384b17f6ad8154f79eeeefa17a1be3f060304a;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/csqcmodellib/cl_player.qc b/qcsrc/csqcmodellib/cl_player.qc index 71fc2f600..46c312f16 100644 --- a/qcsrc/csqcmodellib/cl_player.qc +++ b/qcsrc/csqcmodellib/cl_player.qc @@ -20,39 +20,66 @@ * IN THE SOFTWARE. */ -var float autocvar_cl_predictionerrorcompensation = 0; +var float autocvar_cl_movement_errorcompensation = 0; // engine stuff -.float pmove_flags; -float pmove_onground; // weird engine flag we shouldn't really use but have to for now -#define PMF_JUMP_HELD 1 -#define PMF_DUCKED 4 -#define PMF_ONGROUND 8 #define REFDEFFLAG_TELEPORTED 1 #define REFDEFFLAG_JUMPING 2 +float pmove_onground; // weird engine flag we shouldn't really use but have to for now -entity csqcplayer; vector csqcplayer_origin, csqcplayer_velocity; float csqcplayer_sequence, player_pmflags; float csqcplayer_moveframe; -vector csqcplayer_predictionerror; +vector csqcplayer_predictionerroro; +vector csqcplayer_predictionerrorv; float csqcplayer_predictionerrortime; +float csqcplayer_predictionerrorfactor; -vector CSQCPlayer_GetPredictionError() +vector CSQCPlayer_GetPredictionErrorO() { - if(!autocvar_cl_predictionerrorcompensation) + if(time >= csqcplayer_predictionerrortime) return '0 0 0'; - if(time < csqcplayer_predictionerrortime) - return csqcplayer_predictionerror * (csqcplayer_predictionerrortime - time) * autocvar_cl_predictionerrorcompensation; - return '0 0 0'; + return csqcplayer_predictionerroro * (csqcplayer_predictionerrortime - time) * csqcplayer_predictionerrorfactor; } -void CSQCPlayer_SetPredictionError(vector v) +vector CSQCPlayer_GetPredictionErrorV() { - if(!autocvar_cl_predictionerrorcompensation) + if(time >= csqcplayer_predictionerrortime) + return '0 0 0'; + return csqcplayer_predictionerrorv * (csqcplayer_predictionerrortime - time) * csqcplayer_predictionerrorfactor; +} + +void CSQCPlayer_SetPredictionError(vector o, vector v, float onground_diff) +{ + // error too big to compensate, we LIKELY hit a teleport or a + // jumppad, or it's a jump time disagreement that'll get fixed + // next frame + + // FIXME we sometimes have disagreement in order of jump velocity. Do not act on them! + /* + // commented out as this one did not help + if(onground_diff) + { + print(sprintf("ONGROUND MISMATCH: %d x=%v v=%v\n", onground_diff, o, v)); + return; + } + */ + if(vlen(o) > 32 || vlen(v) > 192) + { + //print(sprintf("TOO BIG: x=%v v=%v\n", o, v)); + return; + } + + if(!autocvar_cl_movement_errorcompensation) + { + csqcplayer_predictionerrorfactor = 0; return; - csqcplayer_predictionerror = (csqcplayer_predictionerrortime - time) * autocvar_cl_predictionerrorcompensation * csqcplayer_predictionerror + v; - csqcplayer_predictionerrortime = time + 1.0 / autocvar_cl_predictionerrorcompensation; + } + + csqcplayer_predictionerroro = CSQCPlayer_GetPredictionErrorO() + o; + csqcplayer_predictionerrorv = CSQCPlayer_GetPredictionErrorV() + v; + csqcplayer_predictionerrorfactor = autocvar_cl_movement_errorcompensation / ticrate; + csqcplayer_predictionerrortime = time + 1.0 / csqcplayer_predictionerrorfactor; } void CSQCPlayer_Unpredict() @@ -92,21 +119,29 @@ void CSQCPlayer_SavePrediction() csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED; } -void CSQCPlayer_PredictTo(float endframe) +void CSQCPlayer_PredictTo(float endframe, float apply_error) { CSQCPlayer_Unpredict(); + if(apply_error) + { + self.origin += CSQCPlayer_GetPredictionErrorO(); + self.velocity += CSQCPlayer_GetPredictionErrorV(); + } CSQCPlayer_SetMinsMaxs(); csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED; - // FIXME do we really NEED this? dead players have servercommandframe - // == 0 and thus won't predict +#if 0 + // we don't need this + // darkplaces makes servercommandframe == 0 in these cases anyway if (getstatf(STAT_HEALTH) <= 0) { csqcplayer_moveframe = clientcommandframe; getinputstate(csqcplayer_moveframe-1); + print("the Weird code path got hit\n"); return; } +#endif if(csqcplayer_moveframe >= endframe) { @@ -138,6 +173,9 @@ void(entity e, float fl) V_CalcRefdef = #640; // DP_CSQC_V_CALCREFDEF void CSQCPlayer_SetCamera() { + vector v0; + v0 = pmove_vel; // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity + if(csqcplayer) { entity oldself; @@ -155,7 +193,7 @@ void CSQCPlayer_SetCamera() // get crouch state from the server if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z) - self.pmove_flags &~= PMF_DUCKED; + self.pmove_flags &= ~PMF_DUCKED; else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z) self.pmove_flags |= PMF_DUCKED; @@ -163,29 +201,37 @@ void CSQCPlayer_SetCamera() if(pmove_onground) self.pmove_flags |= PMF_ONGROUND; else - self.pmove_flags &~= PMF_ONGROUND; + self.pmove_flags &= ~PMF_ONGROUND; CSQCPlayer_SetMinsMaxs(); // override it back just in case self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT); + + // set velocity + self.velocity = v0; } else { + float flg = self.iflags; + self.iflags &= ~(IFLAG_ORIGIN | IFLAG_ANGLES); + InterpolateOrigin_Do(); + self.iflags = flg; + if(csqcplayer_status == CSQCPLAYERSTATUS_FROMSERVER) { vector o, v; o = self.origin; - v = pmove_vel; // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity + v = v0; csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED; - CSQCPlayer_PredictTo(servercommandframe + 1); - CSQCPlayer_SetPredictionError(o - self.origin); + CSQCPlayer_PredictTo(servercommandframe + 1, FALSE); + CSQCPlayer_SetPredictionError(self.origin - o, self.velocity - v, pmove_onground - !!(self.pmove_flags & PMF_ONGROUND)); self.origin = o; self.velocity = v; // get crouch state from the server if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z) - self.pmove_flags &~= PMF_DUCKED; + self.pmove_flags &= ~PMF_DUCKED; else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z) self.pmove_flags |= PMF_DUCKED; @@ -193,11 +239,19 @@ void CSQCPlayer_SetCamera() if(pmove_onground) self.pmove_flags |= PMF_ONGROUND; else - self.pmove_flags &~= PMF_ONGROUND; + self.pmove_flags &= ~PMF_ONGROUND; CSQCPlayer_SavePrediction(); } - CSQCPlayer_PredictTo(clientcommandframe + 1); + CSQCPlayer_PredictTo(clientcommandframe + 1, TRUE); + +#ifdef CSQCMODEL_SERVERSIDE_CROUCH + // get crouch state from the server (LAG) + if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z) + self.pmove_flags &= ~PMF_DUCKED; + else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z) + self.pmove_flags |= PMF_DUCKED; +#endif CSQCPlayer_SetMinsMaxs();