Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions ratoa_gamecode/code/cgame/cg_ents.c
Original file line number Diff line number Diff line change
Expand Up @@ -926,8 +926,7 @@ int CG_ProjectileNudgeTimeshift(centity_t *cent) {
// same delayed view for player and missile
return 1000 / sv_fps.integer;
}
// if it's not, and it's not a grenade launcher
else if ( cent->currentState.weapon != WP_GRENADE_LAUNCHER ) {
else if (cent->currentState.weapon != WP_GRENADE_LAUNCHER) {
// extrapolate based on cg_projectileNudge
switch (cg_projectileNudgeAuto.integer) {
case 1:
Expand All @@ -939,7 +938,13 @@ int CG_ProjectileNudgeTimeshift(centity_t *cent) {

}
}
return 0;
// don't nudge GL because we can't locally predict the way it bounces (for now)
// we still shift it by 1 frame, to avoid moving it
// backwards when it bounces (or is fired by a bot).
// This would happen in that
// case because trTime > cg.time as the missiles are
// added from nextSnap (see early transitioning in CG_AddPacketEntities()).
return 1000 / sv_fps.integer;
}

/*
Expand Down Expand Up @@ -1026,7 +1031,12 @@ static void CG_CalcEntityLerpPositions( centity_t *cent ) {
cent->missileStatus.missileFlags |= MF_DISAPPEARED;
}

CG_Trace( &tr, lastOrigin, vec3_origin, vec3_origin, cent->lerpOrigin, cent->currentState.number, MASK_SHOT );
CG_Trace( &tr, lastOrigin, vec3_origin, vec3_origin, cent->lerpOrigin,
// missiles fly through their owners
// they cannot hit themselves because they are not solid
cent->currentState.eType == ET_MISSILE ?
CG_MissileOwner(cent) : cent->currentState.number,
MASK_SHOT );

// don't let the projectile go through the floor
if ( tr.fraction < 1.0f ) {
Expand Down
14 changes: 0 additions & 14 deletions ratoa_gamecode/code/cgame/cg_predict.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,6 @@ void CG_PredictPlayerState( void ) {
//unlagged - optimized prediction
int stateIndex = 0, predictCmd = 0; //Sago: added initializing
int numPredicted = 0, numPlayedBack = 0; // debug code
int prevMsec;
//unlagged - optimized prediction

cg.hyperspace = qfalse; // will be set if touching a trigger_teleport
Expand Down Expand Up @@ -964,7 +963,6 @@ void CG_PredictPlayerState( void ) {

// run cmds
moved = qfalse;
prevMsec = -1;
for ( cmdNum = current - CMD_BACKUP + 1 ; cmdNum <= current ; cmdNum++ ) {
// get the command
trap_GetUserCmd( cmdNum, &cg_pmove.cmd );
Expand All @@ -973,11 +971,6 @@ void CG_PredictPlayerState( void ) {
PM_UpdateViewAngles( cg_pmove.ps, &cg_pmove.cmd );
}

// save previous time
if (cmdNum < current) {
prevMsec = cg_pmove.cmd.serverTime;
}

// don't do anything if the time is before the snapshot player time
if ( cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime ) {
continue;
Expand Down Expand Up @@ -1042,13 +1035,6 @@ void CG_PredictPlayerState( void ) {
}
}

// store time delta between commands (used for projectile delag)
if (prevMsec != -1 && latestCmd.serverTime - prevMsec > 0) {
cg.cmdMsecDelta = latestCmd.serverTime - prevMsec;
} else {
cg.cmdMsecDelta = 0;
}

// don't predict gauntlet firing, which is only supposed to happen
// when it actually inflicts damage
cg_pmove.gauntletHit = qfalse;
Expand Down
14 changes: 9 additions & 5 deletions ratoa_gamecode/code/cgame/cg_unlagged.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,10 @@ predictedMissile_t *cg_freePMissiles; // single linked list

// how much longer than the player's roundtrip time a predicted missile will
// stay alive awaiting confirmation from the server
#define PMISSILE_WINDOWTIME 30
// if the player's firing command arrives right after the start of the frame,
// the missile will be included in the next snapshot (1000/sv_fps later), so it
// should be at least that long
#define PMISSILE_WINDOWTIME(fps) (1.5*1000/fps)

/*
===================
Expand Down Expand Up @@ -557,8 +560,8 @@ void CG_RemovePredictedMissile( centity_t *missile) {
continue;
}

if (missile->currentState.pos.trTime - PMISSILE_WINDOWTIME > pm->pos.trTime
|| missile->currentState.pos.trTime + PMISSILE_WINDOWTIME < pm->pos.trTime) {
if (missile->currentState.pos.trTime - PMISSILE_WINDOWTIME(sv_fps.integer) > pm->pos.trTime
|| missile->currentState.pos.trTime + PMISSILE_WINDOWTIME(sv_fps.integer) < pm->pos.trTime) {
continue;
}

Expand Down Expand Up @@ -1279,7 +1282,7 @@ void CG_PredictWeaponEffects( centity_t *cent ) {
predictedMissile_t *CG_BasePredictMissile( entityState_t *ent, vec3_t muzzlePoint ) {
predictedMissile_t *pm;
refEntity_t *bolt;
int lifetime = CG_ReliablePing() + PMISSILE_WINDOWTIME;
int lifetime = CG_ReliablePing() + PMISSILE_WINDOWTIME(sv_fps.integer);

pm = CG_AllocPMissile();
pm->removeTime = cg.time + lifetime;
Expand All @@ -1288,7 +1291,8 @@ predictedMissile_t *CG_BasePredictMissile( entityState_t *ent, vec3_t muzzlePoi
bolt = &pm->refEntity;

VectorCopy(muzzlePoint, pm->pos.trBase);
pm->pos.trTime = cg.time-cgs.predictedMissileNudge-cg.cmdMsecDelta;
// oldTime is our attackTime
pm->pos.trTime = cg.oldTime-cgs.predictedMissileNudge;

if (BG_IsElimGT(cgs.gametype)
&& cg.warmup == 0 && cgs.roundStartTime
Expand Down
4 changes: 2 additions & 2 deletions ratoa_gamecode/code/game/g_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define FL_FORCE_GESTURE 0x00008000 // force gesture on client

// for delagged projectiles
//#define MISSILE_PRESTEP_MAX_LATENCY 250
#define DELAG_MAX_BACKTRACK (g_delagMissileMaxLatency.integer + 1000/sv_fps.integer * 2)

#define PLASMA_THINKTIME 10000
Expand Down Expand Up @@ -544,7 +543,7 @@ typedef struct {

//unlagged - backward reconciliation #1
// the size of history we'll keep
#define NUM_CLIENT_HISTORY 17
#define NUM_CLIENT_HISTORY 22

// everything we need to know to backward reconcile
typedef struct {
Expand Down Expand Up @@ -1183,6 +1182,7 @@ void G_UndoTimeShiftFor( gentity_t *ent );
void G_UnTimeShiftClient( gentity_t *client );
void G_TimeShiftClient( gentity_t *ent, int time, qboolean debug, gentity_t *debugger );
void G_PredictPlayerMove( gentity_t *ent, float frametime );
void G_PrintDelagMaxTimeshift(void);
//unlagged - g_unlagged.c

//
Expand Down
1 change: 1 addition & 0 deletions ratoa_gamecode/code/game/g_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1298,6 +1298,7 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) {
G_UpdateMultiTrnGames();
#endif
CalculateRanks();
G_PrintDelagMaxTimeshift();
}


Expand Down
145 changes: 59 additions & 86 deletions ratoa_gamecode/code/game/g_missile.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,63 +24,65 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#define MISSILE_PRESTEP_TIME 50

int G_DelagLatency(gclient_t *client) {
int ping = 0;
switch (g_delagMissileLatencyMode.integer) {
case 2:
ping = client->ps.ping;
break;
case 3:
ping = client->pers.realPing;
break;
case 1:
default:
ping = level.previousTime + client->frameOffset - client->attackTime;
if (ping < 0) {
ping = 0;
}
break;
void G_SetMissileLaunchTime (gentity_t *self, gentity_t *bolt) {
if (!self->client) {
bolt->s.pos.trTime = level.time;
return;
}
if (g_delagMissileLimitVariance.integer && g_delagMissileLimitVarianceMs.integer > 0 && g_truePing.integer) {
int maxping = client->pers.realPing + g_delagMissileLimitVarianceMs.integer;
int minping = client->pers.realPing - g_delagMissileLimitVarianceMs.integer;
qboolean limited = qfalse;
int oldping = ping;

if (minping < 0) {
minping = 0;
}
if (ping > maxping) {
ping = maxping;
limited = qtrue;
} else if (ping < minping) {
ping = minping;
limited = qtrue;
}
if (limited && g_delagMissileDebug.integer) {
Com_Printf("Limited projectile delag ping (c %i): %i -> %i, realPing: %i\n", client->ps.clientNum, oldping, ping, client->pers.realPing);
}
if (!g_delagMissiles.integer) {
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;
return;
}
return MIN(g_delagMissileMaxLatency.integer, ping);
}

int G_MissileLagTime(gclient_t *client) {
int offset = 0;
bolt->s.pos.trTime = self->client->attackTime - g_delagMissileBaseNudge.integer;

if (!g_delagMissiles.integer) {
return MISSILE_PRESTEP_TIME;
if (bolt->s.pos.trTime < level.time - g_delagMissileMaxLatency.integer) {
bolt->s.pos.trTime = level.time - g_delagMissileMaxLatency.integer;
if (g_delagMissileDebug.integer) {
Com_Printf("Limited projectile delag ping (c %i): launchtime %i -> %i, realPing: %i\n",
self->client->ps.clientNum,
bolt->s.pos.trTime + g_delagMissileMaxLatency.integer,
bolt->s.pos.trTime,
self->client->pers.realPing);
}
} else if (bolt->s.pos.trTime > level.time) {
int orig_time = bolt->s.pos.trTime;

// perhaps we could allow level.time + client->frameOffset,
// but this is such a rare case and I'd rather not deal
// with missiles from the future. If we're not careful
// we might evaluate the trajectory at level.time and
// then the missile would move backwards relative to
// its launch position.
bolt->s.pos.trTime = level.time;

if (g_delagMissileDebug.integer) {
Com_Printf("Limited future projectile from (c %i) to level.time (orig launchtime was level.time + %i)\n",
self->client->ps.clientNum,
orig_time - level.time
);
}
}

if (g_delagMissileCorrectFrameOffset.integer) {
offset = level.time - (level.previousTime + client->frameOffset);
if (offset < 0) {
offset = 0;
}
if (offset > 1000/sv_fps.integer) {
offset = 1000/sv_fps.integer;
// need to remember the true launch time for delag in case the missile gets bounced/teleported
bolt->launchTime = bolt->s.pos.trTime;
bolt->needsDelag = qtrue;

if (G_IsElimGT() && level.time > level.roundStartTime - 1000*g_elimination_activewarmup.integer) {
if (bolt->launchTime < level.roundStartTime) {
int prestep = 0;
if (g_delagMissiles.integer) {
prestep = g_delagMissileBaseNudge.integer;
} else {
prestep = MISSILE_PRESTEP_TIME;
}
if (bolt->launchTime < level.roundStartTime-prestep) {
bolt->s.pos.trTime = level.roundStartTime-prestep;
bolt->launchTime = level.roundStartTime-prestep;
}
}
}
return offset + G_DelagLatency(client) + g_delagMissileBaseNudge.integer;

}

void G_MissileRunDelag(gentity_t *ent, int stepmsec) {
Expand Down Expand Up @@ -1001,31 +1003,6 @@ void G_RunMissile( gentity_t *ent ) {
G_RunThink( ent );
}

void G_ApplyMissileNudge (gentity_t *self, gentity_t *bolt) {
if (!self->client) {
return;
}
bolt->s.pos.trTime -= G_MissileLagTime(self->client);
bolt->needsDelag = qtrue;
bolt->launchTime = bolt->s.pos.trTime;

if (G_IsElimGT() && level.time > level.roundStartTime - 1000*g_elimination_activewarmup.integer) {
if (bolt->launchTime < level.roundStartTime) {
int prestep = 0;
if (g_delagMissiles.integer) {
prestep = g_delagMissileBaseNudge.integer;
} else {
prestep = MISSILE_PRESTEP_TIME;
}
if (bolt->launchTime < level.roundStartTime-prestep) {
bolt->s.pos.trTime = level.roundStartTime-prestep;
bolt->launchTime = level.roundStartTime-prestep;
}

}
}
}

//=============================================================================

/*
Expand Down Expand Up @@ -1076,9 +1053,8 @@ gentity_t *fire_plasma (gentity_t *self, vec3_t start, vec3_t dir) {
bolt->target_ent = NULL;

bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time;
//bolt->s.pos.trTime = level.time;
G_ApplyMissileNudge(self, bolt);
G_SetMissileLaunchTime(self, bolt);
VectorCopy( start, bolt->s.pos.trBase );
VectorScale( dir, PLASMA_VELOCITY, bolt->s.pos.trDelta );
//SnapVector( bolt->s.pos.trDelta ); // save net bandwidth //mrd - nah
Expand Down Expand Up @@ -1149,9 +1125,8 @@ gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) {
bolt->target_ent = NULL;

bolt->s.pos.trType = TR_GRAVITY;
bolt->s.pos.trTime = level.time;
//bolt->s.pos.trTime = level.time;
G_ApplyMissileNudge(self, bolt);
G_SetMissileLaunchTime(self, bolt);
VectorCopy( start, bolt->s.pos.trBase );
VectorScale( dir, GRENADE_VELOCITY, bolt->s.pos.trDelta );
//SnapVector( bolt->s.pos.trDelta ); // save net bandwidth //mrd - nah
Expand Down Expand Up @@ -1211,9 +1186,8 @@ gentity_t *fire_bfg (gentity_t *self, vec3_t start, vec3_t dir) {
bolt->target_ent = NULL;

bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time;
//bolt->s.pos.trTime = level.time;
G_ApplyMissileNudge(self, bolt);
G_SetMissileLaunchTime(self, bolt);
VectorCopy( start, bolt->s.pos.trBase );
VectorScale( dir, BFG_VELOCITY, bolt->s.pos.trDelta );
//SnapVector( bolt->s.pos.trDelta ); // save net bandwidth //mrd - nah
Expand Down Expand Up @@ -1272,9 +1246,8 @@ gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir) {
bolt->target_ent = NULL;

bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time;
//bolt->s.pos.trTime = level.time;
G_ApplyMissileNudge(self, bolt);
G_SetMissileLaunchTime(self, bolt);
VectorCopy( start, bolt->s.pos.trBase );
//VectorScale( dir, 900, bolt->s.pos.trDelta );
//VectorScale( dir, 1000, bolt->s.pos.trDelta );
Expand Down Expand Up @@ -1367,8 +1340,8 @@ gentity_t *fire_nail( gentity_t *self, vec3_t start, vec3_t forward, vec3_t righ
bolt->target_ent = NULL;

bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time;
G_ApplyMissileNudge(self, bolt);
//bolt->s.pos.trTime = level.time;
G_SetMissileLaunchTime(self, bolt);
VectorCopy( start, bolt->s.pos.trBase );

//r = random() * M_PI * 2.0f;
Expand Down Expand Up @@ -1432,8 +1405,8 @@ gentity_t *fire_prox( gentity_t *self, vec3_t start, vec3_t dir ) {
bolt->s.generic1 = self->client->sess.sessionTeam;

bolt->s.pos.trType = TR_GRAVITY;
bolt->s.pos.trTime = level.time;
G_ApplyMissileNudge(self, bolt);
//bolt->s.pos.trTime = level.time;
G_SetMissileLaunchTime(self, bolt);
VectorCopy( start, bolt->s.pos.trBase );
VectorScale( dir, PROXMINE_VELOCITY, bolt->s.pos.trDelta );
SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
Expand Down
14 changes: 14 additions & 0 deletions ratoa_gamecode/code/game/g_unlagged.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,20 @@ void G_UndoTimeShiftFor( gentity_t *ent ) {
G_UnTimeShiftAllClients( ent );
}

void G_PrintDelagMaxTimeshift(void) {
int max_shift;
if (!(g_delagHitscan.integer || g_delagMissiles.integer)) {
return;
}
max_shift = NUM_CLIENT_HISTORY * 1000/sv_fps.integer;
Com_Printf("Delag: max timeshift is %ims\n", max_shift);
if (max_shift < DELAG_MAX_BACKTRACK) {
Com_Printf(S_COLOR_YELLOW "WARNING: max timeshift %i is not large enough for g_delagMissileMaxLatency %i at sv_fps %i\n",
max_shift,
g_delagMissileMaxLatency.integer,
sv_fps.integer);
}
}

/*
===========================
Expand Down