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