X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcsqcmodellib%2Fcl_player.qc;h=46c312f160ec8e333bd566897cf37aabc559affd;hp=ec7fe0ddf171d2700138aa327a029de89596a511;hb=6a28c11c8abd729c7f95ad7050d204aa2453d2ff;hpb=5bf53ba7af3a48304314d60bc3a4389c9f1d6586 diff --git a/qcsrc/csqcmodellib/cl_player.qc b/qcsrc/csqcmodellib/cl_player.qc index ec7fe0ddf1..46c312f160 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; - csqcplayer_predictionerror = (csqcplayer_predictionerrortime - time) * autocvar_cl_predictionerrorcompensation * csqcplayer_predictionerror + v; - csqcplayer_predictionerrortime = time + 1.0 / autocvar_cl_predictionerrorcompensation; + } + */ + 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_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,29 +119,45 @@ 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; +#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 - while(csqcplayer_moveframe < endframe) + if(csqcplayer_moveframe >= endframe) + { + getinputstate(csqcplayer_moveframe - 1); + } + else { - if (!getinputstate(csqcplayer_moveframe)) + do { - break; + if (!getinputstate(csqcplayer_moveframe)) + break; + runstandardplayerphysics(self); + CSQCPlayer_SetMinsMaxs(); + csqcplayer_moveframe++; } - runstandardplayerphysics(self); - CSQCPlayer_SetMinsMaxs(); - csqcplayer_moveframe++; + while(csqcplayer_moveframe < endframe); } //add in anything that was applied after (for low packet rate protocols) @@ -130,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; @@ -147,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; @@ -155,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; @@ -185,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(); @@ -237,6 +299,13 @@ void CSQCPlayer_SetCamera() if(input_buttons & 4) refdefflags |= REFDEFFLAG_JUMPING; + // note: these two only work in WIP2, but are harmless in WIP1 + if(getstati(STAT_HEALTH) <= 0) + refdefflags |= REFDEFFLAG_DEAD; + + if(intermission) + refdefflags |= REFDEFFLAG_INTERMISSION; + V_CalcRefdef(view, refdefflags); } else