/* ================ SV_CheckAllEnts ================ */ void SV_CheckAllEnts( void ) { edict_t *e; int i; if( !sv_check_errors->integer || sv.state != ss_active ) return; // check edicts errors for( i = svgame.globals->maxClients + 1; i < svgame.numEntities; i++ ) { e = EDICT_NUM( i ); // DEBUG: check 'gamestate' for using by mods if( e->v.gamestate != 0 ) { MsgDev( D_INFO, "Entity %s[%i] uses gamestate %i\n", SV_ClassName( e ), NUM_FOR_EDICT( e ), e->v.gamestate ); } if( e->free && e->pvPrivateData != NULL ) { MsgDev( D_ERROR, "Freed entity %s (%i) has private data.\n", SV_ClassName( e ), i ); continue; } if( !SV_IsValidEdict( e )) continue; if( !e->v.pContainingEntity || e->v.pContainingEntity != e ) { MsgDev( D_ERROR, "Entity %s (%i) has invalid container, fixed.\n", SV_ClassName( e ), i ); e->v.pContainingEntity = e; continue; } if( !e->pvPrivateData || !Mem_IsAllocatedExt( svgame.mempool, e->pvPrivateData )) { MsgDev( D_ERROR, "Entity %s (%i) trashed private data.\n", SV_ClassName( e ), i ); e->pvPrivateData = NULL; continue; } SV_CheckVelocity( e ); } }
/* ============= SV_Physics_Follow just copy angles and origin of parent ============= */ void SV_Physics_Follow( edict_t *ent ) { edict_t *parent; // regular thinking if( !SV_RunThink( ent )) return; parent = ent->v.aiment; if( !SV_IsValidEdict( parent )) { MsgDev( D_ERROR, "%s have MOVETYPE_FOLLOW with no corresponding ent!", SV_ClassName( ent )); ent->v.movetype = MOVETYPE_NONE; return; } VectorAdd( parent->v.origin, ent->v.v_angle, ent->v.origin ); VectorCopy( parent->v.angles, ent->v.angles ); SV_LinkEdict( ent, true ); }
/* ============= SV_Physics_Compound a glue two entities together ============= */ void SV_Physics_Compound( edict_t *ent ) { edict_t *parent; // regular thinking if( !SV_RunThink( ent )) return; parent = ent->v.aiment; if( !SV_IsValidEdict( parent )) { MsgDev( D_ERROR, "%s have MOVETYPE_COMPOUND with no corresponding ent!", SV_ClassName( ent )); ent->v.movetype = MOVETYPE_NONE; return; } if( ent->v.solid != SOLID_TRIGGER ) ent->v.solid = SOLID_NOT; switch( parent->v.movetype ) { case MOVETYPE_PUSH: case MOVETYPE_PUSHSTEP: break; default: return; } // not initialized ? if( ent->v.ltime == 0.0f ) { VectorCopy( parent->v.origin, ent->v.oldorigin ); VectorCopy( parent->v.angles, ent->v.avelocity ); ent->v.ltime = host.frametime; return; } if( !VectorCompare( parent->v.origin, ent->v.oldorigin ) || !VectorCompare( parent->v.angles, ent->v.avelocity )) { matrix4x4 start_l, end_l, temp_l, child; // create parent old position Matrix4x4_CreateFromEntity( temp_l, ent->v.avelocity, ent->v.oldorigin, 1.0f ); Matrix4x4_Invert_Simple( start_l, temp_l ); // create parent actual position Matrix4x4_CreateFromEntity( end_l, parent->v.angles, parent->v.origin, 1.0f ); // stupid quake bug!!! if( !( host.features & ENGINE_COMPENSATE_QUAKE_BUG )) ent->v.angles[PITCH] = -ent->v.angles[PITCH]; // create child actual position Matrix4x4_CreateFromEntity( child, ent->v.angles, ent->v.origin, 1.0f ); // transform child from start to end Matrix4x4_ConcatTransforms( temp_l, start_l, child ); Matrix4x4_ConcatTransforms( child, end_l, temp_l ); // create child final position Matrix4x4_ConvertToEntity( child, ent->v.angles, ent->v.origin ); // stupid quake bug!!! if( !( host.features & ENGINE_COMPENSATE_QUAKE_BUG )) ent->v.angles[PITCH] = -ent->v.angles[PITCH]; } // notsolid ents never touch triggers SV_LinkEdict( ent, (ent->v.solid == SOLID_NOT) ? false : true ); // shuffle states VectorCopy( parent->v.origin, ent->v.oldorigin ); VectorCopy( parent->v.angles, ent->v.avelocity ); }