Skip to content

Commit

Permalink
game: added Neil Toronto's skip correction code
Browse files Browse the repository at this point in the history
  • Loading branch information
IR4T4 committed Dec 17, 2014
1 parent 20d3d4d commit eb6b0b6
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/game/bg_pmove.c
Expand Up @@ -1637,7 +1637,7 @@ static void PM_CrashLand(void)

// SURF_NODAMAGE is used for bounce pads where you don't ever
// want to take damage or play a crunch sound
if (!(pml.groundTrace.surfaceFlags & SURF_NODAMAGE))
if (!(pml.groundTrace.surfaceFlags & SURF_NODAMAGE) && !pm->predict)
{
if (pm->debugLevel)
{
Expand Down
8 changes: 6 additions & 2 deletions src/game/bg_public.h
Expand Up @@ -522,6 +522,10 @@ typedef struct
// these will be different functions during game and cgame
void (*trace)(trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentMask);
int (*pointcontents)(const vec3_t point, int passEntityNum);

// used to determine if the player move is for prediction if it is, the movement should trigger no events
qboolean predict;

} pmove_t;

// if a full pmove isn't done on the client, you can just update the angles
Expand Down Expand Up @@ -688,8 +692,8 @@ typedef enum
KEY_NUM_KEYS
} wkey_t; // conflicts with types.h

#define NO_AIRSTRIKE 1
#define NO_ARTILLERY 2
#define NO_AIRSTRIKE 1
#define NO_ARTILLERY 2

// NOTE: we can only use up to 15 in the client-server stream
// NOTE: should be 31 now (I added 1 bit in msg.c)
Expand Down
27 changes: 24 additions & 3 deletions src/game/g_active.c
Expand Up @@ -1458,7 +1458,7 @@ void ClientThink_real(gentity_t *ent)
ent->r.eventTime = level.time;
}

BG_PlayerStateToEntityState(&ent->client->ps, &ent->s, level.time, qfalse);
BG_PlayerStateToEntityState(&ent->client->ps, &ent->s, level.time, qtrue);

// use the precise origin for linking
//VectorCopy( ent->client->ps.origin, ent->r.currentOrigin );
Expand Down Expand Up @@ -2068,7 +2068,7 @@ void WolfReviveBbox(gentity_t *self)
*/
void ClientEndFrame(gentity_t *ent)
{
int i;
int i, frames;

// don't count skulled player time
if (g_gamestate.integer == GS_PLAYING && !(ent->client->ps.persistant[PERS_RESPAWNS_LEFT] == 0 && (ent->client->ps.pm_flags & PMF_LIMBO)))
Expand Down Expand Up @@ -2219,14 +2219,35 @@ void ClientEndFrame(gentity_t *ent)
// run entity scripting
G_Script_ScriptRun(ent);

// mark as not missing updates initially
ent->client->ps.eFlags &= ~EF_CONNECTION;

// see how many frames the client has missed
frames = level.framenum - ent->client->lastUpdateFrame - 1;

// etpro antiwarp
// frames = level.framenum - ent->client->lastUpdateFrame - 1)
if (g_maxWarp.integer && (level.framenum - ent->client->lastUpdateFrame - 1) > g_maxWarp.integer && G_DoAntiwarp(ent))
if (g_maxWarp.integer && frames > g_maxWarp.integer && G_DoAntiwarp(ent))
{
ent->client->warping = qtrue;
}
ent->client->warped = qfalse;

if (g_skipCorrection.integer && !ent->client->warped && frames > 0 && !G_DoAntiwarp(ent))
{
if (frames > 3)
{
// josh: I need frames to be = 2 here
frames = 3;
// these are disabled because the phone jack can give
// away other players position through walls.
ent->client->ps.eFlags |= EF_CONNECTION;
ent->s.eFlags |= EF_CONNECTION;
}
G_PredictPmove(ent, (float)frames / (float)sv_fps.integer);
}
ent->client->warped = qfalse;

#ifdef FEATURE_SERVERMDX
mdx_PlayerAnimation(ent);
#endif
Expand Down
151 changes: 147 additions & 4 deletions src/game/g_antilag.c
Expand Up @@ -518,12 +518,9 @@ void G_ResetMarkers(gentity_t *ent)
{
int i, time;
char buffer[MAX_CVAR_VALUE_STRING];
float period;
float period = sv_fps.value;
int eFlags;

trap_Cvar_VariableStringBuffer("sv_fps", buffer, sizeof(buffer) - 1);

period = atoi(buffer);
if (!period)
{
period = 50;
Expand Down Expand Up @@ -794,3 +791,149 @@ void G_Trace(gentity_t *ent, trace_t *results, const vec3_t start, const vec3_t
G_ResetTempTraceIgnoreEnts();
}
}

qboolean G_SkipCorrectionSafe(gentity_t *ent)
{
if (!ent)
{
return qfalse;
}

if (!ent->inuse)
{
return qfalse;
}

if (!ent->r.linked)
{
return qfalse;
}

if (!ent->client)
{
return qfalse;
}

if (ent->client->sess.sessionTeam != TEAM_AXIS
&& ent->client->sess.sessionTeam != TEAM_ALLIES)
{
return qfalse;
}

if ((ent->client->ps.pm_flags & PMF_LIMBO) ||
(ent->client->ps.pm_flags & PMF_TIME_LOCKPLAYER))
{
return qfalse;
}

if (ent->health <= 0)
{
return qfalse;
}

if (ent->client->ps.pm_type != PM_NORMAL)
{
return qfalse;
}

// this causes segfault with new PM_TraceLegs() from 2.60 because it wants to update pm.pmext which
// we don't bother passing.
if ((ent->client->ps.eFlags & EF_PRONE))
{
return qfalse;
}

if ((ent->client->ps.eFlags & EF_MOUNTEDTANK))
{
return qfalse;
}

// perhaps 2 would be OK too?
if (ent->waterlevel > 1)
{
return qfalse;
}

// don't bother with skip correction if the player isn't moving horizontally
if (!ent->client->ps.velocity[0] && !ent->client->ps.velocity[1])
{
return qfalse;
}

return qtrue;
}

/*
* @brief Make use of the 'Pmove' functions to figure out where a player
* would have moved in the short amount of time indicated by frametime.
*
* After the Pmove is complete, copy the values to the player's entity
* state, but then copy the original player state values back to the
* player state so that the player's movements aren't effected in any way.
*
* The only Pmove functions used are PM_StepSlideMove() and
* PM_GroundTrace() since these are all that is needed for this
* short period of time. This means that a lot of movement types
* cannot be predicted and no prediction should be done for them
* See G_SkipCorrectionSafe()
*
*/
void G_PredictPmove(gentity_t *ent, float frametime)
{
pmove_t pm;
vec3_t origin;
vec3_t velocity;
int groundEntityNum;
int pm_flags;
int pm_time;
int eFlags;
gclient_t *client;

if (!G_SkipCorrectionSafe(ent))
{
return;
}

client = ent->client;

// backup all the playerState values that may be altered by PmovePredict()
VectorCopy(client->ps.origin, origin);
VectorCopy(client->ps.velocity, velocity);
groundEntityNum = client->ps.groundEntityNum;
pm_flags = client->ps.pm_flags;
pm_time = client->ps.pm_time;
eFlags = client->ps.eFlags;

memset(&pm, 0, sizeof(pm));
pm.ps = &client->ps;
pm.pmext = &client->pmext;
pm.character = client->pers.character;
pm.trace = trap_TraceCapsuleNoEnts;
pm.pointcontents = trap_PointContents;
pm.tracemask = MASK_PLAYERSOLID;
VectorCopy(ent->r.mins, pm.mins);
VectorCopy(ent->r.maxs, pm.maxs);
pm.predict = qtrue;
//pm.debugLevel = 1;

PmovePredict(&pm, frametime);

// update entity state with the resulting player state
VectorCopy(client->ps.origin, ent->s.pos.trBase);
VectorCopy(client->ps.velocity, ent->s.pos.trDelta);
ent->s.groundEntityNum = client->ps.groundEntityNum;
ent->s.eFlags = client->ps.eFlags;

// this needs to be updated in case g_antilag is not enabled
VectorCopy(client->ps.origin, ent->r.currentOrigin);
// link them to stop them from skipping over mines and being unhittable when antilag is 0
trap_LinkEntity(ent);

// restore player state so that their next command will process as if nothing has happened.
VectorCopy(origin, client->ps.origin);
VectorCopy(velocity, client->ps.velocity);
client->ps.groundEntityNum = groundEntityNum;
client->ps.pm_flags = pm_flags;
client->ps.pm_time = pm_time;
client->ps.eFlags = eFlags;
}
6 changes: 5 additions & 1 deletion src/game/g_local.h
Expand Up @@ -1836,6 +1836,9 @@ extern vmCvar_t g_corpses;

extern vmCvar_t g_realHead;

extern vmCvar_t sv_fps;
extern vmCvar_t g_skipCorrection;

typedef struct GeoIPTag
{
fileHandle_t GeoIPDatabase;
Expand Down Expand Up @@ -1935,6 +1938,7 @@ void G_HistoricalTrace(gentity_t *ent, trace_t *results, const vec3_t start, con
void G_HistoricalTraceBegin(gentity_t *ent);
void G_HistoricalTraceEnd(gentity_t *ent);
void G_Trace(gentity_t *ent, trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask, qboolean ignoreCorpses);
void G_PredictPmove(gentity_t *ent, float frametime);

#define BODY_VALUE(ENT) ENT->watertype
#define BODY_TEAM(ENT) ENT->s.modelindex
Expand Down Expand Up @@ -2403,7 +2407,7 @@ void G_mapvoteinfo_read(void);
#define VOTEF_DISP_CALLER 4 // append "(called by name)" in vote string

// Server frametime is calculated with the sv_fps
#define SERVER_FRAMETIME (1000/trap_Cvar_VariableIntegerValue("sv_fps")) // (1000/20) default
#define SERVER_FRAMETIME (1000 / trap_Cvar_VariableIntegerValue("sv_fps")) // (1000/20) default
#define SERVER_FRAMETIME_F ((float)SERVER_FRAMETIME) // (1000/20) default

// Calculated deltas
Expand Down
5 changes: 5 additions & 0 deletions src/game/g_main.c
Expand Up @@ -329,6 +329,9 @@ vmCvar_t g_oss; // 0 - vanilla/unknown/ET:L auto setup

vmCvar_t g_realHead; // b_realHead functionality from ETPro

vmCvar_t sv_fps;
vmCvar_t g_skipCorrection;

cvarTable_t gameCvarTable[] =
{
// don't override the cheat state set by the system
Expand Down Expand Up @@ -597,6 +600,8 @@ cvarTable_t gameCvarTable[] =

{ &g_corpses, "g_dynBQ", "0", CVAR_LATCH | CVAR_ARCHIVE },
{ &g_realHead, "g_realHead", "1", 0 },
{ &sv_fps, "sv_fps", "20", CVAR_SYSTEMINFO, 0, qfalse},
{ &g_skipCorrection, "g_skipCorrection", "1", 0 },
};

// made static to avoid aliasing
Expand Down

0 comments on commit eb6b0b6

Please sign in to comment.