DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
sv_send.c
Go to the documentation of this file.
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20
21#include "quakedef.h"
22#include "sv_demo.h"
23
25extern cvar_t sv_qcstats;
38
39/*
40=============================================================================
41
42EVENT MESSAGES
43
44=============================================================================
45*/
46
47/*
48=================
49SV_ClientPrint
50
51Sends text across to be displayed
52FIXME: make this just a stuffed echo?
53=================
54*/
63
64/*
65=================
66SV_ClientPrintf
67
68Sends text across to be displayed
69FIXME: make this just a stuffed echo?
70=================
71*/
72void SV_ClientPrintf(const char *fmt, ...)
73{
74 va_list argptr;
75 char msg[MAX_INPUTLINE];
76
77 va_start(argptr,fmt);
78 dpvsnprintf(msg,sizeof(msg),fmt,argptr);
79 va_end(argptr);
80
81 SV_ClientPrint(msg);
82}
83
84/*
85=================
86SV_BroadcastPrint
87
88Sends text to all active clients
89=================
90*/
91void SV_BroadcastPrint(const char *msg)
92{
93 int i;
94 client_t *client;
95
96 for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
97 {
98 if (client->active && client->netconnection)
99 {
101 MSG_WriteString(&client->netconnection->message, msg);
102 }
103 }
104
106 Con_Print(msg);
107}
108
109/*
110=================
111SV_BroadcastPrintf
112
113Sends text to all active clients
114=================
115*/
116void SV_BroadcastPrintf(const char *fmt, ...)
117{
118 va_list argptr;
119 char msg[MAX_INPUTLINE];
120
121 va_start(argptr,fmt);
122 dpvsnprintf(msg,sizeof(msg),fmt,argptr);
123 va_end(argptr);
124
126}
127
128/*
129=================
130SV_ClientCommands
131
132Send text over to the client to be executed
133=================
134*/
135void SV_ClientCommands(const char *fmt, ...)
136{
137 va_list argptr;
138 char string[MAX_INPUTLINE];
139
141 return;
142
143 va_start(argptr,fmt);
144 dpvsnprintf(string, sizeof(string), fmt, argptr);
145 va_end(argptr);
146
149}
150
151/*
152==================
153SV_StartParticle
154
155Make sure the event gets sent to all clients
156==================
157*/
159{
160 int i;
161
163 return;
168 for (i=0 ; i<3 ; i++)
169 MSG_WriteChar (&sv.datagram, (int)bound(-128, dir[i]*16, 127));
173}
174
175/*
176==================
177SV_StartEffect
178
179Make sure the event gets sent to all clients
180==================
181*/
182void SV_StartEffect (vec3_t org, int modelindex, int startframe, int framecount, int framerate)
183{
184 if (modelindex >= 256 || startframe >= 256)
185 {
187 return;
193 MSG_WriteShort (&sv.datagram, startframe);
194 MSG_WriteByte (&sv.datagram, framecount);
195 MSG_WriteByte (&sv.datagram, framerate);
196 }
197 else
198 {
200 return;
206 MSG_WriteByte (&sv.datagram, startframe);
207 MSG_WriteByte (&sv.datagram, framecount);
208 MSG_WriteByte (&sv.datagram, framerate);
209 }
211}
212
213/*
214==================
215SV_StartSound
216
217Each entity can have eight independant sound sources, like voice,
218weapon, feet, etc.
219
220Channel 0 is an auto-allocate channel, the others override anything
221already running on that entity/channel pair.
222
223An attenuation of 0 will play full volume everywhere in the level.
224Larger attenuations will drop off. (max 4 attenuation)
225
226==================
227*/
228void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int nvolume, float attenuation, qbool reliable, float speed)
229{
230 prvm_prog_t *prog = SVVM_prog;
231 sizebuf_t *dest;
232 int sound_num, field_mask, i, ent, speed4000;
233
234 dest = (reliable ? &sv.reliable_datagram : &sv.datagram);
235
236 if (nvolume < 0 || nvolume > 255)
237 {
238 Con_Printf ("SV_StartSound: volume = %i\n", nvolume);
239 return;
240 }
241
242 if (attenuation < 0 || attenuation > 4)
243 {
244 Con_Printf ("SV_StartSound: attenuation = %f\n", attenuation);
245 return;
246 }
247
248 if (!IS_CHAN(channel))
249 {
250 Con_Printf ("SV_StartSound: channel = %i\n", channel);
251 return;
252 }
253
254 channel = CHAN_ENGINE2NET(channel);
255
257 return;
258
259// find precache number for sound
260 sound_num = SV_SoundIndex(sample, 1);
261 if (!sound_num)
262 return;
263
265
266 speed4000 = (int)floor(speed * 4000.0f + 0.5f);
267 field_mask = 0;
268 if (nvolume != DEFAULT_SOUND_PACKET_VOLUME)
269 field_mask |= SND_VOLUME;
270 if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION)
271 field_mask |= SND_ATTENUATION;
272 if (speed4000 && speed4000 != 4000)
273 field_mask |= SND_SPEEDUSHORT4000;
274 if (ent >= 8192 || channel < 0 || channel > 7)
275 field_mask |= SND_LARGEENTITY;
276 if (sound_num >= 256)
277 field_mask |= SND_LARGESOUND;
278
279// directed messages go only to the entity they are targeted on
280 MSG_WriteByte (dest, svc_sound);
281 MSG_WriteByte (dest, field_mask);
282 if (field_mask & SND_VOLUME)
283 MSG_WriteByte (dest, nvolume);
284 if (field_mask & SND_ATTENUATION)
285 MSG_WriteByte (dest, (int)(attenuation*64));
286 if (field_mask & SND_SPEEDUSHORT4000)
287 MSG_WriteShort (dest, speed4000);
288 if (field_mask & SND_LARGEENTITY)
289 {
290 MSG_WriteShort (dest, ent);
291 MSG_WriteChar (dest, channel);
292 }
293 else
294 MSG_WriteShort (dest, (ent<<3) | channel);
296 MSG_WriteShort (dest, sound_num);
297 else
298 MSG_WriteByte (dest, sound_num);
299 for (i = 0;i < 3;i++)
301
302 // TODO do we have to do anything here when dest is &sv.reliable_datagram?
303 if(!reliable)
305}
306
307/*
308==================
309SV_StartPointSound
310
311Nearly the same logic as SV_StartSound, except an origin
312instead of an entity is provided and channel is omitted.
313
314The entity sent to the client is 0 (world) and the channel
315is 0 (CHAN_AUTO). SND_LARGEENTITY will never occur in this
316function, therefore the check for it is omitted.
317
318==================
319*/
320void SV_StartPointSound (vec3_t origin, const char *sample, int nvolume, float attenuation, float speed)
321{
322 int sound_num, field_mask, i, speed4000;
323
324 if (nvolume < 0 || nvolume > 255)
325 {
326 Con_Printf ("SV_StartPointSound: volume = %i\n", nvolume);
327 return;
328 }
329
330 if (attenuation < 0 || attenuation > 4)
331 {
332 Con_Printf ("SV_StartPointSound: attenuation = %f\n", attenuation);
333 return;
334 }
335
337 return;
338
339 // find precache number for sound
340 sound_num = SV_SoundIndex(sample, 1);
341 if (!sound_num)
342 return;
343
344 speed4000 = (int)(speed * 40.0f);
345 field_mask = 0;
346 if (nvolume != DEFAULT_SOUND_PACKET_VOLUME)
347 field_mask |= SND_VOLUME;
348 if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION)
349 field_mask |= SND_ATTENUATION;
350 if (sound_num >= 256)
351 field_mask |= SND_LARGESOUND;
352 if (speed4000 && speed4000 != 4000)
353 field_mask |= SND_SPEEDUSHORT4000;
354
355// directed messages go only to the entity they are targeted on
357 MSG_WriteByte (&sv.datagram, field_mask);
358 if (field_mask & SND_VOLUME)
359 MSG_WriteByte (&sv.datagram, nvolume);
360 if (field_mask & SND_ATTENUATION)
361 MSG_WriteByte (&sv.datagram, (int)(attenuation*64));
362 if (field_mask & SND_SPEEDUSHORT4000)
363 MSG_WriteShort (&sv.datagram, speed4000);
364 // Always write entnum 0 for the world entity
365 MSG_WriteShort (&sv.datagram, (0<<3) | 0);
366 if (field_mask & SND_LARGESOUND)
367 MSG_WriteShort (&sv.datagram, sound_num);
368 else
369 MSG_WriteByte (&sv.datagram, sound_num);
370 for (i = 0;i < 3;i++)
373}
374
375/*
376===============================================================================
377
378FRAME UPDATES
379
380===============================================================================
381*/
382
383/*
384=============================================================================
385
386The PVS must include a small area around the client to allow head bobbing
387or other small motion on the client side. Otherwise, a bob might cause an
388entity that should be visible to not show up, especially when the bob
389crosses a waterline.
390
391=============================================================================
392*/
393
395{
396 prvm_prog_t *prog = SVVM_prog;
397 int i;
398 unsigned int sendflags;
399 unsigned int version;
400 unsigned int modelindex, effects, flags, glowsize, lightstyle, lightpflags, light[4], specialvisibilityradius;
401 unsigned int customizeentityforclient;
402 unsigned int sendentity;
403 float f;
404 prvm_vec_t *v;
405 vec3_t cullmins, cullmaxs;
406 model_t *model;
407
408 // fast path for games that do not use legacy entity networking
409 // note: still networks clients even if they are legacy
410 sendentity = PRVM_serveredictfunction(ent, SendEntity);
411 if (sv_onlycsqcnetworking.integer && !sendentity && enumber > svs.maxclients)
412 return false;
413
414 // this 2 billion unit check is actually to detect NAN origins
415 // (we really don't want to send those)
416 if (!(VectorLength2(PRVM_serveredictvector(ent, origin)) < 2000000000.0*2000000000.0))
417 return false;
418
419 // EF_NODRAW prevents sending for any reason except for your own
420 // client, so we must keep all clients in this superset
421 effects = (unsigned)PRVM_serveredictfloat(ent, effects);
422
423 // we can omit invisible entities with no effects that are not clients
424 // LadyHavoc: this could kill tags attached to an invisible entity, I
425 // just hope we never have to support that case
427 modelindex = (i >= 1 && i < MAX_MODELS && PRVM_serveredictstring(ent, model) && *PRVM_GetString(prog, PRVM_serveredictstring(ent, model)) && sv.models[i]) ? i : 0;
428
429 flags = 0;
430 i = (int)(PRVM_serveredictfloat(ent, glow_size) * 0.25f);
431 glowsize = (unsigned char)bound(0, i, 255);
436
438 f = v[0]*256;
439 light[0] = (unsigned short)bound(0, f, 65535);
440 f = v[1]*256;
441 light[1] = (unsigned short)bound(0, f, 65535);
442 f = v[2]*256;
443 light[2] = (unsigned short)bound(0, f, 65535);
445 light[3] = (unsigned short)bound(0, f, 65535);
446 lightstyle = (unsigned char)PRVM_serveredictfloat(ent, style);
447 lightpflags = (unsigned char)PRVM_serveredictfloat(ent, pflags);
448
449 if (gamemode == GAME_TENEBRAE)
450 {
451 // tenebrae's EF_FULLDYNAMIC conflicts with Q2's EF_NODRAW
452 if (effects & 16)
453 {
454 effects &= ~16;
455 lightpflags |= PFLAGS_FULLDYNAMIC;
456 }
457 // tenebrae's EF_GREEN conflicts with DP's EF_ADDITIVE
458 if (effects & 32)
459 {
460 effects &= ~32;
461 light[0] = (int)(0.2*256);
462 light[1] = (int)(1.0*256);
463 light[2] = (int)(0.2*256);
464 light[3] = 200;
465 lightpflags |= PFLAGS_FULLDYNAMIC;
466 }
467 }
468
469 specialvisibilityradius = 0;
470 if (lightpflags & PFLAGS_FULLDYNAMIC)
471 specialvisibilityradius = max(specialvisibilityradius, light[3]);
472 if (glowsize)
473 specialvisibilityradius = max(specialvisibilityradius, glowsize * 4);
475 specialvisibilityradius = max(specialvisibilityradius, 100);
477 {
479 specialvisibilityradius = max(specialvisibilityradius, 80);
481 specialvisibilityradius = max(specialvisibilityradius, 100);
483 specialvisibilityradius = max(specialvisibilityradius, 400);
484 if (effects & EF_DIMLIGHT)
485 specialvisibilityradius = max(specialvisibilityradius, 200);
486 if (effects & EF_RED)
487 specialvisibilityradius = max(specialvisibilityradius, 200);
488 if (effects & EF_BLUE)
489 specialvisibilityradius = max(specialvisibilityradius, 200);
490 if (effects & EF_FLAME)
491 specialvisibilityradius = max(specialvisibilityradius, 250);
492 if (effects & EF_STARDUST)
493 specialvisibilityradius = max(specialvisibilityradius, 100);
494 }
495
496 // early culling checks
497 // (final culling is done by SV_MarkWriteEntityStateToClient)
498 customizeentityforclient = PRVM_serveredictfunction(ent, customizeentityforclient);
499 if (!customizeentityforclient && enumber > svs.maxclients && (!modelindex && !specialvisibilityradius))
500 return false;
501
502 *cs = defaultstate;
504 cs->number = enumber;
507 cs->flags = flags;
508 cs->effects = effects;
509 cs->colormap = (unsigned)PRVM_serveredictfloat(ent, colormap);
511 cs->skin = (unsigned)PRVM_serveredictfloat(ent, skin);
512 cs->frame = (unsigned)PRVM_serveredictfloat(ent, frame);
517 cs->customizeentityforclient = customizeentityforclient;
519 cs->tagindex = (unsigned char)PRVM_serveredictfloat(ent, tag_index);
520 cs->glowsize = glowsize;
522
523 // don't need to init cs->colormod because the defaultstate did that for us
524 //cs->colormod[0] = cs->colormod[1] = cs->colormod[2] = 32;
526 if (VectorLength2(v))
527 {
528 i = (int)(v[0] * 32.0f);cs->colormod[0] = bound(0, i, 255);
529 i = (int)(v[1] * 32.0f);cs->colormod[1] = bound(0, i, 255);
530 i = (int)(v[2] * 32.0f);cs->colormod[2] = bound(0, i, 255);
531 }
532
533 // don't need to init cs->glowmod because the defaultstate did that for us
534 //cs->glowmod[0] = cs->glowmod[1] = cs->glowmod[2] = 32;
536 if (VectorLength2(v))
537 {
538 i = (int)(v[0] * 32.0f);cs->glowmod[0] = bound(0, i, 255);
539 i = (int)(v[1] * 32.0f);cs->glowmod[1] = bound(0, i, 255);
540 i = (int)(v[2] * 32.0f);cs->glowmod[2] = bound(0, i, 255);
541 }
542
544
545 cs->alpha = 255;
546 f = (PRVM_serveredictfloat(ent, alpha) * 255.0f);
547 if (f)
548 {
549 i = (int)f;
550 cs->alpha = (unsigned char)bound(0, i, 255);
551 }
552 // halflife
553 f = (PRVM_serveredictfloat(ent, renderamt));
554 if (f)
555 {
556 i = (int)f;
557 cs->alpha = (unsigned char)bound(0, i, 255);
558 }
559
560 cs->scale = 16;
561 f = (PRVM_serveredictfloat(ent, scale) * 16.0f);
562 if (f)
563 {
564 i = (int)f;
565 cs->scale = (unsigned char)bound(0, i, 255);
566 }
567
568 cs->glowcolor = 254;
570 if (f)
571 cs->glowcolor = (int)f;
572
573 if (PRVM_serveredictfloat(ent, fullbright))
574 cs->effects |= EF_FULLBRIGHT;
575
577 if (f)
578 cs->effects |= ((unsigned int)f & 0xff) << 24;
579
581 cs->flags |= RENDER_STEP;
582 if (cs->number != sv.writeentitiestoclient_cliententitynumber && (cs->effects & EF_LOWPRECISION) && cs->origin[0] >= -32768 && cs->origin[1] >= -32768 && cs->origin[2] >= -32768 && cs->origin[0] <= 32767 && cs->origin[1] <= 32767 && cs->origin[2] <= 32767)
584 if (PRVM_serveredictfloat(ent, colormap) >= 1024)
586 if (cs->viewmodelforclient)
587 cs->flags |= RENDER_VIEWMODEL; // show relative to the view
588
589 if (PRVM_serveredictfloat(ent, sendcomplexanimation))
590 {
593 cs->skeletonobject = ent->priv.server->skeleton;
605 cs->framegroupblend[0].lerp = 1.0f - cs->framegroupblend[1].lerp - cs->framegroupblend[2].lerp - cs->framegroupblend[3].lerp;
606 cs->frame = 0; // don't need the legacy frame
607 }
608
609 cs->light[0] = light[0];
610 cs->light[1] = light[1];
611 cs->light[2] = light[2];
612 cs->light[3] = light[3];
613 cs->lightstyle = lightstyle;
614 cs->lightpflags = lightpflags;
615
616 cs->specialvisibilityradius = specialvisibilityradius;
617
618 // calculate the visible box of this entity (don't use the physics box
619 // as that is often smaller than a model, and would not count
620 // specialvisibilityradius)
621 if ((model = SV_GetModelByIndex(modelindex)) && (model->type != mod_null))
622 {
623 float scale = cs->scale * (1.0f / 16.0f);
624 if (cs->angles[0] || cs->angles[2]) // pitch and roll
625 {
626 VectorMA(cs->origin, scale, model->rotatedmins, cullmins);
627 VectorMA(cs->origin, scale, model->rotatedmaxs, cullmaxs);
628 }
629 else if (cs->angles[1] || ((effects | model->effects) & EF_ROTATE))
630 {
631 VectorMA(cs->origin, scale, model->yawmins, cullmins);
632 VectorMA(cs->origin, scale, model->yawmaxs, cullmaxs);
633 }
634 else
635 {
636 VectorMA(cs->origin, scale, model->normalmins, cullmins);
637 VectorMA(cs->origin, scale, model->normalmaxs, cullmaxs);
638 }
639 }
640 else
641 {
642 // if there is no model (or it could not be loaded), use the physics box
643 VectorAdd(cs->origin, PRVM_serveredictvector(ent, mins), cullmins);
644 VectorAdd(cs->origin, PRVM_serveredictvector(ent, maxs), cullmaxs);
645 }
646 if (specialvisibilityradius)
647 {
648 cullmins[0] = min(cullmins[0], cs->origin[0] - specialvisibilityradius);
649 cullmins[1] = min(cullmins[1], cs->origin[1] - specialvisibilityradius);
650 cullmins[2] = min(cullmins[2], cs->origin[2] - specialvisibilityradius);
651 cullmaxs[0] = max(cullmaxs[0], cs->origin[0] + specialvisibilityradius);
652 cullmaxs[1] = max(cullmaxs[1], cs->origin[1] + specialvisibilityradius);
653 cullmaxs[2] = max(cullmaxs[2], cs->origin[2] + specialvisibilityradius);
654 }
655
656 // calculate center of bbox for network prioritization purposes
657 VectorMAM(0.5f, cullmins, 0.5f, cullmaxs, cs->netcenter);
658
659 // if culling box has moved, update pvs cluster links
660 if (!VectorCompare(cullmins, ent->priv.server->cullmins) || !VectorCompare(cullmaxs, ent->priv.server->cullmaxs))
661 {
662 VectorCopy(cullmins, ent->priv.server->cullmins);
663 VectorCopy(cullmaxs, ent->priv.server->cullmaxs);
664 // a value of -1 for pvs_numclusters indicates that the links are not
665 // cached, and should be re-tested each time, this is the case if the
666 // culling box touches too many pvs clusters to store, or if the world
667 // model does not support FindBoxClusters
668 ent->priv.server->pvs_numclusters = -1;
669 if (sv.worldmodel && sv.worldmodel->brush.FindBoxClusters)
670 {
671 i = sv.worldmodel->brush.FindBoxClusters(sv.worldmodel, cullmins, cullmaxs, MAX_ENTITYCLUSTERS, ent->priv.server->pvs_clusterlist);
672 if (i <= MAX_ENTITYCLUSTERS)
673 ent->priv.server->pvs_numclusters = i;
674 }
675 }
676
677 // we need to do some csqc entity upkeep here
678 // get self.SendFlags and clear them
679 // (to let the QC know that they've been read)
680 if (sendentity)
681 {
682 sendflags = (unsigned int)PRVM_serveredictfloat(ent, SendFlags);
683 PRVM_serveredictfloat(ent, SendFlags) = 0;
684 // legacy self.Version system
685 if ((version = (unsigned int)PRVM_serveredictfloat(ent, Version)))
686 {
687 if (sv.csqcentityversion[enumber] != version)
688 sendflags = 0xFFFFFF;
689 sv.csqcentityversion[enumber] = version;
690 }
691 // move sendflags into the per-client sendflags
692 if (sendflags)
693 for (i = 0;i < svs.maxclients;i++)
694 svs.clients[i].csqcentitysendflags[enumber] |= sendflags;
695 // mark it as inactive for non-csqc networking
696 cs->active = ACTIVE_SHARED;
697 }
698
699 return true;
700}
701
703{
704 prvm_prog_t *prog = SVVM_prog;
705 int e;
706 prvm_edict_t *ent;
707 // send all entities that touch the pvs
710 memset(sv.sendentitiesindex, 0, prog->num_edicts * sizeof(*sv.sendentitiesindex));
711 for (e = 1, ent = PRVM_NEXT_EDICT(prog->edicts);e < prog->num_edicts;e++, ent = PRVM_NEXT_EDICT(ent))
712 {
714 {
717 }
718 }
719}
720
721#define MAX_LINEOFSIGHTTRACES 64
722
723qbool SV_CanSeeBox(int numtraces, vec_t eyejitter, vec_t enlarge, vec_t entboxexpand, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs)
724{
725 prvm_prog_t *prog = SVVM_prog;
726 float pitchsign;
727 float alpha;
728 float starttransformed[3], endtransformed[3];
729 float boxminstransformed[3], boxmaxstransformed[3];
730 float localboxcenter[3], localboxextents[3], localboxmins[3], localboxmaxs[3];
731 int blocked = 0;
732 int traceindex;
733 int originalnumtouchedicts;
734 int numtouchedicts = 0;
735 int touchindex;
736 matrix4x4_t matrix, imatrix;
737 model_t *model;
738 prvm_edict_t *touch;
739 static prvm_edict_t *touchedicts[MAX_EDICTS];
740 vec3_t eyemins, eyemaxs, start;
741 vec3_t boxmins, boxmaxs;
742 vec3_t clipboxmins, clipboxmaxs;
743 vec3_t endpoints[MAX_LINEOFSIGHTTRACES];
744
745 numtraces = min(numtraces, MAX_LINEOFSIGHTTRACES);
746
747 // jitter the eye location within this box
748 eyemins[0] = eye[0] - eyejitter;
749 eyemaxs[0] = eye[0] + eyejitter;
750 eyemins[1] = eye[1] - eyejitter;
751 eyemaxs[1] = eye[1] + eyejitter;
752 eyemins[2] = eye[2] - eyejitter;
753 eyemaxs[2] = eye[2] + eyejitter;
754 // expand the box a little
755 boxmins[0] = (enlarge+1) * entboxmins[0] - enlarge * entboxmaxs[0] - entboxexpand;
756 boxmaxs[0] = (enlarge+1) * entboxmaxs[0] - enlarge * entboxmins[0] + entboxexpand;
757 boxmins[1] = (enlarge+1) * entboxmins[1] - enlarge * entboxmaxs[1] - entboxexpand;
758 boxmaxs[1] = (enlarge+1) * entboxmaxs[1] - enlarge * entboxmins[1] + entboxexpand;
759 boxmins[2] = (enlarge+1) * entboxmins[2] - enlarge * entboxmaxs[2] - entboxexpand;
760 boxmaxs[2] = (enlarge+1) * entboxmaxs[2] - enlarge * entboxmins[2] + entboxexpand;
761
762 VectorMAM(0.5f, boxmins, 0.5f, boxmaxs, endpoints[0]);
763 for (traceindex = 1;traceindex < numtraces;traceindex++)
764 VectorSet(endpoints[traceindex], lhrandom(boxmins[0], boxmaxs[0]), lhrandom(boxmins[1], boxmaxs[1]), lhrandom(boxmins[2], boxmaxs[2]));
765
766 // calculate sweep box for the entire swarm of traces
767 VectorCopy(eyemins, clipboxmins);
768 VectorCopy(eyemaxs, clipboxmaxs);
769 for (traceindex = 0;traceindex < numtraces;traceindex++)
770 {
771 clipboxmins[0] = min(clipboxmins[0], endpoints[traceindex][0]);
772 clipboxmins[1] = min(clipboxmins[1], endpoints[traceindex][1]);
773 clipboxmins[2] = min(clipboxmins[2], endpoints[traceindex][2]);
774 clipboxmaxs[0] = max(clipboxmaxs[0], endpoints[traceindex][0]);
775 clipboxmaxs[1] = max(clipboxmaxs[1], endpoints[traceindex][1]);
776 clipboxmaxs[2] = max(clipboxmaxs[2], endpoints[traceindex][2]);
777 }
778
779 // get the list of entities in the sweep box
781 numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
782 if (numtouchedicts > MAX_EDICTS)
783 {
784 // this never happens
785 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
786 numtouchedicts = MAX_EDICTS;
787 }
788 // iterate the entities found in the sweep box and filter them
789 originalnumtouchedicts = numtouchedicts;
790 numtouchedicts = 0;
791 for (touchindex = 0;touchindex < originalnumtouchedicts;touchindex++)
792 {
793 touch = touchedicts[touchindex];
795 continue;
797 if (!model || !model->brush.TraceLineOfSight)
798 continue;
799 // skip obviously transparent entities
801 if (alpha && alpha < 1)
802 continue;
803 if ((int)PRVM_serveredictfloat(touch, effects) & EF_ADDITIVE)
804 continue;
805 touchedicts[numtouchedicts++] = touch;
806 }
807
808 // now that we have a filtered list of "interesting" entities, fire each
809 // ray against all of them, this gives us an early-out case when something
810 // is visible (which it often is)
811
812 for (traceindex = 0;traceindex < numtraces;traceindex++)
813 {
814 VectorSet(start, lhrandom(eyemins[0], eyemaxs[0]), lhrandom(eyemins[1], eyemaxs[1]), lhrandom(eyemins[2], eyemaxs[2]));
815 // check world occlusion
816 if (sv.worldmodel && sv.worldmodel->brush.TraceLineOfSight)
817 if (!sv.worldmodel->brush.TraceLineOfSight(sv.worldmodel, start, endpoints[traceindex], boxmins, boxmaxs))
818 continue;
819 for (touchindex = 0;touchindex < numtouchedicts;touchindex++)
820 {
821 touch = touchedicts[touchindex];
823 if(model && model->brush.TraceLineOfSight)
824 {
825 // get the entity matrix
826 pitchsign = SV_GetPitchSign(prog, touch);
828 Matrix4x4_Invert_Simple(&imatrix, &matrix);
829 // see if the ray hits this entity
830 Matrix4x4_Transform(&imatrix, start, starttransformed);
831 Matrix4x4_Transform(&imatrix, endpoints[traceindex], endtransformed);
832 Matrix4x4_Transform(&imatrix, boxmins, boxminstransformed);
833 Matrix4x4_Transform(&imatrix, boxmaxs, boxmaxstransformed);
834 // transform the AABB to local space
835 VectorMAM(0.5f, boxminstransformed, 0.5f, boxmaxstransformed, localboxcenter);
836 localboxextents[0] = fabs(boxmaxstransformed[0] - localboxcenter[0]);
837 localboxextents[1] = fabs(boxmaxstransformed[1] - localboxcenter[1]);
838 localboxextents[2] = fabs(boxmaxstransformed[2] - localboxcenter[2]);
839 localboxmins[0] = localboxcenter[0] - localboxextents[0];
840 localboxmins[1] = localboxcenter[1] - localboxextents[1];
841 localboxmins[2] = localboxcenter[2] - localboxextents[2];
842 localboxmaxs[0] = localboxcenter[0] + localboxextents[0];
843 localboxmaxs[1] = localboxcenter[1] + localboxextents[1];
844 localboxmaxs[2] = localboxcenter[2] + localboxextents[2];
845 if (!model->brush.TraceLineOfSight(model, starttransformed, endtransformed, localboxmins, localboxmaxs))
846 {
847 blocked++;
848 break;
849 }
850 }
851 }
852 // check if the ray was blocked
853 if (touchindex < numtouchedicts)
854 continue;
855 // return if the ray was not blocked
856 return true;
857 }
858
859 // no rays survived
860 return false;
861}
862
864{
865 prvm_prog_t *prog = SVVM_prog;
866 int isbmodel;
867 model_t *model;
868 prvm_edict_t *ed;
870 return;
873
875 {
879 prog->ExecuteProgram(prog, s->customizeentityforclient, "customizeentityforclient: NULL function");
881 return;
882 }
883
884 // never reject player
886 {
887 // check various rejection conditions
889 return;
891 return;
892 if (s->effects & EF_NODRAW)
893 return;
894 // LadyHavoc: only send entities with a model or important effects
895 if (!s->modelindex && s->specialvisibilityradius == 0)
896 return;
897
898 isbmodel = (model = SV_GetModelByIndex(s->modelindex)) != NULL && model->name[0] == '*';
899 // viewmodels don't have visibility checking
900 if (s->viewmodelforclient)
901 {
903 return;
904 }
905 else if (s->tagentity)
906 {
907 // tag attached entities simply check their parent
909 return;
912 return;
913 }
914 // always send world submodels in newer protocols because they don't
915 // generate much traffic (in old protocols they hog bandwidth)
916 // but only if sv_cullentities_nevercullbmodels is off
918 {
919 // entity has survived every check so far, check if visible
920 ed = PRVM_EDICT_NUM(s->number);
921
922 // if not touching a visible leaf
924 {
925 if (ed->priv.server->pvs_numclusters < 0)
926 {
927 // entity too big for clusters list
928 if (sv.worldmodel && sv.worldmodel->brush.BoxTouchingPVS && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, sv.writeentitiestoclient_pvs, ed->priv.server->cullmins, ed->priv.server->cullmaxs))
929 {
931 return;
932 }
933 }
934 else
935 {
936 int i;
937 // check cached clusters list
938 for (i = 0;i < ed->priv.server->pvs_numclusters;i++)
939 if (CHECKPVSBIT(sv.writeentitiestoclient_pvs, ed->priv.server->pvs_clusterlist[i]))
940 break;
941 if (i == ed->priv.server->pvs_numclusters)
942 {
944 return;
945 }
946 }
947 }
948
949 // or not seen by random tracelines
950 if (sv_cullentities_trace.integer && !isbmodel && sv.worldmodel && sv.worldmodel->brush.TraceLineOfSight && !r_trippy.integer && (client->frags != -666 || sv_cullentities_trace_spectators.integer))
951 {
952 int samples =
953 s->number <= svs.maxclients
955 :
959
960 if(samples > 0)
961 {
962 int eyeindex;
963 for (eyeindex = 0;eyeindex < sv.writeentitiestoclient_numeyes;eyeindex++)
965 break;
966 if(eyeindex < sv.writeentitiestoclient_numeyes)
968 host.realtime + (
969 s->number <= svs.maxclients
972 );
973 else if ((float)host.realtime > svs.clients[sv.writeentitiestoclient_clientnumber].visibletime[s->number])
974 {
976 return;
977 }
978 }
979 }
980 }
981 }
982
983 // this just marks it for sending
984 // FIXME: it would be more efficient to send here, but the entity
985 // compressor isn't that flexible
988}
989
990#if MAX_LEVELNETWORKEYES > 0
991#define MAX_EYE_RECURSION 1 // increase if recursion gets supported by portals
992void SV_AddCameraEyes(void)
993{
994 prvm_prog_t *prog = SVVM_prog;
995 int e, i, j, k;
996 prvm_edict_t *ed;
997 int cameras[MAX_LEVELNETWORKEYES];
998 vec3_t camera_origins[MAX_LEVELNETWORKEYES];
999 int eye_levels[MAX_CLIENTNETWORKEYES] = {0};
1000 int n_cameras = 0;
1001 vec3_t mi, ma;
1002
1003 // check line of sight to portal entities and add them to PVS
1004 for (e = 1, ed = PRVM_NEXT_EDICT(prog->edicts);e < prog->num_edicts;e++, ed = PRVM_NEXT_EDICT(ed))
1005 {
1006 if (!ed->free)
1007 {
1008 if(PRVM_serveredictfunction(ed, camera_transform))
1009 {
1016 prog->ExecuteProgram(prog, PRVM_serveredictfunction(ed, camera_transform), "QC function e.camera_transform is missing");
1018 {
1019 VectorCopy(PRVM_serverglobalvector(trace_endpos), camera_origins[n_cameras]);
1020 cameras[n_cameras] = e;
1021 ++n_cameras;
1022 if(n_cameras >= MAX_LEVELNETWORKEYES)
1023 break;
1024 }
1025 }
1026 }
1027 }
1028
1029 if(!n_cameras)
1030 return;
1031
1032 // i is loop counter, is reset to 0 when an eye got added
1033 // j is camera index to check
1034 for(i = 0, j = 0; sv.writeentitiestoclient_numeyes < MAX_CLIENTNETWORKEYES && i < n_cameras; ++i, ++j, j %= n_cameras)
1035 {
1036 if(!cameras[j])
1037 continue;
1038 ed = PRVM_EDICT_NUM(cameras[j]);
1041 for(k = 0; k < sv.writeentitiestoclient_numeyes; ++k)
1042 if(eye_levels[k] <= MAX_EYE_RECURSION)
1043 {
1046
1047 // bones_was_here: this use of visibletime doesn't conflict because sv_cullentities_trace doesn't consider portal entities
1048 // the explicit cast prevents float precision differences that cause the condition to fail
1049 if ((float)host.realtime <= svs.clients[sv.writeentitiestoclient_clientnumber].visibletime[cameras[j]])
1050 {
1051 eye_levels[sv.writeentitiestoclient_numeyes] = eye_levels[k] + 1;
1053 // Con_Printf("added eye %d: %f %f %f because we can see %f %f %f .. %f %f %f from eye %d\n", j, sv.writeentitiestoclient_eyes[sv.writeentitiestoclient_numeyes][0], sv.writeentitiestoclient_eyes[sv.writeentitiestoclient_numeyes][1], sv.writeentitiestoclient_eyes[sv.writeentitiestoclient_numeyes][2], mi[0], mi[1], mi[2], ma[0], ma[1], ma[2], k);
1055 cameras[j] = 0;
1056 i = 0;
1057 break;
1058 }
1059 }
1060 }
1061}
1062#else
1064{
1065}
1066#endif
1067
1068/*
1069=============
1070SV_CleanupEnts
1071
1072=============
1073*/
1074static void SV_CleanupEnts (void)
1075{
1076 prvm_prog_t *prog = SVVM_prog;
1077 int e;
1078 prvm_edict_t *ent;
1079
1080 ent = PRVM_NEXT_EDICT(prog->edicts);
1081 for (e=1 ; e<prog->num_edicts ; e++, ent = PRVM_NEXT_EDICT(ent))
1082 PRVM_serveredictfloat(ent, effects) = (int)PRVM_serveredictfloat(ent, effects) & ~EF_MUZZLEFLASH;
1083}
1084
1085/*
1086==================
1087SV_WriteClientdataToMessage
1088
1089==================
1090*/
1091void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1092{
1093 prvm_prog_t *prog = SVVM_prog;
1094 int bits;
1095 int i;
1097 int items;
1099 int viewzoom;
1100 const char *s;
1101 float *statsf = (float *)stats;
1102 float gravity;
1103
1104//
1105// send a damage message
1106//
1108 {
1113 for (i=0 ; i<3 ; i++)
1115
1118 }
1119
1120//
1121// send the current viewpos offset from the view entity
1122//
1123 SV_SetIdealPitch (); // how much to look up / down ideally
1124
1125// a fixangle might get lost in a dropped packet. Oh well.
1127 {
1128 // angle fixing was requested by global thinking code...
1129 // so store the current angles for later use
1132
1133 // and clear fixangle for the next frame
1135 }
1136
1138 {
1140 for (i=0 ; i < 3 ; i++)
1143 }
1144
1145 // the runes are in serverflags, pack them into the items value, also pack
1146 // in the items2 value for mission pack huds
1147 // (used only in the mission packs, which do not use serverflags)
1149 | (((int)PRVM_serveredictfloat(ent, items2) & ((1<<9)-1)) << 23)
1150 | (((int)PRVM_serverglobalfloat(serverflags) & ((1<<4)-1)) << 28);
1151
1153
1154 // cache weapon model name and index in client struct to save time
1155 // (this search can be almost 1% of cpu time!)
1157 if (strcmp(s, client->weaponmodel))
1158 {
1159 dp_strlcpy(client->weaponmodel, s, sizeof(client->weaponmodel));
1160 client->weaponmodelindex = SV_ModelIndex(s, 1);
1161 }
1162
1163 viewzoom = (int)(PRVM_serveredictfloat(ent, viewzoom) * 255.0f);
1164 if (viewzoom == 0)
1165 viewzoom = 255;
1166
1167 bits = 0;
1168
1169 if ((int)PRVM_serveredictfloat(ent, flags) & FL_ONGROUND)
1170 bits |= SU_ONGROUND;
1171 if (PRVM_serveredictfloat(ent, waterlevel) >= 2)
1172 bits |= SU_INWATER;
1174 bits |= SU_IDEALPITCH;
1175
1176 for (i=0 ; i<3 ; i++)
1177 {
1179 bits |= (SU_PUNCH1<<i);
1181 if (punchvector[i])
1182 bits |= (SU_PUNCHVEC1<<i);
1184 bits |= (SU_VELOCITY1<<i);
1185 }
1186
1187 gravity = PRVM_serveredictfloat(ent, gravity);if (!gravity) gravity = 1.0f;
1188
1189 memset(stats, 0, sizeof(int[MAX_CL_STATS]));
1191 stats[STAT_ITEMS] = items;
1194 stats[STAT_WEAPON] = client->weaponmodelindex;
1202 stats[STAT_VIEWZOOM] = viewzoom;
1205 // the QC bumps these itself by sending svc_'s, so we have to keep them
1206 // zero or they'll be corrected by the engine
1207 //stats[STAT_SECRETS] = PRVM_serverglobalfloat(found_secrets);
1208 //stats[STAT_MONSTERS] = PRVM_serverglobalfloat(killed_monsters);
1209
1210 if(!sv_qcstats.integer)
1211 {
1217 // movement settings for prediction
1218 // note: these are not sent in protocols with lower MAX_CL_STATS limits
1223 ;
1233 statsf[STAT_FRAGLIMIT] = fraglimit.value;
1234 statsf[STAT_TIMELIMIT] = timelimit.value;
1242 statsf[STAT_MOVEVARS_SPECTATORMAXSPEED] = sv_maxspeed.value; // FIXME: QW has a separate cvar for this
1246 statsf[STAT_MOVEVARS_ENTGRAVITY] = gravity;
1253 }
1254
1256 {
1257 if (stats[STAT_VIEWHEIGHT] != DEFAULT_VIEWHEIGHT) bits |= SU_VIEWHEIGHT;
1258 bits |= SU_ITEMS;
1259 if (stats[STAT_WEAPONFRAME]) bits |= SU_WEAPONFRAME;
1260 if (stats[STAT_ARMOR]) bits |= SU_ARMOR;
1261 bits |= SU_WEAPON;
1262 // FIXME: which protocols support this? does PROTOCOL_DARKPLACES3 support viewzoom?
1264 if (viewzoom != 255)
1265 bits |= SU_VIEWZOOM;
1266 }
1267
1268 if (bits >= 65536)
1269 bits |= SU_EXTEND1;
1270 if (bits >= 16777216)
1271 bits |= SU_EXTEND2;
1272
1273 // send the data
1275 MSG_WriteShort (msg, bits);
1276 if (bits & SU_EXTEND1)
1277 MSG_WriteByte(msg, bits >> 16);
1278 if (bits & SU_EXTEND2)
1279 MSG_WriteByte(msg, bits >> 24);
1280
1281 if (bits & SU_VIEWHEIGHT)
1282 MSG_WriteChar (msg, stats[STAT_VIEWHEIGHT]);
1283
1284 if (bits & SU_IDEALPITCH)
1286
1287 for (i=0 ; i<3 ; i++)
1288 {
1289 if (bits & (SU_PUNCH1<<i))
1290 {
1293 else
1295 }
1296 if (bits & (SU_PUNCHVEC1<<i))
1297 {
1300 else
1302 }
1303 if (bits & (SU_VELOCITY1<<i))
1304 {
1306 MSG_WriteChar(msg, (int)(PRVM_serveredictvector(ent, velocity)[i] * (1.0f / 16.0f)));
1307 else
1309 }
1310 }
1311
1312 if (bits & SU_ITEMS)
1313 MSG_WriteLong (msg, stats[STAT_ITEMS]);
1314
1316 {
1317 if (bits & SU_WEAPONFRAME)
1318 MSG_WriteShort (msg, stats[STAT_WEAPONFRAME]);
1319 if (bits & SU_ARMOR)
1320 MSG_WriteShort (msg, stats[STAT_ARMOR]);
1321 if (bits & SU_WEAPON)
1322 MSG_WriteShort (msg, stats[STAT_WEAPON]);
1323 MSG_WriteShort (msg, stats[STAT_HEALTH]);
1324 MSG_WriteShort (msg, stats[STAT_AMMO]);
1325 MSG_WriteShort (msg, stats[STAT_SHELLS]);
1326 MSG_WriteShort (msg, stats[STAT_NAILS]);
1327 MSG_WriteShort (msg, stats[STAT_ROCKETS]);
1328 MSG_WriteShort (msg, stats[STAT_CELLS]);
1329 MSG_WriteShort (msg, stats[STAT_ACTIVEWEAPON]);
1330 if (bits & SU_VIEWZOOM)
1331 MSG_WriteShort (msg, bound(0, stats[STAT_VIEWZOOM], 65535));
1332 }
1334 {
1335 if (bits & SU_WEAPONFRAME)
1336 MSG_WriteByte (msg, stats[STAT_WEAPONFRAME]);
1337 if (bits & SU_ARMOR)
1338 MSG_WriteByte (msg, stats[STAT_ARMOR]);
1339 if (bits & SU_WEAPON)
1340 {
1342 MSG_WriteShort (msg, stats[STAT_WEAPON]);
1343 else
1344 MSG_WriteByte (msg, stats[STAT_WEAPON]);
1345 }
1346 MSG_WriteShort (msg, stats[STAT_HEALTH]);
1347 MSG_WriteByte (msg, stats[STAT_AMMO]);
1348 MSG_WriteByte (msg, stats[STAT_SHELLS]);
1349 MSG_WriteByte (msg, stats[STAT_NAILS]);
1350 MSG_WriteByte (msg, stats[STAT_ROCKETS]);
1351 MSG_WriteByte (msg, stats[STAT_CELLS]);
1353 {
1354 for (i = 0;i < 32;i++)
1355 if (stats[STAT_ACTIVEWEAPON] & (1<<i))
1356 break;
1357 MSG_WriteByte (msg, i);
1358 }
1359 else
1360 MSG_WriteByte (msg, stats[STAT_ACTIVEWEAPON]);
1361 if (bits & SU_VIEWZOOM)
1362 {
1364 MSG_WriteByte (msg, bound(0, stats[STAT_VIEWZOOM], 255));
1365 else
1366 MSG_WriteShort (msg, bound(0, stats[STAT_VIEWZOOM], 65535));
1367 }
1368 }
1369}
1370
1372{
1373 int i;
1374 client_t *client;
1375 if (sv.datagram.cursize <= 0)
1376 return;
1377 for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
1378 {
1379 if (!client->begun || !client->netconnection || client->unreliablemsg.cursize + sv.datagram.cursize > client->unreliablemsg.maxsize || client->unreliablemsg_splitpoints >= (int)(sizeof(client->unreliablemsg_splitpoint)/sizeof(client->unreliablemsg_splitpoint[0])))
1380 continue;
1383 }
1385}
1386
1387static void SV_WriteUnreliableMessages(client_t *client, sizebuf_t *msg, int maxsize, int maxsize2)
1388{
1389 // scan the splitpoints to find out how many we can fit in
1390 int numsegments, j, split;
1391 if (!client->unreliablemsg_splitpoints)
1392 return;
1393 // always accept the first one if it's within 1024 bytes, this ensures
1394 // that very big datagrams which are over the rate limit still get
1395 // through, just to keep it working
1396 for (numsegments = 1;numsegments < client->unreliablemsg_splitpoints;numsegments++)
1397 if (msg->cursize + client->unreliablemsg_splitpoint[numsegments] > maxsize)
1398 break;
1399 // the first segment gets an exemption from the rate limiting, otherwise
1400 // it could get dropped consistently due to a low rate limit
1401 if (numsegments == 1)
1402 maxsize = maxsize2;
1403 // some will fit, so add the ones that will fit
1404 split = client->unreliablemsg_splitpoint[numsegments-1];
1405 // note this discards ones that were accepted by the segments scan but
1406 // can not fit, such as a really huge first one that will never ever
1407 // fit in a packet...
1408 if (msg->cursize + split <= maxsize)
1409 SZ_Write(msg, client->unreliablemsg.data, split);
1410 // remove the part we sent, keeping any remaining data
1411 client->unreliablemsg.cursize -= split;
1412 if (client->unreliablemsg.cursize > 0)
1413 memmove(client->unreliablemsg.data, client->unreliablemsg.data + split, client->unreliablemsg.cursize);
1414 // adjust remaining splitpoints
1415 client->unreliablemsg_splitpoints -= numsegments;
1416 for (j = 0;j < client->unreliablemsg_splitpoints;j++)
1417 client->unreliablemsg_splitpoint[j] = client->unreliablemsg_splitpoint[numsegments + j] - split;
1418}
1419
1420/*
1421=======================
1422SV_SendClientDatagram
1423=======================
1424*/
1425static void SV_SendClientDatagram (client_t *client)
1426{
1427 int clientrate, maxrate, maxsize, maxsize2, downloadsize;
1428 sizebuf_t msg;
1429 int stats[MAX_CL_STATS];
1430 static unsigned char sv_sendclientdatagram_buf[NET_MAXMESSAGE];
1431 double timedelta;
1432
1433 // obey rate limit by limiting packet frequency if the packet size
1434 // limiting fails
1435 // (usually this is caused by reliable messages)
1436 if (!NetConn_CanSend(client->netconnection))
1437 return;
1438
1439 // PROTOCOL_DARKPLACES5 and later support packet size limiting of updates
1440 maxrate = max(NET_MINRATE, sv_maxrate.integer);
1441 if (sv_maxrate.integer != maxrate)
1442 Cvar_SetValueQuick(&sv_maxrate, maxrate);
1443
1444 // clientrate determines the 'cleartime' of a packet
1445 // (how long to wait before sending another, based on this packet's size)
1446 clientrate = bound(NET_MINRATE, client->rate, maxrate);
1447
1448 switch (sv.protocol)
1449 {
1450 case PROTOCOL_QUAKE:
1451 case PROTOCOL_QUAKEDP:
1457 // no packet size limit support on Quake protocols because it just
1458 // causes missing entities/effects
1459 // packets are simply sent less often to obey the rate limit
1460 maxsize = 1024;
1461 maxsize2 = 1024;
1462 break;
1467 // no packet size limit support on DP1-4 protocols because they kick
1468 // the client off if they overflow, and miss effects
1469 // packets are simply sent less often to obey the rate limit
1470 maxsize = sizeof(sv_sendclientdatagram_buf);
1471 maxsize2 = sizeof(sv_sendclientdatagram_buf);
1472 break;
1473 default:
1474 // DP5 and later protocols support packet size limiting which is a
1475 // better method than limiting packet frequency as QW does
1476 //
1477 // at very low rates (or very small sys_ticrate) the packet size is
1478 // not reduced below 128, but packets may be sent less often
1479
1480 // how long are bursts?
1481 timedelta = host_client->rate_burstsize / (double)client->rate;
1482
1483 // how much of the burst do we keep reserved?
1484 timedelta *= 1 - net_burstreserve.value;
1485
1486 // only try to use excess time
1487 timedelta = bound(0, host.realtime - host_client->netconnection->cleartime, timedelta);
1488
1489 // but we know next packet will be in sys_ticrate, so we can use up THAT bandwidth
1490 timedelta += sys_ticrate.value;
1491
1492 // note: packet overhead (not counted in maxsize) is 28 bytes
1493 maxsize = (int)(clientrate * timedelta) - 28;
1494
1495 // put it in sound bounds
1496 maxsize = bound(128, maxsize, 1400);
1497 maxsize2 = 1400;
1498
1499 // csqc entities can easily exceed 128 bytes, so disable throttling in
1500 // mods that use csqc (they are likely to use less bandwidth anyway)
1502 maxsize = maxsize2;
1503
1504 break;
1505 }
1506
1508 {
1509 // for good singleplayer, send huge packets
1510 maxsize = sizeof(sv_sendclientdatagram_buf);
1511 maxsize2 = sizeof(sv_sendclientdatagram_buf);
1512 // never limit frequency in singleplayer
1513 clientrate = 1000000000;
1514 }
1515
1516 // while downloading, limit entity updates to half the packet
1517 // (any leftover space will be used for downloading)
1519 maxsize /= 2;
1520
1521 msg.data = sv_sendclientdatagram_buf;
1522 msg.maxsize = sizeof(sv_sendclientdatagram_buf);
1523 msg.cursize = 0;
1524 msg.allowoverflow = false;
1525
1526 if (host_client->begun)
1527 {
1528 // the player is in the game
1529 MSG_WriteByte (&msg, svc_time);
1530 MSG_WriteFloat (&msg, sv.time);
1531
1532 // add the client specific data to the datagram
1533 SV_WriteClientdataToMessage (client, client->edict, &msg, stats);
1534 // now update the stats[] array using any registered custom fields
1535 VM_SV_UpdateCustomStats(client, client->edict, &msg, stats);
1536 // set host_client->statsdeltabits
1538
1539 // add as many queued unreliable messages (effects) as we can fit
1540 // limit effects to half of the remaining space
1541 if (client->unreliablemsg.cursize)
1542 SV_WriteUnreliableMessages (client, &msg, maxsize/2, maxsize2);
1543
1544 // now write as many entities as we can fit, and also sends stats
1545 SV_WriteEntitiesToClient (client, client->edict, &msg, maxsize);
1546 }
1547 else if (host.realtime > client->keepalivetime)
1548 {
1549 // the player isn't totally in the game yet
1550 // send small keepalive messages if too much time has passed
1551 // (may also be sending downloads)
1552 client->keepalivetime = host.realtime + 5;
1553 MSG_WriteChar (&msg, svc_nop);
1554 }
1555
1556 // if a download is active, see if there is room to fit some download data
1557 // in this packet
1558 downloadsize = min(maxsize*2,maxsize2) - msg.cursize - 7;
1559 if (host_client->download_file && host_client->download_started && downloadsize > 0)
1560 {
1561 fs_offset_t downloadstart;
1562 unsigned char data[1400];
1563 downloadstart = FS_Tell(host_client->download_file);
1564 downloadsize = min(downloadsize, (int)sizeof(data));
1565 downloadsize = FS_Read(host_client->download_file, data, downloadsize);
1566 // note this sends empty messages if at the end of the file, which is
1567 // necessary to keep the packet loss logic working
1568 // (the last blocks may be lost and need to be re-sent, and that will
1569 // only occur if the client acks the empty end messages, revealing
1570 // a gap in the download progress, causing the last blocks to be
1571 // sent again)
1573 MSG_WriteLong (&msg, downloadstart);
1574 MSG_WriteShort (&msg, downloadsize);
1575 if (downloadsize > 0)
1576 SZ_Write (&msg, data, downloadsize);
1577 }
1578
1579 // reliable only if none is in progress
1580 if(client->sendsignon != 2 && !client->netconnection->sendMessageLength)
1581 SV_WriteDemoMessage(client, &(client->netconnection->message), false);
1582 // unreliable
1583 SV_WriteDemoMessage(client, &msg, false);
1584
1585// send the datagram
1586 NetConn_SendUnreliableMessage (client->netconnection, &msg, sv.protocol, clientrate, client->rate_burstsize, client->sendsignon == 2);
1587 if (client->sendsignon == 1 && !client->netconnection->message.cursize)
1588 client->sendsignon = 2; // prevent reliable until client sends prespawn (this is the keepalive phase)
1589}
1590
1591/*
1592=======================
1593SV_UpdateToReliableMessages
1594=======================
1595*/
1597{
1598 prvm_prog_t *prog = SVVM_prog;
1599 int i, j;
1600 client_t *client;
1601 const char *name;
1602 const char *model;
1603 const char *skin;
1604 int clientcamera;
1605
1606// check for changes to be sent over the reliable streams
1607 for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
1608 {
1609 // update the host_client fields we care about according to the entity fields
1611
1612 // DP_SV_CLIENTNAME
1614 if (name == NULL)
1615 name = "";
1616 // always point the string back at host_client->name to keep it safe
1617 //strlcpy (host_client->name, name, sizeof (host_client->name));
1618 if (name != host_client->name) // prevent buffer overlap SIGABRT on Mac OSX
1620 SV_Name(i);
1621
1622 // DP_SV_CLIENTCOLORS
1625 {
1627 // send notification to all clients
1631 }
1632
1633 // NEXUIZ_PLAYERMODEL
1635 if (model == NULL)
1636 model = "";
1637 // always point the string back at host_client->name to keep it safe
1638 //strlcpy (host_client->playermodel, model, sizeof (host_client->playermodel));
1639 if (model != host_client->playermodel) // prevent buffer overlap SIGABRT on Mac OSX
1642
1643 // NEXUIZ_PLAYERSKIN
1645 if (skin == NULL)
1646 skin = "";
1647 // always point the string back at host_client->name to keep it safe
1648 //strlcpy (host_client->playerskin, skin, sizeof (host_client->playerskin));
1649 if (skin != host_client->playerskin) // prevent buffer overlap SIGABRT on Mac OSX
1652
1653 // TODO: add an extension name for this [1/17/2008 Black]
1655 if (clientcamera > 0)
1656 {
1657 int oldclientcamera = host_client->clientcamera;
1658 if (clientcamera >= prog->max_edicts || PRVM_EDICT_NUM(clientcamera)->free)
1661
1662 if (oldclientcamera != host_client->clientcamera && host_client->netconnection)
1663 {
1666 }
1667 }
1668
1669 // frags
1673 host_client->frags = -666;
1675 {
1677 // send notification to all clients
1681 }
1682 }
1683
1684 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1685 if (client->netconnection && (client->begun || client->clientconnectcalled)) // also send MSG_ALL to people who are past ClientConnect, but not spawned yet
1687
1689}
1690
1691
1692/*
1693=======================
1694SV_SendClientMessages
1695=======================
1696*/
1698{
1699 int i, prepared = false;
1700
1702 Sys_Error("SV_SendClientMessages: no quakeworld support\n");
1703
1705
1706// update frags, names, etc
1708
1709// build individual updates
1710 for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
1711 {
1712 if (!host_client->active)
1713 continue;
1715 continue;
1716
1718 {
1719 SV_DropClient (true, "Buffer overflow in net message"); // if the message couldn't send, kick off
1720 continue;
1721 }
1722
1723 if (!prepared)
1724 {
1725 prepared = true;
1726 // only prepare entities once per frame
1728 }
1730 }
1731
1732// clear muzzle flashes
1734}
cvar_t host_timescale
Definition sv_main.c:228
gamemode_t gamemode
Definition com_game.c:26
#define IS_OLDNEXUIZ_DERIVED(g)
Definition com_game.h:73
@ GAME_QUOTH
Definition com_game.h:31
@ GAME_ROGUE
Definition com_game.h:30
@ GAME_TENEBRAE
full of evil hackery
Definition com_game.h:41
@ GAME_HIPNOTIC
Definition com_game.h:29
void MSG_WriteCoord32f(sizebuf_t *sb, float f)
Definition com_msg.c:197
void MSG_WriteShort(sizebuf_t *sb, int c)
Definition com_msg.c:138
void MSG_WriteString(sizebuf_t *sb, const char *s)
Definition com_msg.c:173
void MSG_WriteAngle16i(sizebuf_t *sb, float f)
Definition com_msg.c:227
void MSG_WriteLong(sizebuf_t *sb, int c)
Definition com_msg.c:147
void MSG_WriteCoord(sizebuf_t *sb, float f, protocolversion_t protocol)
Definition com_msg.c:202
void MSG_WriteByte(sizebuf_t *sb, int c)
Definition com_msg.c:130
void MSG_WriteFloat(sizebuf_t *sb, float f)
Definition com_msg.c:158
void MSG_WriteAngle(sizebuf_t *sb, float f, protocolversion_t protocol)
Definition com_msg.c:237
void MSG_WriteChar(sizebuf_t *sb, int c)
Definition com_msg.c:122
void MSG_WriteCoord16i(sizebuf_t *sb, float f)
Definition com_msg.c:192
void SZ_Clear(sizebuf_t *buf)
Definition common.c:44
int dpvsnprintf(char *buffer, size_t buffersize, const char *format, va_list args)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:1010
void SZ_Write(sizebuf_t *buf, const unsigned char *data, int length)
Definition common.c:72
@ PROTOCOL_DARKPLACES2
various changes
Definition common.h:140
@ PROTOCOL_DARKPLACES4
various changes
Definition common.h:138
@ PROTOCOL_NEHAHRABJP2
same as NEHAHRABJP but with 16bit soundindex
Definition common.h:147
@ PROTOCOL_DARKPLACES3
uses EntityFrame4 entity snapshot encoder/decoder which is broken, this attempted to do partial snaps...
Definition common.h:139
@ PROTOCOL_NEHAHRABJP
same as QUAKEDP but with 16bit modelindex
Definition common.h:146
@ PROTOCOL_DARKPLACES5
uses EntityFrame5 entity snapshot encoder/decoder which is based on a Tribes networking article at ht...
Definition common.h:137
@ PROTOCOL_QUAKEDP
darkplaces extended quake protocol (used by TomazQuake and others), backwards compatible as long as n...
Definition common.h:142
@ PROTOCOL_QUAKE
quake (aka netquake/normalquake/nq) protocol
Definition common.h:144
@ PROTOCOL_NEHAHRABJP3
same as NEHAHRABJP2 but with some changes
Definition common.h:148
@ PROTOCOL_NEHAHRAMOVIE
Nehahra movie protocol, a big nasty hack dating back to early days of the Quake Standards Group (but ...
Definition common.h:143
@ PROTOCOL_QUAKEWORLD
quakeworld protocol
Definition common.h:145
@ PROTOCOL_DARKPLACES1
uses EntityFrame entity snapshot encoder/decoder which is a QuakeWorld-like entity snapshot delta com...
Definition common.h:141
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1504
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
float movetype
float flags
float frame3time
float frame1time
entity other
float modelindex
entity self
string netname
float frame2time
float frame2
float lerpfrac
float frame3
float lerpfrac4
vector mins
float frame4time
vector velocity
float lerpfrac3
float effects
float skin
float skeletonindex
float time
vector trace_endpos
vector maxs
vector angles
float colormap
float frame4
vector origin
string model
entity() spawn
float solid
float frame
void Cvar_SetValueQuick(cvar_t *var, float value)
Definition cvar.c:473
float traileffectnum
float light_lev
entity drawonlytoclient
float scale
float style
entity viewmodelforclient
string playerskin
float pflags
float glow_size
entity tag_entity
vector color
float idealpitch
float glow_trail
float glow_color
float modelflags
vector glowmod
float viewzoom
entity exteriormodeltoclient
entity nodrawtoclient
vector punchvector
float tag_index
float alpha
string playermodel
vector colormod
float clientcolors
entity clientcamera
fs_offset_t FS_Read(qfile_t *file, void *buffer, size_t buffersize)
Definition fs.c:3066
fs_offset_t FS_Tell(qfile_t *file)
Definition fs.c:3461
static int(ZEXPORT *qz_inflate)(z_stream *strm
static int const char * version
Definition fs.c:479
int64_t fs_offset_t
Definition fs.h:37
GLsizei samples
Definition glquake.h:623
const GLdouble * v
Definition glquake.h:762
GLenum GLenum GLsizei count
Definition glquake.h:656
GLsizeiptr const GLvoid * data
Definition glquake.h:639
const GLchar * name
Definition glquake.h:601
host_static_t host
Definition host.c:41
cvar_t host_isclient
Definition host.c:61
@ LHNETADDRESSTYPE_LOOP
Definition lhnet.h:13
static lhnetaddresstype_t LHNETADDRESS_GetAddressType(const lhnetaddress_t *address)
Definition lhnet.h:31
#define max(A, B)
Definition mathlib.h:38
#define min(A, B)
Definition mathlib.h:37
#define VectorClear(a)
Definition mathlib.h:97
#define bound(min, num, max)
Definition mathlib.h:34
#define lhrandom(MIN, MAX)
LadyHavoc: this function never returns exactly MIN or exactly MAX, because of a QuakeC bug in id1 whe...
Definition mathlib.h:48
#define VectorLength2(a)
Definition mathlib.h:110
#define VectorSet(vec, x, y, z)
Definition mathlib.h:96
#define VectorCompare(a, b)
Definition mathlib.h:113
#define VectorCopy(in, out)
Definition mathlib.h:101
#define VectorMAM(scale1, b1, scale2, b2, out)
Definition mathlib.h:116
#define VectorAdd(a, b, out)
Definition mathlib.h:100
#define VectorMA(a, scale, b, out)
Definition mathlib.h:114
void Matrix4x4_Transform(const matrix4x4_t *in, const float v[3], float out[3])
Definition matrixlib.c:1657
void Matrix4x4_CreateFromQuakeEntity(matrix4x4_t *out, double x, double y, double z, double pitch, double yaw, double roll, double scale)
Definition matrixlib.c:715
void Matrix4x4_Invert_Simple(matrix4x4_t *out, const matrix4x4_t *in1)
Definition matrixlib.c:422
float fabs(float f)
float floor(float f)
cvar_t r_novis
Definition model_brush.c:31
cvar_t r_trippy
Definition model_brush.c:29
#define CHECKPVSBIT(pvs, b)
@ mod_null
cvar_t net_burstreserve
Definition netconn.c:80
qbool NetConn_CanSend(netconn_t *conn)
Definition netconn.c:789
cvar_t net_usesizelimit
Definition netconn.c:79
int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolversion_t protocol, int rate, int burstsize, qbool quakesignon_suppressreliables)
Definition netconn.c:844
#define OFS_RETURN
Definition pr_comp.h:33
#define OFS_PARM0
Definition pr_comp.h:34
#define OFS_PARM1
Definition pr_comp.h:35
#define MAX_ENTITYCLUSTERS
Definition progs.h:28
float ammo_rockets
Definition progsdefs.qc:143
float frags
Definition progsdefs.qc:138
float serverflags
Definition progsdefs.qc:33
vector punchangle
Definition progsdefs.qc:117
float weapon
Definition progsdefs.qc:139
float ammo_shells
Definition progsdefs.qc:143
float dmg_take
Definition progsdefs.qc:198
float total_secrets
Definition progsdefs.qc:36
vector view_ofs
Definition progsdefs.qc:151
float health
Definition progsdefs.qc:137
float waterlevel
Definition progsdefs.qc:181
float weaponframe
Definition progsdefs.qc:141
float items
Definition progsdefs.qc:145
float armorvalue
Definition progsdefs.qc:179
float fixangle
Definition progsdefs.qc:160
float total_monsters
Definition progsdefs.qc:37
float ammo_nails
Definition progsdefs.qc:143
float currentammo
Definition progsdefs.qc:142
float ammo_cells
Definition progsdefs.qc:143
string weaponmodel
Definition progsdefs.qc:140
float dmg_save
Definition progsdefs.qc:199
entity dmg_inflictor
Definition progsdefs.qc:200
#define PRVM_serveredictvector(ed, fieldname)
Definition progsvm.h:173
#define PRVM_serverglobaledict(fieldname)
Definition progsvm.h:180
#define PRVM_serveredictedict(ed, fieldname)
Definition progsvm.h:175
int PRVM_SetEngineString(prvm_prog_t *prog, const char *s)
#define PRVM_EDICT_NUM(n)
Definition progsvm.h:867
#define PRVM_NEXT_EDICT(e)
Definition progsvm.h:873
const char * PRVM_GetString(prvm_prog_t *prog, int num)
#define PRVM_NUM_FOR_EDICT(e)
Definition progsvm.h:870
#define PRVM_PROG_TO_EDICT(n)
Definition progsvm.h:877
#define PRVM_serverglobalfloat(fieldname)
Definition progsvm.h:177
#define PRVM_serveredictfloat(ed, fieldname)
Definition progsvm.h:172
#define PRVM_serveredictstring(ed, fieldname)
Definition progsvm.h:174
#define PRVM_serveredictfunction(ed, fieldname)
Definition progsvm.h:176
#define PRVM_G_FLOAT(o)
Definition progsvm.h:882
#define PRVM_serverglobalvector(fieldname)
Definition progsvm.h:178
#define PRVM_G_VECTOR(o)
Definition progsvm.h:886
#define SVVM_prog
Definition progsvm.h:766
void Protocol_UpdateClientStats(const int *stats)
Definition protocol.c:118
entity_state_t defaultstate
Definition protocol.c:4
#define SU_VELOCITY1
Definition protocol.h:157
#define svc_particle
Definition protocol.h:237
#define svc_setview
Definition protocol.h:219
#define svc_print
Definition protocol.h:222
#define svc_nop
Definition protocol.h:215
#define EF_FULLBRIGHT
Definition protocol.h:77
#define SU_VIEWHEIGHT
Definition protocol.h:152
#define EF_BRIGHTFIELD
Definition protocol.h:68
#define SU_WEAPON
Definition protocol.h:166
#define SU_WEAPONFRAME
Definition protocol.h:164
#define SND_ATTENUATION
Definition protocol.h:190
#define svc_updatefrags
Definition protocol.h:233
#define SU_EXTEND1
Definition protocol.h:167
#define EF_NODEPTHTEST
Definition protocol.h:81
#define SU_IDEALPITCH
Definition protocol.h:153
#define EF_STARDUST
Definition protocol.h:79
#define EF_ADDITIVE
Definition protocol.h:73
#define svc_downloaddata
Definition protocol.h:269
#define svc_stufftext
Definition protocol.h:223
#define SU_PUNCH1
Definition protocol.h:154
#define SU_PUNCHVEC1
Definition protocol.h:169
#define svc_sound
Definition protocol.h:220
#define RENDER_VIEWMODEL
Definition protocol.h:358
#define EF_BRIGHTLIGHT
Definition protocol.h:70
#define SU_ITEMS
Definition protocol.h:161
#define DEFAULT_VIEWHEIGHT
Definition protocol.h:198
#define SND_VOLUME
Definition protocol.h:189
#define RENDER_COMPLEXANIMATION
Definition protocol.h:363
#define svc_setangle
Definition protocol.h:225
#define EF_LOWPRECISION
Definition protocol.h:90
#define SU_INWATER
no data follows, the bit is it
Definition protocol.h:163
#define PFLAGS_FULLDYNAMIC
Definition protocol.h:108
#define EF_NODRAW
Definition protocol.h:72
#define SND_SPEEDUSHORT4000
Definition protocol.h:194
#define RENDER_GLOWTRAIL
Definition protocol.h:357
#define svc_damage
Definition protocol.h:238
#define SND_LARGEENTITY
Definition protocol.h:192
#define svc_time
Definition protocol.h:221
#define SU_EXTEND2
another byte to follow, future expansion
Definition protocol.h:176
#define RENDER_COLORMAPPED
Definition protocol.h:361
#define SU_VIEWZOOM
byte factor (0 = 0.0 (not valid), 255 = 1.0)
Definition protocol.h:172
#define svc_updatecolors
Definition protocol.h:236
#define SU_ONGROUND
no data follows, the bit is it
Definition protocol.h:162
#define svc_effect
Definition protocol.h:271
#define EF_ROTATE
Definition protocol.h:95
#define RENDER_LOWPRECISION
Definition protocol.h:360
#define svc_clientdata
Definition protocol.h:234
@ ACTIVE_SHARED
Definition protocol.h:434
@ ACTIVE_NETWORK
Definition protocol.h:433
#define RENDER_STEP
Definition protocol.h:356
#define SND_LARGESOUND
Definition protocol.h:193
#define SU_ARMOR
Definition protocol.h:165
#define EF_FLAME
Definition protocol.h:78
#define svc_effect2
Definition protocol.h:272
#define EF_RED
Definition protocol.h:75
#define EF_BLUE
Definition protocol.h:74
#define EF_MUZZLEFLASH
Definition protocol.h:69
#define EF_DIMLIGHT
Definition protocol.h:71
int i
#define MAX_INPUTLINE
maximum size of console commandline, QuakeC strings, and many other text processing buffers
Definition qdefs.h:94
#define MAX_EDICTS
max number of objects in game world at once (32768 protocol limit)
Definition qdefs.h:105
#define NET_MAXMESSAGE
max reliable packet size (sent as multiple fragments of MAX_PACKETFRAGMENT)
Definition qdefs.h:103
#define NET_MINRATE
limits "rate" and "sv_maxrate" cvars
Definition qdefs.h:180
#define MAX_PACKETFRAGMENT
max length of packet fragment
Definition qdefs.h:104
#define MAX_LEVELNETWORKEYES
max number of locations that can be added to pvs when culling network entities (must be at least 2 fo...
Definition qdefs.h:123
#define MAX_CLIENTNETWORKEYES
max number of locations that can be added to pvs when culling network entities (must be at least 2 fo...
Definition qdefs.h:122
#define MAX_MODELS
max number of models loaded at once (including during level transitions)
Definition qdefs.h:106
#define STAT_MOVEVARS_WARSOWBUNNY_ACCEL
DP.
Definition qstats.h:37
#define STAT_WEAPONFRAME
Definition qstats.h:13
#define STAT_MOVEFLAGS
DP.
Definition qstats.h:35
#define STAT_MOVEVARS_MAXAIRSPEED
DP.
Definition qstats.h:62
#define STAT_HEALTH
Definition qstats.h:8
#define STAT_MOVEVARS_AIRACCELERATE
DP.
Definition qstats.h:57
#define STAT_MOVEVARS_WATERACCELERATE
DP.
Definition qstats.h:58
#define STAT_SHELLS
Definition qstats.h:14
#define STAT_TOTALMONSTERS
Definition qstats.h:20
#define STAT_MOVEVARS_AIRACCEL_QW
DP.
Definition qstats.h:64
#define STAT_MOVEVARS_AIRSTOPACCELERATE
DP.
Definition qstats.h:41
#define STAT_MOVEVARS_TIMESCALE
DP.
Definition qstats.h:51
#define STAT_NAILS
Definition qstats.h:15
#define STAT_MOVEVARS_AIRSTRAFEACCEL_QW
DP.
Definition qstats.h:33
#define STAT_MOVEVARS_AIRCONTROL
DP.
Definition qstats.h:44
#define STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO
DP.
Definition qstats.h:40
#define STAT_MOVEVARS_GRAVITY
DP.
Definition qstats.h:52
#define STAT_MOVEVARS_AIRSTRAFEACCELERATE
DP.
Definition qstats.h:42
#define STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR
DP.
Definition qstats.h:30
#define STAT_MOVEVARS_TICRATE
DP.
Definition qstats.h:50
#define STAT_TOTALSECRETS
Definition qstats.h:19
#define STAT_FRAGLIMIT
DP.
Definition qstats.h:45
#define STAT_ACTIVEWEAPON
Definition qstats.h:18
#define STAT_MOVEVARS_SPECTATORMAXSPEED
DP.
Definition qstats.h:55
#define STAT_MOVEVARS_MAXSPEED
DP.
Definition qstats.h:54
#define STAT_CELLS
Definition qstats.h:17
#define STAT_MOVEVARS_STEPHEIGHT
DP.
Definition qstats.h:63
#define STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW
DP.
Definition qstats.h:32
#define STAT_MOVEVARS_AIRCONTROL_PENALTY
DP.
Definition qstats.h:31
#define STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION
DP.
Definition qstats.h:65
#define STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL
DP.
Definition qstats.h:36
#define STAT_MOVEVARS_MAXAIRSTRAFESPEED
DP.
Definition qstats.h:43
#define STAT_MOVEVARS_STOPSPEED
DP.
Definition qstats.h:53
#define STAT_MOVEVARS_ACCELERATE
DP.
Definition qstats.h:56
#define STAT_ARMOR
Definition qstats.h:12
#define MAX_CL_STATS
Definition qstats.h:7
#define STAT_MOVEVARS_ENTGRAVITY
DP.
Definition qstats.h:59
#define STAT_AMMO
Definition qstats.h:11
#define STAT_MOVEVARS_WATERFRICTION
DP.
Definition qstats.h:49
#define STAT_MOVEVARS_EDGEFRICTION
DP.
Definition qstats.h:61
#define STAT_TIMELIMIT
DP.
Definition qstats.h:46
#define STAT_MOVEVARS_AIRCONTROL_POWER
DP.
Definition qstats.h:34
#define STAT_ITEMS
FTE, DP.
Definition qstats.h:23
#define STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL
DP.
Definition qstats.h:39
#define STAT_WEAPON
Definition qstats.h:10
#define STAT_MOVEVARS_JUMPVELOCITY
DP.
Definition qstats.h:60
#define STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED
DP.
Definition qstats.h:38
#define STAT_ROCKETS
Definition qstats.h:16
#define STAT_MOVEVARS_FRICTION
DP.
Definition qstats.h:48
#define STAT_VIEWZOOM
DP.
Definition qstats.h:27
#define STAT_VIEWHEIGHT
FTE, DP.
Definition qstats.h:24
#define NULL
Definition qtypes.h:12
float vec_t
Definition qtypes.h:68
vec_t vec3_t[3]
Definition qtypes.h:71
bool qbool
Definition qtypes.h:9
float prvm_vec_t
Definition qtypes.h:55
#define MOVEFLAG_Q2AIRACCELERATE
Definition quakedef.h:33
#define MOVEFLAG_NOGRAVITYONGROUND
Definition quakedef.h:34
#define MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE
Definition quakedef.h:35
#define MOVEFLAG_VALID
Definition quakedef.h:32
#define FL_MONSTER
movement is smoothed on the client side by step based interpolation
Definition server.h:362
cvar_t sv_waterfriction
Definition sv_main.c:157
server_t sv
local server
Definition sv_main.c:223
int SV_SoundIndex(const char *s, int precachemode)
Definition sv_main.c:1474
cvar_t sv_airaccel_qw
Definition sv_main.c:57
cvar_t sv_maxairstrafespeed
Definition sv_main.c:64
cvar_t sv_airstopaccelerate
Definition sv_main.c:61
cvar_t sv_cullentities_trace_enlarge
Definition sv_main.c:87
cvar_t sv_maxairspeed
Definition sv_main.c:140
cvar_t timelimit
Definition sv_main.c:173
cvar_t sv_cullentities_pvs
Definition sv_main.c:82
void SV_SetIdealPitch(void)
Definition sv_user.c:239
void VM_SV_UpdateCustomStats(client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
Definition svvm_cmds.c:1723
cvar_t sv_jumpvelocity
Definition sv_main.c:138
cvar_t sv_airspeedlimit_nonqw
Definition sv_main.c:62
cvar_t sv_aircontrol
Definition sv_main.c:66
cvar_t sv_maxrate
Definition sv_main.c:141
void SV_Name(int clientnum)
Definition sv_ccmds.c:868
int SV_ModelIndex(const char *s, int precachemode)
Definition sv_main.c:1411
cvar_t sv_gameplayfix_nogravityonground
Definition sv_main.c:120
cvar_t sv_wateraccelerate
Definition sv_main.c:156
model_t * SV_GetModelByIndex(int modelindex)
Definition sv_main.c:1607
cvar_t sv_aircontrol_penalty
Definition sv_main.c:68
cvar_t sv_cullentities_nevercullbmodels
Definition sv_main.c:81
cvar_t sys_ticrate
Definition sv_main.c:166
cvar_t sv_maxspeed
Definition sv_main.c:142
int SV_EntitiesInBox(const vec3_t mins, const vec3_t maxs, int maxedicts, prvm_edict_t **resultedicts)
Definition sv_phys.c:673
cvar_t sv_airstrafeaccelerate
Definition sv_main.c:63
void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, sizebuf_t *msg, int maxsize)
Definition sv_ents.c:337
cvar_t sv_gameplayfix_gravityunaffectedbyticrate
Definition sv_main.c:111
cvar_t sv_gameplayfix_q2airaccelerate
Definition sv_main.c:119
cvar_t sv_aircontrol_power
Definition sv_main.c:67
int SV_GetPitchSign(prvm_prog_t *prog, prvm_edict_t *ent)
Definition sv_phys.c:47
void SV_DropClient(qbool leaving, const char *reason,...)
Definition sv_main.c:1018
cvar_t sv_airstrafeaccel_qw
Definition sv_main.c:65
cvar_t sv_edgefriction
Definition sv_main.c:100
model_t * SV_GetModelFromEdict(prvm_edict_t *ed)
Definition sv_main.c:1612
cvar_t sv_stepheight
Definition sv_main.c:153
server_static_t svs
persistant server info
Definition sv_main.c:224
cvar_t host_limitlocal
Definition sv_main.c:150
cvar_t fraglimit
Definition sv_main.c:45
cvar_t sv_cullentities_trace_samples
Definition sv_main.c:93
cvar_t sv_gravity
Definition sv_main.c:134
cvar_t sv_cullentities_trace
Definition sv_main.c:84
cvar_t sv_friction
Definition sv_main.c:103
cvar_t sv_cullentities_trace_samples_extra
Definition sv_main.c:94
#define FL_ONGROUND
Definition server.h:366
#define MOVETYPE_STEP
gravity, special edge handling, special step based client side interpolation
Definition server.h:316
cvar_t sv_stopspeed
Definition sv_main.c:154
cvar_t sv_airaccel_sideways_friction
Definition sv_main.c:59
client_t * host_client
Definition sv_main.c:29
cvar_t sv_airaccelerate
Definition sv_main.c:60
cvar_t sv_accelerate
Definition sv_main.c:55
cvar_t sv_cullentities_trace_delay
Definition sv_main.c:85
#define SOLID_BSP
bsp clip, touch on edge, block
Definition server.h:336
cvar_t sv_echobprint
Definition sv_main.c:99
vec2 dir
float f
#define DEFAULT_SOUND_PACKET_ATTENUATION
Definition sound.h:33
#define CHAN_ENGINE2NET(c)
Definition sound.h:85
#define DEFAULT_SOUND_PACKET_VOLUME
Definition sound.h:32
#define IS_CHAN(n)
Definition sound.h:82
char playermodel[MAX_QPATH]
Definition server.h:238
qbool active
false = empty client slot
Definition server.h:185
int colors
Definition server.h:236
qbool begun
false = don't send datagrams
Definition server.h:193
char weaponmodel[MAX_QPATH]
cache weaponmodel name lookups
Definition server.h:266
double keepalivetime
keepalive messages must be sent periodically during signon
Definition server.h:207
int unreliablemsg_splitpoint[NET_MAXMESSAGE/16]
Definition server.h:283
int old_colors
Definition server.h:236
int old_frags
Definition server.h:237
qbool clientconnectcalled
false = don't do ClientDisconnect on drop
Definition server.h:187
int unreliablemsg_splitpoints
Definition server.h:282
int frags
Definition server.h:237
int rate
requested rate in bytes per second
Definition server.h:198
int sendsignon
1 = send svc_serverinfo and advance to 2, 2 doesn't send, then advances to 0 (allowing unlimited send...
Definition server.h:195
qbool fixangle_angles_set
Definition server.h:293
char playerskin[MAX_QPATH]
Definition server.h:239
char name[MAX_SCOREBOARDNAME]
Definition server.h:235
sizebuf_t unreliablemsg
Definition server.h:281
int weaponmodelindex
Definition server.h:267
int clientcamera
clientcamera (entity to use as camera)
Definition server.h:270
qfile_t * download_file
Definition server.h:286
netconn_t * netconnection
communications handle
Definition server.h:210
int rate_burstsize
temporarily exceed rate by this amount of bytes
Definition server.h:201
vec3_t fixangle_angles
Definition server.h:294
prvm_edict_t * edict
PRVM_EDICT_NUM(clientnum+1)
Definition server.h:221
qbool download_started
Definition server.h:288
Definition cvar.h:66
float value
Definition cvar.h:74
int integer
Definition cvar.h:73
unsigned char glowmod[3]
Definition protocol.h:472
framegroupblend_t framegroupblend[4]
Definition protocol.h:474
unsigned char flags
Definition protocol.h:468
unsigned char skin
Definition protocol.h:463
unsigned char glowcolor
Definition protocol.h:467
unsigned short specialvisibilityradius
Definition protocol.h:452
unsigned char glowsize
Definition protocol.h:466
float origin[3]
Definition protocol.h:444
unsigned short tagentity
Definition protocol.h:451
unsigned short viewmodelforclient
Definition protocol.h:453
unsigned char lightstyle
Definition protocol.h:460
unsigned char colormap
Definition protocol.h:462
unsigned short modelindex
Definition protocol.h:449
unsigned short drawonlytoclient
Definition protocol.h:456
unsigned char colormod[3]
Definition protocol.h:471
unsigned short traileffectnum
Definition protocol.h:457
skeleton_t skeletonobject
Definition protocol.h:475
unsigned char alpha
Definition protocol.h:464
unsigned short nodrawtoclient
Definition protocol.h:455
unsigned short light[4]
Definition protocol.h:458
unsigned short exteriormodelforclient
Definition protocol.h:454
unsigned char tagindex
Definition protocol.h:470
float netcenter[3]
Definition protocol.h:443
float angles[3]
Definition protocol.h:445
unsigned char active
Definition protocol.h:459
unsigned short frame
Definition protocol.h:450
unsigned short number
Definition protocol.h:448
unsigned char scale
Definition protocol.h:465
unsigned int customizeentityforclient
Definition protocol.h:447
unsigned char lightpflags
Definition protocol.h:461
double realtime
the accumulated mainloop time since application started (with filtering), without any slowmo or clamp...
Definition host.h:46
lhnetaddress_t peeraddress
Definition netconn.h:147
double cleartime
Definition netconn.h:217
int sendMessageLength
reliable message that is currently sending (for building fragments)
Definition netconn.h:167
sizebuf_t message
writing buffer to send to peer as the next reliable message can be added to at any time,...
Definition netconn.h:161
qbool free
true if this edict is unused
Definition progsvm.h:93
union prvm_edict_t::@29 priv
struct edict_engineprivate_s * server
FIXME: this server pointer really means world, not server (it is used by both server qc and client qc...
Definition progsvm.h:106
int num_edicts
copies of some vars that were former read from sv
Definition progsvm.h:671
prvm_edict_t * edicts
Definition progsvm.h:680
int max_edicts
number of edicts for which space has been (should be) allocated
Definition progsvm.h:673
void(* ExecuteProgram)(struct prvm_prog_s *prog, func_t fnum, const char *errormessage)
pointer to one of the *VM_ExecuteProgram functions
Definition progsvm.h:749
struct client_s * clients
client slots
Definition server.h:30
int maxclients
number of svs.clients slots (updated by maxplayers command)
Definition server.h:28
double time
Definition server.h:76
unsigned char * writeentitiestoclient_pvs
Definition server.h:155
vec3_t writeentitiestoclient_eyes[MAX_CLIENTNETWORKEYES]
Definition server.h:153
int sententitiesconsideration[MAX_EDICTS]
Definition server.h:165
int writeentitiestoclient_stats_culled_pvs
Definition server.h:146
int sententitiesmark
Definition server.h:163
int writeentitiestoclient_stats_totalentities
Definition server.h:149
entity_state_t * sendentitiesindex[MAX_EDICTS]
Definition server.h:161
int sententities[MAX_EDICTS]
Definition server.h:164
int writeentitiestoclient_cliententitynumber
Definition server.h:150
sizebuf_t datagram
Definition server.h:126
int csqc_progsize
Definition server.h:102
sizebuf_t reliable_datagram
Definition server.h:130
int writeentitiestoclient_numeyes
Definition server.h:154
int numsendentities
Definition server.h:159
int writeentitiestoclient_stats_visibleentities
Definition server.h:148
entity_state_t sendentities[MAX_EDICTS]
Definition server.h:160
int writeentitiestoclient_stats_culled_trace
Definition server.h:147
struct model_s * worldmodel
Definition server.h:112
unsigned char csqcentityversion[MAX_EDICTS]
legacy support for self.Version based csqc entity networking
Definition server.h:168
struct model_s * models[MAX_MODELS]
Definition server.h:117
int writeentitiestoclient_clientnumber
Definition server.h:151
protocolversion_t protocol
one of the PROTOCOL_ values
Definition server.h:74
unsigned char * data
Definition common.h:52
int cursize
Definition common.h:54
qbool overflowed
set to true if the buffer size failed
Definition common.h:51
qbool allowoverflow
if false, do a Sys_Error
Definition common.h:50
int maxsize
Definition common.h:53
void SV_WriteDemoMessage(client_t *client, sizebuf_t *sendbuffer, qbool clienttoserver)
Definition sv_demo.c:32
static void SV_UpdateToReliableMessages(void)
Definition sv_send.c:1596
#define MAX_LINEOFSIGHTTRACES
Definition sv_send.c:721
static void SV_CleanupEnts(void)
Definition sv_send.c:1074
void SV_ClientPrintf(const char *fmt,...)
Definition sv_send.c:72
void SV_StartParticle(vec3_t org, vec3_t dir, int color, int count)
Definition sv_send.c:158
void SV_FlushBroadcastMessages(void)
Definition sv_send.c:1371
void SV_StartEffect(vec3_t org, int modelindex, int startframe, int framecount, int framerate)
Definition sv_send.c:182
qbool SV_CanSeeBox(int numtraces, vec_t eyejitter, vec_t enlarge, vec_t entboxexpand, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs)
Definition sv_send.c:723
void SV_AddCameraEyes(void)
Definition sv_send.c:1063
static void SV_SendClientDatagram(client_t *client)
Definition sv_send.c:1425
cvar_t sv_airaccel_qw_stretchfactor
Definition sv_main.c:58
cvar_t sv_warsowbunny_turnaccel
Definition sv_main.c:161
void SV_WriteClientdataToMessage(client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
Definition sv_send.c:1091
void SV_BroadcastPrintf(const char *fmt,...)
Definition sv_send.c:116
cvar_t sv_cullentities_trace_expand
Definition sv_main.c:88
cvar_t sv_cullentities_trace_eyejitter
Definition sv_main.c:89
void SV_ClientPrint(const char *msg)
Definition sv_send.c:55
void SV_StartSound(prvm_edict_t *entity, int channel, const char *sample, int nvolume, float attenuation, qbool reliable, float speed)
Definition sv_send.c:228
cvar_t sv_qcstats
Definition sv_main.c:148
cvar_t sv_warsowbunny_airforwardaccel
Definition sv_main.c:158
void SV_SendClientMessages(void)
Definition sv_send.c:1697
void SV_MarkWriteEntityStateToClient(entity_state_t *s, client_t *client)
Definition sv_send.c:863
void SV_ClientCommands(const char *fmt,...)
Definition sv_send.c:135
static qbool SV_PrepareEntityForSending(prvm_edict_t *ent, entity_state_t *cs, int enumber)
Definition sv_send.c:394
static void SV_PrepareEntitiesForSending(void)
Definition sv_send.c:702
void SV_BroadcastPrint(const char *msg)
Definition sv_send.c:91
void SV_StartPointSound(vec3_t origin, const char *sample, int nvolume, float attenuation, float speed)
Definition sv_send.c:320
cvar_t sv_warsowbunny_accel
Definition sv_main.c:159
cvar_t sv_cullentities_trace_entityocclusion
Definition sv_main.c:92
cvar_t sv_warsowbunny_backtosideratio
Definition sv_main.c:162
cvar_t sv_cullentities_trace_delay_players
Definition sv_main.c:86
cvar_t sv_cullentities_trace_samples_players
Definition sv_main.c:95
cvar_t sv_cullentities_trace_spectators
Definition sv_main.c:96
static void SV_WriteUnreliableMessages(client_t *client, sizebuf_t *msg, int maxsize, int maxsize2)
Definition sv_send.c:1387
cvar_t sv_onlycsqcnetworking
Definition sv_main.c:163
cvar_t sv_warsowbunny_topspeed
Definition sv_main.c:160
void Sys_Error(const char *error,...) DP_FUNC_PRINTF(1) DP_FUNC_NORETURN
Causes the entire program to exit ASAP.
Definition sys_shared.c:724