Source/ThunderBeast/QuakeToon/server/sv_ents.c
void SV_BuildClientFrame (client_t *client)
{
	int		e, i;
	vec3_t	org;
	edict_t	*ent;
	edict_t	*clent;
	client_frame_t	*frame;
	entity_state_t	*state;
	int		l;
	int		clientarea, clientcluster;
	int		leafnum;
	int		c_fullsend;
	byte	*clientphs;
	byte	*bitvector;

	clent = client->edict;
	if (!clent->client)
		return;		// not in game yet

#if 0
	numprojs = 0; // no projectiles yet
#endif

	// this is the frame we are creating
	frame = &client->frames[sv.framenum & UPDATE_MASK];

	frame->senttime = svs.realtime; // save it for ping calc later

	// find the client's PVS
	for (i=0 ; i<3 ; i++)
		org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];

	leafnum = CM_PointLeafnum (org);
	clientarea = CM_LeafArea (leafnum);
	clientcluster = CM_LeafCluster (leafnum);

	// calculate the visible areas
	frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);

	// grab the current player_state_t
	frame->ps = clent->client->ps;


	SV_FatPVS (org);
	clientphs = CM_ClusterPHS (clientcluster);

	// build up the list of visible entities
	frame->num_entities = 0;
	frame->first_entity = svs.next_client_entities;

	c_fullsend = 0;

	for (e=1 ; e<ge->num_edicts ; e++)
	{
		ent = EDICT_NUM(e);

		// ignore ents without visible models
		if (ent->svflags & SVF_NOCLIENT)
			continue;

		// ignore ents without visible models unless they have an effect
		if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound
			&& !ent->s.event)
			continue;

		// ignore if not touching a PV leaf
		if (ent != clent)
		{
			// check area
			if (!CM_AreasConnected (clientarea, ent->areanum))
			{	// doors can legally straddle two areas, so
				// we may need to check another one
				if (!ent->areanum2
					|| !CM_AreasConnected (clientarea, ent->areanum2))
					continue;		// blocked by a door
			}

			// beams just check one point for PHS
			if (ent->s.renderfx & RF_BEAM)
			{
				l = ent->clusternums[0];
				if ( !(clientphs[l >> 3] & (1 << (l&7) )) )
					continue;
			}
			else
			{
				// FIXME: if an ent has a model and a sound, but isn't
				// in the PVS, only the PHS, clear the model
				if (ent->s.sound)
				{
					bitvector = fatpvs;	//clientphs;
				}
				else
					bitvector = fatpvs;

				if (ent->num_clusters == -1)
				{	// too many leafs for individual check, go by headnode
					if (!CM_HeadnodeVisible (ent->headnode, bitvector))
						continue;
					c_fullsend++;
				}
				else
				{	// check individual leafs
					for (i=0 ; i < ent->num_clusters ; i++)
					{
						l = ent->clusternums[i];
						if (bitvector[l >> 3] & (1 << (l&7) ))
							break;
					}
					if (i == ent->num_clusters)
						continue;		// not visible
				}

				if (!ent->s.modelindex)
				{	// don't send sounds if they will be attenuated away
					vec3_t	delta;
					float	len;

					VectorSubtract (org, ent->s.origin, delta);
					len = VectorLength (delta);
					if (len > 400)
						continue;
				}
			}
		}

#if 0
		if (SV_AddProjectileUpdate(ent))
			continue; // added as a special projectile
#endif

		// add it to the circular client_entities array
		state = &svs.client_entities[svs.next_client_entities%svs.num_client_entities];
		if (ent->s.number != e)
		{
			Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
			ent->s.number = e;
		}
		*state = ent->s;

		// don't mark players missiles as solid
		if (ent->owner == client->edict)
			state->solid = 0;

		svs.next_client_entities++;
		frame->num_entities++;
	}
}
/*
=============
SV_BuildClientFrame

Decides which entities are going to be visible to the client, and
copies off the playerstat and areabits.
=============
*/
SV_BuildClientFrame
Decides which entities are going to be visible to the client, and
copies off the playerstat and areabits.
SV_BuildClientFrame Decides which entities are going to be visible to the client and copies off the playerstat and areabits .
void SV_BuildClientFrame (client_t *client)
{
	int		e, i;
	vec3_t	org;
	edict_t	*ent;
	edict_t	*clent;
	client_frame_t	*frame;
	entity_state_t	*state;
	int		l;
	int		clientarea, clientcluster;
	int		leafnum;
	int		c_fullsend;
	byte	*clientphs;
	byte	*bitvector;
	clent = client->edict;
	if (!clent->client)
		return;		
#if 0
	numprojs = 0; 
#endif
	frame = &client->frames[sv.framenum & UPDATE_MASK];
	frame->senttime = svs.realtime; 
	for (i=0 ; i<3 ; i++)
		org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];
	leafnum = CM_PointLeafnum (org);
	clientarea = CM_LeafArea (leafnum);
	clientcluster = CM_LeafCluster (leafnum);
	frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
	frame->ps = clent->client->ps;
	SV_FatPVS (org);
	clientphs = CM_ClusterPHS (clientcluster);
	frame->num_entities = 0;
	frame->first_entity = svs.next_client_entities;
	c_fullsend = 0;
	for (e=1 ; e<ge->num_edicts ; e++)
	{
		ent = EDICT_NUM(e);
		if (ent->svflags & SVF_NOCLIENT)
			continue;
		 unless they have an effect
		if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound
			&& !ent->s.event)
			continue;
		if (ent != clent)
		{
			if (!CM_AreasConnected (clientarea, ent->areanum))
			{	
				if (!ent->areanum2
					|| !CM_AreasConnected (clientarea, ent->areanum2))
					continue;		
			}
			if (ent->s.renderfx & RF_BEAM)
			{
				l = ent->clusternums[0];
				if ( !(clientphs[l >> 3] & (1 << (l&7) )) )
					continue;
			}
			else
			{
				if (ent->s.sound)
				{
					bitvector = fatpvs;	
				}
				else
					bitvector = fatpvs;
				if (ent->num_clusters == -1)
				{	
					if (!CM_HeadnodeVisible (ent->headnode, bitvector))
						continue;
					c_fullsend++;
				}
				else
				{	
					for (i=0 ; i < ent->num_clusters ; i++)
					{
						l = ent->clusternums[i];
						if (bitvector[l >> 3] & (1 << (l&7) ))
							break;
					}
					if (i == ent->num_clusters)
						continue;		
				}
				if (!ent->s.modelindex)
				{	
					vec3_t	delta;
					float	len;
					VectorSubtract (org, ent->s.origin, delta);
					len = VectorLength (delta);
					if (len > 400)
						continue;
				}
			}
		}
#if 0
		if (SV_AddProjectileUpdate(ent))
			continue; 
#endif
		state = &svs.client_entities[svs.next_client_entities%svs.num_client_entities];
		if (ent->s.number != e)
		{
			Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
			ent->s.number = e;
		}
		*state = ent->s;
		if (ent->owner == client->edict)
			state->solid = 0;
		svs.next_client_entities++;
		frame->num_entities++;
	}
}
void SV_BuildClientFrame ( client_t * client ) { int e , i ; vec3_t org ; edict_t * ent ; edict_t * clent ; client_frame_t * frame ; entity_state_t * state ; int l ; int clientarea , clientcluster ; int leafnum ; int c_fullsend ; byte * clientphs ; byte * bitvector ; clent = client -> edict ; if ( ! clent -> client ) return ; #if 0 numprojs = 0 ; #endif frame = & client -> frames [ sv . framenum & UPDATE_MASK ] ; frame -> senttime = svs . realtime ; for ( i = 0 ; i < 3 ; i ++ ) org [ i ] = clent -> client -> ps . pmove . origin [ i ] * 0.125 + clent -> client -> ps . viewoffset [ i ] ; leafnum = CM_PointLeafnum ( org ) ; clientarea = CM_LeafArea ( leafnum ) ; clientcluster = CM_LeafCluster ( leafnum ) ; frame -> areabytes = CM_WriteAreaBits ( frame -> areabits , clientarea ) ; frame -> ps = clent -> client -> ps ; SV_FatPVS ( org ) ; clientphs = CM_ClusterPHS ( clientcluster ) ; frame -> num_entities = 0 ; frame -> first_entity = svs . next_client_entities ; c_fullsend = 0 ; for ( e = 1 ; e < ge -> num_edicts ; e ++ ) { ent = EDICT_NUM ( e ) ; if ( ent -> svflags & SVF_NOCLIENT ) continue ; if ( ! ent -> s . modelindex && ! ent -> s . effects && ! ent -> s . sound && ! ent -> s . event ) continue ; if ( ent != clent ) { if ( ! CM_AreasConnected ( clientarea , ent -> areanum ) ) { if ( ! ent -> areanum2 || ! CM_AreasConnected ( clientarea , ent -> areanum2 ) ) continue ; } if ( ent -> s . renderfx & RF_BEAM ) { l = ent -> clusternums [ 0 ] ; if ( ! ( clientphs [ l >> 3 ] & ( 1 << ( l & 7 ) ) ) ) continue ; } else { if ( ent -> s . sound ) { bitvector = fatpvs ; } else bitvector = fatpvs ; if ( ent -> num_clusters == -1 ) { if ( ! CM_HeadnodeVisible ( ent -> headnode , bitvector ) ) continue ; c_fullsend ++ ; } else { for ( i = 0 ; i < ent -> num_clusters ; i ++ ) { l = ent -> clusternums [ i ] ; if ( bitvector [ l >> 3 ] & ( 1 << ( l & 7 ) ) ) break ; } if ( i == ent -> num_clusters ) continue ; } if ( ! ent -> s . modelindex ) { vec3_t delta ; float len ; VectorSubtract ( org , ent -> s . origin , delta ) ; len = VectorLength ( delta ) ; if ( len > 400 ) continue ; } } } #if 0 if ( SV_AddProjectileUpdate ( ent ) ) continue ; #endif state = & svs . client_entities [ svs . next_client_entities % svs . num_client_entities ] ; if ( ent -> s . number != e ) { Com_DPrintf ( " \n " ) ; ent -> s . number = e ; } * state = ent -> s ; if ( ent -> owner == client -> edict ) state -> solid = 0 ; svs . next_client_entities ++ ; frame -> num_entities ++ ; } }
SV_BuildClientFrame
Decides which entities are going to be visible to the client, and
copies off the playerstat and areabits.
SV_BuildClientFrame Decides which entities are going to be visible to the client and copies off the playerstat and areabits .
// not in game yet // no projectiles yet // this is the frame we are creating // save it for ping calc later // find the client's PVS // calculate the visible areas // grab the current player_state_t // build up the list of visible entities // ignore ents without visible models // ignore ents without visible models unless they have an effect // ignore if not touching a PV leaf // check area // doors can legally straddle two areas, so // we may need to check another one // blocked by a door // beams just check one point for PHS // FIXME: if an ent has a model and a sound, but isn't // in the PVS, only the PHS, clear the model //clientphs; // too many leafs for individual check, go by headnode // check individual leafs // not visible // don't send sounds if they will be attenuated away // added as a special projectile // add it to the circular client_entities array // don't mark players missiles as solid