1 /*
2 Copyright (C) 1996-1997 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 "qwsvdef.h"
22
23 /*
24 =============================================================================
25
26 The PVS must include a small area around the client to allow head bobbing
27 or other small motion on the client side. Otherwise, a bob might cause an
28 entity that should be visible to not show up, especially when the bob
29 crosses a waterline.
30
31 =============================================================================
32 */
33
34 int fatbytes;
35 byte fatpvs[MAX_MAP_LEAFS/8];
36
SV_AddToFatPVS(vec3_t org,mnode_t * node)37 void SV_AddToFatPVS (vec3_t org, mnode_t *node)
38 {
39 int i;
40 byte *pvs;
41 mplane_t *plane;
42 float d;
43
44 while (1)
45 {
46 // if this is a leaf, accumulate the pvs bits
47 if (node->contents < 0)
48 {
49 if (node->contents != CONTENTS_SOLID)
50 {
51 pvs = Mod_LeafPVS ( (mleaf_t *)node, sv.worldmodel);
52 for (i=0 ; i<fatbytes ; i++)
53 fatpvs[i] |= pvs[i];
54 }
55 return;
56 }
57
58 plane = node->plane;
59 d = DotProduct (org, plane->normal) - plane->dist;
60 if (d > 8)
61 node = node->children[0];
62 else if (d < -8)
63 node = node->children[1];
64 else
65 { // go down both
66 SV_AddToFatPVS (org, node->children[0]);
67 node = node->children[1];
68 }
69 }
70 }
71
72 /*
73 =============
74 SV_FatPVS
75
76 Calculates a PVS that is the inclusive or of all leafs within 8 pixels of the
77 given point.
78 =============
79 */
SV_FatPVS(vec3_t org)80 byte *SV_FatPVS (vec3_t org)
81 {
82 fatbytes = (sv.worldmodel->numleafs+31)>>3;
83 Q_memset (fatpvs, 0, fatbytes);
84 SV_AddToFatPVS (org, sv.worldmodel->nodes);
85 return fatpvs;
86 }
87
88 //=============================================================================
89
90 // because there can be a lot of nails, there is a special
91 // network protocol for them
92 #define MAX_NAILS 32
93 edict_t *nails[MAX_NAILS];
94 int numnails;
95
96 extern int sv_nailmodel, sv_supernailmodel, sv_playermodel;
97
SV_AddNailUpdate(edict_t * ent)98 qboolean SV_AddNailUpdate (edict_t *ent)
99 {
100 if (ent->v.modelindex != sv_nailmodel
101 && ent->v.modelindex != sv_supernailmodel)
102 return false;
103 if (numnails == MAX_NAILS)
104 return true;
105 nails[numnails] = ent;
106 numnails++;
107 return true;
108 }
109
SV_EmitNailUpdate(sizebuf_t * msg)110 void SV_EmitNailUpdate (sizebuf_t *msg)
111 {
112 byte bits[6]; // [48 bits] xyzpy 12 12 12 4 8
113 int n, i;
114 edict_t *ent;
115 int x, y, z, p, yaw;
116
117 if (!numnails)
118 return;
119
120 MSG_WriteByte (msg, svc_nails);
121 MSG_WriteByte (msg, numnails);
122
123 for (n=0 ; n<numnails ; n++)
124 {
125 ent = nails[n];
126 x = (int)(ent->v.origin[0]+4096)>>1;
127 y = (int)(ent->v.origin[1]+4096)>>1;
128 z = (int)(ent->v.origin[2]+4096)>>1;
129 p = (int)(16*ent->v.angles[0]/360)&15;
130 yaw = (int)(256*ent->v.angles[1]/360)&255;
131
132 bits[0] = x;
133 bits[1] = (x>>8) | (y<<4);
134 bits[2] = (y>>4);
135 bits[3] = z;
136 bits[4] = (z>>8) | (p<<4);
137 bits[5] = yaw;
138
139 for (i=0 ; i<6 ; i++)
140 MSG_WriteByte (msg, bits[i]);
141 }
142 }
143
144 //=============================================================================
145
146
147 /*
148 ==================
149 SV_WriteDelta
150
151 Writes part of a packetentities message.
152 Can delta from either a baseline or a previous packet_entity
153 ==================
154 */
SV_WriteDelta(entity_state_t * from,entity_state_t * to,sizebuf_t * msg,qboolean force)155 void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force)
156 {
157 int bits;
158 int i;
159 float miss;
160
161 // send an update
162 bits = 0;
163
164 for (i=0 ; i<3 ; i++)
165 {
166 miss = to->origin[i] - from->origin[i];
167 if ( miss < -0.1 || miss > 0.1 )
168 bits |= U_ORIGIN1<<i;
169 }
170
171 if ( to->angles[0] != from->angles[0] )
172 bits |= U_ANGLE1;
173
174 if ( to->angles[1] != from->angles[1] )
175 bits |= U_ANGLE2;
176
177 if ( to->angles[2] != from->angles[2] )
178 bits |= U_ANGLE3;
179
180 if ( to->colormap != from->colormap )
181 bits |= U_COLORMAP;
182
183 if ( to->skinnum != from->skinnum )
184 bits |= U_SKIN;
185
186 if ( to->frame != from->frame )
187 bits |= U_FRAME;
188
189 if ( to->effects != from->effects )
190 bits |= U_EFFECTS;
191
192 if ( to->modelindex != from->modelindex )
193 bits |= U_MODEL;
194
195 if (bits & 511)
196 bits |= U_MOREBITS;
197
198 if (to->flags & U_SOLID)
199 bits |= U_SOLID;
200
201 //
202 // write the message
203 //
204 if (!to->number)
205 SV_Error ("Unset entity number");
206 if (to->number >= 512)
207 SV_Error ("Entity number >= 512");
208
209 if (!bits && !force)
210 return; // nothing to send!
211 i = to->number | (bits&~511);
212 if (i & U_REMOVE)
213 Sys_Error ("U_REMOVE");
214 MSG_WriteShort (msg, i);
215
216 if (bits & U_MOREBITS)
217 MSG_WriteByte (msg, bits&255);
218 if (bits & U_MODEL)
219 MSG_WriteByte (msg, to->modelindex);
220 if (bits & U_FRAME)
221 MSG_WriteByte (msg, to->frame);
222 if (bits & U_COLORMAP)
223 MSG_WriteByte (msg, to->colormap);
224 if (bits & U_SKIN)
225 MSG_WriteByte (msg, to->skinnum);
226 if (bits & U_EFFECTS)
227 MSG_WriteByte (msg, to->effects);
228 if (bits & U_ORIGIN1)
229 MSG_WriteCoord (msg, to->origin[0]);
230 if (bits & U_ANGLE1)
231 MSG_WriteAngle(msg, to->angles[0]);
232 if (bits & U_ORIGIN2)
233 MSG_WriteCoord (msg, to->origin[1]);
234 if (bits & U_ANGLE2)
235 MSG_WriteAngle(msg, to->angles[1]);
236 if (bits & U_ORIGIN3)
237 MSG_WriteCoord (msg, to->origin[2]);
238 if (bits & U_ANGLE3)
239 MSG_WriteAngle(msg, to->angles[2]);
240 }
241
242 /*
243 =============
244 SV_EmitPacketEntities
245
246 Writes a delta update of a packet_entities_t to the message.
247
248 =============
249 */
SV_EmitPacketEntities(client_t * client,packet_entities_t * to,sizebuf_t * msg)250 void SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *msg)
251 {
252 edict_t *ent;
253 client_frame_t *fromframe;
254 packet_entities_t *from;
255 int oldindex, newindex;
256 int oldnum, newnum;
257 int oldmax;
258
259 // this is the frame that we are going to delta update from
260 if (client->delta_sequence != -1)
261 {
262 fromframe = &client->frames[client->delta_sequence & UPDATE_MASK];
263 from = &fromframe->entities;
264 oldmax = from->num_entities;
265
266 MSG_WriteByte (msg, svc_deltapacketentities);
267 MSG_WriteByte (msg, client->delta_sequence);
268 }
269 else
270 {
271 oldmax = 0; // no delta update
272 from = NULL;
273
274 MSG_WriteByte (msg, svc_packetentities);
275 }
276
277 newindex = 0;
278 oldindex = 0;
279 //Con_Printf ("---%i to %i ----\n", client->delta_sequence & UPDATE_MASK
280 // , client->netchan.outgoing_sequence & UPDATE_MASK);
281 while (newindex < to->num_entities || oldindex < oldmax)
282 {
283 newnum = newindex >= to->num_entities ? 9999 : to->entities[newindex].number;
284 oldnum = oldindex >= oldmax ? 9999 : from->entities[oldindex].number;
285
286 if (newnum == oldnum)
287 { // delta update from old position
288 //Con_Printf ("delta %i\n", newnum);
289 SV_WriteDelta (&from->entities[oldindex], &to->entities[newindex], msg, false);
290 oldindex++;
291 newindex++;
292 continue;
293 }
294
295 if (newnum < oldnum)
296 { // this is a new entity, send it from the baseline
297 ent = EDICT_NUM(newnum);
298 //Con_Printf ("baseline %i\n", newnum);
299 SV_WriteDelta (&ent->baseline, &to->entities[newindex], msg, true);
300 newindex++;
301 continue;
302 }
303
304 if (newnum > oldnum)
305 { // the old entity isn't present in the new message
306 //Con_Printf ("remove %i\n", oldnum);
307 MSG_WriteShort (msg, oldnum | U_REMOVE);
308 oldindex++;
309 continue;
310 }
311 }
312
313 MSG_WriteShort (msg, 0); // end of packetentities
314 }
315
316 /*
317 =============
318 SV_WritePlayersToClient
319
320 =============
321 */
SV_WritePlayersToClient(client_t * client,edict_t * clent,byte * pvs,sizebuf_t * msg)322 void SV_WritePlayersToClient (client_t *client, edict_t *clent, byte *pvs, sizebuf_t *msg)
323 {
324 int i, j;
325 client_t *cl;
326 edict_t *ent;
327 int msec;
328 usercmd_t cmd;
329 int pflags;
330
331 for (j=0,cl=svs.clients ; j<MAX_CLIENTS ; j++,cl++)
332 {
333 if (cl->state != cs_spawned)
334 continue;
335
336 ent = cl->edict;
337
338 // ZOID visibility tracking
339 if (ent != clent &&
340 !(client->spec_track && client->spec_track - 1 == j))
341 {
342 if (cl->spectator)
343 continue;
344
345 // ignore if not touching a PV leaf
346 for (i=0 ; i < ent->num_leafs ; i++)
347 if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i]&7) ))
348 break;
349 if (i == ent->num_leafs)
350 continue; // not visible
351 }
352
353 pflags = PF_MSEC | PF_COMMAND;
354
355 if (ent->v.modelindex != sv_playermodel)
356 pflags |= PF_MODEL;
357 for (i=0 ; i<3 ; i++)
358 if (ent->v.velocity[i])
359 pflags |= PF_VELOCITY1<<i;
360 if (ent->v.effects)
361 pflags |= PF_EFFECTS;
362 if (ent->v.skin)
363 pflags |= PF_SKINNUM;
364 if (ent->v.health <= 0)
365 pflags |= PF_DEAD;
366 if (ent->v.mins[2] != -24)
367 pflags |= PF_GIB;
368
369 if (cl->spectator)
370 { // only sent origin and velocity to spectators
371 pflags &= PF_VELOCITY1 | PF_VELOCITY2 | PF_VELOCITY3;
372 }
373 else if (ent == clent)
374 { // don't send a lot of data on personal entity
375 pflags &= ~(PF_MSEC|PF_COMMAND);
376 if (ent->v.weaponframe)
377 pflags |= PF_WEAPONFRAME;
378 }
379
380 if (client->spec_track && client->spec_track - 1 == j &&
381 ent->v.weaponframe)
382 pflags |= PF_WEAPONFRAME;
383
384 MSG_WriteByte (msg, svc_playerinfo);
385 MSG_WriteByte (msg, j);
386 MSG_WriteShort (msg, pflags);
387
388 for (i=0 ; i<3 ; i++)
389 MSG_WriteCoord (msg, ent->v.origin[i]);
390
391 MSG_WriteByte (msg, ent->v.frame);
392
393 if (pflags & PF_MSEC)
394 {
395 msec = 1000*(sv.time - cl->localtime);
396 if (msec > 255)
397 msec = 255;
398 MSG_WriteByte (msg, msec);
399 }
400
401 if (pflags & PF_COMMAND)
402 {
403 cmd = cl->lastcmd;
404
405 if (ent->v.health <= 0)
406 { // don't show the corpse looking around...
407 cmd.angles[0] = 0;
408 cmd.angles[1] = ent->v.angles[1];
409 cmd.angles[0] = 0;
410 }
411
412 cmd.buttons = 0; // never send buttons
413 cmd.impulse = 0; // never send impulses
414
415 MSG_WriteDeltaUsercmd (msg, &nullcmd, &cmd);
416 }
417
418 for (i=0 ; i<3 ; i++)
419 if (pflags & (PF_VELOCITY1<<i) )
420 MSG_WriteShort (msg, ent->v.velocity[i]);
421
422 if (pflags & PF_MODEL)
423 MSG_WriteByte (msg, ent->v.modelindex);
424
425 if (pflags & PF_SKINNUM)
426 MSG_WriteByte (msg, ent->v.skin);
427
428 if (pflags & PF_EFFECTS)
429 MSG_WriteByte (msg, ent->v.effects);
430
431 if (pflags & PF_WEAPONFRAME)
432 MSG_WriteByte (msg, ent->v.weaponframe);
433 }
434 }
435
436
437 /*
438 =============
439 SV_WriteEntitiesToClient
440
441 Encodes the current state of the world as
442 a svc_packetentities messages and possibly
443 a svc_nails message and
444 svc_playerinfo messages
445 =============
446 */
SV_WriteEntitiesToClient(client_t * client,sizebuf_t * msg)447 void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
448 {
449 int e, i;
450 byte *pvs;
451 vec3_t org;
452 edict_t *ent;
453 packet_entities_t *pack;
454 edict_t *clent;
455 client_frame_t *frame;
456 entity_state_t *state;
457
458 // this is the frame we are creating
459 frame = &client->frames[client->netchan.incoming_sequence & UPDATE_MASK];
460
461 // find the client's PVS
462 clent = client->edict;
463 VectorAdd (clent->v.origin, clent->v.view_ofs, org);
464 pvs = SV_FatPVS (org);
465
466 // send over the players in the PVS
467 SV_WritePlayersToClient (client, clent, pvs, msg);
468
469 // put other visible entities into either a packet_entities or a nails message
470 pack = &frame->entities;
471 pack->num_entities = 0;
472
473 numnails = 0;
474
475 for (e=MAX_CLIENTS+1, ent=EDICT_NUM(e) ; e<sv.num_edicts ; e++, ent = NEXT_EDICT(ent))
476 {
477 // ignore ents without visible models
478 if (!ent->v.modelindex || !*PR_GetString(ent->v.model))
479 continue;
480
481 // ignore if not touching a PV leaf
482 for (i=0 ; i < ent->num_leafs ; i++)
483 if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i]&7) ))
484 break;
485
486 if (i == ent->num_leafs)
487 continue; // not visible
488
489 if (SV_AddNailUpdate (ent))
490 continue; // added to the special update list
491
492 // add to the packetentities
493 if (pack->num_entities == MAX_PACKET_ENTITIES)
494 continue; // all full
495
496 state = &pack->entities[pack->num_entities];
497 pack->num_entities++;
498
499 state->number = e;
500 state->flags = 0;
501 VectorCopy (ent->v.origin, state->origin);
502 VectorCopy (ent->v.angles, state->angles);
503 state->modelindex = ent->v.modelindex;
504 state->frame = ent->v.frame;
505 state->colormap = ent->v.colormap;
506 state->skinnum = ent->v.skin;
507 state->effects = ent->v.effects;
508 }
509
510 // encode the packet entities as a delta from the
511 // last packetentities acknowledged by the client
512
513 SV_EmitPacketEntities (client, pack, msg);
514
515 // now add the specialized nail update
516 SV_EmitNailUpdate (msg);
517 }
518