From a9be87735a48f0cf3ccf143e661f6bd917091730 Mon Sep 17 00:00:00 2001 From: havoc Date: Mon, 7 May 2007 03:41:11 +0000 Subject: [PATCH] now sends player physics variables as stats, including slowmo, gravity, and sys_ticrate, this avoids the need to stuffcmd cl_movement cvars on servers that provide the ticrate stat the cl_netinputpacketspersecond cvar is no longer important, this also seems to improve demo recording git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7242 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_input.c | 144 ++++++++++++++++++++++++----------------------------- cl_main.c | 3 ++ cl_parse.c | 39 +++++++++------ client.h | 29 +++++++---- host.c | 2 +- host_cmd.c | 1 - quakedef.h | 16 ++++++ server.h | 3 ++ sv_main.c | 24 +++++++++ sv_user.c | 4 ++ 10 files changed, 160 insertions(+), 105 deletions(-) diff --git a/cl_input.c b/cl_input.c index ad392f68..c5e1a376 100644 --- a/cl_input.c +++ b/cl_input.c @@ -640,24 +640,6 @@ typedef struct cl_clientmovement_state_s // (this is in seconds and counts down to 0) float waterjumptime; - // movement parameters for physics code - float movevars_gravity; - float movevars_stopspeed; - float movevars_maxspeed; - float movevars_spectatormaxspeed; - float movevars_accelerate; - float movevars_airaccelerate; - float movevars_wateraccelerate; - float movevars_friction; - float movevars_waterfriction; - float movevars_entgravity; - float movevars_jumpvelocity; - float movevars_edgefriction; - float movevars_maxairspeed; - float movevars_stepheight; - float movevars_airaccel_qw; - float movevars_airaccel_sideways_friction; - // user command client_movementqueue_t q; } @@ -791,8 +773,8 @@ void CL_ClientMovement_Move(cl_clientmovement_state_t *s) { // may be a step or wall, try stepping up // first move forward at a higher level - VectorSet(currentorigin2, s->origin[0], s->origin[1], s->origin[2] + s->movevars_stepheight); - VectorSet(neworigin2, neworigin[0], neworigin[1], s->origin[2] + s->movevars_stepheight); + VectorSet(currentorigin2, s->origin[0], s->origin[1], s->origin[2] + cl.movevars_stepheight); + VectorSet(neworigin2, neworigin[0], neworigin[1], s->origin[2] + cl.movevars_stepheight); trace2 = CL_Move(currentorigin2, s->mins, s->maxs, neworigin2, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false); if (!trace2.startsolid) { @@ -886,7 +868,7 @@ void CL_ClientMovement_Physics_Swim(cl_clientmovement_state_t *s) VectorScale(wishvel, 1 / wishspeed, wishdir); else VectorSet( wishdir, 0.0, 0.0, 0.0 ); - wishspeed = min(wishspeed, s->movevars_maxspeed) * 0.7; + wishspeed = min(wishspeed, cl.movevars_maxspeed) * 0.7; if (s->crouched) wishspeed *= 0.5; @@ -894,7 +876,7 @@ void CL_ClientMovement_Physics_Swim(cl_clientmovement_state_t *s) if (s->waterjumptime <= 0) { // water friction - f = 1 - s->q.frametime * s->movevars_waterfriction * s->waterlevel; + f = 1 - s->q.frametime * cl.movevars_waterfriction * s->waterlevel; f = bound(0, f, 1); VectorScale(s->velocity, f, s->velocity); @@ -902,7 +884,7 @@ void CL_ClientMovement_Physics_Swim(cl_clientmovement_state_t *s) f = wishspeed - DotProduct(s->velocity, wishdir); if (f > 0) { - f = min(s->movevars_wateraccelerate * s->q.frametime * wishspeed, f); + f = min(cl.movevars_wateraccelerate * s->q.frametime * wishspeed, f); VectorMA(s->velocity, f, wishdir, s->velocity); } @@ -947,7 +929,7 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) { if (s->onground && s->q.canjump) { - s->velocity[2] += s->movevars_jumpvelocity; + s->velocity[2] += cl.movevars_jumpvelocity; s->onground = false; s->q.canjump = false; } @@ -966,7 +948,7 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) VectorScale(wishvel, 1 / wishspeed, wishdir); else VectorSet( wishdir, 0.0, 0.0, 0.0 ); - wishspeed = min(wishspeed, s->movevars_maxspeed); + wishspeed = min(wishspeed, cl.movevars_maxspeed); if (s->crouched) wishspeed *= 0.5; @@ -975,8 +957,8 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) { // apply edge friction f = sqrt(s->velocity[0] * s->velocity[0] + s->velocity[1] * s->velocity[1]); - friction = s->movevars_friction; - if (f > 0 && s->movevars_edgefriction != 1) + friction = cl.movevars_friction; + if (f > 0 && cl.movevars_edgefriction != 1) { vec3_t neworigin2; vec3_t neworigin3; @@ -990,16 +972,16 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) else trace = CL_Move(neworigin2, vec3_origin, vec3_origin, neworigin3, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false); if (trace.fraction == 1 && !trace.startsolid) - friction *= s->movevars_edgefriction; + friction *= cl.movevars_edgefriction; } // apply ground friction - f = 1 - s->q.frametime * friction * ((f < s->movevars_stopspeed) ? (s->movevars_stopspeed / f) : 1); + f = 1 - s->q.frametime * friction * ((f < cl.movevars_stopspeed) ? (cl.movevars_stopspeed / f) : 1); f = max(f, 0); VectorScale(s->velocity, f, s->velocity); addspeed = wishspeed - DotProduct(s->velocity, wishdir); if (addspeed > 0) { - accelspeed = min(s->movevars_accelerate * s->q.frametime * wishspeed, addspeed); + accelspeed = min(cl.movevars_accelerate * s->q.frametime * wishspeed, addspeed); VectorMA(s->velocity, accelspeed, wishdir, s->velocity); } s->velocity[2] -= cl_gravity.value * s->q.frametime; @@ -1018,13 +1000,13 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) vec3_t vel_perpend; // apply air speed limit - wishspeed = min(wishspeed, s->movevars_maxairspeed); + wishspeed = min(wishspeed, cl.movevars_maxairspeed); /* addspeed = wishspeed - DotProduct(s->velocity, wishdir); if (addspeed > 0) { - accelspeed = min(s->movevars_accelerate * s->q.frametime * wishspeed, addspeed); + accelspeed = min(cl.movevars_accelerate * s->q.frametime * wishspeed, addspeed); VectorMA(s->velocity, accelspeed, wishdir, s->velocity); } */ @@ -1036,11 +1018,11 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) f = wishspeed - vel_straight; if(f > 0) - vel_straight += min(f, s->movevars_accelerate * s->q.frametime * wishspeed) * s->movevars_airaccel_qw; + vel_straight += min(f, cl.movevars_accelerate * s->q.frametime * wishspeed) * cl.movevars_airaccel_qw; if(wishspeed > 0) - vel_straight += min(wishspeed, s->movevars_accelerate * s->q.frametime * wishspeed) * (1 - s->movevars_airaccel_qw); + vel_straight += min(wishspeed, cl.movevars_accelerate * s->q.frametime * wishspeed) * (1 - cl.movevars_airaccel_qw); - VectorM(1 - (s->q.frametime * (wishspeed / s->movevars_maxairspeed) * s->movevars_airaccel_sideways_friction), vel_perpend, vel_perpend); + VectorM(1 - (s->q.frametime * (wishspeed / cl.movevars_maxairspeed) * cl.movevars_airaccel_sideways_friction), vel_perpend, vel_perpend); VectorMA(vel_perpend, vel_straight, wishdir, s->velocity); s->velocity[2] += vel_z; @@ -1063,6 +1045,53 @@ void CL_ClientMovement_PlayerMove(cl_clientmovement_state_t *s) CL_ClientMovement_Physics_Walk(s); } +extern cvar_t slowmo; +void CL_UpdateMoveVars(void) +{ + if (cls.protocol == PROTOCOL_QUAKEWORLD) + cl.movevars_ticrate = 1.0 / bound(1, cl_netinputpacketspersecond.value, 100); + else if (cl.stats[STAT_MOVEVARS_TICRATE]) + { + cl.movevars_ticrate = cl.statsf[STAT_MOVEVARS_TICRATE]; + cl.movevars_slowmo = cl.statsf[STAT_MOVEVARS_TIMESCALE]; + cl.movevars_gravity = cl.statsf[STAT_MOVEVARS_GRAVITY]; + cl.movevars_stopspeed = cl.statsf[STAT_MOVEVARS_STOPSPEED] ; + cl.movevars_maxspeed = cl.statsf[STAT_MOVEVARS_MAXSPEED]; + cl.movevars_spectatormaxspeed = cl.statsf[STAT_MOVEVARS_SPECTATORMAXSPEED]; + cl.movevars_accelerate = cl.statsf[STAT_MOVEVARS_ACCELERATE]; + cl.movevars_airaccelerate = cl.statsf[STAT_MOVEVARS_AIRACCELERATE]; + cl.movevars_wateraccelerate = cl.statsf[STAT_MOVEVARS_WATERACCELERATE]; + cl.movevars_entgravity = cl.statsf[STAT_MOVEVARS_ENTGRAVITY]; + cl.movevars_jumpvelocity = cl.statsf[STAT_MOVEVARS_JUMPVELOCITY]; + cl.movevars_edgefriction = cl.statsf[STAT_MOVEVARS_EDGEFRICTION]; + cl.movevars_maxairspeed = cl.statsf[STAT_MOVEVARS_MAXAIRSPEED]; + cl.movevars_stepheight = cl.statsf[STAT_MOVEVARS_STEPHEIGHT]; + cl.movevars_airaccel_qw = cl.statsf[STAT_MOVEVARS_AIRACCEL_QW]; + cl.movevars_airaccel_sideways_friction = cl.statsf[STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION]; + } + else + { + cl.movevars_ticrate = 1.0 / bound(1, cl_netinputpacketspersecond.value, 100); + cl.movevars_slowmo = slowmo.value; + cl.movevars_gravity = sv_gravity.value; + cl.movevars_stopspeed = cl_movement_stopspeed.value; + cl.movevars_maxspeed = cl_movement_maxspeed.value; + cl.movevars_spectatormaxspeed = cl_movement_maxspeed.value; + cl.movevars_accelerate = cl_movement_accelerate.value; + cl.movevars_airaccelerate = cl_movement_airaccelerate.value < 0 ? cl_movement_accelerate.value : cl_movement_airaccelerate.value; + cl.movevars_wateraccelerate = cl_movement_wateraccelerate.value < 0 ? cl_movement_accelerate.value : cl_movement_wateraccelerate.value; + cl.movevars_friction = cl_movement_friction.value; + cl.movevars_waterfriction = cl_movement_waterfriction.value < 0 ? cl_movement_friction.value : cl_movement_waterfriction.value; + cl.movevars_entgravity = 1; + cl.movevars_jumpvelocity = cl_movement_jumpvelocity.value; + cl.movevars_edgefriction = cl_movement_edgefriction.value; + cl.movevars_maxairspeed = cl_movement_maxairspeed.value; + cl.movevars_stepheight = cl_movement_stepheight.value; + cl.movevars_airaccel_qw = cl_movement_airaccel_qw.value; + cl.movevars_airaccel_sideways_friction = cl_movement_airaccel_sideways_friction.value; + } +} + void CL_ClientMovement_Replay(void) { int i; @@ -1079,46 +1108,6 @@ void CL_ClientMovement_Replay(void) s.crouched = true; // will be updated on first move //Con_Printf("movement replay starting org %f %f %f vel %f %f %f\n", s.origin[0], s.origin[1], s.origin[2], s.velocity[0], s.velocity[1], s.velocity[2]); - // set up movement variables - if (cls.protocol == PROTOCOL_QUAKEWORLD) - { - s.movevars_gravity = cl.qw_movevars_gravity; - s.movevars_stopspeed = cl.qw_movevars_stopspeed; - s.movevars_maxspeed = cl.qw_movevars_maxspeed; - s.movevars_spectatormaxspeed = cl.qw_movevars_spectatormaxspeed; - s.movevars_accelerate = cl.qw_movevars_accelerate; - s.movevars_airaccelerate = cl.qw_movevars_airaccelerate; - s.movevars_wateraccelerate = cl.qw_movevars_wateraccelerate; - s.movevars_friction = cl.qw_movevars_friction; - s.movevars_waterfriction = cl.qw_movevars_waterfriction; - s.movevars_entgravity = cl.qw_movevars_entgravity; - s.movevars_jumpvelocity = cl_movement_jumpvelocity.value; - s.movevars_edgefriction = cl_movement_edgefriction.value; - s.movevars_maxairspeed = cl_movement_maxairspeed.value; - s.movevars_stepheight = cl_movement_stepheight.value; - s.movevars_airaccel_qw = 1.0; - s.movevars_airaccel_sideways_friction = 0.0; - } - else - { - s.movevars_gravity = sv_gravity.value; - s.movevars_stopspeed = cl_movement_stopspeed.value; - s.movevars_maxspeed = cl_movement_maxspeed.value; - s.movevars_spectatormaxspeed = cl_movement_maxspeed.value; - s.movevars_accelerate = cl_movement_accelerate.value; - s.movevars_airaccelerate = cl_movement_airaccelerate.value < 0 ? cl_movement_accelerate.value : cl_movement_airaccelerate.value; - s.movevars_wateraccelerate = cl_movement_wateraccelerate.value < 0 ? cl_movement_accelerate.value : cl_movement_wateraccelerate.value; - s.movevars_friction = cl_movement_friction.value; - s.movevars_waterfriction = cl_movement_waterfriction.value < 0 ? cl_movement_friction.value : cl_movement_waterfriction.value; - s.movevars_entgravity = 1; - s.movevars_jumpvelocity = cl_movement_jumpvelocity.value; - s.movevars_edgefriction = cl_movement_edgefriction.value; - s.movevars_maxairspeed = cl_movement_maxairspeed.value; - s.movevars_stepheight = cl_movement_stepheight.value; - s.movevars_airaccel_qw = cl_movement_airaccel_qw.value; - s.movevars_airaccel_sideways_friction = cl_movement_airaccel_sideways_friction.value; - } - totalmovetime = 0; for (i = 0;i < cl.movement_numqueue - 1;i++) totalmovetime += cl.movement_queue[i].frametime; @@ -1268,10 +1257,7 @@ void CL_SendMove(void) return; // don't send too often or else network connections can get clogged by a high renderer framerate - if (cl_netinputpacketspersecond.value >= 1) - packettime = 1.0 / bound(1, cl_netinputpacketspersecond.value, 1000); - else - packettime = 0; + packettime = cl.movevars_ticrate; // quakeworld servers take only frametimes // predicted dp7 servers take current interpolation time // unpredicted servers take an echo of the latest server timestamp diff --git a/cl_main.c b/cl_main.c index 994fe164..d07b186a 100644 --- a/cl_main.c +++ b/cl_main.c @@ -110,6 +110,9 @@ void CL_ClearState(void) // reset the view zoom interpolation cl.mviewzoom[0] = cl.mviewzoom[1] = 1; + // set up the float version of the stats array for easier access to float stats + cl.statsf = (float *)cl.stats; + cl.num_entities = 0; cl.num_static_entities = 0; cl.num_temp_entities = 0; diff --git a/cl_parse.c b/cl_parse.c index c77cd252..0542b584 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -1419,16 +1419,24 @@ void CL_ParseServerInfo (void) strlcpy (cl.levelname, str, sizeof(cl.levelname)); // get the movevars - cl.qw_movevars_gravity = MSG_ReadFloat(); - cl.qw_movevars_stopspeed = MSG_ReadFloat(); - cl.qw_movevars_maxspeed = MSG_ReadFloat(); - cl.qw_movevars_spectatormaxspeed = MSG_ReadFloat(); - cl.qw_movevars_accelerate = MSG_ReadFloat(); - cl.qw_movevars_airaccelerate = MSG_ReadFloat(); - cl.qw_movevars_wateraccelerate = MSG_ReadFloat(); - cl.qw_movevars_friction = MSG_ReadFloat(); - cl.qw_movevars_waterfriction = MSG_ReadFloat(); - cl.qw_movevars_entgravity = MSG_ReadFloat(); + cl.movevars_gravity = MSG_ReadFloat(); + cl.movevars_stopspeed = MSG_ReadFloat(); + cl.movevars_maxspeed = MSG_ReadFloat(); + cl.movevars_spectatormaxspeed = MSG_ReadFloat(); + cl.movevars_accelerate = MSG_ReadFloat(); + cl.movevars_airaccelerate = MSG_ReadFloat(); + cl.movevars_wateraccelerate = MSG_ReadFloat(); + cl.movevars_friction = MSG_ReadFloat(); + cl.movevars_waterfriction = MSG_ReadFloat(); + cl.movevars_entgravity = MSG_ReadFloat(); + // other movevars not in the protocol... + cl.movevars_slowmo = 1; + cl.movevars_jumpvelocity = 270; + cl.movevars_edgefriction = 2; + cl.movevars_maxairspeed = 30; + cl.movevars_stepheight = 18; + cl.movevars_airaccel_qw = 1.0; + cl.movevars_airaccel_sideways_friction = 0.0; // seperate the printfs so the server message can have a color Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n\2%s\n", str); @@ -2857,9 +2865,9 @@ static void CL_NetworkTimeReceived(double newtime) else if (fabs(cl.time - cl.mtime[1]) > 0.1) cl.time += 0.5 * (cl.mtime[1] - cl.time); // fast else if (cl.time > cl.mtime[1]) - cl.time -= 0.002 * slowmo.value; // fall into the past by 2ms + cl.time -= 0.002 * cl.movevars_slowmo; // fall into the past by 2ms else - cl.time += 0.001 * slowmo.value; // creep forward 1ms + cl.time += 0.001 * cl.movevars_slowmo; // creep forward 1ms } } // this packet probably contains a player entity update, so we will need @@ -2892,6 +2900,7 @@ CL_ParseServerMessage ===================== */ int parsingerror = false; +extern void CL_UpdateMoveVars(void); void CL_ParseServerMessage(void) { int cmd; @@ -3241,11 +3250,11 @@ void CL_ParseServerMessage(void) break; case qw_svc_maxspeed: - cl.qw_movevars_maxspeed = MSG_ReadFloat(); + cl.movevars_maxspeed = MSG_ReadFloat(); break; case qw_svc_entgravity: - cl.qw_movevars_entgravity = MSG_ReadFloat(); + cl.movevars_entgravity = MSG_ReadFloat(); break; case qw_svc_setpause: @@ -3695,6 +3704,8 @@ void CL_ParseServerMessage(void) EntityFrameQuake_ISeeDeadEntities(); + CL_UpdateMoveVars(); + parsingerror = false; // LordHavoc: this was at the start of the function before cl_autodemo was diff --git a/client.h b/client.h index 139ac55b..8f370009 100644 --- a/client.h +++ b/client.h @@ -691,6 +691,7 @@ typedef struct client_state_s // information for local display // health, etc int stats[MAX_CL_STATS]; + float *statsf; // points to stats[] array // last known inventory bit flags, for blinking int olditems; // cl.time of acquiring item, for blinking @@ -942,16 +943,24 @@ typedef struct client_state_s //qboolean qw_spectator; // movement parameters for client prediction - float qw_movevars_gravity; - float qw_movevars_stopspeed; - float qw_movevars_maxspeed; // can change during play - float qw_movevars_spectatormaxspeed; - float qw_movevars_accelerate; - float qw_movevars_airaccelerate; - float qw_movevars_wateraccelerate; - float qw_movevars_friction; - float qw_movevars_waterfriction; - float qw_movevars_entgravity; // can change during play + float movevars_ticrate; + float movevars_slowmo; + float movevars_gravity; + float movevars_stopspeed; + float movevars_maxspeed; + float movevars_spectatormaxspeed; + float movevars_accelerate; + float movevars_airaccelerate; + float movevars_wateraccelerate; + float movevars_friction; + float movevars_waterfriction; + float movevars_entgravity; + float movevars_jumpvelocity; + float movevars_edgefriction; + float movevars_maxairspeed; + float movevars_stepheight; + float movevars_airaccel_qw; + float movevars_airaccel_sideways_friction; // models used by qw protocol int qw_modelindex_spike; diff --git a/host.c b/host.c index 735905cb..637c2be6 100644 --- a/host.c +++ b/host.c @@ -771,7 +771,7 @@ void Host_Main(void) clframetime = cl.realframetime = 0.1; // apply slowmo scaling - clframetime *= slowmo.value; + clframetime *= cl.movevars_slowmo; // host_framerate overrides all else if (host_framerate.value) diff --git a/host_cmd.c b/host_cmd.c index 95647886..20b0a9a3 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -697,7 +697,6 @@ void Host_Loadgame_f (void) Host_Error("Host_PerformLoadGame: too many edicts in save file (reached MAX_EDICTS %i)", MAX_EDICTS); } while (entnum >= prog->max_edicts) - //SV_IncreaseEdicts(); PRVM_MEM_IncreaseEdicts(); ent = PRVM_EDICT_NUM(entnum); memset (ent->fields.server, 0, prog->progs->entityfields * 4); diff --git a/quakedef.h b/quakedef.h index 936ec175..fed34ab8 100644 --- a/quakedef.h +++ b/quakedef.h @@ -94,6 +94,22 @@ extern char engineversion[128]; //#define STAT_TIME 17 // FTE //#define STAT_VIEW2 20 // FTE #define STAT_VIEWZOOM 21 // DP +#define STAT_MOVEVARS_TICRATE 240 // DP +#define STAT_MOVEVARS_TIMESCALE 241 // DP +#define STAT_MOVEVARS_GRAVITY 242 // DP +#define STAT_MOVEVARS_STOPSPEED 243 // DP +#define STAT_MOVEVARS_MAXSPEED 244 // DP +#define STAT_MOVEVARS_SPECTATORMAXSPEED 245 // DP +#define STAT_MOVEVARS_ACCELERATE 246 // DP +#define STAT_MOVEVARS_AIRACCELERATE 247 // DP +#define STAT_MOVEVARS_WATERACCELERATE 248 // DP +#define STAT_MOVEVARS_ENTGRAVITY 249 // DP +#define STAT_MOVEVARS_JUMPVELOCITY 250 // DP +#define STAT_MOVEVARS_EDGEFRICTION 251 // DP +#define STAT_MOVEVARS_MAXAIRSPEED 252 // DP +#define STAT_MOVEVARS_STEPHEIGHT 253 // DP +#define STAT_MOVEVARS_AIRACCEL_QW 254 // DP +#define STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION 255 // DP // stock defines diff --git a/server.h b/server.h index 0eda6332..34c95851 100644 --- a/server.h +++ b/server.h @@ -294,6 +294,9 @@ extern cvar_t sv_maxairspeed; extern cvar_t sv_accelerate; extern cvar_t sv_airaccelerate; extern cvar_t sv_wateraccelerate; +extern cvar_t sv_jumpvelocity; +extern cvar_t sv_airaccel_qw; +extern cvar_t sv_airaccel_sideways_friction; extern cvar_t sv_idealpitchscale; extern cvar_t sv_aim; extern cvar_t sv_stepheight; diff --git a/sv_main.c b/sv_main.c index 7b89111e..73d2edde 100644 --- a/sv_main.c +++ b/sv_main.c @@ -123,6 +123,9 @@ void SV_Init (void) Cvar_RegisterVariable (&sv_accelerate); Cvar_RegisterVariable (&sv_airaccelerate); Cvar_RegisterVariable (&sv_wateraccelerate); + Cvar_RegisterVariable (&sv_jumpvelocity); + Cvar_RegisterVariable (&sv_airaccel_qw); + Cvar_RegisterVariable (&sv_airaccel_sideways_friction); Cvar_RegisterVariable (&sv_clmovement_enable); Cvar_RegisterVariable (&sv_clmovement_minping); Cvar_RegisterVariable (&sv_clmovement_minping_disabletime); @@ -1078,6 +1081,8 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t vec3_t punchvector; int viewzoom; const char *s; + float *statsf = (float *)stats; +extern cvar_t slowmo; // // send a damage message @@ -1188,6 +1193,25 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t //stats[STAT_SECRETS] = prog->globals.server->found_secrets; //stats[STAT_MONSTERS] = prog->globals.server->killed_monsters; + // movement settings for prediction + statsf[STAT_MOVEVARS_TICRATE] = sys_ticrate.value; + statsf[STAT_MOVEVARS_TIMESCALE] = slowmo.value; + statsf[STAT_MOVEVARS_GRAVITY] = sv_gravity.value; + statsf[STAT_MOVEVARS_STOPSPEED] = sv_stopspeed.value; + statsf[STAT_MOVEVARS_MAXSPEED] = sv_maxspeed.value; + statsf[STAT_MOVEVARS_SPECTATORMAXSPEED] = sv_maxspeed.value; // FIXME: QW has a separate cvar for this + statsf[STAT_MOVEVARS_ACCELERATE] = sv_accelerate.value; + statsf[STAT_MOVEVARS_AIRACCELERATE] = sv_airaccelerate.value >= 0 ? sv_airaccelerate.value : sv_accelerate.value; + statsf[STAT_MOVEVARS_WATERACCELERATE] = sv_wateraccelerate.value >= 0 ? sv_wateraccelerate.value : sv_accelerate.value; + val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.gravity); + statsf[STAT_MOVEVARS_ENTGRAVITY] = val ? val->_float : 1.0f; + statsf[STAT_MOVEVARS_JUMPVELOCITY] = sv_jumpvelocity.value; + statsf[STAT_MOVEVARS_EDGEFRICTION] = sv_edgefriction.value; + statsf[STAT_MOVEVARS_MAXAIRSPEED] = sv_maxairspeed.value; + statsf[STAT_MOVEVARS_STEPHEIGHT] = sv_stepheight.value; + statsf[STAT_MOVEVARS_AIRACCEL_QW] = sv_airaccel_qw.value; + statsf[STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION] = sv_airaccel_sideways_friction.value; + if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5) { if (stats[STAT_VIEWHEIGHT] != DEFAULT_VIEWHEIGHT) bits |= SU_VIEWHEIGHT; diff --git a/sv_user.c b/sv_user.c index f00cc3ad..df8e90ec 100644 --- a/sv_user.c +++ b/sv_user.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // sv_user.c -- server code for moving users #include "quakedef.h" +#define DEBUGMOVES 0 cvar_t sv_edgefriction = {0, "edgefriction", "2", "how much you slow down when nearing a ledge you might fall off"}; cvar_t sv_idealpitchscale = {0, "sv_idealpitchscale","0.8", "how much to look up/down slopes and stairs when not using freelook"}; @@ -28,6 +29,9 @@ cvar_t sv_maxairspeed = {0, "sv_maxairspeed", "30", "maximum speed a player can cvar_t sv_accelerate = {0, "sv_accelerate", "10", "rate at which a player accelerates to sv_maxspeed"}; cvar_t sv_airaccelerate = {0, "sv_airaccelerate", "-1", "rate at which a player accelerates to sv_maxairspeed while in the air, if less than 0 the sv_accelerate variable is used instead"}; cvar_t sv_wateraccelerate = {0, "sv_wateraccelerate", "-1", "rate at which a player accelerates to sv_maxspeed while in the air, if less than 0 the sv_accelerate variable is used instead"}; +cvar_t sv_jumpvelocity = {0, "sv_jumpvelocity", "270", "cvar that can be used by QuakeC code for jump velocity"}; +cvar_t sv_airaccel_qw = {0, "sv_airaccelerate", "1", "ratio of QW-style air control as opposed to simple acceleration"}; +cvar_t sv_airaccel_sideways_friction = {0, "sv_airaccelerate", "", "anti-sideways movement stabilization (reduces speed gain when zigzagging)"}; cvar_t sv_clmovement_enable = {0, "sv_clmovement_enable", "1", "whether to allow clients to use cl_movement prediction, which can cause choppy movement on the server which may annoy other players"}; cvar_t sv_clmovement_minping = {0, "sv_clmovement_minping", "0", "if client ping is below this time in milliseconds, then their ability to use cl_movement prediction is disabled for a while (as they don't need it)"}; cvar_t sv_clmovement_minping_disabletime = {0, "sv_clmovement_minping_disabletime", "1000", "when client falls below minping, disable their prediction for this many milliseconds (should be at least 1000 or else their prediction may turn on/off frequently)"}; -- 2.39.2