engine: server: refactoring.

This commit is contained in:
Alibek Omarov
2026-07-22 20:13:14 +05:00
committed by a1batross
parent 04fbe1a356
commit 24f8525fad
5 changed files with 112 additions and 142 deletions

View File

@@ -705,4 +705,23 @@ int SV_LightForEntity( edict_t *pEdict );
//
void SV_SourceQuery_HandleConnnectionlessPacket( const char *c, netadr_t from, sizebuf_t *msg );
static inline qboolean SV_CheckGroupOp( int op, int groupinfo, int mask )
{
if( op == GROUP_OP_AND && !FBitSet( groupinfo, mask ))
return false;
if( op == GROUP_OP_NAND && FBitSet( groupinfo, mask ))
return false;
return true;
}
static inline qboolean SV_CheckGroupTrace( const edict_t *e1, const edict_t *e2 )
{
if( e1->v.groupinfo && e2->v.groupinfo )
return SV_CheckGroupOp( svs.groupop, e1->v.groupinfo, e2->v.groupinfo );
return true;
}
#endif//SERVER_H

View File

@@ -435,15 +435,9 @@ static int SV_Multicast( int dest, const vec3_t origin, const edict_t *ent, qboo
if( filter && cl == sv.current_client && FBitSet( sv.current_client->flags, FCL_PREDICT_MOVEMENT ))
continue;
if( SV_IsValidEdict( ent ) && ent->v.groupinfo && cl->edict->v.groupinfo )
{
if( svs.groupop == GROUP_OP_AND && !FBitSet( cl->edict->v.groupinfo, ent->v.groupinfo ))
if( SV_IsValidEdict( ent ) && !SV_CheckGroupTrace( ent, cl->edict ))
continue;
if( svs.groupop == GROUP_OP_NAND && FBitSet( cl->edict->v.groupinfo, ent->v.groupinfo ))
continue;
}
if( !SV_CheckClientVisiblity( cl, mask ))
continue;
@@ -4123,15 +4117,9 @@ void GAME_EXPORT SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word
if( cl->state != cs_spawned || !cl->edict || FBitSet( cl->flags, FCL_FAKECLIENT ))
continue;
if( SV_IsValidEdict( pInvoker ) && pInvoker->v.groupinfo && cl->edict->v.groupinfo )
{
if( svs.groupop == GROUP_OP_AND && !FBitSet( cl->edict->v.groupinfo, pInvoker->v.groupinfo ))
if( SV_IsValidEdict( pInvoker ) && !SV_CheckGroupTrace( pInvoker, cl->edict ))
continue;
if( svs.groupop == GROUP_OP_NAND && FBitSet( cl->edict->v.groupinfo, pInvoker->v.groupinfo ))
continue;
}
if( SV_IsValidEdict( pInvoker ))
{
if( !SV_CheckClientVisiblity( cl, mask ))

View File

@@ -60,6 +60,47 @@ Utility functions
===============================================================================
*/
/*
================
SV_CheckVelocity
================
*/
void SV_CheckVelocity( edict_t *ent )
{
float wishspd;
float maxspd;
// bound velocity
for( int i = 0; i < 3; i++ )
{
if( IS_NAN( ent->v.velocity[i] ))
{
if( sv_check_errors.value )
Con_Printf( "Got a NaN velocity on %s\n", SV_GetString( ent->v.classname ));
ent->v.velocity[i] = 0.0f;
}
if( IS_NAN( ent->v.origin[i] ))
{
if( sv_check_errors.value )
Con_Printf( "Got a NaN origin on %s\n", SV_GetString( ent->v.classname ));
ent->v.origin[i] = 0.0f;
}
}
wishspd = DotProduct( ent->v.velocity, ent->v.velocity );
maxspd = sv_maxvelocity.value * sv_maxvelocity.value * 1.73f; // half-diagonal
if( wishspd > maxspd )
{
wishspd = sqrt( wishspd );
if( sv_check_errors.value )
Con_Printf( "Got a velocity too high on %s ( %.2f > %.2f )\n", SV_GetString( ent->v.classname ), wishspd, sqrt( maxspd ));
wishspd = sv_maxvelocity.value / wishspd;
VectorScale( ent->v.velocity, wishspd, ent->v.velocity );
}
}
/*
================
SV_CheckAllEnts
@@ -110,47 +151,6 @@ static void SV_CheckAllEnts( void )
}
}
/*
================
SV_CheckVelocity
================
*/
void SV_CheckVelocity( edict_t *ent )
{
float wishspd;
float maxspd;
// bound velocity
for( int i = 0; i < 3; i++ )
{
if( IS_NAN( ent->v.velocity[i] ))
{
if( sv_check_errors.value )
Con_Printf( "Got a NaN velocity on %s\n", SV_GetString( ent->v.classname ));
ent->v.velocity[i] = 0.0f;
}
if( IS_NAN( ent->v.origin[i] ))
{
if( sv_check_errors.value )
Con_Printf( "Got a NaN origin on %s\n", SV_GetString( ent->v.classname ));
ent->v.origin[i] = 0.0f;
}
}
wishspd = DotProduct( ent->v.velocity, ent->v.velocity );
maxspd = sv_maxvelocity.value * sv_maxvelocity.value * 1.73f; // half-diagonal
if( wishspd > maxspd )
{
wishspd = sqrt( wishspd );
if( sv_check_errors.value )
Con_Printf( "Got a velocity too high on %s ( %.2f > %.2f )\n", SV_GetString( ent->v.classname ), wishspd, sqrt( maxspd ));
wishspd = sv_maxvelocity.value / wishspd;
VectorScale( ent->v.velocity, wishspd, ent->v.velocity );
}
}
/*
================
SV_UpdateBaseVelocity
@@ -158,26 +158,20 @@ SV_UpdateBaseVelocity
*/
void SV_UpdateBaseVelocity( edict_t *ent )
{
if( ent->v.flags & FL_ONGROUND )
{
edict_t *groundentity = ent->v.groundentity;
if( !FBitSet( ent->v.flags, FL_ONGROUND ))
return;
if( SV_IsValidEdict( groundentity ))
{
// On conveyor belt that's moving?
if( groundentity->v.flags & FL_CONVEYOR )
{
vec3_t new_basevel;
const edict_t *groundentity = ent->v.groundentity;
VectorScale( groundentity->v.movedir, groundentity->v.speed, new_basevel );
if( ent->v.flags & FL_BASEVELOCITY )
VectorAdd( new_basevel, ent->v.basevelocity, new_basevel );
if( !SV_IsValidEdict( groundentity ) || !FBitSet( groundentity->v.flags, FL_CONVEYOR ))
return;
if( FBitSet( ent->v.flags, FL_BASEVELOCITY ))
VectorMA( ent->v.basevelocity, groundentity->v.speed, groundentity->v.movedir, ent->v.basevelocity );
else
VectorScale( groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity );
ent->v.flags |= FL_BASEVELOCITY;
VectorCopy( new_basevel, ent->v.basevelocity );
}
}
}
}
/*
@@ -189,18 +183,15 @@ returns true if the entity is in solid currently
*/
static qboolean SV_TestEntityPosition( edict_t *ent, edict_t *blocker )
{
qboolean monsterClip = FBitSet( ent->v.flags, FL_MONSTERCLIP ) ? true : false;
trace_t trace;
if( FBitSet( ent->v.flags, FL_CLIENT|FL_FAKECLIENT ))
{
// to avoid falling through tracktrain update client mins\maxs here
if( FBitSet( ent->v.flags, FL_DUCKING ))
SV_SetMinMaxSize( ent, host.player_mins[1], host.player_maxs[1], true );
else SV_SetMinMaxSize( ent, host.player_mins[0], host.player_maxs[0], true );
int hull = FBitSet( ent->v.flags, FL_DUCKING ) ? 1 : 0;
SV_SetMinMaxSize( ent, host.player_mins[hull], host.player_maxs[hull], true );
}
trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent, monsterClip );
qboolean monsterClip = FBitSet( ent->v.flags, FL_MONSTERCLIP ) ? true : false;
trace_t trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent, monsterClip );
if( SV_IsValidEdict( blocker ) && SV_IsValidEdict( trace.ent ))
{
@@ -212,6 +203,25 @@ static qboolean SV_TestEntityPosition( edict_t *ent, edict_t *blocker )
return trace.startsolid;
}
static qboolean SV_TryThink( edict_t *ent, double frametime, double time )
{
float thinktime = ent->v.nextthink;
if( thinktime <= 0.0f || thinktime > ( time + frametime ))
return false;
// don't let things stay in the past.
// it is possible to start that way
// by a trigger with a local time.
if( thinktime < time )
thinktime = time;
ent->v.nextthink = 0.0f;
svgame.globals->time = thinktime;
svgame.dllFuncs.pfnThink( ent );
return true;
}
/*
=============
SV_RunThink
@@ -224,21 +234,10 @@ Returns false if the entity removed itself.
*/
static qboolean SV_RunThink( edict_t *ent )
{
float thinktime;
if( !FBitSet( ent->v.flags, FL_KILLME ))
{
thinktime = ent->v.nextthink;
if( thinktime <= 0.0f || thinktime > (sv.time + sv.frametime))
if( !SV_TryThink( ent, sv.frametime, sv.time ))
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( FBitSet( ent->v.flags, FL_KILLME ))
@@ -259,25 +258,13 @@ Returns false if the entity removed itself.
*/
qboolean SV_PlayerRunThink( edict_t *ent, float frametime, double time )
{
float thinktime;
if( svgame.physFuncs.SV_PlayerThink )
return svgame.physFuncs.SV_PlayerThink( ent, frametime, time );
if( !FBitSet( ent->v.flags, FL_KILLME|FL_DORMANT ))
{
thinktime = ent->v.nextthink;
if( thinktime <= 0.0f || thinktime > (time + frametime))
if( !SV_TryThink( ent, frametime, time ))
return true;
if( thinktime < time )
thinktime = 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( FBitSet( ent->v.flags, FL_KILLME ))
@@ -297,18 +284,12 @@ void SV_Impact( edict_t *e1, edict_t *e2, trace_t *trace )
{
svgame.globals->time = sv.time;
if(( e1->v.flags|e2->v.flags ) & FL_KILLME )
if( FBitSet( e1->v.flags|e2->v.flags, FL_KILLME ))
return;
if( e1->v.groupinfo && e2->v.groupinfo )
{
if( svs.groupop == GROUP_OP_AND && !FBitSet( e1->v.groupinfo, e2->v.groupinfo ))
if( !SV_CheckGroupTrace( e1, e2 ))
return;
if( svs.groupop == GROUP_OP_NAND && FBitSet( e1->v.groupinfo, e2->v.groupinfo ))
return;
}
if( e1->v.solid != SOLID_NOT )
{
SV_CopyTraceToGlobal( trace );

View File

@@ -205,10 +205,7 @@ static void SV_AddLinksToPmove( areanode_t *node, const vec3_t pmove_mins, const
if( check->v.groupinfo != 0 )
{
if( svs.groupop == GROUP_OP_AND && !FBitSet( check->v.groupinfo, pl->v.groupinfo ))
continue;
if( svs.groupop == GROUP_OP_NAND && FBitSet( check->v.groupinfo, pl->v.groupinfo ))
if( !SV_CheckGroupOp( svs.groupop, check->v.groupinfo, pl->v.groupinfo ))
continue;
}

View File

@@ -522,15 +522,9 @@ static void SV_TouchLinks( edict_t *ent, areanode_t *node )
if( touch == ent || touch->v.solid != SOLID_TRIGGER ) // disabled ?
continue;
if( touch->v.groupinfo && ent->v.groupinfo )
{
if( svs.groupop == GROUP_OP_AND && !FBitSet( touch->v.groupinfo, ent->v.groupinfo ))
if( !SV_CheckGroupTrace( touch, ent ))
continue;
if( svs.groupop == GROUP_OP_NAND && FBitSet( touch->v.groupinfo, ent->v.groupinfo ))
continue;
}
if( !BoundsIntersect( ent->v.absmin, ent->v.absmax, touch->v.absmin, touch->v.absmax ))
continue;
@@ -725,10 +719,7 @@ static void SV_WaterLinks( const vec3_t origin, int *pCont, areanode_t *node )
if( touch->v.groupinfo )
{
if( svs.groupop == GROUP_OP_AND && !FBitSet( touch->v.groupinfo, svs.groupmask ))
continue;
if( svs.groupop == GROUP_OP_NAND && FBitSet( touch->v.groupinfo, svs.groupmask ))
if( !SV_CheckGroupOp( svs.groupop, touch->v.groupinfo, svs.groupmask ))
continue;
}
@@ -1101,15 +1092,9 @@ static qboolean SV_ClipToEntity( edict_t *touch, moveclip_t *clip )
trace_t trace;
model_t *mod;
if( touch->v.groupinfo && SV_IsValidEdict( clip->passedict ) && clip->passedict->v.groupinfo != 0 )
{
if( svs.groupop == GROUP_OP_AND && !FBitSet( touch->v.groupinfo, clip->passedict->v.groupinfo ))
if( SV_IsValidEdict( clip->passedict ) && !SV_CheckGroupTrace( touch, clip->passedict ))
return true;
if( svs.groupop == GROUP_OP_NAND && FBitSet( touch->v.groupinfo, clip->passedict->v.groupinfo ))
return true;
}
if( touch == clip->passedict || touch->v.solid == SOLID_NOT )
return true;