1 /*
2  * sv_ents.c -- server entities handling
3  * $Id: sv_ents.c 4767 2012-06-16 20:48:51Z sezero $
4  *
5  * Copyright (C) 1996-1997  Id Software, Inc.
6  * Copyright (C) 1997-1998  Raven Software Corp.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or (at
11  * your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * See the GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23 
24 #include "quakedef.h"
25 
26 /*
27 =============================================================================
28 
29 The PVS must include a small area around the client to allow head bobbing
30 or other small motion on the client side.  Otherwise, a bob might cause an
31 entity that should be visible to not show up, especially when the bob
32 crosses a waterline.
33 
34 =============================================================================
35 */
36 
37 static int	fatbytes;
38 static byte	fatpvs[MAX_MAP_LEAFS/8];
39 
SV_AddToFatPVS(vec3_t org,mnode_t * node)40 static void SV_AddToFatPVS (vec3_t org, mnode_t *node)
41 {
42 	int		i;
43 	byte	*pvs;
44 	mplane_t	*plane;
45 	float	d;
46 
47 	while (1)
48 	{
49 	// if this is a leaf, accumulate the pvs bits
50 		if (node->contents < 0)
51 		{
52 			if (node->contents != CONTENTS_SOLID)
53 			{
54 				pvs = Mod_LeafPVS ( (mleaf_t *)node, sv.worldmodel);
55 				for (i = 0; i < fatbytes; i++)
56 					fatpvs[i] |= pvs[i];
57 			}
58 			return;
59 		}
60 
61 		plane = node->plane;
62 		d = DotProduct (org, plane->normal) - plane->dist;
63 		if (d > 8)
64 			node = node->children[0];
65 		else if (d < -8)
66 			node = node->children[1];
67 		else
68 		{	// go down both
69 			SV_AddToFatPVS (org, node->children[0]);
70 			node = node->children[1];
71 		}
72 	}
73 }
74 
75 /*
76 =============
77 SV_FatPVS
78 
79 Calculates a PVS that is the inclusive or of all leafs within 8 pixels of the
80 given point.
81 =============
82 */
SV_FatPVS(vec3_t org)83 static byte *SV_FatPVS (vec3_t org)
84 {
85 	fatbytes = (sv.worldmodel->numleafs+31)>>3;
86 	memset (fatpvs, 0, fatbytes);
87 	SV_AddToFatPVS (org, sv.worldmodel->nodes);
88 	return fatpvs;
89 }
90 
91 //=============================================================================
92 /*
93 // because there can be a lot of nails, there is a special
94 // network protocol for them
95 
96 	RDM: changed to use packed missiles, this code left here in case we
97 	decide to pack missiles which require a velocity as well
98 
99 #define	MAX_NAILS	32
100 edict_t	*nails[MAX_NAILS];
101 int		numnails;
102 
103 extern	int	sv_nailmodel, sv_supernailmodel, sv_playermodel[MAX_PLAYER_CLASS];
104 
105 qboolean SV_AddNailUpdate (edict_t *ent)
106 {
107 	if (ent->v.modelindex != sv_nailmodel
108 		&& ent->v.modelindex != sv_supernailmodel)
109 		return false;
110 	if (numnails == MAX_NAILS)
111 		return true;
112 	nails[numnails] = ent;
113 	numnails++;
114 	return true;
115 }
116 
117 void SV_EmitNailUpdate (sizebuf_t *msg)
118 {
119 	byte	bits[6];	// [48 bits] xyzpy 12 12 12 4 8
120 	int		n, i;
121 	edict_t	*ent;
122 	int		x, y, z, p, yaw;
123 
124 	if (!numnails)
125 		return;
126 
127 	MSG_WriteByte (msg, svc_nails);
128 	MSG_WriteByte (msg, numnails);
129 
130 	for (n = 0; n < numnails; n++)
131 	{
132 		ent = nails[n];
133 		x = (int)(ent->v.origin[0] + 4096) >> 1;
134 		y = (int)(ent->v.origin[1] + 4096) >> 1;
135 		z = (int)(ent->v.origin[2] + 4096) >> 1;
136 		p = (int)(16 * ent->v.angles[0] / 360) & 15;
137 		yaw = (int)(256 * ent->v.angles[1] / 360) & 255;
138 
139 		bits[0] = x;
140 		bits[1] = (x>>8) | (y<<4);
141 		bits[2] = (y>>4);
142 		bits[3] = z;
143 		bits[4] = (z>>8) | (p<<4);
144 		bits[5] = yaw;
145 
146 		for (i = 0; i < 6; i++)
147 			MSG_WriteByte (msg, bits[i]);
148 	}
149 }
150 */
151 
152 #define	MAX_MISSILES	32
153 static	edict_t	*missiles[MAX_MISSILES];
154 static	edict_t	*ravens[MAX_MISSILES];
155 static	edict_t	*raven2s[MAX_MISSILES];
156 static	int	nummissiles, numravens, numraven2s;
157 extern	int	sv_magicmissmodel, sv_playermodel[MAX_PLAYER_CLASS], sv_ravenmodel, sv_raven2model;
158 
SV_AddMissileUpdate(edict_t * ent)159 static qboolean SV_AddMissileUpdate (edict_t *ent)
160 {
161 	if (ent->v.modelindex == sv_magicmissmodel)
162 	{
163 		if (nummissiles == MAX_MISSILES)
164 			return true;
165 		missiles[nummissiles] = ent;
166 		nummissiles++;
167 		return true;
168 	}
169 	if (ent->v.modelindex == sv_ravenmodel)
170 	{
171 		if (numravens == MAX_MISSILES)
172 			return true;
173 		ravens[numravens] = ent;
174 		numravens++;
175 		return true;
176 	}
177 	if (ent->v.modelindex == sv_raven2model)
178 	{
179 		if (numraven2s == MAX_MISSILES)
180 			return true;
181 		raven2s[numraven2s] = ent;
182 		numraven2s++;
183 		return true;
184 	}
185 	return false;
186 }
187 
SV_EmitMissileUpdate(sizebuf_t * msg)188 static void SV_EmitMissileUpdate (sizebuf_t *msg)
189 {
190 	byte	bits[5];	// [40 bits] xyz type 12 12 12 4
191 	int		n, i;
192 	edict_t	*ent;
193 	int		x, y, z, type;
194 
195 	if (!nummissiles)
196 		return;
197 
198 	MSG_WriteByte (msg, svc_packmissile);
199 	MSG_WriteByte (msg, nummissiles);
200 
201 	for (n = 0; n < nummissiles; n++)
202 	{
203 		ent = missiles[n];
204 		x = (int)(ent->v.origin[0] + 4096) >> 1;
205 		y = (int)(ent->v.origin[1] + 4096) >> 1;
206 		z = (int)(ent->v.origin[2] + 4096) >> 1;
207 		if (fabs(ent->v.scale - 0.1) < 0.05)
208 			type = 1;	//assume ice mace
209 		else
210 			type = 2;	//assume magic missile
211 
212 		bits[0] = x;
213 		bits[1] = (x>>8) | (y<<4);
214 		bits[2] = (y>>4);
215 		bits[3] = z;
216 		bits[4] = (z>>8) | (type<<4);
217 
218 		for (i = 0; i < 5; i++)
219 			MSG_WriteByte (msg, bits[i]);
220 	}
221 }
222 
SV_EmitRavenUpdate(sizebuf_t * msg)223 static void SV_EmitRavenUpdate (sizebuf_t *msg)
224 {
225 	byte	bits[6];	// [48 bits] xyzpy 12 12 12 4 8
226 	int		n, i;
227 	edict_t	*ent;
228 	int		x, y, z, p, yaw, frame;
229 
230 	if ((!numravens) && (!numraven2s))
231 		return;
232 
233 	MSG_WriteByte (msg, svc_nails);	//svc nails overloaded for ravens
234 	MSG_WriteByte (msg, numravens);
235 
236 	for (n = 0; n < numravens; n++)
237 	{
238 		ent = ravens[n];
239 		x = (int)(ent->v.origin[0] + 4096) >> 1;
240 		y = (int)(ent->v.origin[1] + 4096) >> 1;
241 		z = (int)(ent->v.origin[2] + 4096) >> 1;
242 		p = (int)(16 * ent->v.angles[0] / 360) & 15;
243 		frame = (int)(ent->v.frame) & 7;
244 		yaw = (int)(32 * ent->v.angles[1] / 360) & 31;
245 
246 		bits[0] = x;
247 		bits[1] = (x>>8) | (y<<4);
248 		bits[2] = (y>>4);
249 		bits[3] = z;
250 		bits[4] = (z>>8) | (p<<4);
251 		bits[5] = yaw | (frame<<5);
252 
253 		for (i = 0; i < 6; i++)
254 			MSG_WriteByte (msg, bits[i]);
255 	}
256 	MSG_WriteByte (msg, numraven2s);
257 
258 	for (n = 0; n < numraven2s; n++)
259 	{
260 		ent = raven2s[n];
261 		x = (int)(ent->v.origin[0] + 4096) >> 1;
262 		y = (int)(ent->v.origin[1] + 4096) >> 1;
263 		z = (int)(ent->v.origin[2] + 4096) >> 1;
264 		p = (int)(16 * ent->v.angles[0] / 360) & 15;
265 		yaw = (int)(256 * ent->v.angles[1] / 360) & 255;
266 
267 		bits[0] = x;
268 		bits[1] = (x>>8) | (y<<4);
269 		bits[2] = (y>>4);
270 		bits[3] = z;
271 		bits[4] = (z>>8) | (p<<4);
272 		bits[5] = yaw;
273 
274 		for (i = 0; i < 6; i++)
275 			MSG_WriteByte (msg, bits[i]);
276 	}
277 }
278 
SV_EmitPackedEntities(sizebuf_t * msg)279 static void SV_EmitPackedEntities(sizebuf_t *msg)
280 {
281 	SV_EmitMissileUpdate(msg);
282 	SV_EmitRavenUpdate(msg);
283 }
284 
285 
286 //=============================================================================
287 
288 /*
289 ==================
290 SV_WriteDelta
291 
292 Writes part of a packetentities message.
293 Can delta from either a baseline or a previous packet_entity
294 ==================
295 */
SV_WriteDelta(entity_state_t * from,entity_state_t * to,sizebuf_t * msg,qboolean force,edict_t * ent,client_t * client)296 static void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force, edict_t *ent, client_t *client)
297 {
298 	int		bits;
299 	int		i;
300 	float	miss;
301 	int		temp_index;
302 	char	NewName[MAX_QPATH];
303 
304 // send an update
305 	bits = 0;
306 
307 	for (i = 0; i < 3; i++)
308 	{
309 		miss = to->origin[i] - from->origin[i];
310 		if ( miss < -0.1 || miss > 0.1 )
311 			bits |= U_ORIGIN1<<i;
312 	}
313 
314 	if ( to->angles[0] != from->angles[0] )
315 		bits |= U_ANGLE1;
316 
317 	if ( to->angles[1] != from->angles[1] )
318 		bits |= U_ANGLE2;
319 
320 	if ( to->angles[2] != from->angles[2] )
321 		bits |= U_ANGLE3;
322 
323 	if ( to->colormap != from->colormap )
324 		bits |= U_COLORMAP;
325 
326 	if ( to->skinnum != from->skinnum)
327 	{
328 		bits |= U_SKIN;
329 	}
330 
331 	if (to->drawflags != from->drawflags)
332 		bits |= U_DRAWFLAGS;
333 
334 	if ( to->frame != from->frame )
335 		bits |= U_FRAME;
336 
337 	if ( to->effects != from->effects )
338 		bits |= U_EFFECTS;
339 
340 	temp_index = to->modelindex;
341 	if (((int)ent->v.flags & FL_CLASS_DEPENDENT) && ent->v.model)
342 	{
343 		strcpy (NewName, PR_GetString(ent->v.model));
344 		if (client->playerclass <= 0 || client->playerclass > MAX_PLAYER_CLASS)
345 		{
346 			NewName[strlen(NewName)-5] = '1';
347 		}
348 		else
349 		{
350 			NewName[strlen(NewName)-5] = client->playerclass + 48;
351 		}
352 		temp_index = SV_ModelIndex (NewName);
353 	}
354 
355 	if (temp_index != from->modelindex )
356 	{
357 		bits |= U_MODEL;
358 		if (temp_index > 255)
359 		{
360 			bits |= U_MODEL16;
361 		}
362 	}
363 
364 	if (to->scale != from->scale)
365 	{
366 		bits |= U_SCALE;
367 	}
368 
369 	if (to->abslight != from->abslight)
370 	{
371 		bits |= U_ABSLIGHT;
372 	}
373 
374 	if (to->wpn_sound)
375 	{	//not delta'ed, sound gets cleared after send
376 		bits |= U_SOUND;
377 	}
378 
379 	if (bits & 0xff0000)
380 		bits |= U_MOREBITS2;
381 
382 	if (bits & 511)
383 		bits |= U_MOREBITS;
384 
385 	//
386 	// write the message
387 	//
388 	if (!to->number)
389 		SV_Error ("Unset entity number");
390 	if (to->number >= 512)
391 		SV_Error ("Entity number >= 512");
392 
393 	if (!bits && !force)
394 		return;		// nothing to send!
395 	i = to->number | (bits & ~511);
396 	if (i & U_REMOVE)
397 		Sys_Error ("U_REMOVE");
398 	MSG_WriteShort (msg, i & 0xffff);
399 
400 	if (bits & U_MOREBITS)
401 		MSG_WriteByte (msg, bits & 255);
402 	if (bits & U_MOREBITS2)
403 		MSG_WriteByte (msg, (bits >> 16) & 0xff);
404 	if (bits & U_MODEL)
405 	{
406 		if (bits & U_MODEL16)
407 		{
408 			MSG_WriteShort (msg, temp_index);
409 		}
410 		else
411 		{
412 			MSG_WriteByte (msg, temp_index);
413 		}
414 	}
415 	if (bits & U_FRAME)
416 		MSG_WriteByte (msg, to->frame);
417 	if (bits & U_COLORMAP)
418 		MSG_WriteByte (msg, to->colormap);
419 	if (bits & U_SKIN)
420 		MSG_WriteByte (msg, to->skinnum);
421 	if (bits & U_DRAWFLAGS)
422 		MSG_WriteByte (msg, to->drawflags);
423 	if (bits & U_EFFECTS)
424 		MSG_WriteLong (msg, to->effects);
425 	if (bits & U_ORIGIN1)
426 		MSG_WriteCoord (msg, to->origin[0]);
427 	if (bits & U_ANGLE1)
428 		MSG_WriteAngle(msg, to->angles[0]);
429 	if (bits & U_ORIGIN2)
430 		MSG_WriteCoord (msg, to->origin[1]);
431 	if (bits & U_ANGLE2)
432 		MSG_WriteAngle(msg, to->angles[1]);
433 	if (bits & U_ORIGIN3)
434 		MSG_WriteCoord (msg, to->origin[2]);
435 	if (bits & U_ANGLE3)
436 		MSG_WriteAngle(msg, to->angles[2]);
437 	if (bits & U_SCALE)
438 		MSG_WriteByte (msg, to->scale);
439 	if (bits & U_ABSLIGHT)
440 		MSG_WriteByte (msg, to->abslight);
441 	if (bits & U_SOUND)
442 		MSG_WriteShort (msg, to->wpn_sound);
443 }
444 
445 /*
446 =============
447 SV_EmitPacketEntities
448 
449 Writes a delta update of a packet_entities_t to the message.
450 =============
451 */
SV_EmitPacketEntities(client_t * client,packet_entities_t * to,sizebuf_t * msg)452 static void SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *msg)
453 {
454 	edict_t	*ent;
455 	client_frame_t	*fromframe;
456 	packet_entities_t *from;
457 	int		oldindex, newindex;
458 	int		oldnum, newnum;
459 	int		oldmax;
460 
461 	// this is the frame that we are going to delta update from
462 	if (client->delta_sequence != -1)
463 	{
464 		fromframe = &client->frames[client->delta_sequence & UPDATE_MASK];
465 		from = &fromframe->entities;
466 		oldmax = from->num_entities;
467 
468 		MSG_WriteByte (msg, svc_deltapacketentities);
469 		MSG_WriteByte (msg, client->delta_sequence);
470 	}
471 	else
472 	{
473 		oldmax = 0;	// no delta update
474 		from = NULL;
475 
476 		MSG_WriteByte (msg, svc_packetentities);
477 	}
478 
479 	newindex = 0;
480 	oldindex = 0;
481 //	Con_Printf ("---%i to %i ----\n", client->delta_sequence & UPDATE_MASK,
482 //				client->netchan.outgoing_sequence & UPDATE_MASK);
483 	while (newindex < to->num_entities || oldindex < oldmax)
484 	{
485 		newnum = newindex >= to->num_entities ? 9999 : to->entities[newindex].number;
486 		oldnum = oldindex >= oldmax ? 9999 : from->entities[oldindex].number;
487 
488 		if (newnum == oldnum)
489 		{	// delta update from old position
490 		//	Con_Printf ("delta %i\n", newnum);
491 			SV_WriteDelta (&from->entities[oldindex], &to->entities[newindex], msg, false, EDICT_NUM(newnum), client);
492 			oldindex++;
493 			newindex++;
494 			continue;
495 		}
496 
497 		if (newnum < oldnum)
498 		{	// this is a new entity, send it from the baseline
499 			ent = EDICT_NUM(newnum);
500 		//	Con_Printf ("baseline %i\n", newnum);
501 			SV_WriteDelta (&ent->baseline, &to->entities[newindex], msg, true, ent, client);
502 			newindex++;
503 			continue;
504 		}
505 
506 		if (newnum > oldnum)
507 		{	// the old entity isn't present in the new message
508 		//	Con_Printf ("remove %i\n", oldnum);
509 			MSG_WriteShort (msg, oldnum | U_REMOVE);
510 			oldindex++;
511 			continue;
512 		}
513 	}
514 
515 	MSG_WriteShort (msg, 0);	// end of packetentities
516 }
517 
518 
SV_WriteInventory(client_t * host_cl,edict_t * ent,sizebuf_t * msg)519 void SV_WriteInventory (client_t *host_cl, edict_t *ent, sizebuf_t *msg)
520 {
521 	int		sc1, sc2;
522 	byte	test;
523 
524 	if (host_cl->send_all_v)
525 	{
526 		sc1 = sc2 = 0xffffffff;
527 		host_cl->send_all_v = false;
528 	}
529 	else
530 	{
531 		sc1 = sc2 = 0;
532 
533 		if (ent->v.health != host_cl->old_v.health)
534 			sc1 |= SC1_HEALTH;
535 		if (ent->v.level != host_cl->old_v.level)
536 			sc1 |= SC1_LEVEL;
537 		if (ent->v.intelligence != host_cl->old_v.intelligence)
538 			sc1 |= SC1_INTELLIGENCE;
539 		if (ent->v.wisdom != host_cl->old_v.wisdom)
540 			sc1 |= SC1_WISDOM;
541 		if (ent->v.strength != host_cl->old_v.strength)
542 			sc1 |= SC1_STRENGTH;
543 		if (ent->v.dexterity != host_cl->old_v.dexterity)
544 			sc1 |= SC1_DEXTERITY;
545 		if (ent->v.teleport_time > sv.time)
546 		{
547 		//	Con_Printf ("Teleport_time>time, sending bit\n");
548 			sc1 |= SC1_TELEPORT_TIME;
549 		//	ent->v.teleport_time = 0;
550 		}
551 
552 //		if (ent->v.weapon != host_cl->old_v.weapon)
553 //			sc1 |= SC1_WEAPON;
554 		if (ent->v.bluemana != host_cl->old_v.bluemana)
555 			sc1 |= SC1_BLUEMANA;
556 		if (ent->v.greenmana != host_cl->old_v.greenmana)
557 			sc1 |= SC1_GREENMANA;
558 		if (ent->v.experience != host_cl->old_v.experience)
559 			sc1 |= SC1_EXPERIENCE;
560 		if (ent->v.cnt_torch != host_cl->old_v.cnt_torch)
561 			sc1 |= SC1_CNT_TORCH;
562 		if (ent->v.cnt_h_boost != host_cl->old_v.cnt_h_boost)
563 			sc1 |= SC1_CNT_H_BOOST;
564 		if (ent->v.cnt_sh_boost != host_cl->old_v.cnt_sh_boost)
565 			sc1 |= SC1_CNT_SH_BOOST;
566 		if (ent->v.cnt_mana_boost != host_cl->old_v.cnt_mana_boost)
567 			sc1 |= SC1_CNT_MANA_BOOST;
568 		if (ent->v.cnt_teleport != host_cl->old_v.cnt_teleport)
569 			sc1 |= SC1_CNT_TELEPORT;
570 		if (ent->v.cnt_tome != host_cl->old_v.cnt_tome)
571 			sc1 |= SC1_CNT_TOME;
572 		if (ent->v.cnt_summon != host_cl->old_v.cnt_summon)
573 			sc1 |= SC1_CNT_SUMMON;
574 		if (ent->v.cnt_invisibility != host_cl->old_v.cnt_invisibility)
575 			sc1 |= SC1_CNT_INVISIBILITY;
576 		if (ent->v.cnt_glyph != host_cl->old_v.cnt_glyph)
577 			sc1 |= SC1_CNT_GLYPH;
578 		if (ent->v.cnt_haste != host_cl->old_v.cnt_haste)
579 			sc1 |= SC1_CNT_HASTE;
580 		if (ent->v.cnt_blast != host_cl->old_v.cnt_blast)
581 			sc1 |= SC1_CNT_BLAST;
582 		if (ent->v.cnt_polymorph != host_cl->old_v.cnt_polymorph)
583 			sc1 |= SC1_CNT_POLYMORPH;
584 		if (ent->v.cnt_flight != host_cl->old_v.cnt_flight)
585 			sc1 |= SC1_CNT_FLIGHT;
586 		if (ent->v.cnt_cubeofforce != host_cl->old_v.cnt_cubeofforce)
587 			sc1 |= SC1_CNT_CUBEOFFORCE;
588 		if (ent->v.cnt_invincibility != host_cl->old_v.cnt_invincibility)
589 			sc1 |= SC1_CNT_INVINCIBILITY;
590 		if (ent->v.artifact_active != host_cl->old_v.artifact_active)
591 			sc1 |= SC1_ARTIFACT_ACTIVE;
592 		if (ent->v.artifact_low != host_cl->old_v.artifact_low)
593 			sc1 |= SC1_ARTIFACT_LOW;
594 		if (ent->v.movetype != host_cl->old_v.movetype)
595 			sc1 |= SC1_MOVETYPE;
596 		if (ent->v.cameramode != host_cl->old_v.cameramode)
597 			sc1 |= SC1_CAMERAMODE;
598 		if (ent->v.hasted != host_cl->old_v.hasted)
599 			sc1 |= SC1_HASTED;
600 		if (ent->v.inventory != host_cl->old_v.inventory)
601 			sc1 |= SC1_INVENTORY;
602 		if (ent->v.rings_active != host_cl->old_v.rings_active)
603 			sc1 |= SC1_RINGS_ACTIVE;
604 
605 		if (ent->v.rings_low != host_cl->old_v.rings_low)
606 			sc2 |= SC2_RINGS_LOW;
607 		if (ent->v.armor_amulet != host_cl->old_v.armor_amulet)
608 			sc2 |= SC2_AMULET;
609 		if (ent->v.armor_bracer != host_cl->old_v.armor_bracer)
610 			sc2 |= SC2_BRACER;
611 		if (ent->v.armor_breastplate != host_cl->old_v.armor_breastplate)
612 			sc2 |= SC2_BREASTPLATE;
613 		if (ent->v.armor_helmet != host_cl->old_v.armor_helmet)
614 			sc2 |= SC2_HELMET;
615 		if (ent->v.ring_flight != host_cl->old_v.ring_flight)
616 			sc2 |= SC2_FLIGHT_T;
617 		if (ent->v.ring_water != host_cl->old_v.ring_water)
618 			sc2 |= SC2_WATER_T;
619 		if (ent->v.ring_turning != host_cl->old_v.ring_turning)
620 			sc2 |= SC2_TURNING_T;
621 		if (ent->v.ring_regeneration != host_cl->old_v.ring_regeneration)
622 			sc2 |= SC2_REGEN_T;
623 //		if (ent->v.haste_time != host_cl->old_v.haste_time)
624 //			sc2 |= SC2_HASTE_T;
625 //		if (ent->v.tome_time != host_cl->old_v.tome_time)
626 //			sc2 |= SC2_TOME_T;
627 		if (ent->v.puzzle_inv1 != host_cl->old_v.puzzle_inv1)
628 			sc2 |= SC2_PUZZLE1;
629 		if (ent->v.puzzle_inv2 != host_cl->old_v.puzzle_inv2)
630 			sc2 |= SC2_PUZZLE2;
631 		if (ent->v.puzzle_inv3 != host_cl->old_v.puzzle_inv3)
632 			sc2 |= SC2_PUZZLE3;
633 		if (ent->v.puzzle_inv4 != host_cl->old_v.puzzle_inv4)
634 			sc2 |= SC2_PUZZLE4;
635 		if (ent->v.puzzle_inv5 != host_cl->old_v.puzzle_inv5)
636 			sc2 |= SC2_PUZZLE5;
637 		if (ent->v.puzzle_inv6 != host_cl->old_v.puzzle_inv6)
638 			sc2 |= SC2_PUZZLE6;
639 		if (ent->v.puzzle_inv7 != host_cl->old_v.puzzle_inv7)
640 			sc2 |= SC2_PUZZLE7;
641 		if (ent->v.puzzle_inv8 != host_cl->old_v.puzzle_inv8)
642 			sc2 |= SC2_PUZZLE8;
643 		if (ent->v.max_health != host_cl->old_v.max_health)
644 			sc2 |= SC2_MAXHEALTH;
645 		if (ent->v.max_mana != host_cl->old_v.max_mana)
646 			sc2 |= SC2_MAXMANA;
647 		if (ent->v.flags != host_cl->old_v.flags)
648 			sc2 |= SC2_FLAGS;
649 	}
650 
651 	if (!sc1 && !sc2)
652 		goto end;
653 
654 	MSG_WriteByte (msg, svc_update_inv);
655 	test = 0;
656 	if (sc1 & 0x000000ff)
657 		test |= 1;
658 	if (sc1 & 0x0000ff00)
659 		test |= 2;
660 	if (sc1 & 0x00ff0000)
661 		test |= 4;
662 	if (sc1 & 0xff000000)
663 		test |= 8;
664 	if (sc2 & 0x000000ff)
665 		test |= 16;
666 	if (sc2 & 0x0000ff00)
667 		test |= 32;
668 	if (sc2 & 0x00ff0000)
669 		test |= 64;
670 	if (sc2 & 0xff000000)
671 		test |= 128;
672 
673 	MSG_WriteByte (msg, test);
674 
675 	if (test & 1)
676 		MSG_WriteByte (msg, sc1 & 0xff);
677 	if (test & 2)
678 		MSG_WriteByte (msg, (sc1 >> 8) & 0xff);
679 	if (test & 4)
680 		MSG_WriteByte (msg, (sc1 >> 16) & 0xff);
681 	if (test & 8)
682 		MSG_WriteByte (msg, (sc1 >> 24) & 0xff);
683 	if (test & 16)
684 		MSG_WriteByte (msg, sc2 & 0xff);
685 	if (test & 32)
686 		MSG_WriteByte (msg, (sc2 >> 8) & 0xff);
687 	if (test & 64)
688 		MSG_WriteByte (msg, (sc2 >> 16) & 0xff);
689 	if (test & 128)
690 		MSG_WriteByte (msg, (sc2 >> 24) & 0xff);
691 
692 	if (sc1 & SC1_HEALTH)
693 		MSG_WriteShort (msg, ent->v.health);
694 	if (sc1 & SC1_LEVEL)
695 		MSG_WriteByte(msg, ent->v.level);
696 	if (sc1 & SC1_INTELLIGENCE)
697 		MSG_WriteByte(msg, ent->v.intelligence);
698 	if (sc1 & SC1_WISDOM)
699 		MSG_WriteByte(msg, ent->v.wisdom);
700 	if (sc1 & SC1_STRENGTH)
701 		MSG_WriteByte(msg, ent->v.strength);
702 	if (sc1 & SC1_DEXTERITY)
703 		MSG_WriteByte(msg, ent->v.dexterity);
704 //	if (sc1 & SC1_WEAPON)
705 //		MSG_WriteByte (msg, ent->v.weapon);
706 	if (sc1 & SC1_BLUEMANA)
707 		MSG_WriteByte (msg, ent->v.bluemana);
708 	if (sc1 & SC1_GREENMANA)
709 		MSG_WriteByte (msg, ent->v.greenmana);
710 	if (sc1 & SC1_EXPERIENCE)
711 		MSG_WriteLong (msg, ent->v.experience);
712 	if (sc1 & SC1_CNT_TORCH)
713 		MSG_WriteByte (msg, ent->v.cnt_torch);
714 	if (sc1 & SC1_CNT_H_BOOST)
715 		MSG_WriteByte (msg, ent->v.cnt_h_boost);
716 	if (sc1 & SC1_CNT_SH_BOOST)
717 		MSG_WriteByte (msg, ent->v.cnt_sh_boost);
718 	if (sc1 & SC1_CNT_MANA_BOOST)
719 		MSG_WriteByte (msg, ent->v.cnt_mana_boost);
720 	if (sc1 & SC1_CNT_TELEPORT)
721 		MSG_WriteByte (msg, ent->v.cnt_teleport);
722 	if (sc1 & SC1_CNT_TOME)
723 		MSG_WriteByte (msg, ent->v.cnt_tome);
724 	if (sc1 & SC1_CNT_SUMMON)
725 		MSG_WriteByte (msg, ent->v.cnt_summon);
726 	if (sc1 & SC1_CNT_INVISIBILITY)
727 		MSG_WriteByte (msg, ent->v.cnt_invisibility);
728 	if (sc1 & SC1_CNT_GLYPH)
729 		MSG_WriteByte (msg, ent->v.cnt_glyph);
730 	if (sc1 & SC1_CNT_HASTE)
731 		MSG_WriteByte (msg, ent->v.cnt_haste);
732 	if (sc1 & SC1_CNT_BLAST)
733 		MSG_WriteByte (msg, ent->v.cnt_blast);
734 	if (sc1 & SC1_CNT_POLYMORPH)
735 		MSG_WriteByte (msg, ent->v.cnt_polymorph);
736 	if (sc1 & SC1_CNT_FLIGHT)
737 		MSG_WriteByte (msg, ent->v.cnt_flight);
738 	if (sc1 & SC1_CNT_CUBEOFFORCE)
739 		MSG_WriteByte (msg, ent->v.cnt_cubeofforce);
740 	if (sc1 & SC1_CNT_INVINCIBILITY)
741 		MSG_WriteByte (msg, ent->v.cnt_invincibility);
742 	if (sc1 & SC1_ARTIFACT_ACTIVE)
743 		MSG_WriteByte (msg, ent->v.artifact_active);
744 	if (sc1 & SC1_ARTIFACT_LOW)
745 		MSG_WriteByte (msg, ent->v.artifact_low);
746 	if (sc1 & SC1_MOVETYPE)
747 		MSG_WriteByte (msg, ent->v.movetype);
748 	if (sc1 & SC1_CAMERAMODE)
749 		MSG_WriteByte (msg, ent->v.cameramode);
750 	if (sc1 & SC1_HASTED)
751 		MSG_WriteFloat (msg, ent->v.hasted);
752 	if (sc1 & SC1_INVENTORY)
753 		MSG_WriteByte (msg, ent->v.inventory);
754 	if (sc1 & SC1_RINGS_ACTIVE)
755 		MSG_WriteByte (msg, ent->v.rings_active);
756 
757 	if (sc2 & SC2_RINGS_LOW)
758 		MSG_WriteByte (msg, ent->v.rings_low);
759 	if (sc2 & SC2_AMULET)
760 		MSG_WriteByte(msg, ent->v.armor_amulet);
761 	if (sc2 & SC2_BRACER)
762 		MSG_WriteByte(msg, ent->v.armor_bracer);
763 	if (sc2 & SC2_BREASTPLATE)
764 		MSG_WriteByte(msg, ent->v.armor_breastplate);
765 	if (sc2 & SC2_HELMET)
766 		MSG_WriteByte(msg, ent->v.armor_helmet);
767 	if (sc2 & SC2_FLIGHT_T)
768 		MSG_WriteByte(msg, ent->v.ring_flight);
769 	if (sc2 & SC2_WATER_T)
770 		MSG_WriteByte(msg, ent->v.ring_water);
771 	if (sc2 & SC2_TURNING_T)
772 		MSG_WriteByte(msg, ent->v.ring_turning);
773 	if (sc2 & SC2_REGEN_T)
774 		MSG_WriteByte(msg, ent->v.ring_regeneration);
775 //	if (sc2 & SC2_HASTE_T)
776 //		MSG_WriteFloat(msg, ent->v.haste_time);
777 //	if (sc2 & SC2_TOME_T)
778 //		MSG_WriteFloat(msg, ent->v.tome_time);
779 	if (sc2 & SC2_PUZZLE1)
780 		MSG_WriteString(msg, PR_GetString(ent->v.puzzle_inv1));
781 	if (sc2 & SC2_PUZZLE2)
782 		MSG_WriteString(msg, PR_GetString(ent->v.puzzle_inv2));
783 	if (sc2 & SC2_PUZZLE3)
784 		MSG_WriteString(msg, PR_GetString(ent->v.puzzle_inv3));
785 	if (sc2 & SC2_PUZZLE4)
786 		MSG_WriteString(msg, PR_GetString(ent->v.puzzle_inv4));
787 	if (sc2 & SC2_PUZZLE5)
788 		MSG_WriteString(msg, PR_GetString(ent->v.puzzle_inv5));
789 	if (sc2 & SC2_PUZZLE6)
790 		MSG_WriteString(msg, PR_GetString(ent->v.puzzle_inv6));
791 	if (sc2 & SC2_PUZZLE7)
792 		MSG_WriteString(msg, PR_GetString(ent->v.puzzle_inv7));
793 	if (sc2 & SC2_PUZZLE8)
794 		MSG_WriteString(msg, PR_GetString(ent->v.puzzle_inv8));
795 	if (sc2 & SC2_MAXHEALTH)
796 		MSG_WriteShort(msg, ent->v.max_health);
797 	if (sc2 & SC2_MAXMANA)
798 		MSG_WriteByte(msg, ent->v.max_mana);
799 	if (sc2 & SC2_FLAGS)
800 		MSG_WriteFloat(msg, ent->v.flags);
801 
802 end:
803 	memcpy (&host_cl->old_v, &ent->v, sizeof(host_cl->old_v));
804 }
805 
806 
807 #ifdef MGNET
808 /*
809 =============
810 float cardioid_rating (edict_t *targ , edict_t *self)
811 
812 Determines how important a visclient is- based on offset from
813 forward angle and distance.  Resultant pattern is a somewhat
814 extended 3-dimensional cleaved cardioid with each point on
815 the surface being equal in priority(0) and increasing linearly
816 towards equal priority(1) along a straight line to the center.
817 =============
818 */
cardioid_rating(edict_t * targ,edict_t * self)819 static float cardioid_rating (edict_t *targ , edict_t *self)
820 {
821 	vec3_t	vec, spot1, spot2;
822 	vec3_t	forward, right, up;
823 	float	dot, dist;
824 
825 	AngleVectors (self->v.v_angle,forward,right,up);
826 
827 	VectorAdd(self->v.origin,self->v.view_ofs,spot1);
828 	VectorSubtract(targ->v.absmax,targ->v.absmin,spot2);
829 	VectorMA(targ->v.absmin,0.5,spot2,spot2);
830 
831 	VectorSubtract(spot2,spot1,vec);
832 	dist = VectorNormalize(vec);
833 	dot = DotProduct(vec,forward);	//from 1 to -1
834 
835 	if (dot < -0.3)	//see only from -125 to 125 degrees
836 		return false;
837 
838 	if (dot > 0)	//to front of perpendicular plane to forward
839 		dot *= 31;//much more distance leniency in front, max dist = 2048 directly in front
840 	dot = (dot + 1) * 64;//64 = base distance if along the perpendicular plane, max is 2048 straight ahead
841 	if (dist >= dot)//too far away for that angle to be important
842 		return false;
843 
844 	//from 0.000000? to almost 1
845 	return 1 - (dist/dot);//The higher this number is, the more important it is to send this ent
846 }
847 
848 #define	MAX_VISCLIENTS	2
849 /*
850 =============
851 SV_WritePlayersToClient
852 
853 =============
854 */
SV_WritePlayersToClient(client_t * client,edict_t * clent,byte * pvs,sizebuf_t * msg)855 static void SV_WritePlayersToClient (client_t *client, edict_t *clent, byte *pvs, sizebuf_t *msg)
856 {
857 	int			i, j;
858 	client_t	*cl;
859 	edict_t		*ent;
860 	int			msec;
861 	usercmd_t	cmd;
862 	int			pflags;
863 	int			invis_level;
864 	qboolean	playermodel = false;
865 	// vars for the cardioid_rating/MGNET code
866 	int			k, l;
867 	int			visclient[MAX_CLIENTS];
868 	int			forcevisclient[MAX_CLIENTS];
869 	int			cl_v_priority[MAX_CLIENTS];
870 	int			cl_v_psort[MAX_CLIENTS];
871 	int			numvc, forcevc, totalvc, num_eliminated;
872 
873 	for (j = 0, cl = svs.clients, numvc = 0, forcevc = 0; j < MAX_CLIENTS; j++, cl++)
874 	{
875 		if (cl->state != cs_spawned)
876 			continue;
877 
878 		ent = cl->edict;
879 
880 		// ZOID visibility tracking
881 		invis_level = false;
882 		if (ent != clent &&
883 			!(client->spec_track && client->spec_track - 1 == j))
884 		{
885 			if ((int)ent->v.effects & EF_NODRAW)
886 			{
887 				if (dmMode.integer == DM_SIEGE && SV_PROGS_HAVE_SIEGE &&
888 						clent->v.playerclass == CLASS_DWARF)
889 					invis_level = false;
890 				else
891 					invis_level = true; //still can hear
892 			}
893 			//could be invisiblenow and still sent, cull out by other methods as well
894 			if (cl->spectator)
895 			{
896 				invis_level = 2; //no vis or weaponsound
897 			}
898 			else
899 			{
900 				// ignore if not touching a PV leaf
901 				for (i = 0; i < ent->num_leafs; i++)
902 				{
903 					if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i] & 7)) )
904 						break;
905 				}
906 
907 				if (i == ent->num_leafs)
908 					invis_level = 2; //no vis or weaponsound
909 			}
910 		}
911 
912 		if (invis_level == true)
913 		{	//ok to send weaponsound
914 			if (ent->v.wpn_sound)
915 			{
916 				MSG_WriteByte (msg, svc_player_sound);
917 				MSG_WriteByte (msg, j);
918 				for (i = 0; i < 3; i++)
919 					MSG_WriteCoord (msg, ent->v.origin[i]);
920 				MSG_WriteShort (msg, ent->v.wpn_sound);
921 			}
922 		}
923 		if (invis_level > 0)
924 			continue;
925 
926 		if (!cl->skipsend && ent != clent)
927 		{	//don't count self
928 			visclient[numvc]=j;
929 			numvc++;
930 		}
931 		else
932 		{	//Self, or Wasn't sent last time, must send this frame
933 			cl->skipsend = false;
934 			forcevisclient[forcevc] = j;
935 			forcevc++;
936 			continue;
937 		}
938 	}
939 
940 	totalvc = numvc + forcevc;
941 	if (totalvc > MAX_VISCLIENTS)
942 	{
943 		// You have more than 5 clients in your view, cull some out
944 		// prioritize by
945 		//	line of sight (20%)
946 		//	distance (50%)
947 		//	dot off v_forward (30%)
948 		// put this in "priority" then sort by priority
949 		// and send the highest priority
950 		// number of highest priority sent depends on how
951 		// many are forced through because they were skipped
952 		// last send.  Ideally, no more than 5 are sent.
953 		for (j = 0; j < numvc && totalvc > MAX_VISCLIENTS; j++)
954 		{	//priority 1 - if behind, cull out
955 			for (k = 0, cl = svs.clients; k < visclient[j]; k++, cl++);
956 		//	cl = svs.clients + visclient[j];
957 			ent = cl->edict;
958 			cl_v_priority[j] = cardioid_rating(ent, clent);
959 			if (!cl_v_priority[j])
960 			{	//% they won't be sent, l represents how many
961 				// were forced through
962 				cl->skipsend = true;
963 				totalvc--;
964 			}
965 		}
966 
967 		if (totalvc > MAX_VISCLIENTS)
968 		{
969 			//still more than 5 inside cardioid, sort by priority
970 			//and drop those after 5
971 
972 			//CHECK this make sure it works
973 
974 			for (i = 0; i < numvc; i++)
975 			{	//do this as many times as there are visclients
976 				for (j = 0; j < numvc-1-i; j++)
977 				{	//go through the list
978 					if (cl_v_priority[j] < cl_v_priority[j+1])
979 					{
980 						//store lower one
981 						k = cl_v_psort[j];
982 						//put next one in it's spot
983 						cl_v_psort[j] = cl_v_psort[j+1];
984 						//put lower one next
985 						cl_v_psort[j+1] = k;
986 					}
987 				}
988 			}
989 
990 			num_eliminated = 0;
991 
992 			while (totalvc > MAX_VISCLIENTS)
993 			{	//eliminate all over 5 unless not sent last time
994 				if (!cl->skipsend)
995 				{
996 					cl = svs.clients + cl_v_psort[numvc - num_eliminated];
997 					cl->skipsend = true;
998 					num_eliminated++;
999 					totalvc--;
1000 				}
1001 			}
1002 		}
1003 
1004 		// Alternate Possibilities: ...?
1005 		// priority 2 - if too many numleafs away, cull out
1006 		// priority 3 - don't send those farthest away, flag for re-send next time
1007 		// priority 4 - flat percentage based on how many over 5
1008 		/*	if (rand() % 10 < (numvc + l - 5))
1009 			{//% they won't be sent, l represents how many were forced through
1010 				cl->skipsend = true;
1011 				numvc--;
1012 			}
1013 		*/
1014 		// priority 5 - send less info on clients
1015 	}
1016 
1017 	for (j = 0, l = 0, k = 0, cl = svs.clients; j < MAX_CLIENTS; j++, cl++)
1018 	{	//priority 1 - if behind, cull out
1019 		if (forcevisclient[l] == j && l <= forcevc)
1020 			l++;
1021 		else if (visclient[k] == j && k <= numvc)
1022 			k++;	//clent is always forced
1023 		else
1024 			continue;//not in PVS or forced
1025 
1026 		if (cl->skipsend)
1027 		{	//still 2 bytes, but what ya gonna do?
1028 			MSG_WriteByte (msg, svc_playerskipped);
1029 			MSG_WriteByte (msg, j);
1030 			continue;
1031 		}
1032 
1033 		ent = cl->edict;
1034 
1035 		pflags = PF_MSEC | PF_COMMAND;
1036 
1037 		if (ent->v.modelindex != sv_playermodel[0] &&//paladin
1038 		    ent->v.modelindex != sv_playermodel[1] &&//crusader
1039 		    ent->v.modelindex != sv_playermodel[2] &&//necro
1040 		    ent->v.modelindex != sv_playermodel[3] &&//assassin
1041 		    ent->v.modelindex != sv_playermodel[4] &&//succ
1042 		    ent->v.modelindex != sv_playermodel[5])//dwarf
1043 			pflags |= PF_MODEL;
1044 		else
1045 			playermodel = true;
1046 
1047 		for (i = 0; i < 3; i++)
1048 		{
1049 			if (ent->v.velocity[i])
1050 				pflags |= PF_VELOCITY1<<i;
1051 		}
1052 		if (((long)ent->v.effects & 0xff))
1053 			pflags |= PF_EFFECTS;
1054 		if (((long)ent->v.effects & 0xff00))
1055 			pflags |= PF_EFFECTS2;
1056 		if (ent->v.skin)
1057 		{
1058 			if (dmMode.integer == DM_SIEGE && SV_PROGS_HAVE_SIEGE &&
1059 						playermodel && ent->v.skin == 1);
1060 			// in siege, don't send skin if 2nd skin and using
1061 			// playermodel, it will know on other side- saves
1062 			// us 1 byte per client per frame!
1063 			else
1064 				pflags |= PF_SKINNUM;
1065 		}
1066 		if (ent->v.health <= 0)
1067 			pflags |= PF_DEAD;
1068 		if (ent->v.hull == HULL_CROUCH)
1069 			pflags |= PF_CROUCH;
1070 
1071 		if (cl->spectator)
1072 		{	// only sent origin and velocity to spectators
1073 			pflags &= PF_VELOCITY1 | PF_VELOCITY2 | PF_VELOCITY3;
1074 		}
1075 		else if (ent == clent)
1076 		{	// don't send a lot of data on personal entity
1077 			pflags &= ~(PF_MSEC|PF_COMMAND);
1078 			if (ent->v.weaponframe)
1079 				pflags |= PF_WEAPONFRAME;
1080 		}
1081 		if (ent->v.drawflags)
1082 		{
1083 			pflags |= PF_DRAWFLAGS;
1084 		}
1085 		if (ent->v.scale != 0 && ent->v.scale != 1.0)
1086 		{
1087 			pflags |= PF_SCALE;
1088 		}
1089 		if (ent->v.abslight != 0)
1090 		{
1091 			pflags |= PF_ABSLIGHT;
1092 		}
1093 		if (ent->v.wpn_sound)
1094 		{
1095 			pflags |= PF_SOUND;
1096 		}
1097 
1098 		MSG_WriteByte (msg, svc_playerinfo);
1099 		MSG_WriteByte (msg, j);
1100 		MSG_WriteShort (msg, pflags);
1101 
1102 		for (i = 0; i < 3; i++)
1103 			MSG_WriteCoord (msg, ent->v.origin[i]);
1104 
1105 		MSG_WriteByte (msg, ent->v.frame);
1106 
1107 		if (pflags & PF_MSEC)
1108 		{
1109 			msec = 1000*(sv.time - cl->localtime);
1110 			if (msec > 255)
1111 				msec = 255;
1112 			MSG_WriteByte (msg, msec);
1113 		}
1114 
1115 		if (pflags & PF_COMMAND)
1116 		{
1117 			cmd = cl->lastcmd;
1118 
1119 			if (ent->v.health <= 0)
1120 			{	// don't show the corpse looking around...
1121 				cmd.angles[0] = 0;
1122 				cmd.angles[1] = ent->v.angles[1];
1123 				cmd.angles[0] = 0;
1124 			}
1125 
1126 			cmd.buttons = 0;	// never send buttons
1127 			cmd.impulse = 0;	// never send impulses
1128 			MSG_WriteUsercmd (msg, &cmd, false);
1129 		}
1130 
1131 		for (i = 0; i < 3; i++)
1132 		{
1133 			if (pflags & (PF_VELOCITY1<<i) )
1134 				MSG_WriteShort (msg, ent->v.velocity[i]);
1135 		}
1136 
1137 		// rjr
1138 		if (pflags & PF_MODEL)
1139 			MSG_WriteShort (msg, ent->v.modelindex);
1140 
1141 		if (pflags & PF_SKINNUM)
1142 			MSG_WriteByte (msg, ent->v.skin);
1143 
1144 		if (pflags & PF_EFFECTS)
1145 			MSG_WriteByte (msg, ((long)ent->v.effects & 0xff));
1146 
1147 		if (pflags & PF_EFFECTS2)
1148 			MSG_WriteByte(msg, ((long)ent->v.effects & 0xff00) >> 8);
1149 
1150 		if (pflags & PF_WEAPONFRAME)
1151 			MSG_WriteByte (msg, ent->v.weaponframe);
1152 
1153 		if (pflags & PF_DRAWFLAGS)
1154 		{
1155 			MSG_WriteByte (msg, ent->v.drawflags);
1156 		}
1157 		if (pflags & PF_SCALE)
1158 		{
1159 			MSG_WriteByte (msg, (int)(ent->v.scale * 100.0) & 255);
1160 		}
1161 		if (pflags & PF_ABSLIGHT)
1162 		{
1163 			MSG_WriteByte (msg, (int)(ent->v.abslight * 100.0) & 255);
1164 		}
1165 		if (pflags & PF_SOUND)
1166 		{
1167 			MSG_WriteShort (msg, ent->v.wpn_sound);
1168 		}
1169 	}
1170 }
1171 
1172 /*	End of MGNET code		*/
1173 
1174 #else
1175 
1176 /*
1177 =============
1178 SV_WritePlayersToClient
1179 
1180 =============
1181 */
SV_WritePlayersToClient(client_t * client,edict_t * clent,byte * pvs,sizebuf_t * msg)1182 static void SV_WritePlayersToClient (client_t *client, edict_t *clent, byte *pvs, sizebuf_t *msg)
1183 {
1184 	int			i, j;
1185 	client_t	*cl;
1186 	edict_t		*ent;
1187 	int			msec;
1188 	usercmd_t	cmd;
1189 	int			pflags;
1190 	int			invis_level;
1191 	qboolean	playermodel = false;
1192 
1193 	for (j = 0, cl = svs.clients; j < MAX_CLIENTS; j++, cl++)
1194 	{
1195 		if (cl->state != cs_spawned)
1196 			continue;
1197 
1198 		ent = cl->edict;
1199 
1200 		// ZOID visibility tracking
1201 		invis_level = false;
1202 		if (ent != clent &&
1203 			!(client->spec_track && client->spec_track - 1 == j))
1204 		{
1205 			if ((int)ent->v.effects & EF_NODRAW)
1206 			{
1207 				if (dmMode.integer == DM_SIEGE && SV_PROGS_HAVE_SIEGE &&
1208 						clent->v.playerclass == CLASS_DWARF)
1209 					invis_level = false;
1210 				else
1211 					invis_level = true; //still can hear
1212 			}
1213 			else if (cl->spectator)
1214 			{
1215 				invis_level = 2; //no vis or weaponsound
1216 			}
1217 			else
1218 			{
1219 				// ignore if not touching a PV leaf
1220 				for (i = 0; i < ent->num_leafs; i++)
1221 				{
1222 					if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i] & 7)) )
1223 						break;
1224 				}
1225 
1226 				if (i == ent->num_leafs)
1227 					invis_level = 2; //no vis or weaponsound
1228 			}
1229 		}
1230 
1231 		if (invis_level == true)
1232 		{	//ok to send weaponsound
1233 			if (ent->v.wpn_sound)
1234 			{
1235 				MSG_WriteByte (msg, svc_player_sound);
1236 				MSG_WriteByte (msg, j);
1237 				for (i = 0; i < 3; i++)
1238 					MSG_WriteCoord (msg, ent->v.origin[i]);
1239 				MSG_WriteShort (msg, ent->v.wpn_sound);
1240 			}
1241 		}
1242 		if (invis_level > 0)
1243 			continue;
1244 
1245 		pflags = PF_MSEC | PF_COMMAND;
1246 
1247 		if (ent->v.modelindex != sv_playermodel[0] &&//paladin
1248 		    ent->v.modelindex != sv_playermodel[1] &&//crusader
1249 		    ent->v.modelindex != sv_playermodel[2] &&//necro
1250 		    ent->v.modelindex != sv_playermodel[3] &&//assassin
1251 		    ent->v.modelindex != sv_playermodel[4] &&//succ
1252 		    ent->v.modelindex != sv_playermodel[5])//dwarf
1253 			pflags |= PF_MODEL;
1254 		else
1255 			playermodel = true;
1256 
1257 		for (i = 0; i < 3; i++)
1258 		{
1259 			if (ent->v.velocity[i])
1260 				pflags |= PF_VELOCITY1<<i;
1261 		}
1262 		if (((long)ent->v.effects & 0xff))
1263 			pflags |= PF_EFFECTS;
1264 		if (((long)ent->v.effects & 0xff00))
1265 			pflags |= PF_EFFECTS2;
1266 		if (ent->v.skin)
1267 		{
1268 			if (dmMode.integer == DM_SIEGE && SV_PROGS_HAVE_SIEGE &&
1269 						playermodel && ent->v.skin == 1);
1270 			// in siege, don't send skin if 2nd skin and using
1271 			// playermodel, it will know on other side- saves
1272 			// us 1 byte per client per frame!
1273 			else
1274 				pflags |= PF_SKINNUM;
1275 		}
1276 		if (ent->v.health <= 0)
1277 			pflags |= PF_DEAD;
1278 		if (ent->v.hull == HULL_CROUCH)
1279 			pflags |= PF_CROUCH;
1280 
1281 		if (cl->spectator)
1282 		{	// only sent origin and velocity to spectators
1283 			pflags &= PF_VELOCITY1 | PF_VELOCITY2 | PF_VELOCITY3;
1284 		}
1285 		else if (ent == clent)
1286 		{	// don't send a lot of data on personal entity
1287 			pflags &= ~(PF_MSEC|PF_COMMAND);
1288 			if (ent->v.weaponframe)
1289 				pflags |= PF_WEAPONFRAME;
1290 		}
1291 		if (ent->v.drawflags)
1292 		{
1293 			pflags |= PF_DRAWFLAGS;
1294 		}
1295 		if (ent->v.scale != 0 && ent->v.scale != 1.0)
1296 		{
1297 			pflags |= PF_SCALE;
1298 		}
1299 		if (ent->v.abslight != 0)
1300 		{
1301 			pflags |= PF_ABSLIGHT;
1302 		}
1303 		if (ent->v.wpn_sound)
1304 		{
1305 			pflags |= PF_SOUND;
1306 		}
1307 
1308 		MSG_WriteByte (msg, svc_playerinfo);
1309 		MSG_WriteByte (msg, j);
1310 		MSG_WriteShort (msg, pflags);
1311 
1312 		for (i = 0; i < 3; i++)
1313 			MSG_WriteCoord (msg, ent->v.origin[i]);
1314 
1315 		MSG_WriteByte (msg, ent->v.frame);
1316 
1317 		if (pflags & PF_MSEC)
1318 		{
1319 			msec = 1000*(sv.time - cl->localtime);
1320 			if (msec > 255)
1321 				msec = 255;
1322 			MSG_WriteByte (msg, msec);
1323 		}
1324 
1325 		if (pflags & PF_COMMAND)
1326 		{
1327 			cmd = cl->lastcmd;
1328 
1329 			if (ent->v.health <= 0)
1330 			{	// don't show the corpse looking around...
1331 				cmd.angles[0] = 0;
1332 				cmd.angles[1] = ent->v.angles[1];
1333 				cmd.angles[0] = 0;
1334 			}
1335 
1336 			cmd.buttons = 0;	// never send buttons
1337 			cmd.impulse = 0;	// never send impulses
1338 			MSG_WriteUsercmd (msg, &cmd, false);
1339 		}
1340 
1341 		for (i = 0; i < 3; i++)
1342 		{
1343 			if (pflags & (PF_VELOCITY1<<i) )
1344 				MSG_WriteShort (msg, ent->v.velocity[i]);
1345 		}
1346 
1347 		// rjr
1348 		if (pflags & PF_MODEL)
1349 			MSG_WriteShort (msg, ent->v.modelindex);
1350 
1351 		if (pflags & PF_SKINNUM)
1352 			MSG_WriteByte (msg, ent->v.skin);
1353 
1354 		if (pflags & PF_EFFECTS)
1355 			MSG_WriteByte (msg, ((long)ent->v.effects & 0xff));
1356 
1357 		if (pflags & PF_EFFECTS2)
1358 			MSG_WriteByte(msg, ((long)ent->v.effects & 0xff00) >> 8);
1359 
1360 		if (pflags & PF_WEAPONFRAME)
1361 			MSG_WriteByte (msg, ent->v.weaponframe);
1362 
1363 		if (pflags & PF_DRAWFLAGS)
1364 		{
1365 			MSG_WriteByte (msg, ent->v.drawflags);
1366 		}
1367 		if (pflags & PF_SCALE)
1368 		{
1369 			MSG_WriteByte (msg, (int)(ent->v.scale * 100.0) & 255);
1370 		}
1371 		if (pflags & PF_ABSLIGHT)
1372 		{
1373 			MSG_WriteByte (msg, (int)(ent->v.abslight * 100.0) & 255);
1374 		}
1375 		if (pflags & PF_SOUND)
1376 		{
1377 			MSG_WriteShort (msg, ent->v.wpn_sound);
1378 		}
1379 	}
1380 }
1381 #endif
1382 
1383 /*
1384 =============
1385 SV_WriteEntitiesToClient
1386 
1387 Encodes the current state of the world as
1388 a svc_packetentities messages and possibly
1389 a svc_nails message and
1390 svc_playerinfo messages
1391 =============
1392 */
SV_WriteEntitiesToClient(client_t * client,sizebuf_t * msg)1393 void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
1394 {
1395 	int		e, i;
1396 	byte	*pvs;
1397 	vec3_t	org;
1398 	edict_t	*ent;
1399 	packet_entities_t	*pack;
1400 	edict_t	*clent;
1401 	client_frame_t	*frame;
1402 	entity_state_t	*state;
1403 
1404 	// this is the frame we are creating
1405 	frame = &client->frames[client->netchan.incoming_sequence & UPDATE_MASK];
1406 
1407 	// find the client's PVS
1408 	clent = client->edict;
1409 	VectorAdd (clent->v.origin, clent->v.view_ofs, org);
1410 	pvs = SV_FatPVS (org);
1411 
1412 	// send over the players in the PVS
1413 	SV_WritePlayersToClient (client, clent, pvs, msg);
1414 
1415 	// put other visible entities into either a packet_entities or a nails message
1416 	pack = &frame->entities;
1417 	pack->num_entities = 0;
1418 
1419 //	numnails = 0;
1420 	nummissiles = 0;
1421 	numravens = 0;
1422 	numraven2s = 0;
1423 
1424 	for (e = MAX_CLIENTS+1, ent = EDICT_NUM(e); e < sv.num_edicts; e++, ent = NEXT_EDICT(ent))
1425 	{
1426 		// ignore ents without visible models
1427 		if (!ent->v.modelindex || !*PR_GetString(ent->v.model))
1428 			continue;
1429 
1430 		if ((int)ent->v.effects & EF_NODRAW)
1431 		{
1432 			continue;
1433 		}
1434 
1435 		// ignore if not touching a PV leaf
1436 		for (i = 0; i < ent->num_leafs; i++)
1437 		{
1438 			if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i] & 7)) )
1439 				break;
1440 		}
1441 
1442 		if (i == ent->num_leafs)
1443 			continue;	// not visible
1444 
1445 //		if (SV_AddNailUpdate (ent))
1446 //			continue;
1447 		if (SV_AddMissileUpdate (ent))
1448 			continue;	// added to the special update list
1449 
1450 		// add to the packetentities
1451 		if (pack->num_entities == MAX_PACKET_ENTITIES)
1452 			continue;	// all full
1453 
1454 		state = &pack->entities[pack->num_entities];
1455 		pack->num_entities++;
1456 
1457 		state->number = e;
1458 		state->flags = 0;
1459 		VectorCopy (ent->v.origin, state->origin);
1460 		VectorCopy (ent->v.angles, state->angles);
1461 		state->modelindex = ent->v.modelindex;
1462 		state->frame = ent->v.frame;
1463 		state->colormap = ent->v.colormap;
1464 		state->skinnum = ent->v.skin;
1465 		state->effects = ent->v.effects;
1466 		state->scale = (int)(ent->v.scale * 100.0) & 255;
1467 		state->drawflags = ent->v.drawflags;
1468 		state->abslight = (int)(ent->v.abslight * 255.0) & 255;
1469 		//clear sound so it doesn't send twice
1470 		state->wpn_sound = ent->v.wpn_sound;
1471 	}
1472 
1473 	// encode the packet entities as a delta from the
1474 	// last packetentities acknowledged by the client
1475 
1476 	SV_EmitPacketEntities (client, pack, msg);
1477 
1478 	// now add the specialized nail update
1479 //	SV_EmitNailUpdate (msg);
1480 	SV_EmitPackedEntities (msg);
1481 }
1482 
1483