/* ============= SV_RunThink Runs thinking code if time. There is some play in the exact time the think function will be called, because it is called before any movement is done in a frame. Not used for pushmove objects, because they must be exact. Returns false if the entity removed itself. ============= */ qboolean SV_RunThink( edict_t *ent ) { float thinktime; if(!( ent->v.flags & FL_KILLME )) { thinktime = ent->v.nextthink; if( thinktime <= 0.0f || thinktime > sv.time + host.frametime ) return true; if( thinktime < sv.time ) thinktime = sv.time; // don't let things stay in the past. // it is possible to start that way // by a trigger with a local time. ent->v.nextthink = 0.0f; svgame.globals->time = thinktime; svgame.dllFuncs.pfnThink( ent ); } if( ent->v.flags & FL_KILLME ) { //MsgDev( D_NOTE, "SV_RunThink: FreeEdict\n"); SV_FreeEdict( ent ); } return !ent->free; }
//============================================================================ static void SV_Physics_Entity( edict_t *ent ) { // user dll can override movement type (Xash3D extension) if( svgame.physFuncs.SV_PhysicsEntity && svgame.physFuncs.SV_PhysicsEntity( ent )) return; // overrided SV_UpdateBaseVelocity( ent ); if(!( ent->v.flags & FL_BASEVELOCITY ) && !VectorIsNull( ent->v.basevelocity )) { // Apply momentum (add in half of the previous frame of velocity first) VectorMA( ent->v.velocity, 1.0f + (host.frametime * 0.5f), ent->v.basevelocity, ent->v.velocity ); VectorClear( ent->v.basevelocity ); } ent->v.flags &= ~FL_BASEVELOCITY; if( svgame.globals->force_retouch != 0.0f ) { // force retouch even for stationary SV_LinkEdict( ent, true ); } switch( ent->v.movetype ) { case MOVETYPE_NONE: SV_Physics_None( ent ); break; case MOVETYPE_NOCLIP: SV_Physics_Noclip( ent ); break; case MOVETYPE_FOLLOW: SV_Physics_Follow( ent ); break; case MOVETYPE_COMPOUND: SV_Physics_Compound( ent ); break; case MOVETYPE_STEP: case MOVETYPE_PUSHSTEP: SV_Physics_Step( ent ); break; case MOVETYPE_FLY: case MOVETYPE_TOSS: case MOVETYPE_BOUNCE: case MOVETYPE_FLYMISSILE: case MOVETYPE_BOUNCEMISSILE: SV_Physics_Toss( ent ); break; case MOVETYPE_PUSH: SV_Physics_Pusher( ent ); break; case MOVETYPE_WALK: Host_Error( "SV_Physics: bad movetype %i\n", ent->v.movetype ); break; } // g-cont. don't alow free entities during loading because // this produce a corrupted baselines if( sv.state == ss_active && ent->v.flags & FL_KILLME ) SV_FreeEdict( ent ); }
/* ================ SV_FreeOldEntities remove immediate entities ================ */ void SV_FreeOldEntities( void ) { edict_t *ent; int i; // at end of frame kill all entities which supposed to it for( i = svgame.globals->maxClients + 1; i < svgame.numEntities; i++ ) { ent = EDICT_NUM( i ); if( ent->free ) continue; if( ent->v.flags & FL_KILLME ) SV_FreeEdict( ent ); } // decrement svgame.numEntities if the highest number entities died for( ; EDICT_NUM( svgame.numEntities - 1 )->free; svgame.numEntities-- ); }
/* ============= SV_PlayerRunThink Runs thinking code if player time. There is some play in the exact time the think function will be called, because it is called before any movement is done in a frame. Not used for pushmove objects, because they must be exact. Returns false if the entity removed itself. ============= */ qboolean SV_PlayerRunThink( edict_t *ent, float frametime, double time ) { float thinktime; if(!( ent->v.flags & (FL_KILLME|FL_DORMANT ))) { thinktime = ent->v.nextthink; if( thinktime <= 0.0f || thinktime > time + frametime ) return true; if( thinktime > time ) thinktime = time; ent->v.nextthink = 0.0f; svgame.globals->time = thinktime; svgame.dllFuncs.pfnThink( ent ); } if( ent->v.flags & FL_KILLME ) SV_FreeEdict( ent ); return !ent->free; }