Skip to content

Commit

Permalink
game: factorize antilag trace, refs #1408
Browse files Browse the repository at this point in the history
  • Loading branch information
Aranud committed Oct 23, 2020
1 parent 0d8502b commit 8eff4c6
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 119 deletions.
141 changes: 30 additions & 111 deletions src/game/g_antilag.c
Expand Up @@ -181,8 +181,10 @@ void G_StoreClientPosition(gentity_t *ent)
* @brief Move a client back to where he was at the specified "time"
* @param[in,out] ent client entity which to shift
* @param[in] time timestamp which to use
* @param[in] adjustHeight adjusted player height or not
* @param[in] height value to use for adjustement
*/
static void G_AdjustSingleClientPosition(gentity_t *ent, int time)
static void G_AdjustSingleClientPosition(gentity_t *ent, int time, qboolean adjustHeight, float height)
{
int i, j;

Expand Down Expand Up @@ -225,6 +227,13 @@ static void G_AdjustSingleClientPosition(gentity_t *ent, int time)
VectorCopy(ent->r.currentOrigin, ent->client->backupMarker.origin);
VectorCopy(ent->r.mins, ent->client->backupMarker.mins);
VectorCopy(ent->r.maxs, ent->client->backupMarker.maxs);

// adjust player height
if (adjustHeight)
{
ent->r.maxs[2] = height;
}

// Head, Legs
VectorCopy(ent->client->ps.viewangles, ent->client->backupMarker.viewangles);
ent->client->backupMarker.eFlags = ent->client->ps.eFlags;
Expand Down Expand Up @@ -511,7 +520,22 @@ static void G_AdjustClientPositions(gentity_t *skip, int time, qboolean backward

if (backwards)
{
G_AdjustSingleClientPosition(list, time);
float height;

if (list->takedamage)
{
// use higher hitbox for syringe only
if (skip->s.weapon != WP_MEDIC_SYRINGE)
{
height = ClientHitboxMaxZ(list);
}
else
{
height = CROUCH_BODYHEIGHT;
}
}

G_AdjustSingleClientPosition(list, time, list->takedamage, height);
}
else
{
Expand Down Expand Up @@ -683,66 +707,15 @@ static int G_SwitchBodyPartEntity(gentity_t *ent)
*/
void G_HistoricalTrace(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)
{
float maxsBackup[MAX_CLIENTS];
vec3_t dir;
int res, clientNum, i;

if (!g_antilag.integer || !ent->client)
{
G_AttachBodyParts(ent);

trap_Trace(results, start, mins, maxs, end, passEntityNum, contentmask);

res = G_SwitchBodyPartEntity(&g_entities[results->entityNum]);
POSITION_READJUST

G_DettachBodyParts();
G_Trace(ent, results, start, mins, maxs, end, passEntityNum, contentmask);
return;
}

Com_Memset(&maxsBackup, 0, sizeof(maxsBackup));

G_AdjustClientPositions(ent, ent->client->pers.cmd.serverTime, qtrue);

G_AttachBodyParts(ent);

for (i = 0; i < level.numConnectedClients; ++i)
{
clientNum = level.sortedClients[i];
if (&g_entities[clientNum] && g_entities[clientNum].client && g_entities[clientNum].takedamage)
{
maxsBackup[clientNum] = g_entities[clientNum].r.maxs[2];
// use higher hitbox for syringe only
if (ent->s.weapon != WP_MEDIC_SYRINGE)
{
g_entities[clientNum].r.maxs[2] = ClientHitboxMaxZ(&g_entities[clientNum]);
}
else
{
g_entities[clientNum].r.maxs[2] = CROUCH_BODYHEIGHT;
}

trap_LinkEntity(&g_entities[clientNum]);
}
}

trap_Trace(results, start, mins, maxs, end, passEntityNum, contentmask);

for (i = 0; i < level.numConnectedClients; ++i)
{
clientNum = level.sortedClients[i];
if (&g_entities[clientNum] && g_entities[clientNum].client && g_entities[clientNum].takedamage)
{
g_entities[clientNum].r.maxs[2] = maxsBackup[clientNum];

trap_LinkEntity(&g_entities[clientNum]);
}
}

res = G_SwitchBodyPartEntity(&g_entities[results->entityNum]);
POSITION_READJUST

G_DettachBodyParts();
G_Trace(ent, results, start, mins, maxs, end, passEntityNum, contentmask);

G_AdjustClientPositions(ent, 0, qfalse);
}
Expand Down Expand Up @@ -785,74 +758,20 @@ void G_HistoricalTraceEnd(gentity_t *ent)
* @param[in] end
* @param[in] passEntityNum
* @param[in] contentmask
* @param[in] ignoreCorpses Skip corpses for bullet tracing (=non gibbing weapons)
*/
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_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)
{
float maxsBackup[MAX_CLIENTS];
vec3_t dir;
int res, clientNum, i;

Com_Memset(&maxsBackup, 0, sizeof(maxsBackup));
int res;

G_AttachBodyParts(ent);

// ignore bodies for bullet tracing
if (ignoreCorpses)
{
if (g_corpses.integer == 0)
{
for (i = 0; i < BODY_QUEUE_SIZE; i++)
{
G_TempTraceIgnoreEntity(level.bodyQue[i]);
}
}
else
{
for (i = MAX_CLIENTS; i < level.num_entities; i++) // slower way, improve by time
{
if (g_entities[i].s.eType == ET_CORPSE)
{
G_TempTraceIgnoreEntity(&g_entities[i]);
}
}
}
}

for (i = 0; i < level.numConnectedClients; ++i)
{
clientNum = level.sortedClients[i];
if (&g_entities[clientNum] && g_entities[clientNum].client && g_entities[clientNum].takedamage)
{
maxsBackup[clientNum] = g_entities[clientNum].r.maxs[2];
g_entities[clientNum].r.maxs[2] = ClientHitboxMaxZ(&g_entities[clientNum]);

trap_LinkEntity(&g_entities[clientNum]);
}
}

trap_Trace(results, start, mins, maxs, end, passEntityNum, contentmask);

for (i = 0; i < level.numConnectedClients; ++i)
{
clientNum = level.sortedClients[i];
if (&g_entities[clientNum] && g_entities[clientNum].client && g_entities[clientNum].takedamage)
{
g_entities[clientNum].r.maxs[2] = maxsBackup[clientNum];

trap_LinkEntity(&g_entities[clientNum]);
}
}

res = G_SwitchBodyPartEntity(&g_entities[results->entityNum]);
POSITION_READJUST

G_DettachBodyParts();
// ok let the bodies be traced again
if (ignoreCorpses)
{
G_ResetTempTraceIgnoreEnts();
}
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/game/g_local.h
Expand Up @@ -2199,7 +2199,7 @@ void G_ResetMarkers(gentity_t *ent);
void G_HistoricalTrace(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);
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_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);
void G_PredictPmove(gentity_t *ent, float frametime);

#define BODY_VALUE(ENT) ENT->watertype
Expand Down Expand Up @@ -2636,7 +2636,7 @@ void G_GlobalClientEvent(entity_event_t event, int param, int client);
void G_InitTempTraceIgnoreEnts(void);
void G_ResetTempTraceIgnoreEnts(void);
void G_TempTraceIgnoreEntity(gentity_t *ent);
void G_TeamTraceIgnoreBodies(void);
void G_TempTraceIgnoreBodies(void);
void G_TempTraceIgnorePlayersAndBodies(void);
void G_TempTraceIgnorePlayersFromTeam(team_t team);
void G_TempTraceRealHitBox(gentity_t *ent);
Expand Down
6 changes: 3 additions & 3 deletions src/game/g_misc.c
Expand Up @@ -1000,7 +1000,7 @@ void Fire_Lead_Ext(gentity_t *ent, gentity_t *activator, float spread, int damag
// use activator for historicaltrace, not ent which may be
// the weapon itself (e.g. for mg42s)
// G_HistoricalTrace(activator, &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT);
G_Trace(activator, &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT, qfalse);
G_Trace(activator, &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT);

// bullet debugging using Q3A's railtrail
if (g_debugBullets.integer & 1)
Expand Down Expand Up @@ -2507,7 +2507,7 @@ void G_TempTraceIgnoreEntity(gentity_t *ent)
/**
* @brief G_TeamTraceIgnoreBodies
*/
void G_TeamTraceIgnoreBodies(void)
void G_TempTraceIgnoreBodies(void)
{
int i;

Expand Down Expand Up @@ -2543,7 +2543,7 @@ void G_TempTraceIgnorePlayersAndBodies(void)
G_TempTraceIgnoreEntity(&g_entities[i]);
}

G_TeamTraceIgnoreBodies();
G_TempTraceIgnoreBodies();
}


Expand Down
18 changes: 15 additions & 3 deletions src/game/g_weapon.c
Expand Up @@ -432,7 +432,7 @@ gentity_t *Weapon_Syringe(gentity_t *ent)

// right on top of intended revivee.
G_TempTraceIgnorePlayersFromTeam(ent->s.teamNum == TEAM_AXIS ? TEAM_ALLIES : TEAM_AXIS);
G_TeamTraceIgnoreBodies();
G_TempTraceIgnoreBodies();
G_HistoricalTrace(ent, &tr, muzzleTrace, NULL, NULL, end, ent->s.number, MASK_SHOT);
G_ResetTempTraceIgnoreEnts();

Expand Down Expand Up @@ -3340,8 +3340,20 @@ gentity_t *Bullet_Fire(gentity_t *ent)
Bullet_Endpos(ent, spread, &end);

G_HistoricalTraceBegin(ent);

// skip corpses for bullet tracing (=non gibbing weapons)
if (!GetWeaponTableData(ent->s.weapon)->splashDamage)
{
G_TempTraceIgnoreBodies();
}

Bullet_Fire_Extended(ent, ent, muzzleTrace, end, GetWeaponTableData(ent->s.weapon)->damage, GetWeaponTableData(ent->s.weapon)->attributes & WEAPON_ATTRIBUT_FALL_OFF);

// ok let the bodies be traced again
if (!GetWeaponTableData(ent->s.weapon)->splashDamage)
{
G_ResetTempTraceIgnoreEnts();
}

G_HistoricalTraceEnd(ent);

Expand Down Expand Up @@ -3378,7 +3390,7 @@ qboolean Bullet_Fire_Extended(gentity_t *source, gentity_t *attacker, vec3_t sta
waslinked = qtrue;
}

G_Trace(source, &tr, start, NULL, NULL, end, source->s.number, MASK_SHOT, !GetWeaponTableData(attacker->s.weapon)->splashDamage);
G_Trace(source, &tr, start, NULL, NULL, end, source->s.number, MASK_SHOT);

// prevent shooting ourselves in the head when prone, firing through a breakable
if (waslinked == qtrue)
Expand Down Expand Up @@ -3487,7 +3499,7 @@ qboolean Bullet_Fire_Extended(gentity_t *source, gentity_t *attacker, vec3_t sta

tent = G_TempEntity(tr.endpos, EV_BULLET_HIT_WALL);

G_Trace(source, &tr2, start, NULL, NULL, end, source->s.number, MASK_WATER | MASK_SHOT, !GetWeaponTableData(attacker->s.weapon)->splashDamage);
G_Trace(source, &tr2, start, NULL, NULL, end, source->s.number, MASK_WATER | MASK_SHOT);

if ((tr.entityNum != tr2.entityNum && tr2.fraction != 1.f))
{
Expand Down

0 comments on commit 8eff4c6

Please sign in to comment.