Merge branch 'original'

This commit is contained in:
mittorn 2018-04-21 13:44:06 +00:00
commit 8704c07e4b
15 changed files with 134 additions and 139 deletions

View File

@ -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 #define ENGINE_COMPENSATE_QUAKE_BUG (1<<5) // compensate stupid quake bug (inverse pitch) for mods where this bug is fixed
// reserved // reserved
#define ENGINE_COMPUTE_STUDIO_LERP (1<<7) // enable MOVETYPE_STEP lerping back in engine #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 #endif//FEATURES_H

View File

@ -410,8 +410,8 @@ int CL_InterpolateModel( cl_entity_t *e )
if( cls.timedemo || !e->model ) if( cls.timedemo || !e->model )
return 1; return 1;
if( cl.maxclients <= 1 && !FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) if( fabs( cl_serverframetime() - cl_clientframetime()) < 0.0001f )
return 1; return 1; // interpolation disabled
if( e->model->type == mod_brush && !cl_bmodelinterp->value ) if( e->model->type == mod_brush && !cl_bmodelinterp->value )
return 1; return 1;
@ -419,10 +419,8 @@ int CL_InterpolateModel( cl_entity_t *e )
if( cl.local.moving && cl.local.onground == e->index ) if( cl.local.moving && cl.local.onground == e->index )
return 1; return 1;
if( cl.maxclients <= 1 && FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) // t = cl.time - cl_serverframetime();
t = cl.time - cl_serverframetime(); t = cl.time - cl_interp->value;
else t = cl.time - cl_interp->value;
CL_FindInterpolationUpdates( e, t, &ph0, &ph1 ); CL_FindInterpolationUpdates( e, t, &ph0, &ph1 );
if( ph0 == NULL || ph1 == NULL ) if( ph0 == NULL || ph1 == NULL )

View File

@ -253,7 +253,7 @@ static float CL_LerpPoint( void )
return 1.0f; 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) // manual lerp value (goldsrc mode)
frac = ( cl.time - cl.mtime[0] ) / cl_interp->value; frac = ( cl.time - cl.mtime[0] ) / cl_interp->value;
@ -442,12 +442,11 @@ void CL_FindInterpolatedAddAngle( float t, float *frac, pred_viewangle_t **prev,
void CL_ApplyAddAngle( void ) void CL_ApplyAddAngle( void )
{ {
float curtime = cl.time - cl_serverframetime();
pred_viewangle_t *prev = NULL, *next = NULL; pred_viewangle_t *prev = NULL, *next = NULL;
float addangletotal = 0.0f; float addangletotal = 0.0f;
float amove, frac = 0.0f; float amove, frac = 0.0f;
CL_FindInterpolatedAddAngle( curtime, &frac, &prev, &next ); CL_FindInterpolatedAddAngle( cl.time, &frac, &prev, &next );
if( prev && next ) if( prev && next )
addangletotal = prev->total + frac * ( next->total - prev->total ); addangletotal = prev->total + frac * ( next->total - prev->total );
@ -619,7 +618,6 @@ void CL_CreateCmd( void )
pcmd->receivedtime = -1.0; pcmd->receivedtime = -1.0;
pcmd->heldback = false; pcmd->heldback = false;
pcmd->sendsize = 0; pcmd->sendsize = 0;
CL_ApplyAddAngle();
} }
active = (( cls.signon == SIGNONS ) && !cl.paused && !cls.demoplayback ); active = (( cls.signon == SIGNONS ) && !cl.paused && !cls.demoplayback );
@ -1562,6 +1560,9 @@ void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg )
CL_FixupColorStringsForInfoString( s, infostring ); CL_FixupColorStringsForInfoString( s, infostring );
if( !COM_CheckString( Info_ValueForKey( infostring, "gamedir" )))
return; // unsupported proto
// more info about servers // more info about servers
Con_Printf( "Server: %s, Game: %s\n", NET_AdrToString( from ), Info_ValueForKey( infostring, "gamedir" )); Con_Printf( "Server: %s, Game: %s\n", NET_AdrToString( from ), Info_ValueForKey( infostring, "gamedir" ));
@ -2023,6 +2024,8 @@ void CL_ReadPackets( void )
cls.demotime += host.frametime; cls.demotime += host.frametime;
CL_ReadNetMessage(); CL_ReadNetMessage();
CL_ApplyAddAngle();
#if 0 #if 0
// keep cheat cvars are unchanged // keep cheat cvars are unchanged
if( cl.maxclients > 1 && cls.state == ca_active && !host_developer.value ) if( cl.maxclients > 1 && cls.state == ca_active && !host_developer.value )

View File

@ -1448,13 +1448,10 @@ void CL_ParseAddAngle( sizebuf_t *msg )
float delta_yaw; float delta_yaw;
delta_yaw = MSG_ReadBitAngle( msg, 16 ); delta_yaw = MSG_ReadBitAngle( msg, 16 );
#if 0
if( cl.maxclients <= 1 && !FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) cl.viewangles[YAW] += delta_yaw;
{ return;
cl.viewangles[YAW] += delta_yaw; #endif
return;
}
// update running counter // update running counter
cl.addangletotal += delta_yaw; cl.addangletotal += delta_yaw;

View File

@ -248,7 +248,7 @@ void CL_CheckPredictionError( void )
// save for error interpolation // save for error interpolation
VectorCopy( delta, cl.local.prediction_error ); 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; cls.correction_time = cl_smoothtime->value;
} }
} }

View File

@ -1244,15 +1244,16 @@ COM_CheckParm
*/ */
int COM_CheckParm( char *parm, char **ppnext ) 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( i != 0 && i < host.argc - 1 )
if( ppnext ) *ppnext = str; *ppnext = (char *)host.argv[i + 1];
return 1; else *ppnext = NULL;
} }
return 0;
return i;
} }
/* /*

View File

@ -173,7 +173,7 @@ typedef enum
// PERFORMANCE INFO // PERFORMANCE INFO
#define MIN_FPS 20.0 // host minimum fps value for maxfps. #define MIN_FPS 20.0 // host minimum fps value for maxfps.
#define MAX_FPS 200.0 // upper limit 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 MAX_FRAMETIME 0.25
#define MIN_FRAMETIME 0.0001 #define MIN_FRAMETIME 0.0001

View File

@ -94,9 +94,6 @@ void Host_PrintEngineFeatures( void )
if( FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG )) if( FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG ))
MsgDev( D_REPORT, "^3EXT:^7 Compensate quake bug enabled\n" ); 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" );
} }
/* /*
@ -151,7 +148,7 @@ void Host_CheckSleep( void )
if( host.type == HOST_DEDICATED ) if( host.type == HOST_DEDICATED )
{ {
// let the dedicated server some sleep // let the dedicated server some sleep
Sys_Sleep( 1 ); // Sys_Sleep( 1 );
} }
else else
{ {
@ -716,7 +713,8 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
host.mempool = Mem_AllocPool( "Zone Engine" ); 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; host.allow_console = true;
if( Sys_CheckParm( "-dev" )) if( Sys_CheckParm( "-dev" ))
@ -873,7 +871,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Cmd_AddCommand ( "crash", Host_Crash_f, "a way to force a bus error for development reasons"); 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_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_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" ); host_clientloaded = Cvar_Get( "host_clientloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" );

View File

@ -386,7 +386,9 @@ int Sys_CheckParm( const char *parm )
for( i = 1; i < host.argc; i++ ) for( i = 1; i < host.argc; i++ )
{ {
if( !host.argv[i] ) continue; if( !host.argv[i] )
continue;
if( !Q_stricmp( parm, host.argv[i] )) if( !Q_stricmp( parm, host.argv[i] ))
return i; return i;
} }

View File

@ -195,8 +195,8 @@ typedef struct server_s
model_t *worldmodel; // pointer to world model_t *worldmodel; // pointer to world
qboolean simulating;
qboolean playersonly; qboolean playersonly;
qboolean simulating; // physics is running
qboolean paused; qboolean paused;
// statistics // statistics
@ -237,7 +237,6 @@ typedef struct sv_client_s
double next_sendinfotime; // time to send info about all players double next_sendinfotime; // time to send info about all players
double cl_updaterate; // client requested updaterate double cl_updaterate; // client requested updaterate
double timebase; // client timebase double timebase; // client timebase
double lastservertime; // check if server time was not changed so no resaon to send update
double connection_started; double connection_started;
char hashedcdkey[34]; // MD5 hash is 32 hex #'s, plus trailing 0 char hashedcdkey[34]; // MD5 hash is 32 hex #'s, plus trailing 0

View File

@ -380,7 +380,6 @@ void SV_ConnectClient( netadr_t from )
#endif #endif
newcl->next_messagetime = host.realtime + newcl->cl_updaterate; newcl->next_messagetime = host.realtime + newcl->cl_updaterate;
newcl->next_sendinfotime = 0.0; newcl->next_sendinfotime = 0.0;
newcl->lastservertime = -1.0;
newcl->ignored_ents = 0; newcl->ignored_ents = 0;
newcl->chokecount = 0; newcl->chokecount = 0;

View File

@ -652,20 +652,11 @@ void SV_SendClientDatagram( sv_client_t *cl )
byte msg_buf[MAX_DATAGRAM]; byte msg_buf[MAX_DATAGRAM];
sizebuf_t msg; 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 )); MSG_Init( &msg, "Datagram", msg_buf, sizeof( msg_buf ));
// always send servertime at new frame // always send servertime at new frame
MSG_BeginServerCmd( &msg, svc_time ); MSG_BeginServerCmd( &msg, svc_time );
MSG_WriteFloat( &msg, sv.time ); MSG_WriteFloat( &msg, sv.time );
cl->lastservertime = sv.time;
SV_WriteClientdataToMessage( cl, &msg ); SV_WriteClientdataToMessage( cl, &msg );
SV_WriteEntitiesToClient( cl, &msg ); SV_WriteEntitiesToClient( cl, &msg );
@ -825,11 +816,8 @@ void SV_SendClientMessages( void )
continue; 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 ) if( cl->state == cs_spawned )
{ {

View File

@ -4850,8 +4850,7 @@ qboolean SV_LoadProgs( const char *name )
{ {
Con_Printf( S_WARN "SV_LoadProgs: couldn't get physics API\n" ); Con_Printf( S_WARN "SV_LoadProgs: couldn't get physics API\n" );
} }
// TESTTEST
//host.features |= ENGINE_FIXED_FRAMERATE;
// grab function SV_SaveGameComment // grab function SV_SaveGameComment
SV_InitSaveRestore (); SV_InitSaveRestore ();

View File

@ -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_airmove, "1", FCVAR_SERVER, "obsolete, compatibility issues" );
CVAR_DEFINE_AUTO( sv_version, "", FCVAR_READ_ONLY, "engine version string" ); 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( hostname, "", FCVAR_SERVER|FCVAR_PRINTABLEONLY, "name of current host" );
CVAR_DEFINE_AUTO( sv_fps, "0.0", FCVAR_SERVER, "server framerate" );
// gore-related cvars // gore-related cvars
CVAR_DEFINE_AUTO( violence_hblood, "1", 0, "draw human blood" ); CVAR_DEFINE_AUTO( violence_hblood, "1", 0, "draw human blood" );
@ -217,6 +218,15 @@ void SV_CheckCmdTimes( void )
float diff; float diff;
int i; 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( )) if( Host_IsLocalGame( ))
return; return;
@ -544,32 +554,37 @@ SV_RunGameFrame
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( ))) if( !sv.simulating )
return; 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_Physics();
sv.time_residual -= sv.frametime; sv.time_residual -= fps;
sv.time += sv.frametime; sv.time += fps;
numFrames++; numFrames++;
} }
return (numFrames != 0);
} }
else else
{ {
SV_Physics(); SV_Physics();
sv.time += sv.frametime; sv.time += sv.frametime;
numFrames++; return true;
} }
} }
@ -584,10 +599,11 @@ void Host_ServerFrame( void )
// if server is not active, do nothing // if server is not active, do nothing
if( !svs.initialized ) return; if( !svs.initialized ) return;
if( FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) if( sv.simulating || sv.state != ss_active )
sv.frametime = ( 1.0 / (double)GAME_FPS ); sv.time_residual += host.frametime;
else sv.frametime = host.frametime; // GoldSrc style
if( sv_fps.value == 0.0f )
sv.frametime = host.frametime;
svgame.globals->frametime = sv.frametime; svgame.globals->frametime = sv.frametime;
// check clients timewindow // check clients timewindow
@ -596,9 +612,6 @@ void Host_ServerFrame( void )
// read packets from clients // read packets from clients
SV_ReadPackets (); SV_ReadPackets ();
// let everything in the world think and move
SV_RunGameFrame ();
// refresh physic movevars on the client side // refresh physic movevars on the client side
SV_UpdateMovevars ( false ); SV_UpdateMovevars ( false );
@ -607,6 +620,9 @@ void Host_ServerFrame( void )
// check timeouts // check timeouts
SV_CheckTimeouts (); 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 // send messages back to the clients that had packets read this frame
SV_SendClientMessages (); SV_SendClientMessages ();
@ -770,7 +786,7 @@ void SV_Init( void )
Cvar_RegisterVariable (&sv_wateralpha); Cvar_RegisterVariable (&sv_wateralpha);
Cvar_RegisterVariable (&sv_cheats); Cvar_RegisterVariable (&sv_cheats);
Cvar_RegisterVariable (&sv_airmove); Cvar_RegisterVariable (&sv_airmove);
Cvar_RegisterVariable (&sv_fps);
Cvar_RegisterVariable (&showtriggers); Cvar_RegisterVariable (&showtriggers);
Cvar_RegisterVariable (&sv_aim); Cvar_RegisterVariable (&sv_aim);
Cvar_RegisterVariable (&motdfile); Cvar_RegisterVariable (&motdfile);

View File

@ -67,19 +67,19 @@ qboolean SV_CopyEdictToPhysEnt( physent_t *pe, edict_t *ed )
VectorCopy( ed->v.origin, pe->origin ); VectorCopy( ed->v.origin, pe->origin );
VectorCopy( ed->v.angles, pe->angles ); 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 ));
pe->player = pe->info;
}
else if( ed->v.flags & FL_FAKECLIENT && ed->v.solid != MOVETYPE_PUSH )
{ {
// bot // bot
Q_strncpy( pe->name, "bot", sizeof( pe->name )); Q_strncpy( pe->name, "bot", sizeof( pe->name ));
pe->player = pe->info; pe->player = pe->info;
} }
else if( FBitSet( ed->v.flags, FL_CLIENT ))
{
// 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 else
{ {
// otherwise copy the classname // otherwise copy the classname
@ -148,39 +148,51 @@ qboolean SV_CopyEdictToPhysEnt( physent_t *pe, edict_t *ed )
return true; return true;
} }
qboolean SV_ShouldUnlagForPlayer( sv_client_t *cl )
{
// can't unlag in singleplayer
if( svs.maxclients <= 1 )
return false;
// unlag disabled globally
if( !svgame.dllFuncs.pfnAllowLagCompensation() || !sv_unlag.value )
return false;
if( !FBitSet( cl->flags, FCL_LAG_COMPENSATION ))
return false;
// player not ready
if( cl->state != cs_spawned )
return false;
return true;
}
void SV_GetTrueOrigin( sv_client_t *cl, int edictnum, vec3_t origin ) void SV_GetTrueOrigin( sv_client_t *cl, int edictnum, vec3_t origin )
{ {
// don't allow unlag in singleplayer if( !SV_ShouldUnlagForPlayer( cl ))
if( svs.maxclients <= 1 ) return;
if( cl->state < cs_connected || edictnum < 0 || edictnum >= svs.maxclients )
return; return;
if( !FBitSet( cl->flags, FCL_LAG_COMPENSATION ) || !sv_unlag.value ) if( edictnum < 1 || edictnum > svs.maxclients )
return; return;
if( !svgame.interp[edictnum].active || !svgame.interp[edictnum].moving ) if( svgame.interp[edictnum-1].active && svgame.interp[edictnum-1].moving )
return; VectorCopy( svgame.interp[edictnum-1].newpos, origin );
VectorCopy( svgame.interp[edictnum].newpos, origin );
} }
void SV_GetTrueMinMax( sv_client_t *cl, int edictnum, vec3_t mins, vec3_t maxs ) void SV_GetTrueMinMax( sv_client_t *cl, int edictnum, vec3_t mins, vec3_t maxs )
{ {
// don't allow unlag in singleplayer if( !SV_ShouldUnlagForPlayer( cl ))
if( svs.maxclients <= 1 ) return;
if( cl->state < cs_connected || edictnum < 0 || edictnum >= svs.maxclients )
return; return;
if( !FBitSet( cl->flags, FCL_LAG_COMPENSATION ) || !sv_unlag.value ) if( edictnum < 1 || edictnum > svs.maxclients )
return; return;
if( !svgame.interp[edictnum].active || !svgame.interp[edictnum].moving ) if( svgame.interp[edictnum-1].active && svgame.interp[edictnum-1].moving )
return; {
VectorCopy( svgame.interp[edictnum-1].mins, mins );
VectorCopy( svgame.interp[edictnum].mins, mins ); VectorCopy( svgame.interp[edictnum-1].maxs, maxs );
VectorCopy( svgame.interp[edictnum].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.absmin, mins );
VectorCopy( check->v.absmax, maxs ); 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; if( sv.current_client )
{
// trying to get interpolated values // trying to get interpolated values
SV_GetTrueMinMax( &svs.clients[e], e, mins, maxs ); SV_GetTrueMinMax( sv.current_client, NUM_FOR_EDICT( check ), mins, maxs );
}
} }
if( !BoundsIntersect( pmove_mins, pmove_maxs, mins, maxs )) if( !BoundsIntersect( pmove_mins, pmove_maxs, mins, maxs ))
@ -828,16 +841,7 @@ void SV_SetupMoveInterpolant( sv_client_t *cl )
memset( svgame.interp, 0, sizeof( svgame.interp )); memset( svgame.interp, 0, sizeof( svgame.interp ));
has_update = false; has_update = false;
// don't allow unlag in singleplayer if( !SV_ShouldUnlagForPlayer( cl ))
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 ))
return; return;
has_update = true; has_update = true;
@ -855,17 +859,13 @@ void SV_SetupMoveInterpolant( sv_client_t *cl )
lerp->active = true; lerp->active = true;
} }
if( cl->latency > 1.5f ) latency = Q_min( cl->latency, 1.5f );
latency = 1.5f;
else latency = cl->latency;
if( sv_maxunlag.value != 0.0f ) if( sv_maxunlag.value != 0.0f )
{ {
if (sv_maxunlag.value < 0.0f ) if (sv_maxunlag.value < 0.0f )
Cvar_SetValue( "sv_maxunlag", 0.0f ); Cvar_SetValue( "sv_maxunlag", 0.0f );
latency = Q_min( latency, sv_maxunlag.value );
if( latency >= sv_maxunlag.value )
latency = sv_maxunlag.value;
} }
lerp_msec = cl->lastcmd.lerp_msec * 0.001f; lerp_msec = cl->lastcmd.lerp_msec * 0.001f;
@ -877,9 +877,9 @@ void SV_SetupMoveInterpolant( sv_client_t *cl )
finalpush = ( host.realtime - latency - lerp_msec ) + sv_unlagpush.value; finalpush = ( host.realtime - latency - lerp_msec ) + sv_unlagpush.value;
if( finalpush > host.realtime ) finalpush = host.realtime; // pushed too much ? 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]; frame = &cl->frames[(cl->netchan.outgoing_sequence - (i + 1)) & SV_UPDATE_MASK];
@ -887,19 +887,24 @@ void SV_SetupMoveInterpolant( sv_client_t *cl )
{ {
state = &svs.packet_entities[(frame->first_entity+j)%svs.num_client_entities]; 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; continue;
lerp = &svgame.interp[state->number-1]; lerp = &svgame.interp[state->number-1];
if( lerp->nointerp ) continue; if( lerp->nointerp ) continue;
if( state->health <= 0 || ( state->effects & EF_NOINTERP )) if( state->health <= 0 || FBitSet( state->effects, EF_NOINTERP ))
lerp->nointerp = true; lerp->nointerp = true;
if( !lerp->firstframe ) if( lerp->firstframe )
{
if( SV_UnlagCheckTeleport( state->origin, lerp->finalpos ))
lerp->nointerp = true;
}
else
{
lerp->firstframe = true; lerp->firstframe = true;
else if( SV_UnlagCheckTeleport( state->origin, lerp->finalpos )) }
lerp->nointerp = true;
VectorCopy( state->origin, lerp->finalpos ); VectorCopy( state->origin, lerp->finalpos );
} }
@ -937,7 +942,7 @@ void SV_SetupMoveInterpolant( sv_client_t *cl )
{ {
state = &svs.packet_entities[(frame->first_entity+i)%svs.num_client_entities]; 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; continue;
clientnum = state->number - 1; clientnum = state->number - 1;
@ -987,16 +992,7 @@ void SV_RestoreMoveInterpolant( sv_client_t *cl )
return; return;
} }
// don't allow unlag in singleplayer if( !SV_ShouldUnlagForPlayer( cl ))
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 ))
return; return;
for( i = 0, check = svs.clients; i < svs.maxclients; i++, check++ ) for( i = 0, check = svs.clients; i < svs.maxclients; i++, check++ )
@ -1006,11 +1002,11 @@ void SV_RestoreMoveInterpolant( sv_client_t *cl )
oldlerp = &svgame.interp[i]; oldlerp = &svgame.interp[i];
if( VectorCompare( oldlerp->oldpos, oldlerp->newpos )) if( VectorCompare( oldlerp->oldpos, oldlerp->newpos ) || !oldlerp->moving )
continue; // they didn't actually move. continue; // they didn't actually move.
if( !oldlerp->moving || !oldlerp->active ) if( !oldlerp->active )
return; continue;
if( VectorCompare( oldlerp->curpos, check->edict->v.origin )) if( VectorCompare( oldlerp->curpos, check->edict->v.origin ))
{ {