Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

sv_ents.c (17232B)


      1 /*
      2 Copyright (C) 1997-2001 Id Software, Inc.
      3 
      4 This program is free software; you can redistribute it and/or
      5 modify it under the terms of the GNU General Public License
      6 as published by the Free Software Foundation; either version 2
      7 of the License, or (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
     12 
     13 See the GNU General Public License for more details.
     14 
     15 You should have received a copy of the GNU General Public License
     16 along with this program; if not, write to the Free Software
     17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 
     19 */
     20 
     21 #include "server.h"
     22 
     23 /*
     24 =============================================================================
     25 
     26 Encode a client frame onto the network channel
     27 
     28 =============================================================================
     29 */
     30 
     31 #if 0
     32 
     33 // because there can be a lot of projectiles, there is a special
     34 // network protocol for them
     35 #define	MAX_PROJECTILES		64
     36 edict_t	*projectiles[MAX_PROJECTILES];
     37 int		numprojs;
     38 cvar_t  *sv_projectiles;
     39 
     40 qboolean SV_AddProjectileUpdate (edict_t *ent)
     41 {
     42 	if (!sv_projectiles)
     43 		sv_projectiles = Cvar_Get("sv_projectiles", "1", 0);
     44 
     45 	if (!sv_projectiles->value)
     46 		return false;
     47 
     48 	if (!(ent->svflags & SVF_PROJECTILE))
     49 		return false;
     50 	if (numprojs == MAX_PROJECTILES)
     51 		return true;
     52 
     53 	projectiles[numprojs++] = ent;
     54 	return true;
     55 }
     56 
     57 void SV_EmitProjectileUpdate (sizebuf_t *msg)
     58 {
     59 	byte	bits[16];	// [modelindex] [48 bits] xyz p y 12 12 12 8 8 [entitynum] [e2]
     60 	int		n, i;
     61 	edict_t	*ent;
     62 	int		x, y, z, p, yaw;
     63 	int len;
     64 
     65 	if (!numprojs)
     66 		return;
     67 
     68 	MSG_WriteByte (msg, numprojs);
     69 
     70 	for (n=0 ; n<numprojs ; n++)
     71 	{
     72 		ent = projectiles[n];
     73 		x = (int)(ent->s.origin[0]+4096)>>1;
     74 		y = (int)(ent->s.origin[1]+4096)>>1;
     75 		z = (int)(ent->s.origin[2]+4096)>>1;
     76 		p = (int)(256*ent->s.angles[0]/360)&255;
     77 		yaw = (int)(256*ent->s.angles[1]/360)&255;
     78 
     79 		len = 0;
     80 		bits[len++] = x;
     81 		bits[len++] = (x>>8) | (y<<4);
     82 		bits[len++] = (y>>4);
     83 		bits[len++] = z;
     84 		bits[len++] = (z>>8);
     85 		if (ent->s.effects & EF_BLASTER)
     86 			bits[len-1] |= 64;
     87 
     88 		if (ent->s.old_origin[0] != ent->s.origin[0] ||
     89 			ent->s.old_origin[1] != ent->s.origin[1] ||
     90 			ent->s.old_origin[2] != ent->s.origin[2]) {
     91 			bits[len-1] |= 128;
     92 			x = (int)(ent->s.old_origin[0]+4096)>>1;
     93 			y = (int)(ent->s.old_origin[1]+4096)>>1;
     94 			z = (int)(ent->s.old_origin[2]+4096)>>1;
     95 			bits[len++] = x;
     96 			bits[len++] = (x>>8) | (y<<4);
     97 			bits[len++] = (y>>4);
     98 			bits[len++] = z;
     99 			bits[len++] = (z>>8);
    100 		}
    101 
    102 		bits[len++] = p;
    103 		bits[len++] = yaw;
    104 		bits[len++] = ent->s.modelindex;
    105 
    106 		bits[len++] = (ent->s.number & 0x7f);
    107 		if (ent->s.number > 255) {
    108 			bits[len-1] |= 128;
    109 			bits[len++] = (ent->s.number >> 7);
    110 		}
    111 
    112 		for (i=0 ; i<len ; i++)
    113 			MSG_WriteByte (msg, bits[i]);
    114 	}
    115 }
    116 #endif
    117 
    118 /*
    119 =============
    120 SV_EmitPacketEntities
    121 
    122 Writes a delta update of an entity_state_t list to the message.
    123 =============
    124 */
    125 void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
    126 {
    127 	entity_state_t	*oldent, *newent;
    128 	int		oldindex, newindex;
    129 	int		oldnum, newnum;
    130 	int		from_num_entities;
    131 	int		bits;
    132 
    133 #if 0
    134 	if (numprojs)
    135 		MSG_WriteByte (msg, svc_packetentities2);
    136 	else
    137 #endif
    138 		MSG_WriteByte (msg, svc_packetentities);
    139 
    140 	if (!from)
    141 		from_num_entities = 0;
    142 	else
    143 		from_num_entities = from->num_entities;
    144 
    145 	newindex = 0;
    146 	oldindex = 0;
    147 	while (newindex < to->num_entities || oldindex < from_num_entities)
    148 	{
    149 		if (newindex >= to->num_entities)
    150 			newnum = 9999;
    151 		else
    152 		{
    153 			newent = &svs.client_entities[(to->first_entity+newindex)%svs.num_client_entities];
    154 			newnum = newent->number;
    155 		}
    156 
    157 		if (oldindex >= from_num_entities)
    158 			oldnum = 9999;
    159 		else
    160 		{
    161 			oldent = &svs.client_entities[(from->first_entity+oldindex)%svs.num_client_entities];
    162 			oldnum = oldent->number;
    163 		}
    164 
    165 		if (newnum == oldnum)
    166 		{	// delta update from old position
    167 			// because the force parm is false, this will not result
    168 			// in any bytes being emited if the entity has not changed at all
    169 			// note that players are always 'newentities', this updates their oldorigin always
    170 			// and prevents warping
    171 			MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= maxclients->value);
    172 			oldindex++;
    173 			newindex++;
    174 			continue;
    175 		}
    176 
    177 		if (newnum < oldnum)
    178 		{	// this is a new entity, send it from the baseline
    179 			MSG_WriteDeltaEntity (&sv.baselines[newnum], newent, msg, true, true);
    180 			newindex++;
    181 			continue;
    182 		}
    183 
    184 		if (newnum > oldnum)
    185 		{	// the old entity isn't present in the new message
    186 			bits = U_REMOVE;
    187 			if (oldnum >= 256)
    188 				bits |= U_NUMBER16 | U_MOREBITS1;
    189 
    190 			MSG_WriteByte (msg,	bits&255 );
    191 			if (bits & 0x0000ff00)
    192 				MSG_WriteByte (msg,	(bits>>8)&255 );
    193 
    194 			if (bits & U_NUMBER16)
    195 				MSG_WriteShort (msg, oldnum);
    196 			else
    197 				MSG_WriteByte (msg, oldnum);
    198 
    199 			oldindex++;
    200 			continue;
    201 		}
    202 	}
    203 
    204 	MSG_WriteShort (msg, 0);	// end of packetentities
    205 
    206 #if 0
    207 	if (numprojs)
    208 		SV_EmitProjectileUpdate(msg);
    209 #endif
    210 }
    211 
    212 
    213 
    214 /*
    215 =============
    216 SV_WritePlayerstateToClient
    217 
    218 =============
    219 */
    220 void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
    221 {
    222 	int				i;
    223 	int				pflags;
    224 	player_state_t	*ps, *ops;
    225 	player_state_t	dummy;
    226 	int				statbits;
    227 
    228 	ps = &to->ps;
    229 	if (!from)
    230 	{
    231 		memset (&dummy, 0, sizeof(dummy));
    232 		ops = &dummy;
    233 	}
    234 	else
    235 		ops = &from->ps;
    236 
    237 	//
    238 	// determine what needs to be sent
    239 	//
    240 	pflags = 0;
    241 
    242 	if (ps->pmove.pm_type != ops->pmove.pm_type)
    243 		pflags |= PS_M_TYPE;
    244 
    245 	if (ps->pmove.origin[0] != ops->pmove.origin[0]
    246 		|| ps->pmove.origin[1] != ops->pmove.origin[1]
    247 		|| ps->pmove.origin[2] != ops->pmove.origin[2] )
    248 		pflags |= PS_M_ORIGIN;
    249 
    250 	if (ps->pmove.velocity[0] != ops->pmove.velocity[0]
    251 		|| ps->pmove.velocity[1] != ops->pmove.velocity[1]
    252 		|| ps->pmove.velocity[2] != ops->pmove.velocity[2] )
    253 		pflags |= PS_M_VELOCITY;
    254 
    255 	if (ps->pmove.pm_time != ops->pmove.pm_time)
    256 		pflags |= PS_M_TIME;
    257 
    258 	if (ps->pmove.pm_flags != ops->pmove.pm_flags)
    259 		pflags |= PS_M_FLAGS;
    260 
    261 	if (ps->pmove.gravity != ops->pmove.gravity)
    262 		pflags |= PS_M_GRAVITY;
    263 
    264 	if (ps->pmove.delta_angles[0] != ops->pmove.delta_angles[0]
    265 		|| ps->pmove.delta_angles[1] != ops->pmove.delta_angles[1]
    266 		|| ps->pmove.delta_angles[2] != ops->pmove.delta_angles[2] )
    267 		pflags |= PS_M_DELTA_ANGLES;
    268 
    269 
    270 	if (ps->viewoffset[0] != ops->viewoffset[0]
    271 		|| ps->viewoffset[1] != ops->viewoffset[1]
    272 		|| ps->viewoffset[2] != ops->viewoffset[2] )
    273 		pflags |= PS_VIEWOFFSET;
    274 
    275 	if (ps->viewangles[0] != ops->viewangles[0]
    276 		|| ps->viewangles[1] != ops->viewangles[1]
    277 		|| ps->viewangles[2] != ops->viewangles[2] )
    278 		pflags |= PS_VIEWANGLES;
    279 
    280 	if (ps->kick_angles[0] != ops->kick_angles[0]
    281 		|| ps->kick_angles[1] != ops->kick_angles[1]
    282 		|| ps->kick_angles[2] != ops->kick_angles[2] )
    283 		pflags |= PS_KICKANGLES;
    284 
    285 	if (ps->blend[0] != ops->blend[0]
    286 		|| ps->blend[1] != ops->blend[1]
    287 		|| ps->blend[2] != ops->blend[2]
    288 		|| ps->blend[3] != ops->blend[3] )
    289 		pflags |= PS_BLEND;
    290 
    291 	if (ps->fov != ops->fov)
    292 		pflags |= PS_FOV;
    293 
    294 	if (ps->rdflags != ops->rdflags)
    295 		pflags |= PS_RDFLAGS;
    296 
    297 	if (ps->gunframe != ops->gunframe)
    298 		pflags |= PS_WEAPONFRAME;
    299 
    300 	pflags |= PS_WEAPONINDEX;
    301 
    302 	//
    303 	// write it
    304 	//
    305 	MSG_WriteByte (msg, svc_playerinfo);
    306 	MSG_WriteShort (msg, pflags);
    307 
    308 	//
    309 	// write the pmove_state_t
    310 	//
    311 	if (pflags & PS_M_TYPE)
    312 		MSG_WriteByte (msg, ps->pmove.pm_type);
    313 
    314 	if (pflags & PS_M_ORIGIN)
    315 	{
    316 		MSG_WriteShort (msg, ps->pmove.origin[0]);
    317 		MSG_WriteShort (msg, ps->pmove.origin[1]);
    318 		MSG_WriteShort (msg, ps->pmove.origin[2]);
    319 	}
    320 
    321 	if (pflags & PS_M_VELOCITY)
    322 	{
    323 		MSG_WriteShort (msg, ps->pmove.velocity[0]);
    324 		MSG_WriteShort (msg, ps->pmove.velocity[1]);
    325 		MSG_WriteShort (msg, ps->pmove.velocity[2]);
    326 	}
    327 
    328 	if (pflags & PS_M_TIME)
    329 		MSG_WriteByte (msg, ps->pmove.pm_time);
    330 
    331 	if (pflags & PS_M_FLAGS)
    332 		MSG_WriteByte (msg, ps->pmove.pm_flags);
    333 
    334 	if (pflags & PS_M_GRAVITY)
    335 		MSG_WriteShort (msg, ps->pmove.gravity);
    336 
    337 	if (pflags & PS_M_DELTA_ANGLES)
    338 	{
    339 		MSG_WriteShort (msg, ps->pmove.delta_angles[0]);
    340 		MSG_WriteShort (msg, ps->pmove.delta_angles[1]);
    341 		MSG_WriteShort (msg, ps->pmove.delta_angles[2]);
    342 	}
    343 
    344 	//
    345 	// write the rest of the player_state_t
    346 	//
    347 	if (pflags & PS_VIEWOFFSET)
    348 	{
    349 		MSG_WriteChar (msg, ps->viewoffset[0]*4);
    350 		MSG_WriteChar (msg, ps->viewoffset[1]*4);
    351 		MSG_WriteChar (msg, ps->viewoffset[2]*4);
    352 	}
    353 
    354 	if (pflags & PS_VIEWANGLES)
    355 	{
    356 		MSG_WriteAngle16 (msg, ps->viewangles[0]);
    357 		MSG_WriteAngle16 (msg, ps->viewangles[1]);
    358 		MSG_WriteAngle16 (msg, ps->viewangles[2]);
    359 	}
    360 
    361 	if (pflags & PS_KICKANGLES)
    362 	{
    363 		MSG_WriteChar (msg, ps->kick_angles[0]*4);
    364 		MSG_WriteChar (msg, ps->kick_angles[1]*4);
    365 		MSG_WriteChar (msg, ps->kick_angles[2]*4);
    366 	}
    367 
    368 	if (pflags & PS_WEAPONINDEX)
    369 	{
    370 		MSG_WriteByte (msg, ps->gunindex);
    371 	}
    372 
    373 	if (pflags & PS_WEAPONFRAME)
    374 	{
    375 		MSG_WriteByte (msg, ps->gunframe);
    376 		MSG_WriteChar (msg, ps->gunoffset[0]*4);
    377 		MSG_WriteChar (msg, ps->gunoffset[1]*4);
    378 		MSG_WriteChar (msg, ps->gunoffset[2]*4);
    379 		MSG_WriteChar (msg, ps->gunangles[0]*4);
    380 		MSG_WriteChar (msg, ps->gunangles[1]*4);
    381 		MSG_WriteChar (msg, ps->gunangles[2]*4);
    382 	}
    383 
    384 	if (pflags & PS_BLEND)
    385 	{
    386 		MSG_WriteByte (msg, ps->blend[0]*255);
    387 		MSG_WriteByte (msg, ps->blend[1]*255);
    388 		MSG_WriteByte (msg, ps->blend[2]*255);
    389 		MSG_WriteByte (msg, ps->blend[3]*255);
    390 	}
    391 	if (pflags & PS_FOV)
    392 		MSG_WriteByte (msg, ps->fov);
    393 	if (pflags & PS_RDFLAGS)
    394 		MSG_WriteByte (msg, ps->rdflags);
    395 
    396 	// send stats
    397 	statbits = 0;
    398 	for (i=0 ; i<MAX_STATS ; i++)
    399 		if (ps->stats[i] != ops->stats[i])
    400 			statbits |= 1<<i;
    401 	MSG_WriteLong (msg, statbits);
    402 	for (i=0 ; i<MAX_STATS ; i++)
    403 		if (statbits & (1<<i) )
    404 			MSG_WriteShort (msg, ps->stats[i]);
    405 }
    406 
    407 
    408 /*
    409 ==================
    410 SV_WriteFrameToClient
    411 ==================
    412 */
    413 void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg)
    414 {
    415 	client_frame_t		*frame, *oldframe;
    416 	int					lastframe;
    417 
    418 //Com_Printf ("%i -> %i\n", client->lastframe, sv.framenum);
    419 	// this is the frame we are creating
    420 	frame = &client->frames[sv.framenum & UPDATE_MASK];
    421 
    422 	if (client->lastframe <= 0)
    423 	{	// client is asking for a retransmit
    424 		oldframe = NULL;
    425 		lastframe = -1;
    426 	}
    427 	else if (sv.framenum - client->lastframe >= (UPDATE_BACKUP - 3) )
    428 	{	// client hasn't gotten a good message through in a long time
    429 //		Com_Printf ("%s: Delta request from out-of-date packet.\n", client->name);
    430 		oldframe = NULL;
    431 		lastframe = -1;
    432 	}
    433 	else
    434 	{	// we have a valid message to delta from
    435 		oldframe = &client->frames[client->lastframe & UPDATE_MASK];
    436 		lastframe = client->lastframe;
    437 	}
    438 
    439 	MSG_WriteByte (msg, svc_frame);
    440 	MSG_WriteLong (msg, sv.framenum);
    441 	MSG_WriteLong (msg, lastframe);	// what we are delta'ing from
    442 	MSG_WriteByte (msg, client->surpressCount);	// rate dropped packets
    443 	client->surpressCount = 0;
    444 
    445 	// send over the areabits
    446 	MSG_WriteByte (msg, frame->areabytes);
    447 	SZ_Write (msg, frame->areabits, frame->areabytes);
    448 
    449 	// delta encode the playerstate
    450 	SV_WritePlayerstateToClient (oldframe, frame, msg);
    451 
    452 	// delta encode the entities
    453 	SV_EmitPacketEntities (oldframe, frame, msg);
    454 }
    455 
    456 
    457 /*
    458 =============================================================================
    459 
    460 Build a client frame structure
    461 
    462 =============================================================================
    463 */
    464 
    465 byte		fatpvs[65536/8];	// 32767 is MAX_MAP_LEAFS
    466 
    467 /*
    468 ============
    469 SV_FatPVS
    470 
    471 The client will interpolate the view position,
    472 so we can't use a single PVS point
    473 ===========
    474 */
    475 void SV_FatPVS (vec3_t org)
    476 {
    477 	int		leafs[64];
    478 	int		i, j, count;
    479 	int		longs;
    480 	byte	*src;
    481 	vec3_t	mins, maxs;
    482 
    483 	for (i=0 ; i<3 ; i++)
    484 	{
    485 		mins[i] = org[i] - 8;
    486 		maxs[i] = org[i] + 8;
    487 	}
    488 
    489 	count = CM_BoxLeafnums (mins, maxs, leafs, 64, NULL);
    490 	if (count < 1)
    491 		Com_Error (ERR_FATAL, "SV_FatPVS: count < 1");
    492 	longs = (CM_NumClusters()+31)>>5;
    493 
    494 	// convert leafs to clusters
    495 	for (i=0 ; i<count ; i++)
    496 		leafs[i] = CM_LeafCluster(leafs[i]);
    497 
    498 	memcpy (fatpvs, CM_ClusterPVS(leafs[0]), longs<<2);
    499 	// or in all the other leaf bits
    500 	for (i=1 ; i<count ; i++)
    501 	{
    502 		for (j=0 ; j<i ; j++)
    503 			if (leafs[i] == leafs[j])
    504 				break;
    505 		if (j != i)
    506 			continue;		// already have the cluster we want
    507 		src = CM_ClusterPVS(leafs[i]);
    508 		for (j=0 ; j<longs ; j++)
    509 			((long *)fatpvs)[j] |= ((long *)src)[j];
    510 	}
    511 }
    512 
    513 
    514 /*
    515 =============
    516 SV_BuildClientFrame
    517 
    518 Decides which entities are going to be visible to the client, and
    519 copies off the playerstat and areabits.
    520 =============
    521 */
    522 void SV_BuildClientFrame (client_t *client)
    523 {
    524 	int		e, i;
    525 	vec3_t	org;
    526 	edict_t	*ent;
    527 	edict_t	*clent;
    528 	client_frame_t	*frame;
    529 	entity_state_t	*state;
    530 	int		l;
    531 	int		clientarea, clientcluster;
    532 	int		leafnum;
    533 	int		c_fullsend;
    534 	byte	*clientphs;
    535 	byte	*bitvector;
    536 
    537 	clent = client->edict;
    538 	if (!clent->client)
    539 		return;		// not in game yet
    540 
    541 #if 0
    542 	numprojs = 0; // no projectiles yet
    543 #endif
    544 
    545 	// this is the frame we are creating
    546 	frame = &client->frames[sv.framenum & UPDATE_MASK];
    547 
    548 	frame->senttime = svs.realtime; // save it for ping calc later
    549 
    550 	// find the client's PVS
    551 	for (i=0 ; i<3 ; i++)
    552 		org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];
    553 
    554 	leafnum = CM_PointLeafnum (org);
    555 	clientarea = CM_LeafArea (leafnum);
    556 	clientcluster = CM_LeafCluster (leafnum);
    557 
    558 	// calculate the visible areas
    559 	frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
    560 
    561 	// grab the current player_state_t
    562 	frame->ps = clent->client->ps;
    563 
    564 
    565 	SV_FatPVS (org);
    566 	clientphs = CM_ClusterPHS (clientcluster);
    567 
    568 	// build up the list of visible entities
    569 	frame->num_entities = 0;
    570 	frame->first_entity = svs.next_client_entities;
    571 
    572 	c_fullsend = 0;
    573 
    574 	for (e=1 ; e<ge->num_edicts ; e++)
    575 	{
    576 		ent = EDICT_NUM(e);
    577 
    578 		// ignore ents without visible models
    579 		if (ent->svflags & SVF_NOCLIENT)
    580 			continue;
    581 
    582 		// ignore ents without visible models unless they have an effect
    583 		if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound
    584 			&& !ent->s.event)
    585 			continue;
    586 
    587 		// ignore if not touching a PV leaf
    588 		if (ent != clent)
    589 		{
    590 			// check area
    591 			if (!CM_AreasConnected (clientarea, ent->areanum))
    592 			{	// doors can legally straddle two areas, so
    593 				// we may need to check another one
    594 				if (!ent->areanum2
    595 					|| !CM_AreasConnected (clientarea, ent->areanum2))
    596 					continue;		// blocked by a door
    597 			}
    598 
    599 			// beams just check one point for PHS
    600 			if (ent->s.renderfx & RF_BEAM)
    601 			{
    602 				l = ent->clusternums[0];
    603 				if ( !(clientphs[l >> 3] & (1 << (l&7) )) )
    604 					continue;
    605 			}
    606 			else
    607 			{
    608 				// FIXME: if an ent has a model and a sound, but isn't
    609 				// in the PVS, only the PHS, clear the model
    610 				if (ent->s.sound)
    611 				{
    612 					bitvector = fatpvs;	//clientphs;
    613 				}
    614 				else
    615 					bitvector = fatpvs;
    616 
    617 				if (ent->num_clusters == -1)
    618 				{	// too many leafs for individual check, go by headnode
    619 					if (!CM_HeadnodeVisible (ent->headnode, bitvector))
    620 						continue;
    621 					c_fullsend++;
    622 				}
    623 				else
    624 				{	// check individual leafs
    625 					for (i=0 ; i < ent->num_clusters ; i++)
    626 					{
    627 						l = ent->clusternums[i];
    628 						if (bitvector[l >> 3] & (1 << (l&7) ))
    629 							break;
    630 					}
    631 					if (i == ent->num_clusters)
    632 						continue;		// not visible
    633 				}
    634 
    635 				if (!ent->s.modelindex)
    636 				{	// don't send sounds if they will be attenuated away
    637 					vec3_t	delta;
    638 					float	len;
    639 
    640 					VectorSubtract (org, ent->s.origin, delta);
    641 					len = VectorLength (delta);
    642 					if (len > 400)
    643 						continue;
    644 				}
    645 			}
    646 		}
    647 
    648 #if 0
    649 		if (SV_AddProjectileUpdate(ent))
    650 			continue; // added as a special projectile
    651 #endif
    652 
    653 		// add it to the circular client_entities array
    654 		state = &svs.client_entities[svs.next_client_entities%svs.num_client_entities];
    655 		if (ent->s.number != e)
    656 		{
    657 			Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
    658 			ent->s.number = e;
    659 		}
    660 		*state = ent->s;
    661 
    662 		// don't mark players missiles as solid
    663 		if (ent->owner == client->edict)
    664 			state->solid = 0;
    665 
    666 		svs.next_client_entities++;
    667 		frame->num_entities++;
    668 	}
    669 }
    670 
    671 
    672 /*
    673 ==================
    674 SV_RecordDemoMessage
    675 
    676 Save everything in the world out without deltas.
    677 Used for recording footage for merged or assembled demos
    678 ==================
    679 */
    680 void SV_RecordDemoMessage (void)
    681 {
    682 	int			e;
    683 	edict_t		*ent;
    684 	entity_state_t	nostate;
    685 	sizebuf_t	buf;
    686 	byte		buf_data[32768];
    687 	int			len;
    688 
    689 	if (!svs.demofile)
    690 		return;
    691 
    692 	memset (&nostate, 0, sizeof(nostate));
    693 	SZ_Init (&buf, buf_data, sizeof(buf_data));
    694 
    695 	// write a frame message that doesn't contain a player_state_t
    696 	MSG_WriteByte (&buf, svc_frame);
    697 	MSG_WriteLong (&buf, sv.framenum);
    698 
    699 	MSG_WriteByte (&buf, svc_packetentities);
    700 
    701 	e = 1;
    702 	ent = EDICT_NUM(e);
    703 	while (e < ge->num_edicts) 
    704 	{
    705 		// ignore ents without visible models unless they have an effect
    706 		if (ent->inuse &&
    707 			ent->s.number && 
    708 			(ent->s.modelindex || ent->s.effects || ent->s.sound || ent->s.event) && 
    709 			!(ent->svflags & SVF_NOCLIENT))
    710 			MSG_WriteDeltaEntity (&nostate, &ent->s, &buf, false, true);
    711 
    712 		e++;
    713 		ent = EDICT_NUM(e);
    714 	}
    715 
    716 	MSG_WriteShort (&buf, 0);		// end of packetentities
    717 
    718 	// now add the accumulated multicast information
    719 	SZ_Write (&buf, svs.demo_multicast.data, svs.demo_multicast.cursize);
    720 	SZ_Clear (&svs.demo_multicast);
    721 
    722 	// now write the entire message to the file, prefixed by the length
    723 	len = LittleLong (buf.cursize);
    724 	fwrite (&len, 4, 1, svs.demofile);
    725 	fwrite (buf.data, buf.cursize, 1, svs.demofile);
    726 }
    727