Skip to content

Commit

Permalink
mod: fix pmove_fixed 1 with g_antiwarp 1 and cg_optimizePrediction 1,…
Browse files Browse the repository at this point in the history
… refs #1379
  • Loading branch information
ryzyk-krzysiek committed Jan 16, 2023
1 parent 780fae6 commit 21e0fcc
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 39 deletions.
1 change: 1 addition & 0 deletions src/cgame/cg_local.h
Expand Up @@ -3449,6 +3449,7 @@ typedef struct
// cg_playerstate.c
void CG_Respawn(qboolean revived);
void CG_TransitionPlayerState(playerState_t *ps, playerState_t *ops);
void CG_ResetTimers(void);

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

Expand Down
32 changes: 29 additions & 3 deletions src/cgame/cg_playerstate.c
Expand Up @@ -150,7 +150,9 @@ void CG_Respawn(qboolean revived)
cg.serverRespawning = qfalse; // just in case

// no error decay on player movement
cg.thisFrameTeleport = qtrue;
cg.thisFrameTeleport = qtrue;
cg.predictedErrorTime = 0;
VectorClear(cg.predictedError);

// need to reset client-side weapon animations
cg.predictedPlayerState.weapAnim = ((cg.predictedPlayerState.weapAnim & ANIM_TOGGLEBIT) ^ ANIM_TOGGLEBIT) | WEAP_IDLE1; // reset weapon animations
Expand Down Expand Up @@ -208,7 +210,7 @@ void CG_Respawn(qboolean revived)
cg.pmext.silencedSideArm = 2;
}

cg.proneMovingTime = 0;
CG_ResetTimers();

// reset fog to world fog (if present)
trap_R_SetFog(FOG_CMD_SWITCHFOG, FOG_MAP, 20, 0, 0, 0, 0);
Expand Down Expand Up @@ -456,13 +458,18 @@ void CG_TransitionPlayerState(playerState_t *ps, playerState_t *ops)

// make sure we don't get any unwanted transition effects
*ops = *ps;
CG_ResetTimers();

// After Limbo, make sure and do a CG_Respawn
if (ps->clientNum == cg.clientNum)
{
ops->persistant[PERS_SPAWN_COUNT]--;
}
}
else
{
cg.thisFrameTeleport = qfalse;
}

if (ps->eFlags & EF_FIRING)
{
Expand Down Expand Up @@ -547,11 +554,30 @@ void CG_TransitionPlayerState(playerState_t *ps, playerState_t *ops)
CG_CheckPlayerstateEvents(ps, ops);

// smooth the ducking viewheight change
if (ps->viewheight != ops->viewheight)
if (ps->viewheight != ops->viewheight && !cg.thisFrameTeleport)
{
cg.duckChange = ps->viewheight - ops->viewheight;
cg.duckTime = cg.time;
cg.wasProne = ops->eFlags & EF_PRONE;
VectorSubtract(ops->origin, ps->origin, cg.deltaProne);
}
}

/**
* @brief CG_ResetTimers resets playerstate related timers
*/
void CG_ResetTimers(void)
{
cg.cameraShakeScale = 0;
cg.cameraShakeLength = 0;
cg.cameraShakeTime = 0;
cg.cameraShakePhase = 0;
cg.damageTime = 0;
cg.stepTime = 0;
cg.duckTime = 0;
cg.landTime = 0;
cg.proneMovingTime = 0;
cg.v_dmg_time = 0;
cg.v_noFireTime = 0;
cg.v_fireTime = 0;
}
54 changes: 31 additions & 23 deletions src/cgame/cg_predict.c
Expand Up @@ -981,7 +981,7 @@ void CG_PredictPlayerState(void)
{
int cmdNum, current;
playerState_t oldPlayerState;
qboolean moved;
qboolean moved, predictError;
usercmd_t oldestCmd;
usercmd_t latestCmd;
vec3_t deltaAngles;
Expand Down Expand Up @@ -1249,42 +1249,37 @@ void CG_PredictPlayerState(void)
// unlagged - optimized prediction

// run cmds
moved = qfalse;
moved = qfalse;
predictError = qtrue;
for (cmdNum = current - CMD_BACKUP + 1 ; cmdNum <= current ; cmdNum++)
{
// get the command
trap_GetUserCmd(cmdNum, &cg_pmove.cmd);
// get the previous command
trap_GetUserCmd(cmdNum - 1, &cg_pmove.oldcmd);

//if (cg_pmove.pmove_fixed
// && !BG_PlayerMounted(cg.snap->ps.eFlags) // don't update view angles - causes issues in 1st person view with weapons using special view
// && cg.predictedPlayerState.weapon != WP_MOBILE_MG42_SET && cg.predictedPlayerState.weapon != WP_MOBILE_BROWNING_SET) // see cg_view.c fov_x = 55;
//{
// added tracemask
// PM_UpdateViewAngles(cg_pmove.ps, cg_pmove.pmext, &cg_pmove.cmd, CG_Trace, cg_pmove.tracemask);
//}

// don't do anything if the time is before the snapshot player time
if (cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime)
{
continue;
}

// don't do anything if the command was from a previous map_restart
if (cg_pmove.cmd.serverTime > latestCmd.serverTime)
{
continue;
}

// check for a prediction error from last frame
// on a lan, this will often be the exact value
// from the snapshot, but on a wan we will have
// to predict several commands to get to the point
// we want to compare
if (cg.predictedPlayerState.commandTime == oldPlayerState.commandTime)

// this was moved here to fix pmove_fixed prediction error detection and
// subsequent error smoothing:
// when using pmove_fixed not all user commands will result in
// an actual move because commands are run for the duration of pmove_msec
// if commands are generated every 4ms (250fps) and pmove_msec is 8ms,
// only 1 out of those 2 commands will be run
// this will mean that in most situations, the check below would happen
// on 2nd user command which is not run, and the prediction error
// is not registered, causing more jittery game when miss prediction happens
// since there might be many user commands for same playerstate commandTime
// (as explained above) need to make sure it is only checked once per frame

if (cg.predictedPlayerState.commandTime == oldPlayerState.commandTime && predictError)
{
vec3_t delta;
predictError = qfalse;

if (BG_PlayerMounted(cg_pmove.ps->eFlags)) // TODO: clarify MG & Browning are locked in place too?
{
Expand Down Expand Up @@ -1354,6 +1349,19 @@ void CG_PredictPlayerState(void)
}
}

// don't do anything if the time is before the snapshot player time
if (cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime)
{
Com_Memcpy(&pmext, &oldpmext[cmdNum & CMD_MASK], sizeof(pmoveExt_t));
continue;
}

// don't do anything if the command was from a previous map_restart
if (cg_pmove.cmd.serverTime > latestCmd.serverTime)
{
continue;
}

if (cg_pmove.pmove_fixed)
{
cg_pmove.cmd.serverTime = ((cg_pmove.cmd.serverTime + pmove_msec.integer - 1) / pmove_msec.integer) * pmove_msec.integer;
Expand Down
4 changes: 1 addition & 3 deletions src/cgame/cg_servercmds.c
Expand Up @@ -1429,9 +1429,7 @@ static void CG_MapRestart(void)
cg.latchVictorySound = qfalse;

// we really should clear more parts of cg here and stop sounds
cg.v_dmg_time = 0;
cg.v_noFireTime = 0;
cg.v_fireTime = 0;
CG_ResetTimers();

cg.filtercams = Q_atoi(CG_ConfigString(CS_FILTERCAMS)) ? qtrue : qfalse;

Expand Down
9 changes: 1 addition & 8 deletions src/cgame/cg_view.c
Expand Up @@ -2002,14 +2002,7 @@ static void CG_DemoRewindFixEffects(void)
trap_R_ClearDecals(); // bullet and explosion marks (cg_markTime) are on renderer side

// reset camera view effects
cg.damageTime = 0;
cg.v_dmg_time = 0;
cg.v_noFireTime = 0;
cg.v_fireTime = 0;
cg.cameraShakeScale = 0;
cg.cameraShakeLength = 0;
cg.cameraShakeTime = 0;
cg.cameraShakePhase = 0;
CG_ResetTimers();

cgs.serverCommandSequence = cg.snap->serverCommandSequence;
}
Expand Down
2 changes: 1 addition & 1 deletion src/game/et-antiwarp.c
Expand Up @@ -193,7 +193,7 @@ void DoClientThinks(gentity_t *ent)
serverTime = cmd->serverTime;
totalDelta = latestTime - cmd->serverTime;

if (ent->client->pers.pmoveFixed)
if (pmove_fixed.integer || ent->client->pers.pmoveFixed)
{
serverTime = ((serverTime + pmove_msec.integer - 1) / pmove_msec.integer) * pmove_msec.integer;
}
Expand Down
2 changes: 1 addition & 1 deletion src/game/g_active.c
Expand Up @@ -1236,7 +1236,7 @@ void ClientThink_real(gentity_t *ent)

// zinx etpro antiwarp
client->pers.pmoveMsec = pmove_msec.integer;
if (!G_DoAntiwarp(ent) && (pmove_fixed.integer || client->pers.pmoveFixed))
if (pmove_fixed.integer || client->pers.pmoveFixed)
{
ucmd->serverTime = ((ucmd->serverTime + client->pers.pmoveMsec - 1) /
client->pers.pmoveMsec) * client->pers.pmoveMsec;
Expand Down

0 comments on commit 21e0fcc

Please sign in to comment.