Make visibility filter smarter

This commit is contained in:
mittorn 2018-08-06 05:40:20 +07:00
parent 40fb02d32f
commit 7173648785

View File

@ -1221,6 +1221,11 @@ we could also use the pas/ pvs that we set in SetupVisibility, if we wanted to.
int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet )
{
int i;
static int counter; // XASH3DMAX_VISIBLE_PACKET == 512
bool hide = false;
if( ( ent == host || player ) && counter > gpGlobals->maxClients + 1 )
counter = 0;
// don't send if flagged for NODRAW and it's not the host getting the message
if( ( ent->v.effects & EF_NODRAW ) && ( ent != host ) )
@ -1236,6 +1241,70 @@ int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *h
return 0;
}
if( mp_serverdistclip.value )
{
bool bmodel = false, trash = false;
const char *classname = "";
if( ent->v.model && STRING(ent->v.model) && *STRING(ent->v.model) == '*' )
bmodel = true;
if( ent->v.classname && STRING(ent->v.classname) )
classname = STRING( ent->v.classname );
if( !strcmp( classname, "gib" ) || !strncmp( classname, "weapon_", 7) || !strncmp( classname, "ammo_", 5) || !strncmp( classname, "item_", 5) )
trash = true;
Vector delta = VecBModelOrigin(&ent->v) - host->v.origin;
float dist = 0;
if( abs(delta.x) > dist )
dist = abs(delta.x);
if( abs(delta.y) > dist )
dist = abs(delta.y);
if( abs(delta.z) > dist )
dist = abs(delta.z);
float size = 0;
if( ent->v.size.x > size )
size = ent->v.size.x;
if( ent->v.size.y > size )
size = ent->v.size.y;
if( ent->v.size.z > size )
size = ent->v.size.z;
dist -= size;
if( bmodel ) // brushes needed to pmove prediction
{
if( dist > mp_maxbmodeldist.value )
hide = true;
} // low priority models. Nothing will break if we hide it, so hide if packet full
else if( trash && ( dist > mp_maxtrashdist.value || counter > 480 ) )
hide = true; // other entities. May break beams, etc...
else if( dist > mp_maxotherdist.value )
hide = true;
// func_water renders too slow
if( !strcmp( classname, "func_water" ) && dist > mp_maxwaterdist.value )
hide = true;
else if( size > 512 ) // big brushes may be rotated, but dist check does not cover this
hide = false;
if( hide )
{
// printf("%s %d\n", classname, counter );
// trash class does not have any important
// attachments/sounds, so we may just skip adding it to packet
// but left it just hidden if we have enough visents to prevent
// sending big delta packets, but reserve 256 slots for visible
if( counter > 128 && !trash || counter > 256 )
return 0;
}
}
// Ignore if not the host and not touching a PVS/PAS leaf
// If pSet is NULL, then the test will always succeed and the entity will be added to the update
if ( ent != host )
@ -1319,6 +1388,8 @@ int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *h
state->skin = ent->v.skin;
state->effects = ent->v.effects;
if( hide )
state->effects |= EF_NODRAW;
// This non-player entity is being moved by the game .dll and not the physics simulation system
// make sure that we interpolate it's position on the client if it moves
@ -1392,62 +1463,7 @@ int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *h
//state->effects |= EF_NOINTERP;
state->movetype = MOVETYPE_TOSS;
if( mp_serverdistclip.value )
{
bool bmodel = false, trash = false;
const char *classname = "";
if( ent->v.model && STRING(ent->v.model) && *STRING(ent->v.model) == '*' )
bmodel = true;
if( ent->v.classname && STRING(ent->v.classname) )
classname = STRING( ent->v.classname );
if( !strcmp( classname, "gib" ) || !strncmp( classname, "weapon_", 7) || !strncmp( classname, "ammo_", 5) || !strncmp( classname, "item_", 5) )
trash = true;
Vector delta = VecBModelOrigin(&ent->v) - host->v.origin;
float dist = 0;
if( abs(delta.x) > dist )
dist = abs(delta.x);
if( abs(delta.y) > dist )
dist = abs(delta.y);
if( abs(delta.z) > dist )
dist = abs(delta.z);
float size = 0;
if( ent->v.size.x > size )
size = ent->v.size.x;
if( ent->v.size.y > size )
size = ent->v.size.y;
if( ent->v.size.z > size )
size = ent->v.size.z;
dist -= size;
bool hide = false;
if( bmodel )
{
if( dist > mp_maxbmodeldist.value )
hide = true;
}
else if( trash && dist > mp_maxtrashdist.value )
hide = true;
else if( dist > mp_maxotherdist.value )
hide = true;
// func_water renders too slow
if( !strcmp( classname, "func_water" ) && dist > mp_maxwaterdist.value )
hide = true;
else if( size > 512 ) // big brushes may be rotated, but dist check does not cover this
hide = false;
if( hide )
state->effects |= EF_NODRAW;
}
// gravgun hacks
if( ent->pvPrivateData && CBaseEntity::Instance( ent)->m_fireState == ENTINDEX(host) )
{
@ -1497,6 +1513,8 @@ int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *h
}
}
counter++;
return 1;
}