mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
Add support for sv_antilag (from fteqw).
I'm not 100% certain it actually works, but it doesn't seem to have broken anything :)
This commit is contained in:
parent
40da338674
commit
276b6f9662
7 changed files with 175 additions and 30 deletions
|
@ -32,6 +32,11 @@
|
|||
#include "QF/mathlib.h"
|
||||
#include "QF/model.h"
|
||||
|
||||
typedef struct {
|
||||
qboolean present;
|
||||
vec3_t laggedpos;
|
||||
} laggedentinfo_t;
|
||||
|
||||
typedef enum {
|
||||
tr_point,
|
||||
tr_box,
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include "QF/quakeio.h"
|
||||
#include "QF/sizebuf.h"
|
||||
|
||||
#include "world.h"
|
||||
|
||||
#include "host.h"
|
||||
#include "netchan.h"
|
||||
#include "qw/bothdefs.h"
|
||||
|
@ -86,6 +88,11 @@ typedef struct {
|
|||
|
||||
byte *pvs, *phs; // fully expanded and decompressed
|
||||
|
||||
//antilag
|
||||
float lagentsfrac;
|
||||
laggedentinfo_t *lagents;
|
||||
unsigned maxlagents;
|
||||
|
||||
// added to every client's unreliable buffer each frame, then cleared
|
||||
sizebuf_t datagram;
|
||||
byte datagram_buf[MAX_DATAGRAM];
|
||||
|
@ -133,6 +140,8 @@ typedef struct {
|
|||
// reply
|
||||
double senttime;
|
||||
float ping_time;
|
||||
vec3_t playerpositions[MAX_CLIENTS];
|
||||
qboolean playerpresent[MAX_CLIENTS];
|
||||
packet_entities_t entities;
|
||||
packet_players_t players;
|
||||
} client_frame_t;
|
||||
|
@ -215,6 +224,11 @@ typedef struct client_s {
|
|||
double connection_started; // or time of disconnect for zombies
|
||||
qboolean send_message; // set on frames a datagram arived on
|
||||
|
||||
//antilag stuff
|
||||
laggedentinfo_t laggedents[MAX_CLIENTS];
|
||||
unsigned laggedents_count;
|
||||
float laggedents_frac;
|
||||
|
||||
// spawn parms are carried from level to level
|
||||
float spawn_parms[NUM_SPAWN_PARMS];
|
||||
|
||||
|
@ -369,21 +383,22 @@ typedef enum {
|
|||
#define DAMAGE_AIM 2
|
||||
|
||||
// edict->flags
|
||||
#define FL_FLY 1
|
||||
#define FL_SWIM 2
|
||||
#define FL_GLIMPSE 4
|
||||
#define FL_CLIENT 8
|
||||
#define FL_INWATER 16
|
||||
#define FL_MONSTER 32
|
||||
#define FL_GODMODE 64
|
||||
#define FL_NOTARGET 128
|
||||
#define FL_ITEM 256
|
||||
#define FL_ONGROUND 512
|
||||
#define FL_PARTIALGROUND 1024 // not all corners are valid
|
||||
#define FL_WATERJUMP 2048 // player jumping out of water
|
||||
#define FL_FLY (1<<0)
|
||||
#define FL_SWIM (1<<1)
|
||||
#define FL_GLIMPSE (1<<2)
|
||||
#define FL_CLIENT (1<<3)
|
||||
#define FL_INWATER (1<<4)
|
||||
#define FL_MONSTER (1<<5)
|
||||
#define FL_GODMODE (1<<6)
|
||||
#define FL_NOTARGET (1<<7)
|
||||
#define FL_ITEM (1<<8)
|
||||
#define FL_ONGROUND (1<<9)
|
||||
#define FL_PARTIALGROUND (1<<10) // not all corners are valid
|
||||
#define FL_WATERJUMP (1<<11) // player jumping out of water
|
||||
// 4096 used by quakec
|
||||
#define FL_FINALIZED 8192
|
||||
#define FL_FINDABLE_NONSOLID 16384
|
||||
#define FL_FINALIZED (1<<13)
|
||||
#define FL_FINDABLE_NONSOLID (1<<14)
|
||||
#define FLQW_LAGGEDMOVE (1<<16)
|
||||
|
||||
// entity effects
|
||||
|
||||
|
@ -531,7 +546,8 @@ void SV_RunNewmis (void);
|
|||
void SV_SetMoveVars(void);
|
||||
struct trace_s;
|
||||
int SV_FlyMove (struct edict_s *ent, float time, struct trace_s *steptrace);
|
||||
struct trace_s SV_PushEntity (struct edict_s *ent, vec3_t push);
|
||||
struct trace_s SV_PushEntity (struct edict_s *ent, vec3_t push,
|
||||
unsigned traceflags);
|
||||
int SV_EntCanSupportJump (struct edict_s *ent);
|
||||
|
||||
//
|
||||
|
@ -609,6 +625,8 @@ void SV_WriteEntitiesToClient (delta_t *delta, sizebuf_t *msg);
|
|||
|
||||
void Cvar_Info (struct cvar_s *var);
|
||||
|
||||
extern struct cvar_s *sv_antilag;
|
||||
extern struct cvar_s *sv_antilag_frac;
|
||||
extern struct cvar_s *sv_timecheck_fuzz;
|
||||
extern struct cvar_s *sv_timecheck_decay;
|
||||
extern struct cvar_s *sv_maxrate;
|
||||
|
|
|
@ -377,7 +377,7 @@ SV_FinishGravity (edict_t *ent, vec3_t move)
|
|||
Does not change the entities velocity at all
|
||||
*/
|
||||
trace_t
|
||||
SV_PushEntity (edict_t *ent, vec3_t push)
|
||||
SV_PushEntity (edict_t *ent, vec3_t push, unsigned traceflags)
|
||||
{
|
||||
trace_t trace;
|
||||
vec3_t end;
|
||||
|
@ -392,13 +392,17 @@ SV_PushEntity (edict_t *ent, vec3_t push)
|
|||
|
||||
VectorAdd (e_origin, push, end);
|
||||
|
||||
if ((int) SVfloat (ent, flags) & FLQW_LAGGEDMOVE)
|
||||
traceflags |= MOVE_LAGGED;
|
||||
|
||||
if (e_movetype == MOVETYPE_FLYMISSILE)
|
||||
trace = SV_Move (e_origin, e_mins, e_maxs, end, MOVE_MISSILE, ent);
|
||||
traceflags |= MOVE_MISSILE;
|
||||
else if (e_solid == SOLID_TRIGGER || e_solid == SOLID_NOT)
|
||||
// clip against only bmodels
|
||||
trace = SV_Move (e_origin, e_mins, e_maxs, end, MOVE_NOMONSTERS, ent);
|
||||
traceflags |= MOVE_NOMONSTERS;
|
||||
else
|
||||
trace = SV_Move (e_origin, e_mins, e_maxs, end, MOVE_NORMAL, ent);
|
||||
traceflags |= MOVE_NORMAL;
|
||||
trace = SV_Move (e_origin, e_mins, e_maxs, end, traceflags, ent);
|
||||
|
||||
VectorCopy (trace.endpos, e_origin);
|
||||
SV_LinkEdict (ent, true);
|
||||
|
@ -511,7 +515,7 @@ SV_Push (edict_t *pusher, const vec3_t tmove, const vec3_t amove)
|
|||
// try moving the contacted entity
|
||||
solid_save = SVfloat (pusher, solid);
|
||||
SVfloat (pusher, solid) = SOLID_NOT;
|
||||
SV_PushEntity (check, move);
|
||||
SV_PushEntity (check, move, MOVE_NORMAL);
|
||||
SVfloat (pusher, solid) = solid_save;
|
||||
|
||||
block = SV_TestEntityPosition (check);
|
||||
|
@ -691,6 +695,7 @@ SV_Physics_Toss (edict_t *ent)
|
|||
float backoff;
|
||||
trace_t trace;
|
||||
vec3_t move;
|
||||
int fl;
|
||||
|
||||
// regular thinking
|
||||
if (!SV_RunThink (ent))
|
||||
|
@ -720,7 +725,11 @@ SV_Physics_Toss (edict_t *ent)
|
|||
SVdata (ent)->add_grav = false;
|
||||
SV_FinishGravity (ent, move);
|
||||
}
|
||||
trace = SV_PushEntity (ent, move);
|
||||
|
||||
fl = 0;
|
||||
if (sv_antilag->int_val == 2)
|
||||
fl |= MOVE_LAGGED;
|
||||
trace = SV_PushEntity (ent, move, fl);
|
||||
if (trace.fraction == 1)
|
||||
return;
|
||||
if (ent->free)
|
||||
|
|
|
@ -387,6 +387,9 @@ PF_traceline (progs_t *pr)
|
|||
nomonsters = P_FLOAT (pr, 2);
|
||||
ent = P_EDICT (pr, 3);
|
||||
|
||||
if (sv_antilag->int_val == 2)
|
||||
nomonsters |= MOVE_LAGGED;
|
||||
|
||||
trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent);
|
||||
|
||||
*sv_globals.trace_allsolid = trace.allsolid;
|
||||
|
|
|
@ -750,6 +750,9 @@ CPQW_traceline (progs_t *pr)
|
|||
nomonsters = TL_ANY_SOLID;
|
||||
nomonsters = tl_to_move[nomonsters];
|
||||
|
||||
if (sv_antilag->int_val == 2)
|
||||
nomonsters |= MOVE_LAGGED;
|
||||
|
||||
trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent);
|
||||
|
||||
*sv_globals.trace_allsolid = trace.allsolid;
|
||||
|
|
|
@ -79,6 +79,9 @@ edict_t *sv_player;
|
|||
|
||||
usercmd_t cmd;
|
||||
|
||||
cvar_t *sv_antilag;
|
||||
cvar_t *sv_antilag_frac;
|
||||
|
||||
cvar_t *sv_accelerate;
|
||||
cvar_t *sv_airaccelerate;
|
||||
cvar_t *sv_maxspeed;
|
||||
|
@ -1869,6 +1872,21 @@ SV_ExecuteClientMessage (client_t *cl)
|
|||
frame = &cl->delta.frames[cl->delta.cur_frame];
|
||||
frame->ping_time = realtime - frame->senttime;
|
||||
|
||||
cl->laggedents_count = 0;
|
||||
if (sv_antilag->int_val) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
cl->laggedents[i].present = frame->playerpresent[i];
|
||||
if (cl->laggedents[i].present) {
|
||||
VectorCopy(frame->playerpositions[i],
|
||||
cl->laggedents[i].laggedpos);
|
||||
}
|
||||
}
|
||||
cl->laggedents_count = MAX_CLIENTS;
|
||||
cl->laggedents_frac = sv_antilag_frac->value;
|
||||
}
|
||||
|
||||
// save time for ping calculations
|
||||
cl->delta.frames[cl->delta.out_frame].senttime = realtime;
|
||||
cl->delta.frames[cl->delta.out_frame].ping_time = -1;
|
||||
|
@ -2001,6 +2019,15 @@ SV_UserInit (void)
|
|||
cl_rollangle = Cvar_Get ("cl_rollangle", "2", CVAR_NONE, NULL, "How much "
|
||||
"a player's screen tilts when strafing");
|
||||
|
||||
sv_antilag = Cvar_Get ("sv_antilag", "1", CVAR_SERVERINFO, Cvar_Info,
|
||||
"Attempt to backdate impacts to compensate for "
|
||||
"lag. 0=completely off. 1=mod-controlled. "
|
||||
"2=forced, which might break certain uses of "
|
||||
"traceline.");
|
||||
sv_antilag_frac = Cvar_Get ("sv_antilag_frac", "1", CVAR_SERVERINFO,
|
||||
Cvar_Info,
|
||||
"FIXME something to do with sv_antilag");
|
||||
|
||||
sv_allowfake = Cvar_Get ("sv_allowfake", "2", CVAR_NONE, NULL, "Allow 'fake' messages (FuhQuake $\\). 1 = "
|
||||
"always, 2 = only say_team");
|
||||
sv_spectalk = Cvar_Get ("sv_spectalk", "1", CVAR_NONE, NULL, "Toggles "
|
||||
|
|
|
@ -717,16 +717,18 @@ ctl_pretest_other (edict_t *touch, moveclip_t *clip)
|
|||
}
|
||||
|
||||
static inline int
|
||||
ctl_touch_test (edict_t *touch, moveclip_t *clip)
|
||||
ctl_pretest_lagged (edict_t *touch, moveclip_t *clip)
|
||||
{
|
||||
if (clip->boxmins[0] > SVvector (touch, absmax)[0]
|
||||
|| clip->boxmins[1] > SVvector (touch, absmax)[1]
|
||||
|| clip->boxmins[2] > SVvector (touch, absmax)[2]
|
||||
|| clip->boxmaxs[0] < SVvector (touch, absmin)[0]
|
||||
|| clip->boxmaxs[1] < SVvector (touch, absmin)[1]
|
||||
|| clip->boxmaxs[2] < SVvector (touch, absmin)[2])
|
||||
return 0;
|
||||
if (clip->type & MOVE_LAGGED)
|
||||
if ((unsigned) (touch->entnum - 1) < sv.maxlagents)
|
||||
if (sv.lagents[touch->entnum - 1].present)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ctl_touch_common (edict_t *touch, moveclip_t *clip)
|
||||
{
|
||||
if (clip->passedict && SVvector (clip->passedict, size)[0]
|
||||
&& !SVvector (touch, size)[0])
|
||||
return 0; // points never interact
|
||||
|
@ -743,6 +745,34 @@ ctl_touch_test (edict_t *touch, moveclip_t *clip)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ctl_touch_test (edict_t *touch, moveclip_t *clip)
|
||||
{
|
||||
if (clip->boxmins[0] > SVvector (touch, absmax)[0]
|
||||
|| clip->boxmins[1] > SVvector (touch, absmax)[1]
|
||||
|| clip->boxmins[2] > SVvector (touch, absmax)[2]
|
||||
|| clip->boxmaxs[0] < SVvector (touch, absmin)[0]
|
||||
|| clip->boxmaxs[1] < SVvector (touch, absmin)[1]
|
||||
|| clip->boxmaxs[2] < SVvector (touch, absmin)[2])
|
||||
return 0;
|
||||
|
||||
return ctl_touch_common (touch, clip);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ctl_touch_test_origin (edict_t *touch, const vec3_t origin, moveclip_t *clip)
|
||||
{
|
||||
if (clip->boxmins[0] > origin[0] + SVvector (touch, maxs)[0]
|
||||
|| clip->boxmins[1] > origin[1] + SVvector (touch, maxs)[1]
|
||||
|| clip->boxmins[2] > origin[2] + SVvector (touch, maxs)[2]
|
||||
|| clip->boxmaxs[0] < origin[0] + SVvector (touch, mins)[0]
|
||||
|| clip->boxmaxs[1] < origin[1] + SVvector (touch, mins)[1]
|
||||
|| clip->boxmaxs[2] < origin[2] + SVvector (touch, mins)[2])
|
||||
return 0;
|
||||
|
||||
return ctl_touch_common (touch, clip);
|
||||
}
|
||||
|
||||
static void
|
||||
ctl_do_clip (edict_t *touch, moveclip_t *clip, trace_t *trace)
|
||||
{
|
||||
|
@ -793,6 +823,8 @@ SV_ClipToLinks (areanode_t *node, moveclip_t *clip)
|
|||
return;
|
||||
if (!ctl_pretest_everything (touch, clip))
|
||||
continue;
|
||||
if (!ctl_pretest_lagged (touch, clip))
|
||||
continue;
|
||||
if (!ctl_touch_test (touch, clip))
|
||||
continue;
|
||||
ctl_do_clip (touch, clip, &trace);
|
||||
|
@ -806,6 +838,8 @@ SV_ClipToLinks (areanode_t *node, moveclip_t *clip)
|
|||
return;
|
||||
if (!ctl_pretest_triggers (touch, clip))
|
||||
continue;
|
||||
if (!ctl_pretest_lagged (touch, clip))
|
||||
continue;
|
||||
if (!ctl_touch_test (touch, clip))
|
||||
continue;
|
||||
ctl_do_clip (touch, clip, &trace);
|
||||
|
@ -820,6 +854,8 @@ SV_ClipToLinks (areanode_t *node, moveclip_t *clip)
|
|||
return;
|
||||
if (!ctl_pretest_other (touch, clip))
|
||||
continue;
|
||||
if (!ctl_pretest_lagged (touch, clip))
|
||||
continue;
|
||||
if (!ctl_touch_test (touch, clip))
|
||||
continue;
|
||||
ctl_do_clip (touch, clip, &trace);
|
||||
|
@ -892,7 +928,51 @@ SV_Move (const vec3_t start, const vec3_t mins, const vec3_t maxs,
|
|||
clip.boxmaxs);
|
||||
|
||||
// clip to entities
|
||||
SV_ClipToLinks (sv_areanodes, &clip);
|
||||
if (clip.type & MOVE_LAGGED) {
|
||||
clip.type &= ~MOVE_LAGGED;
|
||||
if (passedict->entnum && passedict->entnum <= MAX_CLIENTS) {
|
||||
client_t *cl = &svs.clients[passedict->entnum - 1];
|
||||
clip.type |= MOVE_LAGGED;
|
||||
sv.lagents = cl->laggedents;
|
||||
sv.maxlagents = cl->laggedents_count;
|
||||
sv.lagentsfrac = cl->laggedents_frac;
|
||||
} else if (PROG_TO_EDICT (&sv_pr_state, SVentity (passedict, owner))) {
|
||||
edict_t *owner;
|
||||
owner = PROG_TO_EDICT (&sv_pr_state, SVentity (passedict, owner));
|
||||
if (owner->entnum && owner->entnum <= MAX_CLIENTS) {
|
||||
client_t *cl = &svs.clients[passedict->entnum - 1];
|
||||
clip.type |= MOVE_LAGGED;
|
||||
sv.lagents = cl->laggedents;
|
||||
sv.maxlagents = cl->laggedents_count;
|
||||
sv.lagentsfrac = cl->laggedents_frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (clip.type & MOVE_LAGGED) {
|
||||
trace_t trace;
|
||||
edict_t *touch;
|
||||
vec3_t lp;
|
||||
unsigned li;
|
||||
|
||||
SV_ClipToLinks (sv_areanodes, &clip);
|
||||
for (li = 0; li < sv.maxlagents; li++) {
|
||||
if (!sv.lagents[li].present)
|
||||
continue;
|
||||
if (clip.trace.allsolid)
|
||||
break;
|
||||
|
||||
touch = EDICT_NUM (&sv_pr_state, li + 1);
|
||||
if (!ctl_pretest_other (touch, &clip))
|
||||
continue;
|
||||
VectorBlend (SVvector(touch, origin), sv.lagents[li].laggedpos,
|
||||
sv.lagentsfrac, lp);
|
||||
if (!ctl_touch_test_origin (touch, lp, &clip))
|
||||
continue;
|
||||
ctl_do_clip (touch, &clip, &trace);
|
||||
}
|
||||
} else {
|
||||
SV_ClipToLinks (sv_areanodes, &clip);
|
||||
}
|
||||
|
||||
return clip.trace;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue