From ab0bcc55f87ad004052b5f8dbf42d938ea197c80 Mon Sep 17 00:00:00 2001 From: mittorn Date: Sat, 21 Apr 2018 08:06:55 +0000 Subject: [PATCH] Apply Apr20 update --- common/features.h | 1 - engine/client/cl_frame.c | 10 ++- engine/client/cl_main.c | 11 ++-- engine/client/cl_parse.c | 11 ++-- engine/client/cl_pmove.c | 2 +- engine/common/common.c | 13 ++-- engine/common/common.h | 2 +- engine/common/host.c | 10 ++- engine/common/sys_win.c | 4 +- engine/server/server.h | 3 +- engine/server/sv_client.c | 1 - engine/server/sv_frame.c | 16 +---- engine/server/sv_game.c | 3 +- engine/server/sv_main.c | 52 +++++++++------ engine/server/sv_pmove.c | 130 ++++++++++++++++++-------------------- 15 files changed, 132 insertions(+), 137 deletions(-) diff --git a/common/features.h b/common/features.h index 4efc5578..bee561fd 100644 --- a/common/features.h +++ b/common/features.h @@ -25,6 +25,5 @@ GNU General Public License for more details. #define ENGINE_COMPENSATE_QUAKE_BUG (1<<5) // compensate stupid quake bug (inverse pitch) for mods where this bug is fixed // reserved #define ENGINE_COMPUTE_STUDIO_LERP (1<<7) // enable MOVETYPE_STEP lerping back in engine -#define ENGINE_FIXED_FRAMERATE (1<<8) // keep constant rate for client and server (but don't clamp renderer calls) #endif//FEATURES_H \ No newline at end of file diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index 1e6b8ed4..fa88f05a 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -410,8 +410,8 @@ int CL_InterpolateModel( cl_entity_t *e ) if( cls.timedemo || !e->model ) return 1; - if( cl.maxclients <= 1 && !FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) - return 1; + if( fabs( cl_serverframetime() - cl_clientframetime()) < 0.0001f ) + return 1; // interpolation disabled if( e->model->type == mod_brush && !cl_bmodelinterp->value ) return 1; @@ -419,10 +419,8 @@ int CL_InterpolateModel( cl_entity_t *e ) if( cl.local.moving && cl.local.onground == e->index ) return 1; - if( cl.maxclients <= 1 && FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) - t = cl.time - cl_serverframetime(); - else t = cl.time - cl_interp->value; - +// t = cl.time - cl_serverframetime(); + t = cl.time - cl_interp->value; CL_FindInterpolationUpdates( e, t, &ph0, &ph1 ); if( ph0 == NULL || ph1 == NULL ) diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 094f47c2..17d2bb5c 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -250,7 +250,7 @@ static float CL_LerpPoint( void ) return 1.0f; } - if( cl_interp->value > 0.001f && !FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) + if( cl_interp->value > 0.001f ) { // manual lerp value (goldsrc mode) frac = ( cl.time - cl.mtime[0] ) / cl_interp->value; @@ -439,12 +439,11 @@ void CL_FindInterpolatedAddAngle( float t, float *frac, pred_viewangle_t **prev, void CL_ApplyAddAngle( void ) { - float curtime = cl.time - cl_serverframetime(); pred_viewangle_t *prev = NULL, *next = NULL; float addangletotal = 0.0f; float amove, frac = 0.0f; - CL_FindInterpolatedAddAngle( curtime, &frac, &prev, &next ); + CL_FindInterpolatedAddAngle( cl.time, &frac, &prev, &next ); if( prev && next ) addangletotal = prev->total + frac * ( next->total - prev->total ); @@ -616,7 +615,6 @@ void CL_CreateCmd( void ) pcmd->receivedtime = -1.0; pcmd->heldback = false; pcmd->sendsize = 0; - CL_ApplyAddAngle(); } active = (( cls.signon == SIGNONS ) && !cl.paused && !cls.demoplayback ); @@ -1591,6 +1589,9 @@ void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg ) CL_FixupColorStringsForInfoString( s, infostring ); + if( !COM_CheckString( Info_ValueForKey( infostring, "gamedir" ))) + return; // unsupported proto + // more info about servers Con_Printf( "Server: %s, Game: %s\n", NET_AdrToString( from ), Info_ValueForKey( infostring, "gamedir" )); @@ -2051,6 +2052,8 @@ void CL_ReadPackets( void ) cls.demotime += host.frametime; CL_ReadNetMessage(); + + CL_ApplyAddAngle(); #if 0 // keep cheat cvars are unchanged if( cl.maxclients > 1 && cls.state == ca_active && !host_developer.value ) diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 9b19da66..f1cf3232 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -1448,13 +1448,10 @@ void CL_ParseAddAngle( sizebuf_t *msg ) float delta_yaw; delta_yaw = MSG_ReadBitAngle( msg, 16 ); - - if( cl.maxclients <= 1 && !FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) - { - cl.viewangles[YAW] += delta_yaw; - return; - } - +#if 0 + cl.viewangles[YAW] += delta_yaw; + return; +#endif // update running counter cl.addangletotal += delta_yaw; diff --git a/engine/client/cl_pmove.c b/engine/client/cl_pmove.c index 347a6573..f6ddde84 100644 --- a/engine/client/cl_pmove.c +++ b/engine/client/cl_pmove.c @@ -248,7 +248,7 @@ void CL_CheckPredictionError( void ) // save for error interpolation VectorCopy( delta, cl.local.prediction_error ); - if(( dist > MIN_CORRECTION_DISTANCE ) && (( cl.maxclients > 1 ) || FBitSet( host.features, ENGINE_FIXED_FRAMERATE ))) + if( dist > MIN_CORRECTION_DISTANCE ) cls.correction_time = cl_smoothtime->value; } } diff --git a/engine/common/common.c b/engine/common/common.c index 45ebba93..df4b928d 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -1244,15 +1244,16 @@ COM_CheckParm */ int COM_CheckParm( char *parm, char **ppnext ) { - static char str[64]; + int i = Sys_CheckParm( parm ); - if( Sys_GetParmFromCmdLine( parm, str )) + if( ppnext ) { - // get the pointer on cmdline param - if( ppnext ) *ppnext = str; - return 1; + if( i != 0 && i < host.argc - 1 ) + *ppnext = (char *)host.argv[i + 1]; + else *ppnext = NULL; } - return 0; + + return i; } /* diff --git a/engine/common/common.h b/engine/common/common.h index fc64dd22..d654ab1d 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -128,7 +128,7 @@ typedef enum // PERFORMANCE INFO #define MIN_FPS 20.0 // host minimum fps value for maxfps. #define MAX_FPS 200.0 // upper limit for maxfps. -#define HOST_FPS 72.0 // multiplayer games typical fps +#define HOST_FPS 100.0 // multiplayer games typical fps #define MAX_FRAMETIME 0.25 #define MIN_FRAMETIME 0.0001 diff --git a/engine/common/host.c b/engine/common/host.c index 09bb626e..67fbd1f7 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -78,9 +78,6 @@ void Host_PrintEngineFeatures( void ) if( FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG )) MsgDev( D_REPORT, "^3EXT:^7 Compensate quake bug enabled\n" ); - - if( FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) - MsgDev( D_REPORT, "^3EXT:^7 runnung server at constant fps\n" ); } /* @@ -133,7 +130,7 @@ void Host_CheckSleep( void ) if( host.type == HOST_DEDICATED ) { // let the dedicated server some sleep - Sys_Sleep( 1 ); +// Sys_Sleep( 1 ); } else { @@ -645,7 +642,8 @@ void Host_InitCommon( const char *hostname, qboolean bChangeGame ) host.mempool = Mem_AllocPool( "Zone Engine" ); - if( Sys_CheckParm( "-console" )) + // HACKHACK: Quake console is always allowed + if( Sys_CheckParm( "-console" ) || !Q_stricmp( progname, "id1" )) host.allow_console = true; if( Sys_CheckParm( "-dev" )) @@ -789,7 +787,7 @@ int EXPORT Host_Main( const char *progname, int bChangeGame, pfnChangeGame func Cmd_AddCommand ( "crash", Host_Crash_f, "a way to force a bus error for development reasons"); } - host_maxfps = Cvar_Get( "fps_max", "72", FCVAR_ARCHIVE, "host fps upper limit" ); + host_maxfps = Cvar_Get( "fps_max", "100", FCVAR_ARCHIVE, "host fps upper limit" ); host_framerate = Cvar_Get( "host_framerate", "0", 0, "locks frame timing to this value in seconds" ); host_gameloaded = Cvar_Get( "host_gameloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded game.dll" ); host_clientloaded = Cvar_Get( "host_clientloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" ); diff --git a/engine/common/sys_win.c b/engine/common/sys_win.c index ecfeecf0..9f5023ba 100644 --- a/engine/common/sys_win.c +++ b/engine/common/sys_win.c @@ -314,7 +314,9 @@ int Sys_CheckParm( const char *parm ) for( i = 1; i < host.argc; i++ ) { - if( !host.argv[i] ) continue; + if( !host.argv[i] ) + continue; + if( !Q_stricmp( parm, host.argv[i] )) return i; } diff --git a/engine/server/server.h b/engine/server/server.h index b4966c5a..61df4704 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -195,8 +195,8 @@ typedef struct server_s model_t *worldmodel; // pointer to world - qboolean simulating; qboolean playersonly; + qboolean simulating; // physics is running qboolean paused; // statistics @@ -237,7 +237,6 @@ typedef struct sv_client_s double next_sendinfotime; // time to send info about all players double cl_updaterate; // client requested updaterate double timebase; // client timebase - double lastservertime; // check if server time was not changed so no resaon to send update double connection_started; char hashedcdkey[34]; // MD5 hash is 32 hex #'s, plus trailing 0 diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index 8dbce5b5..1cdcb87b 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -380,7 +380,6 @@ void SV_ConnectClient( netadr_t from ) #endif newcl->next_messagetime = host.realtime + newcl->cl_updaterate; newcl->next_sendinfotime = 0.0; - newcl->lastservertime = -1.0; newcl->ignored_ents = 0; newcl->chokecount = 0; diff --git a/engine/server/sv_frame.c b/engine/server/sv_frame.c index d663d478..28b1bc07 100644 --- a/engine/server/sv_frame.c +++ b/engine/server/sv_frame.c @@ -652,20 +652,11 @@ void SV_SendClientDatagram( sv_client_t *cl ) byte msg_buf[MAX_DATAGRAM]; sizebuf_t msg; - // if we running server with fixed fps so no reason - // to send updates too fast: time just not changed - if( FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) - { - if( sv.simulating && cl->lastservertime == sv.time ) - return; - } - MSG_Init( &msg, "Datagram", msg_buf, sizeof( msg_buf )); // always send servertime at new frame MSG_BeginServerCmd( &msg, svc_time ); MSG_WriteFloat( &msg, sv.time ); - cl->lastservertime = sv.time; SV_WriteClientdataToMessage( cl, &msg ); SV_WriteEntitiesToClient( cl, &msg ); @@ -825,11 +816,8 @@ void SV_SendClientMessages( void ) continue; } - if( !FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) - { - if( !host_limitlocal->value && NET_IsLocalAddress( cl->netchan.remote_address )) - SetBits( cl->flags, FCL_SEND_NET_MESSAGE ); - } + if( !host_limitlocal->value && NET_IsLocalAddress( cl->netchan.remote_address )) + SetBits( cl->flags, FCL_SEND_NET_MESSAGE ); if( cl->state == cs_spawned ) { diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 4e58ae1a..381ccb14 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -4848,8 +4848,7 @@ qboolean SV_LoadProgs( const char *name ) { Con_Printf( S_WARN "SV_LoadProgs: couldn't get physics API\n" ); } -// TESTTEST -//host.features |= ENGINE_FIXED_FRAMERATE; + // grab function SV_SaveGameComment SV_InitSaveRestore (); diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index fbdc067d..e749e2ad 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -96,6 +96,7 @@ CVAR_DEFINE_AUTO( showtriggers, "0", FCVAR_LATCH, "debug cvar shows triggers" ); CVAR_DEFINE_AUTO( sv_airmove, "1", FCVAR_SERVER, "obsolete, compatibility issues" ); CVAR_DEFINE_AUTO( sv_version, "", FCVAR_READ_ONLY, "engine version string" ); CVAR_DEFINE_AUTO( hostname, "", FCVAR_SERVER|FCVAR_PRINTABLEONLY, "name of current host" ); +CVAR_DEFINE_AUTO( sv_fps, "0.0", FCVAR_SERVER, "server framerate" ); // gore-related cvars CVAR_DEFINE_AUTO( violence_hblood, "1", 0, "draw human blood" ); @@ -217,6 +218,15 @@ void SV_CheckCmdTimes( void ) float diff; int i; + if( sv_fps.value != 0.0f ) + { + if( sv_fps.value < MIN_FPS ) + Cvar_SetValue( "sv_fps", MIN_FPS ); + + if( sv_fps.value > MAX_FPS ) + Cvar_SetValue( "sv_fps", MAX_FPS ); + } + if( Host_IsLocalGame( )) return; @@ -544,32 +554,37 @@ SV_RunGameFrame SV_RunGameFrame ================= */ -void SV_RunGameFrame( void ) +qboolean SV_RunGameFrame( void ) { - int numFrames = 0; // debug + sv.simulating = SV_IsSimulating(); - if(!( sv.simulating = SV_IsSimulating( ))) - return; + if( !sv.simulating ) + return true; - if( FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) + if( sv_fps.value != 0.0f ) { - sv.time_residual += host.frametime; + double fps = (1.0 / (double)( sv_fps.value - 0.01 )); // FP issues + int numFrames = 0; + static double oldtime; - if( sv.time_residual >= sv.frametime ) + while( sv.time_residual >= fps ) { + sv.frametime = fps; + SV_Physics(); - sv.time_residual -= sv.frametime; - sv.time += sv.frametime; + sv.time_residual -= fps; + sv.time += fps; numFrames++; } + + return (numFrames != 0); } else { SV_Physics(); - sv.time += sv.frametime; - numFrames++; + return true; } } @@ -584,10 +599,11 @@ void Host_ServerFrame( void ) // if server is not active, do nothing if( !svs.initialized ) return; - if( FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) - sv.frametime = ( 1.0 / (double)GAME_FPS ); - else sv.frametime = host.frametime; // GoldSrc style + if( sv.simulating || sv.state != ss_active ) + sv.time_residual += host.frametime; + if( sv_fps.value == 0.0f ) + sv.frametime = host.frametime; svgame.globals->frametime = sv.frametime; // check clients timewindow @@ -596,9 +612,6 @@ void Host_ServerFrame( void ) // read packets from clients SV_ReadPackets (); - // let everything in the world think and move - SV_RunGameFrame (); - // refresh physic movevars on the client side SV_UpdateMovevars ( false ); @@ -607,6 +620,9 @@ void Host_ServerFrame( void ) // check timeouts SV_CheckTimeouts (); + + // let everything in the world think and move + if( !SV_RunGameFrame ()) return; // send messages back to the clients that had packets read this frame SV_SendClientMessages (); @@ -770,7 +786,7 @@ void SV_Init( void ) Cvar_RegisterVariable (&sv_wateralpha); Cvar_RegisterVariable (&sv_cheats); Cvar_RegisterVariable (&sv_airmove); - + Cvar_RegisterVariable (&sv_fps); Cvar_RegisterVariable (&showtriggers); Cvar_RegisterVariable (&sv_aim); Cvar_RegisterVariable (&motdfile); diff --git a/engine/server/sv_pmove.c b/engine/server/sv_pmove.c index 86db26b5..7577bd6e 100644 --- a/engine/server/sv_pmove.c +++ b/engine/server/sv_pmove.c @@ -67,17 +67,17 @@ qboolean SV_CopyEdictToPhysEnt( physent_t *pe, edict_t *ed ) VectorCopy( ed->v.origin, pe->origin ); VectorCopy( ed->v.angles, pe->angles ); - if( ed->v.flags & FL_CLIENT ) + if( FBitSet( ed->v.flags, FL_FAKECLIENT )) { - // client - SV_GetTrueOrigin( &svs.clients[pe->info - 1], (pe->info - 1), pe->origin ); - Q_strncpy( pe->name, "player", sizeof( pe->name )); + // bot + Q_strncpy( pe->name, "bot", sizeof( pe->name )); pe->player = pe->info; } - else if( ed->v.flags & FL_FAKECLIENT && ed->v.solid != MOVETYPE_PUSH ) + else if( FBitSet( ed->v.flags, FL_CLIENT )) { - // bot - Q_strncpy( pe->name, "bot", sizeof( pe->name )); + // client + SV_GetTrueOrigin( &svs.clients[pe->info - 1], pe->info, pe->origin ); + Q_strncpy( pe->name, "player", sizeof( pe->name )); pe->player = pe->info; } else @@ -148,39 +148,51 @@ qboolean SV_CopyEdictToPhysEnt( physent_t *pe, edict_t *ed ) return true; } -void SV_GetTrueOrigin( sv_client_t *cl, int edictnum, vec3_t origin ) +qboolean SV_ShouldUnlagForPlayer( sv_client_t *cl ) { - // don't allow unlag in singleplayer - if( svs.maxclients <= 1 ) return; + // can't unlag in singleplayer + if( svs.maxclients <= 1 ) + return false; - if( cl->state < cs_connected || edictnum < 0 || edictnum >= svs.maxclients ) - return; + // unlag disabled globally + if( !svgame.dllFuncs.pfnAllowLagCompensation() || !sv_unlag.value ) + return false; - if( !FBitSet( cl->flags, FCL_LAG_COMPENSATION ) || !sv_unlag.value ) - return; + if( !FBitSet( cl->flags, FCL_LAG_COMPENSATION )) + return false; - if( !svgame.interp[edictnum].active || !svgame.interp[edictnum].moving ) - return; + // player not ready + if( cl->state != cs_spawned ) + return false; - VectorCopy( svgame.interp[edictnum].newpos, origin ); + return true; } -void SV_GetTrueMinMax( sv_client_t *cl, int edictnum, vec3_t mins, vec3_t maxs ) +void SV_GetTrueOrigin( sv_client_t *cl, int edictnum, vec3_t origin ) { - // don't allow unlag in singleplayer - if( svs.maxclients <= 1 ) return; + if( !SV_ShouldUnlagForPlayer( cl )) + return; - if( cl->state < cs_connected || edictnum < 0 || edictnum >= svs.maxclients ) + if( edictnum < 1 || edictnum > svs.maxclients ) return; - if( !FBitSet( cl->flags, FCL_LAG_COMPENSATION ) || !sv_unlag.value ) + if( svgame.interp[edictnum-1].active && svgame.interp[edictnum-1].moving ) + VectorCopy( svgame.interp[edictnum-1].newpos, origin ); +} + +void SV_GetTrueMinMax( sv_client_t *cl, int edictnum, vec3_t mins, vec3_t maxs ) +{ + if( !SV_ShouldUnlagForPlayer( cl )) return; - if( !svgame.interp[edictnum].active || !svgame.interp[edictnum].moving ) + if( edictnum < 1 || edictnum > svs.maxclients ) return; - VectorCopy( svgame.interp[edictnum].mins, mins ); - VectorCopy( svgame.interp[edictnum].maxs, maxs ); + if( svgame.interp[edictnum-1].active && svgame.interp[edictnum-1].moving ) + { + VectorCopy( svgame.interp[edictnum-1].mins, mins ); + VectorCopy( svgame.interp[edictnum-1].maxs, maxs ); + } } /* @@ -247,12 +259,13 @@ void SV_AddLinksToPmove( areanode_t *node, const vec3_t pmove_mins, const vec3_t VectorCopy( check->v.absmin, mins ); VectorCopy( check->v.absmax, maxs ); - if( FBitSet( check->v.flags, FL_CLIENT )) + if( FBitSet( check->v.flags, FL_CLIENT ) && !FBitSet( check->v.flags, FL_FAKECLIENT )) { - int e = NUM_FOR_EDICT( check ) - 1; - - // trying to get interpolated values - SV_GetTrueMinMax( &svs.clients[e], e, mins, maxs ); + if( sv.current_client ) + { + // trying to get interpolated values + SV_GetTrueMinMax( sv.current_client, NUM_FOR_EDICT( check ), mins, maxs ); + } } if( !BoundsIntersect( pmove_mins, pmove_maxs, mins, maxs )) @@ -807,16 +820,7 @@ void SV_SetupMoveInterpolant( sv_client_t *cl ) memset( svgame.interp, 0, sizeof( svgame.interp )); has_update = false; - // don't allow unlag in singleplayer - if( svs.maxclients <= 1 || cl->state != cs_spawned ) - return; - - // unlag disabled by game request - if( !svgame.dllFuncs.pfnAllowLagCompensation() || !sv_unlag.value ) - return; - - // unlag disabled for current client - if( !FBitSet( cl->flags, FCL_LAG_COMPENSATION )) + if( !SV_ShouldUnlagForPlayer( cl )) return; has_update = true; @@ -834,17 +838,13 @@ void SV_SetupMoveInterpolant( sv_client_t *cl ) lerp->active = true; } - if( cl->latency > 1.5f ) - latency = 1.5f; - else latency = cl->latency; + latency = Q_min( cl->latency, 1.5f ); if( sv_maxunlag.value != 0.0f ) { if (sv_maxunlag.value < 0.0f ) Cvar_SetValue( "sv_maxunlag", 0.0f ); - - if( latency >= sv_maxunlag.value ) - latency = sv_maxunlag.value; + latency = Q_min( latency, sv_maxunlag.value ); } lerp_msec = cl->lastcmd.lerp_msec * 0.001f; @@ -856,9 +856,9 @@ void SV_SetupMoveInterpolant( sv_client_t *cl ) finalpush = ( host.realtime - latency - lerp_msec ) + sv_unlagpush.value; if( finalpush > host.realtime ) finalpush = host.realtime; // pushed too much ? - frame = NULL; + frame = frame2 = NULL; - for( frame2 = NULL, i = 0; i < SV_UPDATE_BACKUP; i++, frame2 = frame ) + for( i = 0; i < SV_UPDATE_BACKUP; i++, frame2 = frame ) { frame = &cl->frames[(cl->netchan.outgoing_sequence - (i + 1)) & SV_UPDATE_MASK]; @@ -866,19 +866,24 @@ void SV_SetupMoveInterpolant( sv_client_t *cl ) { state = &svs.packet_entities[(frame->first_entity+j)%svs.num_client_entities]; - if( state->number <= 0 || state->number >= svs.maxclients ) + if( state->number < 1 || state->number > svs.maxclients ) continue; lerp = &svgame.interp[state->number-1]; if( lerp->nointerp ) continue; - if( state->health <= 0 || ( state->effects & EF_NOINTERP )) + if( state->health <= 0 || FBitSet( state->effects, EF_NOINTERP )) lerp->nointerp = true; - if( !lerp->firstframe ) + if( lerp->firstframe ) + { + if( SV_UnlagCheckTeleport( state->origin, lerp->finalpos )) + lerp->nointerp = true; + } + else + { lerp->firstframe = true; - else if( SV_UnlagCheckTeleport( state->origin, lerp->finalpos )) - lerp->nointerp = true; + } VectorCopy( state->origin, lerp->finalpos ); } @@ -916,7 +921,7 @@ void SV_SetupMoveInterpolant( sv_client_t *cl ) { state = &svs.packet_entities[(frame->first_entity+i)%svs.num_client_entities]; - if( state->number <= 0 || state->number >= svs.maxclients ) + if( state->number < 1 || state->number > svs.maxclients ) continue; clientnum = state->number - 1; @@ -966,16 +971,7 @@ void SV_RestoreMoveInterpolant( sv_client_t *cl ) return; } - // don't allow unlag in singleplayer - if( svs.maxclients <= 1 || cl->state != cs_spawned ) - return; - - // unlag disabled by game request - if( !svgame.dllFuncs.pfnAllowLagCompensation() || !sv_unlag.value ) - return; - - // unlag disabled for current client - if( !FBitSet( cl->flags, FCL_LAG_COMPENSATION )) + if( !SV_ShouldUnlagForPlayer( cl )) return; for( i = 0, check = svs.clients; i < svs.maxclients; i++, check++ ) @@ -985,11 +981,11 @@ void SV_RestoreMoveInterpolant( sv_client_t *cl ) oldlerp = &svgame.interp[i]; - if( VectorCompare( oldlerp->oldpos, oldlerp->newpos )) + if( VectorCompare( oldlerp->oldpos, oldlerp->newpos ) || !oldlerp->moving ) continue; // they didn't actually move. - if( !oldlerp->moving || !oldlerp->active ) - return; + if( !oldlerp->active ) + continue; if( VectorCompare( oldlerp->curpos, check->edict->v.origin )) {