04 Apr 2010
This commit is contained in:
parent
0915c8647b
commit
9f0fb3da32
|
@ -260,6 +260,63 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
ent->v.rendercolor[i] = LerpPoint( prev->rendercolor[i], state->rendercolor[i], m_fLerp );
|
||||
}
|
||||
|
||||
if( ent->v.movetype == MOVETYPE_STEP )
|
||||
{
|
||||
float f = 0;
|
||||
float d;
|
||||
|
||||
// don't do it if the goalstarttime hasn't updated in a while.
|
||||
|
||||
// NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit
|
||||
// was increased to 1.0 s., which is 2x the max lag we are accounting for.
|
||||
|
||||
if(( gpGlobals->time < state->animtime + 1.0f ) && ( state->animtime != prev->animtime ))
|
||||
{
|
||||
f = (gpGlobals->time - state->animtime) / (state->animtime - prev->animtime);
|
||||
//ALERT( at_console, "%4.2f %.2f %.2f\n", f, state->animtime, gpGlobals->time );
|
||||
}
|
||||
|
||||
if(!( ent->v.flags & EF_NOINTERP ))
|
||||
{
|
||||
// ugly hack to interpolate angle, position.
|
||||
// current is reached 0.1 seconds after being set
|
||||
f = f - 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = 0;
|
||||
}
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
ent->v.origin[i] += (ent->v.origin[i] - prev->origin[i]) * f;
|
||||
}
|
||||
|
||||
// NOTE: Because multiplayer lag can be relatively large, we don't want to cap
|
||||
// f at 1.5 anymore.
|
||||
//if( f > -1.0 && f < 1.5 ) {}
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
float ang1, ang2;
|
||||
|
||||
ang1 = ent->v.angles[i];
|
||||
ang2 = prev->angles[i];
|
||||
|
||||
d = ang1 - ang2;
|
||||
if( d > 180 )
|
||||
{
|
||||
d -= 360;
|
||||
}
|
||||
else if( d < -180 )
|
||||
{
|
||||
d += 360;
|
||||
}
|
||||
ent->v.angles[i] += d * f;
|
||||
}
|
||||
//ALERT( at_console, "%.3f \n", f );
|
||||
}
|
||||
|
||||
// interpolate scale, renderamount etc
|
||||
ent->v.renderamt = LerpPoint( prev->renderamt, state->renderamt, m_fLerp );
|
||||
ent->v.scale = LerpPoint( prev->scale, state->scale, m_fLerp );
|
||||
|
@ -272,7 +329,7 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
|
||||
if( ent->v.animtime )
|
||||
{
|
||||
if( ent->v.effects & EF_NOINTERP )
|
||||
if(!( ent->v.effects & EF_NOINTERP ))
|
||||
{
|
||||
// adjust lerping values if animation restarted
|
||||
if( lerpTime < 0 ) prevframe = 1.001;
|
||||
|
|
|
@ -246,7 +246,7 @@ void CL_DeleteDemo_f( void )
|
|||
{
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( "Usage: deldemo <name>\n" );
|
||||
Msg( "Usage: killdemo <name>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1044,7 +1044,7 @@ void CL_InitLocal( void )
|
|||
Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server" );
|
||||
Cmd_AddCommand ("record", CL_Record_f, "record a demo" );
|
||||
Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "playing a demo" );
|
||||
Cmd_AddCommand ("deldemo", CL_DeleteDemo_f, "delete a specified demo file and demoshot" );
|
||||
Cmd_AddCommand ("killdemo", CL_DeleteDemo_f, "delete a specified demo file and demoshot" );
|
||||
Cmd_AddCommand ("startdemos", CL_StartDemos_f, "start playing back the selected demos sequentially" );
|
||||
Cmd_AddCommand ("demos", CL_Demos_f, "restart looping demos defined by the last startdemos command" );
|
||||
Cmd_AddCommand ("movie", CL_PlayVideo_f, "playing a movie" );
|
||||
|
|
|
@ -290,7 +290,7 @@ extern byte net_message_buffer[MAX_MSGLEN];
|
|||
#define PORT_CLIENT 27901
|
||||
#define PORT_SERVER 27910
|
||||
#define MULTIPLAYER_BACKUP 64 // how many data slots to use when in multiplayer (must be power of 2)
|
||||
#define SINGLEPLAYER_BACKUP 8 // same for single player
|
||||
#define SINGLEPLAYER_BACKUP 16 // same for single player
|
||||
#define MAX_FLAGS 32 // 32 bits == 32 flags
|
||||
#define MASK_FLAGS (MAX_FLAGS - 1)
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ typedef struct sv_client_s
|
|||
char userinfo[MAX_INFO_STRING]; // name, etc (received from client)
|
||||
char physinfo[MAX_INFO_STRING]; // set on server (transmit to client)
|
||||
bool physinfo_modified; // transmit at next opportunity
|
||||
bool send_message;
|
||||
bool sendmovevars;
|
||||
bool sendinfo;
|
||||
|
||||
|
@ -390,6 +391,7 @@ void SV_WriteFrameToClient( sv_client_t *client, sizebuf_t *msg );
|
|||
void SV_BuildClientFrame( sv_client_t *client );
|
||||
void SV_UpdateEntityState( const edict_t *ent, bool baseline );
|
||||
void SV_InactivateClients( void );
|
||||
void SV_SendMessagesToAll( void );
|
||||
|
||||
//
|
||||
// sv_game.c
|
||||
|
|
|
@ -1467,7 +1467,8 @@ void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg )
|
|||
// make sure the reply sequence number matches the incoming sequence number
|
||||
if( cl->netchan.incoming_sequence >= cl->netchan.outgoing_sequence )
|
||||
cl->netchan.outgoing_sequence = cl->netchan.incoming_sequence;
|
||||
|
||||
else cl->send_message = false; // don't reply, sequences have slipped
|
||||
|
||||
// read optional clientCommand strings
|
||||
while( cl->state != cs_zombie )
|
||||
{
|
||||
|
|
|
@ -585,8 +585,12 @@ void SV_SendClientMessages( void )
|
|||
MSG_Clear( &cl->datagram );
|
||||
SV_BroadcastPrintf( PRINT_HIGH, "%s overflowed\n", cl->name );
|
||||
SV_DropClient( cl );
|
||||
cl->send_message = true;
|
||||
}
|
||||
|
||||
// only send messages if the client has sent one
|
||||
if( !cl->send_message ) continue;
|
||||
|
||||
if( cl->state == cs_spawned )
|
||||
{
|
||||
// don't overrun bandwidth
|
||||
|
@ -595,13 +599,36 @@ void SV_SendClientMessages( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
// just update reliable if needed
|
||||
// just update reliable
|
||||
if( cl->netchan.message.cursize || svs.realtime - cl->netchan.last_sent > 1000 )
|
||||
Netchan_Transmit( &cl->netchan, 0, NULL );
|
||||
}
|
||||
|
||||
// yes, message really sended
|
||||
cl->send_message = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
SV_SendMessagesToAll
|
||||
|
||||
e.g. before changing level
|
||||
=======================
|
||||
*/
|
||||
void SV_SendMessagesToAll( void )
|
||||
{
|
||||
int i;
|
||||
sv_client_t *cl;
|
||||
|
||||
for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
|
||||
{
|
||||
if( cl->state >= cs_connected )
|
||||
cl->send_message = true;
|
||||
}
|
||||
SV_SendClientMessages();
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
SV_InactivateClients
|
||||
|
|
|
@ -1151,14 +1151,14 @@ free edict private mem, unlink physics etc
|
|||
*/
|
||||
void pfnRemoveEntity( edict_t* e )
|
||||
{
|
||||
if( !e || e->free )
|
||||
if( !SV_IsValidEdict( e ))
|
||||
{
|
||||
MsgDev( D_ERROR, "SV_RemoveEntity: entity already freed\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// never free client or world entity
|
||||
if(( NUM_FOR_EDICT( e ) - 1 ) < svgame.globals->maxClients )
|
||||
if( e->serialnumber < ( svgame.globals->maxClients + 1 ))
|
||||
{
|
||||
MsgDev( D_ERROR, "SV_RemoveEntity: can't delete %s\n", (e == EDICT_NUM( 0 )) ? "world" : "client" );
|
||||
return;
|
||||
|
|
|
@ -258,8 +258,11 @@ void SV_ReadPackets( void )
|
|||
MsgDev( D_INFO, "SV_ReadPackets: fixing up a translated port\n");
|
||||
cl->netchan.remote_address.port = net_from.port;
|
||||
}
|
||||
|
||||
if( Netchan_Process( &cl->netchan, &net_message ))
|
||||
{
|
||||
cl->send_message = true; // reply at end of frame
|
||||
|
||||
// this is a valid, sequenced packet, so process it
|
||||
if( cl->state != cs_zombie )
|
||||
{
|
||||
|
@ -357,8 +360,13 @@ void SV_PrepWorldFrame( void )
|
|||
{
|
||||
ent = EDICT_NUM( i );
|
||||
if( ent->free ) continue;
|
||||
|
||||
ent->pvServerData->s.ed_flags = 0;
|
||||
ent->v.effects &= ~EF_MUZZLEFLASH;
|
||||
|
||||
// clear NOINTERP flag automatically only for alive creatures
|
||||
if( ent->v.flags & ( FL_MONSTER|FL_CLIENT|FL_FAKECLIENT ) && ent->v.health > 0.0f )
|
||||
ent->v.effects &= ~EF_NOINTERP;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,14 +399,14 @@ SV_RunGameFrame
|
|||
*/
|
||||
void SV_RunGameFrame( void )
|
||||
{
|
||||
if( !SV_HasActivePlayers()) return;
|
||||
|
||||
// we always need to bump framenum, even if we
|
||||
// don't run the world, otherwise the delta
|
||||
// compression can get confused when a client
|
||||
// has the "current" frame
|
||||
sv.framenum++;
|
||||
|
||||
if( !SV_HasActivePlayers()) return;
|
||||
|
||||
// don't run if paused or not in game
|
||||
if( !sv.paused && CL_IsInGame( ))
|
||||
SV_Physics();
|
||||
|
|
|
@ -650,11 +650,10 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd )
|
|||
if(!( clent->v.flags & FL_SPECTATOR ))
|
||||
{
|
||||
svgame.globals->time = sv.time * 0.001f;
|
||||
svgame.globals->frametime = 0.0f;
|
||||
svgame.dllFuncs.pfnPlayerPreThink( clent );
|
||||
svgame.globals->frametime = ucmd->msec * 0.001f;
|
||||
svgame.dllFuncs.pfnPlayerPreThink( clent );
|
||||
|
||||
SV_RunThink( clent );
|
||||
SV_RunThink( clent ); // clients cannot be deleted from map
|
||||
|
||||
// If conveyor, or think, set basevelocity, then send to client asap too.
|
||||
if( VectorLength( clent->v.basevelocity ) > 0.0f )
|
||||
|
@ -711,21 +710,15 @@ void SV_PostRunCmd( sv_client_t *cl )
|
|||
|
||||
clent = cl->edict;
|
||||
if( !clent || clent->free ) return;
|
||||
svgame.pmove->runfuncs = false; // all next calls ignore footstep sounds
|
||||
|
||||
svgame.pmove->runfuncs = false; // all next calls ignore footstep sounds
|
||||
svgame.globals->frametime = 0.0f; // PlayerPostThink uses it
|
||||
svgame.globals->time = sv.time * 0.001f;
|
||||
|
||||
// run post-think
|
||||
if(!( clent->v.flags & FL_SPECTATOR ))
|
||||
{
|
||||
svgame.globals->time = sv.time * 0.001f;
|
||||
svgame.globals->frametime = 0;
|
||||
svgame.dllFuncs.pfnPlayerPostThink( clent );
|
||||
}
|
||||
else
|
||||
{
|
||||
svgame.globals->time = sv.time * 0.001f;
|
||||
svgame.globals->frametime = 0;
|
||||
if( clent->v.flags & FL_SPECTATOR )
|
||||
svgame.dllFuncs.pfnSpectatorThink( clent );
|
||||
}
|
||||
else svgame.dllFuncs.pfnPlayerPostThink( clent );
|
||||
|
||||
// restore frametime
|
||||
svgame.globals->frametime = sv.frametime * 0.001f;
|
||||
|
|
|
@ -174,21 +174,21 @@ bool SV_RunThink( edict_t *ent )
|
|||
int i;
|
||||
float newtime;
|
||||
|
||||
newtime = (sv.time + sv.frametime) * 0.001f;
|
||||
newtime = (sv.time * 0.001f) + (sv.frametime * 0.001f);
|
||||
|
||||
// don't let things stay in the past.
|
||||
// it is possible to start that way by a trigger with a local time.
|
||||
if( ent->v.nextthink <= 0.0f || ent->v.nextthink > newtime )
|
||||
return true;
|
||||
|
||||
for( i = 0; i < 128 && !ent->free; i++ )
|
||||
for( i = 0; i < SV_UPDATE_BACKUP && !ent->free; i++ )
|
||||
{
|
||||
svgame.globals->time = max( (sv.time * 0.001f), ent->v.nextthink );
|
||||
svgame.globals->time = max(( sv.time * 0.001f ), ent->v.nextthink );
|
||||
ent->v.nextthink = 0.0f;
|
||||
|
||||
svgame.dllFuncs.pfnThink( ent );
|
||||
|
||||
newtime = (sv.time + sv.frametime) * 0.001f;
|
||||
newtime = (sv.time * 0.001f) + (sv.frametime * 0.001f);
|
||||
|
||||
// mods often set nextthink to time to cause a think every frame,
|
||||
// we don't want to loop in that case, so exit if the new nextthink is
|
||||
|
@ -1063,6 +1063,7 @@ void SV_PushMove( edict_t *pusher, float movetime )
|
|||
|
||||
// if the pusher has a "blocked" function, call it
|
||||
// otherwise, just stay in place until the obstacle is gone
|
||||
svgame.globals->time = (sv.time * 0.001f);
|
||||
svgame.dllFuncs.pfnBlocked( pusher, check );
|
||||
break;
|
||||
}
|
||||
|
@ -1209,6 +1210,7 @@ bool SV_PushAngles( edict_t *pusher, vec3_t move, vec3_t amove )
|
|||
}
|
||||
|
||||
MsgDev( D_INFO, "Pusher hit %s\n", SV_ClassName( check ));
|
||||
svgame.globals->time = (sv.time * 0.001f);
|
||||
svgame.dllFuncs.pfnBlocked( pusher, check );
|
||||
|
||||
// move back any entities we already moved
|
||||
|
@ -1907,10 +1909,7 @@ void SV_Physics_Step_RunTimestep( edict_t *ent, float timestep )
|
|||
|
||||
void SV_Physics_Step( edict_t *ent )
|
||||
{
|
||||
svgame.globals->time = sv.time * 0.001f;
|
||||
|
||||
SV_Physics_Step_RunTimestep( ent, svgame.globals->frametime );
|
||||
|
||||
if( !SV_RunThink( ent )) return;
|
||||
SV_CheckWaterTransition( ent );
|
||||
}
|
||||
|
@ -2008,7 +2007,7 @@ void SV_Physics_None( edict_t *ent )
|
|||
{
|
||||
float newtime;
|
||||
|
||||
newtime = (sv.time + sv.frametime) * 0.001f;
|
||||
newtime = (sv.time * 0.001f) + svgame.globals->frametime;
|
||||
if( ent->v.nextthink > 0.0f && ent->v.nextthink <= newtime )
|
||||
SV_RunThink( ent );
|
||||
}
|
||||
|
@ -2093,8 +2092,8 @@ SV_Physics
|
|||
*/
|
||||
void SV_Physics( void )
|
||||
{
|
||||
edict_t *ent;
|
||||
int i;
|
||||
edict_t *ent;
|
||||
|
||||
// let the progs know that a new frame has started
|
||||
svgame.globals->time = sv.time * 0.001f;
|
||||
|
@ -2135,6 +2134,5 @@ void SV_Physics( void )
|
|||
|
||||
svgame.dllFuncs.pfnEndFrame();
|
||||
|
||||
if( !sv_playersonly->integer )
|
||||
sv.time += sv.frametime;
|
||||
if( !sv_playersonly->integer ) sv.time += sv.frametime;
|
||||
}
|
|
@ -756,6 +756,8 @@ void PlayerPostThink( edict_t *pEntity )
|
|||
|
||||
// use the old frametime, even if the engine has reset it
|
||||
gpGlobals->frametime = cached_frametime;
|
||||
|
||||
PhysicsPostFrame();
|
||||
}
|
||||
|
||||
void BuildLevelList( void )
|
||||
|
@ -958,13 +960,11 @@ void StartFrame( void )
|
|||
}
|
||||
|
||||
ServerPostActivate(); // called once
|
||||
PhysicsPostFrame();
|
||||
|
||||
PhysicsFrame();
|
||||
}
|
||||
|
||||
void EndFrame( void )
|
||||
{
|
||||
PhysicsFrame();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1206,9 +1206,6 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline )
|
|||
if( pNet->pev->fov < 0.0 ) pNet->pev->fov = 0.0;
|
||||
if( pNet->pev->fov > 160 ) pNet->pev->fov = 160;
|
||||
to->fov = pNet->pev->fov;
|
||||
|
||||
// clear EF_NOINTERP flag each frame for client
|
||||
pNet->pev->effects &= ~EF_NOINTERP;
|
||||
}
|
||||
else if( to->ed_type == ED_AMBIENT )
|
||||
{
|
||||
|
|
|
@ -1174,9 +1174,6 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline )
|
|||
if( pNet->pev->fov < 0.0 ) pNet->pev->fov = 0.0;
|
||||
if( pNet->pev->fov > 160 ) pNet->pev->fov = 160;
|
||||
to->fov = pNet->pev->fov;
|
||||
|
||||
// clear EF_NOINTERP flag each frame for client
|
||||
pNet->pev->effects &= ~EF_NOINTERP;
|
||||
}
|
||||
else if( to->ed_type == ED_AMBIENT )
|
||||
{
|
||||
|
|
5
todo.log
5
todo.log
|
@ -26,7 +26,8 @@ Xash 0.71 Beta 05.05.10
|
|||
2. fix sky changelevel bug
|
||||
3. complete lights.shader
|
||||
4. revision server physic
|
||||
5. revision monster moving
|
||||
5. revision monster moving OK
|
||||
6. fix save\restore global state OK
|
||||
7. rewrite WalkMove OK
|
||||
8. tune UPDATE_BACKUP value for singleplayer
|
||||
8. tune UPDATE_BACKUP value for singleplayer OK
|
||||
9. fix monsters interpolation
|
Reference in New Issue