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;
}
}
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)
{
- if(this.csqcmodel_teleported || !IS_ONGROUND(this) || autocvar_cl_stairsmoothspeed <= 0)
+ 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)
stairsmoothz = v.z;
else
{
- if(v.z > stairsmoothz)
- v.z = stairsmoothz = bound(v.z - PHYS_STEPHEIGHT(this), stairsmoothz + frametime * autocvar_cl_stairsmoothspeed, v.z);
- else if(v.z < stairsmoothz)
- v.z = stairsmoothz = bound(v.z, stairsmoothz - frametime * autocvar_cl_stairsmoothspeed, v.z + PHYS_STEPHEIGHT(this));
+ if(stairsmoothz < v.z)
+ v.z = stairsmoothz = bound(v.z - PHYS_STEPHEIGHT(this), stairsmoothz + smoothtime * autocvar_cl_stairsmoothspeed, v.z);
+ else if(stairsmoothz > v.z)
+ v.z = stairsmoothz = bound(v.z, stairsmoothz - smoothtime * autocvar_cl_stairsmoothspeed, v.z + PHYS_STEPHEIGHT(this));
}
float viewheight = bound(0, (time - smooth_prevtime) / max(0.0001, autocvar_cl_smoothviewheight), 1);
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.y = autocvar_v_deathtiltangle;
+ view_angles.z = autocvar_v_deathtiltangle;
}
float autocvar_v_idlescale;
//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)
return v;
// bounded XY speed, used by several effects below
- float xyspeed = bound(0, sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y), autocvar_cl_bob_velocity_limit);
float bob, cycle;
// vertical view bobbing code
cycle = sin(M_PI + M_PI * (cycle - autocvar_cl_bobup) / (1.0 - autocvar_cl_bobup));
// bob is proportional to velocity in the xy plane
// (don't count Z, or jumping messes it up)
+ float xyspeed = bound(0, sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y), autocvar_cl_bob_velocity_limit);
bob = xyspeed * autocvar_cl_bob;
bob = bound(0, bob, bob_limit);
bob = bob * 0.3 + bob * 0.7 * cycle;
float autocvar_chase_pitchangle;
vector CSQCPlayer_ApplyChase(entity this, vector v)
{
- // don't need to do offset for view height here, it's done in smoothing!
- //v += this.view_ofs;
vector forward;
vector chase_dest;
return v;
}
-bool autocvar_cl_useenginerefdef;
+void CSQCPlayer_CalcRefdef(entity this)
+{
+ vector vieworg = this.origin;
+ if(intermission)
+ {
+ // just update view offset, don't need to do anything else
+ vieworg.z += this.view_ofs.z;
+ }
+ else
+ {
+ vieworg = CSQCPlayer_ApplySmoothing(this, vieworg);
+ if(autocvar_chase_active)
+ vieworg = CSQCPlayer_ApplyChase(this, vieworg);
+ else
+ {
+ // angles
+ CSQCPlayer_ApplyDeathTilt(this);
+ view_angles = view_angles + view_punchangle;
+ view_angles.z += CSQCPlayer_CalcRoll(this);
+ // TODO? we don't have damage time accessible here
+ // origin
+ vieworg = vieworg + view_punchvector;
+ vieworg = CSQCPlayer_ApplyBobbing(this, vieworg);
+ }
+ CSQCPlayer_ApplyIdleScaling(this);
+ }
+ setproperty(VF_ORIGIN, vieworg);
+ setproperty(VF_ANGLES, view_angles);
+}
+
+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
}
else
{
- vector vieworg = view.origin;
- vieworg = CSQCPlayer_ApplySmoothing(view, vieworg);
- if(autocvar_chase_active)
- vieworg = CSQCPlayer_ApplyChase(view, vieworg);
- else
- {
- // angles
- CSQCPlayer_ApplyDeathTilt(view);
- view_angles = view_angles + view_punchangle;
- view_angles.z += CSQCPlayer_CalcRoll(view);
- // TODO? we don't have damage time accessible here
- // origin
- vieworg = vieworg + view_punchvector;
- vieworg = CSQCPlayer_ApplyBobbing(view, vieworg);
- CSQCPlayer_ApplyIdleScaling(view);
- }
- setproperty(VF_ORIGIN, vieworg);
- setproperty(VF_ANGLES, view_angles);
+ CSQCPlayer_CalcRefdef(view);
}
-
}
else
{