csqcplayer_predictionerroro = CSQCPlayer_GetPredictionErrorO() + o;
csqcplayer_predictionerrorv = CSQCPlayer_GetPredictionErrorV() + v;
- csqcplayer_predictionerrorfactor = autocvar_cl_movement_errorcompensation / ticrate;
+ csqcplayer_predictionerrorfactor = autocvar_cl_movement_errorcompensation / ((ticrate) ? ticrate : 1);
csqcplayer_predictionerrortime = time + 1.0 / csqcplayer_predictionerrorfactor;
}
{
this.mins = PHYS_PL_MIN(this);
this.maxs = PHYS_PL_MAX(this);
+ if (IS_DEAD(this))
+ this.maxs.z = 5;
this.view_ofs = PHYS_PL_VIEWOFS(this);
}
}
{
if(!autocvar_cl_movement) { return; }
- _Movetype_CheckWater(this); // we apparently need to check water *before* physics so it can use this for water jump
+ //_Movetype_CheckWater(this); // we apparently need to check water *before* physics so it can use this for water jump
vector oldv_angle = this.v_angle;
vector oldangles = this.angles; // we need to save these, as they're abused by other code
}
float stairsmoothz;
-float autocvar_cl_stairsmoothspeed;
-float autocvar_cl_smoothviewheight;
+float autocvar_cl_stairsmoothspeed = 200;
+float autocvar_cl_smoothviewheight = 0.05;
float smooth_prevtime;
float viewheightavg;
vector CSQCPlayer_ApplySmoothing(entity this, vector v)
float smoothtime = bound(0, time - smooth_prevtime, 0.1);
smooth_prevtime = max(smooth_prevtime, drawtime); // drawtime is the previous frame's time at this point
- if(this.csqcmodel_teleported || !(this.pmove_flags & PMF_ONGROUND) || autocvar_cl_stairsmoothspeed <= 0)
+ if(this.csqcmodel_teleported || !(this.pmove_flags & PMF_ONGROUND) || autocvar_cl_stairsmoothspeed <= 0 || this.ground_networkentity)
stairsmoothz = v.z;
else
{
return v;
}
+// simplified copy of CSQCPlayer_ApplySmoothing for use on player models
+.float stairsmooth_offset;
+.float stairsmooth_prevtime;
+.float stairsmooth_drawtime; // holds the previous draw time
+vector CSQCModel_ApplyStairSmoothing(entity this, bool isonground, vector v)
+{
+ float smoothtime = bound(0, time - this.stairsmooth_prevtime, 0.1);
+ this.stairsmooth_prevtime = max(this.stairsmooth_prevtime, this.stairsmooth_drawtime); // stairsmooth_drawtime is the previous frame's time at this point
+
+ if(this.csqcmodel_teleported || !isonground || autocvar_cl_stairsmoothspeed <= 0 || this.ground_networkentity)
+ this.stairsmooth_offset = v.z;
+ else
+ {
+ if(this.stairsmooth_offset < v.z)
+ v.z = this.stairsmooth_offset = bound(v.z - PHYS_STEPHEIGHT(this), this.stairsmooth_offset + smoothtime * autocvar_cl_stairsmoothspeed, v.z);
+ else if(this.stairsmooth_offset > v.z)
+ v.z = this.stairsmooth_offset = bound(v.z, this.stairsmooth_offset - smoothtime * autocvar_cl_stairsmoothspeed, v.z + PHYS_STEPHEIGHT(this));
+ }
+
+ this.stairsmooth_prevtime = time;
+ this.stairsmooth_drawtime = drawtime;
+
+ return v;
+}
+
bool autocvar_v_deathtilt;
float autocvar_v_deathtiltangle;
void CSQCPlayer_ApplyDeathTilt(entity this)
{
- if(!IS_DEAD(this) || !autocvar_v_deathtilt)
+ if(!this.csqcmodel_isdead || !autocvar_v_deathtilt)
return;
view_angles.z = autocvar_v_deathtiltangle;
}
//setproperty(VF_CL_VIEWANGLES, view_angles); // update view angles as well so we can aim
}
-float autocvar_cl_bob;
-float autocvar_cl_bobcycle;
-float autocvar_cl_bob_limit;
-float autocvar_cl_bob_limit_heightcheck;
-float autocvar_cl_bob_velocity_limit;
-float autocvar_cl_bobup;
-float autocvar_cl_bobfall;
-float autocvar_cl_bobfallcycle;
-float autocvar_cl_bobfallminspeed;
-float autocvar_cl_bob2;
-float autocvar_cl_bob2cycle;
-float autocvar_cl_bob2smooth;
+float autocvar_cl_bob = 0;
+float autocvar_cl_bobcycle = 0.5;
+float autocvar_cl_bob_limit = 7;
+float autocvar_cl_bob_limit_heightcheck = 0;
+float autocvar_cl_bob_velocity_limit = 400;
+float autocvar_cl_bobup = 0.5;
+float autocvar_cl_bobfall = 0.05;
+float autocvar_cl_bobfallcycle = 3;
+float autocvar_cl_bobfallminspeed = 200;
+float autocvar_cl_bob2 = 0;
+float autocvar_cl_bob2cycle = 1;
+float autocvar_cl_bob2smooth = 0.05;
float bobfall_swing;
float bobfall_speed;
float bob2_smooth;
vector CSQCPlayer_ApplyBobbing(entity this, vector v)
{
- if(IS_DEAD(this))
+ if(this.csqcmodel_isdead || PHYS_INVEHICLE(this) || !(this.isplayermodel & ISPLAYER_PLAYER))
return v;
// bounded XY speed, used by several effects below
{
makevectors(view_angles);
forward = v_forward;
+ if(autocvar_chase_front)
+ forward = normalize(forward * -1);
// trace a little further so it hits a surface more consistently (to avoid 'snapping' on the edge of the range)
float cdist = -autocvar_chase_back - 8;
chase_dest.x = v.x + forward.x * cdist;
v.x = 1 * trace_endpos.x + 8 * forward.x + 4 * trace_plane_normal.x;
v.y = 1 * trace_endpos.y + 8 * forward.y + 4 * trace_plane_normal.y;
v.z = 1 * trace_endpos.z + 8 * forward.z + 4 * trace_plane_normal.z;
+
+ if(autocvar_chase_front)
+ {
+ // now flip the view so the player is looking at themselves
+ vector newang = vectoangles(forward);
+ view_angles.x = view_angles.x * -1; // inverse up-down looking direction
+ view_angles.y = newang.y;
+ }
}
#if 0
setproperty(VF_ANGLES, view_angles);
}
-bool autocvar_cl_useenginerefdef = true;
+bool autocvar_cl_useenginerefdef = false;
/** Called once per CSQC_UpdateView() */
void CSQCPlayer_SetCamera()
#endif
CSQCPlayer_SetMinsMaxs(e);
- e.angles_y = input_angles.y;
+ if (!IS_DEAD(e))
+ e.angles.y = input_angles.y;
}
// relink
+ e.stairsmooth_drawtime = drawtime; // since drawtime is a frame old at this point, copy it now to avoid using a drawtime 2 frames old!
+ e.origin = CSQCModel_ApplyStairSmoothing(e, (e.pmove_flags & PMF_ONGROUND), e.origin);
setorigin(e, e.origin);
}
{
CSQCPlayer_CalcRefdef(view);
}
-
}
else
{
if (this.entnum != player_localnum + 1) return false;
csqcplayer = this;
csqcplayer_status = CSQCPLAYERSTATUS_FROMSERVER;
- cvar_settemp("cl_movement_replay", "0");
+ if (cvar("cl_movement_replay"))
+ cvar_settemp("cl_movement_replay", "0");
this.entremove = CSQCPlayer_Remove;
return true;
}