]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - sv_main.c
7aa15301af324b6d5e6c3f954dcde629bb2e0fc0
[xonotic/darkplaces.git] / sv_main.c
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 // sv_main.c -- server main program
21
22 #include "quakedef.h"
23
24 // select which protocol to host, by name
25 // this is named the same as PROTOCOL_DARKPLACES5 for example, minus the PROTOCOL_ prefix
26 cvar_t sv_protocolname = {0, "sv_protocolname", "DARKPLACES5"};
27 cvar_t sv_ratelimitlocalplayer = {0, "sv_ratelimitlocalplayer", "0"};
28 cvar_t sv_maxrate = {CVAR_SAVE | CVAR_NOTIFY, "sv_maxrate", "10000"};
29
30 static cvar_t sv_cullentities_pvs = {0, "sv_cullentities_pvs", "1"}; // fast but loose
31 static cvar_t sv_cullentities_trace = {0, "sv_cullentities_trace", "0"}; // tends to get false negatives, uses a timeout to keep entities visible a short time after becoming hidden
32 static cvar_t sv_cullentities_stats = {0, "sv_cullentities_stats", "0"};
33 static cvar_t sv_entpatch = {0, "sv_entpatch", "1"};
34
35 cvar_t sv_gameplayfix_grenadebouncedownslopes = {0, "sv_gameplayfix_grenadebouncedownslopes", "1"};
36 cvar_t sv_gameplayfix_noairborncorpse = {0, "sv_gameplayfix_noairborncorpse", "1"};
37 cvar_t sv_gameplayfix_stepdown = {0, "sv_gameplayfix_stepdown", "1"};
38 cvar_t sv_gameplayfix_stepwhilejumping = {0, "sv_gameplayfix_stepwhilejumping", "1"};
39 cvar_t sv_gameplayfix_swiminbmodels = {0, "sv_gameplayfix_swiminbmodels", "1"};
40
41 server_t sv;
42 server_static_t svs;
43
44 static char localmodels[MAX_MODELS][5];                 // inline model names for precache
45
46 mempool_t *sv_edicts_mempool = NULL;
47
48 //============================================================================
49
50 extern void SV_Phys_Init (void);
51 extern void SV_World_Init (void);
52 static void SV_SaveEntFile_f(void);
53
54 /*
55 ===============
56 SV_Init
57 ===============
58 */
59 void SV_Init (void)
60 {
61         int i;
62
63         Cmd_AddCommand("sv_saveentfile", SV_SaveEntFile_f);
64         Cvar_RegisterVariable (&sv_maxvelocity);
65         Cvar_RegisterVariable (&sv_gravity);
66         Cvar_RegisterVariable (&sv_friction);
67         Cvar_RegisterVariable (&sv_edgefriction);
68         Cvar_RegisterVariable (&sv_stopspeed);
69         Cvar_RegisterVariable (&sv_maxspeed);
70         Cvar_RegisterVariable (&sv_accelerate);
71         Cvar_RegisterVariable (&sv_idealpitchscale);
72         Cvar_RegisterVariable (&sv_aim);
73         Cvar_RegisterVariable (&sv_nostep);
74         Cvar_RegisterVariable (&sv_deltacompress);
75         Cvar_RegisterVariable (&sv_cullentities_pvs);
76         Cvar_RegisterVariable (&sv_cullentities_trace);
77         Cvar_RegisterVariable (&sv_cullentities_stats);
78         Cvar_RegisterVariable (&sv_entpatch);
79         Cvar_RegisterVariable (&sv_gameplayfix_grenadebouncedownslopes);
80         Cvar_RegisterVariable (&sv_gameplayfix_noairborncorpse);
81         Cvar_RegisterVariable (&sv_gameplayfix_stepdown);
82         Cvar_RegisterVariable (&sv_gameplayfix_stepwhilejumping);
83         Cvar_RegisterVariable (&sv_gameplayfix_swiminbmodels);
84         Cvar_RegisterVariable (&sv_protocolname);
85         Cvar_RegisterVariable (&sv_ratelimitlocalplayer);
86         Cvar_RegisterVariable (&sv_maxrate);
87
88         SV_Phys_Init();
89         SV_World_Init();
90
91         for (i = 0;i < MAX_MODELS;i++)
92                 sprintf (localmodels[i], "*%i", i);
93
94         sv_edicts_mempool = Mem_AllocPool("server edicts", 0, NULL);
95 }
96
97 static void SV_SaveEntFile_f(void)
98 {
99         char basename[MAX_QPATH];
100         if (!sv.active || !sv.worldmodel)
101         {
102                 Con_Print("Not running a server\n");
103                 return;
104         }
105         FS_StripExtension(sv.worldmodel->name, basename, sizeof(basename));
106         FS_WriteFile(va("%s.ent", basename), sv.worldmodel->brush.entities, strlen(sv.worldmodel->brush.entities));
107 }
108
109 /*
110 =============================================================================
111
112 EVENT MESSAGES
113
114 =============================================================================
115 */
116
117 /*
118 ==================
119 SV_StartParticle
120
121 Make sure the event gets sent to all clients
122 ==================
123 */
124 void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count)
125 {
126         int             i, v;
127
128         if (sv.datagram.cursize > MAX_PACKETFRAGMENT-18)
129                 return;
130         MSG_WriteByte (&sv.datagram, svc_particle);
131         MSG_WriteCoord (&sv.datagram, org[0], sv.protocol);
132         MSG_WriteCoord (&sv.datagram, org[1], sv.protocol);
133         MSG_WriteCoord (&sv.datagram, org[2], sv.protocol);
134         for (i=0 ; i<3 ; i++)
135         {
136                 v = dir[i]*16;
137                 if (v > 127)
138                         v = 127;
139                 else if (v < -128)
140                         v = -128;
141                 MSG_WriteChar (&sv.datagram, v);
142         }
143         MSG_WriteByte (&sv.datagram, count);
144         MSG_WriteByte (&sv.datagram, color);
145 }
146
147 /*
148 ==================
149 SV_StartEffect
150
151 Make sure the event gets sent to all clients
152 ==================
153 */
154 void SV_StartEffect (vec3_t org, int modelindex, int startframe, int framecount, int framerate)
155 {
156         if (modelindex >= 256 || startframe >= 256)
157         {
158                 if (sv.datagram.cursize > MAX_PACKETFRAGMENT-19)
159                         return;
160                 MSG_WriteByte (&sv.datagram, svc_effect2);
161                 MSG_WriteCoord (&sv.datagram, org[0], sv.protocol);
162                 MSG_WriteCoord (&sv.datagram, org[1], sv.protocol);
163                 MSG_WriteCoord (&sv.datagram, org[2], sv.protocol);
164                 MSG_WriteShort (&sv.datagram, modelindex);
165                 MSG_WriteShort (&sv.datagram, startframe);
166                 MSG_WriteByte (&sv.datagram, framecount);
167                 MSG_WriteByte (&sv.datagram, framerate);
168         }
169         else
170         {
171                 if (sv.datagram.cursize > MAX_PACKETFRAGMENT-17)
172                         return;
173                 MSG_WriteByte (&sv.datagram, svc_effect);
174                 MSG_WriteCoord (&sv.datagram, org[0], sv.protocol);
175                 MSG_WriteCoord (&sv.datagram, org[1], sv.protocol);
176                 MSG_WriteCoord (&sv.datagram, org[2], sv.protocol);
177                 MSG_WriteByte (&sv.datagram, modelindex);
178                 MSG_WriteByte (&sv.datagram, startframe);
179                 MSG_WriteByte (&sv.datagram, framecount);
180                 MSG_WriteByte (&sv.datagram, framerate);
181         }
182 }
183
184 /*
185 ==================
186 SV_StartSound
187
188 Each entity can have eight independant sound sources, like voice,
189 weapon, feet, etc.
190
191 Channel 0 is an auto-allocate channel, the others override anything
192 already running on that entity/channel pair.
193
194 An attenuation of 0 will play full volume everywhere in the level.
195 Larger attenuations will drop off.  (max 4 attenuation)
196
197 ==================
198 */
199 void SV_StartSound (edict_t *entity, int channel, char *sample, int volume, float attenuation)
200 {
201         int sound_num, field_mask, i, ent;
202
203         if (volume < 0 || volume > 255)
204                 Host_Error ("SV_StartSound: volume = %i", volume);
205
206         if (attenuation < 0 || attenuation > 4)
207                 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
208
209         if (channel < 0 || channel > 7)
210                 Host_Error ("SV_StartSound: channel = %i", channel);
211
212         if (sv.datagram.cursize > MAX_PACKETFRAGMENT-21)
213                 return;
214
215 // find precache number for sound
216         for (sound_num=1 ; sound_num<MAX_SOUNDS && sv.sound_precache[sound_num] ; sound_num++)
217                 if (!strcmp(sample, sv.sound_precache[sound_num]))
218                         break;
219
220         if ( sound_num == MAX_SOUNDS || !sv.sound_precache[sound_num] )
221         {
222                 Con_Printf("SV_StartSound: %s not precached\n", sample);
223                 return;
224         }
225
226         ent = NUM_FOR_EDICT(entity);
227
228         field_mask = 0;
229         if (volume != DEFAULT_SOUND_PACKET_VOLUME)
230                 field_mask |= SND_VOLUME;
231         if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION)
232                 field_mask |= SND_ATTENUATION;
233         if (ent >= 8192)
234                 field_mask |= SND_LARGEENTITY;
235         if (sound_num >= 256 || channel >= 8)
236                 field_mask |= SND_LARGESOUND;
237
238 // directed messages go only to the entity they are targeted on
239         MSG_WriteByte (&sv.datagram, svc_sound);
240         MSG_WriteByte (&sv.datagram, field_mask);
241         if (field_mask & SND_VOLUME)
242                 MSG_WriteByte (&sv.datagram, volume);
243         if (field_mask & SND_ATTENUATION)
244                 MSG_WriteByte (&sv.datagram, attenuation*64);
245         if (field_mask & SND_LARGEENTITY)
246         {
247                 MSG_WriteShort (&sv.datagram, ent);
248                 MSG_WriteByte (&sv.datagram, channel);
249         }
250         else
251                 MSG_WriteShort (&sv.datagram, (ent<<3) | channel);
252         if (field_mask & SND_LARGESOUND)
253                 MSG_WriteShort (&sv.datagram, sound_num);
254         else
255                 MSG_WriteByte (&sv.datagram, sound_num);
256         for (i = 0;i < 3;i++)
257                 MSG_WriteCoord (&sv.datagram, entity->v->origin[i]+0.5*(entity->v->mins[i]+entity->v->maxs[i]), sv.protocol);
258 }
259
260 /*
261 ==============================================================================
262
263 CLIENT SPAWNING
264
265 ==============================================================================
266 */
267
268 /*
269 ================
270 SV_SendServerinfo
271
272 Sends the first message from the server to a connected client.
273 This will be sent on the initial connection and upon each server load.
274 ================
275 */
276 void SV_SendServerinfo (client_t *client)
277 {
278         char                    **s;
279         char                    message[128];
280
281         // edicts get reallocated on level changes, so we need to update it here
282         client->edict = EDICT_NUM(client->number + 1);
283
284
285         // LordHavoc: clear entityframe tracking
286
287         if (client->entitydatabase)
288                 EntityFrame_FreeDatabase(client->entitydatabase);
289         if (client->entitydatabase4)
290                 EntityFrame4_FreeDatabase(client->entitydatabase4);
291         if (client->entitydatabase5)
292                 EntityFrame5_FreeDatabase(client->entitydatabase5);
293
294         if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3)
295                 client->entitydatabase = EntityFrame_AllocDatabase(sv_clients_mempool);
296         if (sv.protocol == PROTOCOL_DARKPLACES4)
297                 client->entitydatabase4 = EntityFrame4_AllocDatabase(sv_clients_mempool);
298         if (sv.protocol == PROTOCOL_DARKPLACES5)
299                 client->entitydatabase5 = EntityFrame5_AllocDatabase(sv_clients_mempool);
300
301         MSG_WriteByte (&client->message, svc_print);
302         snprintf (message, sizeof (message), "\002\nServer: %s build %s (progs %i crc)", gamename, buildstring, pr_crc);
303         MSG_WriteString (&client->message,message);
304
305         MSG_WriteByte (&client->message, svc_serverinfo);
306         MSG_WriteLong (&client->message, sv.protocol);
307         MSG_WriteByte (&client->message, svs.maxclients);
308
309         if (!coop.integer && deathmatch.integer)
310                 MSG_WriteByte (&client->message, GAME_DEATHMATCH);
311         else
312                 MSG_WriteByte (&client->message, GAME_COOP);
313
314         MSG_WriteString (&client->message,PR_GetString(sv.edicts->v->message));
315
316         for (s = sv.model_precache+1 ; *s ; s++)
317                 MSG_WriteString (&client->message, *s);
318         MSG_WriteByte (&client->message, 0);
319
320         for (s = sv.sound_precache+1 ; *s ; s++)
321                 MSG_WriteString (&client->message, *s);
322         MSG_WriteByte (&client->message, 0);
323
324 // send music
325         MSG_WriteByte (&client->message, svc_cdtrack);
326         MSG_WriteByte (&client->message, sv.edicts->v->sounds);
327         MSG_WriteByte (&client->message, sv.edicts->v->sounds);
328
329 // set view
330         MSG_WriteByte (&client->message, svc_setview);
331         MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict));
332
333         MSG_WriteByte (&client->message, svc_signonnum);
334         MSG_WriteByte (&client->message, 1);
335
336         client->sendsignon = true;
337         client->spawned = false;                // need prespawn, spawn, etc
338 }
339
340 /*
341 ================
342 SV_ConnectClient
343
344 Initializes a client_t for a new net connection.  This will only be called
345 once for a player each game, not once for each level change.
346 ================
347 */
348 void SV_ConnectClient (int clientnum, netconn_t *netconnection)
349 {
350         client_t                *client;
351         int                             i;
352         float                   spawn_parms[NUM_SPAWN_PARMS];
353
354         client = svs.clients + clientnum;
355
356 // set up the client_t
357         if (sv.loadgame)
358                 memcpy (spawn_parms, client->spawn_parms, sizeof(spawn_parms));
359         memset (client, 0, sizeof(*client));
360         client->active = true;
361         client->netconnection = netconnection;
362
363         Con_DPrintf("Client %s connected\n", client->netconnection->address);
364
365         strcpy(client->name, "unconnected");
366         strcpy(client->old_name, "unconnected");
367         client->number = clientnum;
368         client->spawned = false;
369         client->edict = EDICT_NUM(clientnum+1);
370         client->message.data = client->msgbuf;
371         client->message.maxsize = sizeof(client->msgbuf);
372         client->message.allowoverflow = true;           // we can catch it
373
374         if (sv.loadgame)
375                 memcpy (client->spawn_parms, spawn_parms, sizeof(spawn_parms));
376         else
377         {
378                 // call the progs to get default spawn parms for the new client
379                 PR_ExecuteProgram (pr_global_struct->SetNewParms, "QC function SetNewParms is missing");
380                 for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
381                         client->spawn_parms[i] = (&pr_global_struct->parm1)[i];
382         }
383
384         SV_SendServerinfo (client);
385 }
386
387
388 /*
389 ===============================================================================
390
391 FRAME UPDATES
392
393 ===============================================================================
394 */
395
396 /*
397 ==================
398 SV_ClearDatagram
399
400 ==================
401 */
402 void SV_ClearDatagram (void)
403 {
404         SZ_Clear (&sv.datagram);
405 }
406
407 /*
408 =============================================================================
409
410 The PVS must include a small area around the client to allow head bobbing
411 or other small motion on the client side.  Otherwise, a bob might cause an
412 entity that should be visible to not show up, especially when the bob
413 crosses a waterline.
414
415 =============================================================================
416 */
417
418 int sv_writeentitiestoclient_pvsbytes;
419 qbyte sv_writeentitiestoclient_pvs[MAX_MAP_LEAFS/8];
420
421 /*
422 =============
423 SV_WriteEntitiesToClient
424
425 =============
426 */
427 /*
428 void SV_WriteEntitiesToClient_QUAKE (client_t *client, edict_t *clent, sizebuf_t *msg)
429 {
430         int e, clentnum, bits, alpha, glowcolor, glowsize, scale, effects, lightsize;
431         int culled_pvs, culled_trace, visibleentities, totalentities;
432         qbyte *pvs;
433         vec3_t origin, angles, entmins, entmaxs, testorigin, testeye;
434         float nextfullupdate, alphaf;
435         edict_t *ent;
436         eval_t *val;
437         entity_state_t *baseline; // LordHavoc: delta or startup baseline
438         model_t *model;
439
440         Mod_CheckLoaded(sv.worldmodel);
441
442 // find the client's PVS
443         VectorAdd (clent->v->origin, clent->v->view_ofs, testeye);
444         fatbytes = 0;
445         if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
446                 fatbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, testeye, 8, sv_writeentitiestoclient_pvs, sizeof(sv_writeentitiestoclient_pvs));
447
448         culled_pvs = 0;
449         culled_trace = 0;
450         visibleentities = 0;
451         totalentities = 0;
452
453         clentnum = EDICT_TO_PROG(clent); // LordHavoc: for comparison purposes
454         // send all entities that touch the pvs
455         ent = NEXT_EDICT(sv.edicts);
456         for (e = 1;e < sv.num_edicts;e++, ent = NEXT_EDICT(ent))
457         {
458                 bits = 0;
459
460                 // prevent delta compression against this frame (unless actually sent, which will restore this later)
461                 nextfullupdate = client->nextfullupdate[e];
462                 client->nextfullupdate[e] = -1;
463
464                 if (ent != clent) // LordHavoc: always send player
465                 {
466                         if ((val = GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)) && val->edict)
467                         {
468                                 if (val->edict != clentnum)
469                                 {
470                                         // don't show to anyone else
471                                         continue;
472                                 }
473                                 else
474                                         bits |= U_VIEWMODEL; // show relative to the view
475                         }
476                         else
477                         {
478                                 // LordHavoc: never draw something told not to display to this client
479                                 if ((val = GETEDICTFIELDVALUE(ent, eval_nodrawtoclient)) && val->edict == clentnum)
480                                         continue;
481                                 if ((val = GETEDICTFIELDVALUE(ent, eval_drawonlytoclient)) && val->edict && val->edict != clentnum)
482                                         continue;
483                         }
484                 }
485
486                 glowsize = 0;
487
488                 if ((val = GETEDICTFIELDVALUE(ent, eval_glow_size)))
489                         glowsize = (int) val->_float >> 2;
490                 if (glowsize > 255) glowsize = 255;
491                 if (glowsize < 0) glowsize = 0;
492
493                 if ((val = GETEDICTFIELDVALUE(ent, eval_glow_trail)))
494                 if (val->_float != 0)
495                         bits |= U_GLOWTRAIL;
496
497                 if (ent->v->modelindex >= 0 && ent->v->modelindex < MAX_MODELS && *PR_GetString(ent->v->model))
498                 {
499                         model = sv.models[(int)ent->v->modelindex];
500                         Mod_CheckLoaded(model);
501                 }
502                 else
503                 {
504                         model = NULL;
505                         if (ent != clent) // LordHavoc: always send player
506                                 if (glowsize == 0 && (bits & U_GLOWTRAIL) == 0) // no effects
507                                         continue;
508                 }
509
510                 VectorCopy(ent->v->angles, angles);
511                 VectorCopy(ent->v->origin, origin);
512
513                 // ent has survived every check so far, check if it is visible
514                 if (ent != clent && ((bits & U_VIEWMODEL) == 0))
515                 {
516                         // use the predicted origin
517                         entmins[0] = origin[0] - 1.0f;
518                         entmins[1] = origin[1] - 1.0f;
519                         entmins[2] = origin[2] - 1.0f;
520                         entmaxs[0] = origin[0] + 1.0f;
521                         entmaxs[1] = origin[1] + 1.0f;
522                         entmaxs[2] = origin[2] + 1.0f;
523                         // using the model's bounding box to ensure things are visible regardless of their physics box
524                         if (model)
525                         {
526                                 if (ent->v->angles[0] || ent->v->angles[2]) // pitch and roll
527                                 {
528                                         VectorAdd(entmins, model->rotatedmins, entmins);
529                                         VectorAdd(entmaxs, model->rotatedmaxs, entmaxs);
530                                 }
531                                 else if (ent->v->angles[1])
532                                 {
533                                         VectorAdd(entmins, model->yawmins, entmins);
534                                         VectorAdd(entmaxs, model->yawmaxs, entmaxs);
535                                 }
536                                 else
537                                 {
538                                         VectorAdd(entmins, model->normalmins, entmins);
539                                         VectorAdd(entmaxs, model->normalmaxs, entmaxs);
540                                 }
541                         }
542
543                         totalentities++;
544
545                         // if not touching a visible leaf
546                         if (sv_cullentities_pvs.integer && fatbytes && sv.worldmodel && sv.worldmodel->brush.BoxTouchingPVS && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, sv_writeentitiestoclient_pvs, entmins, entmaxs))
547                         {
548                                 culled_pvs++;
549                                 continue;
550                         }
551
552                         // don't try to cull embedded brush models with this, they're sometimes huge (spanning several rooms)
553                         if (sv_cullentities_trace.integer && (model == NULL || model->name[0] != '*'))
554                         {
555                                 // LordHavoc: test random offsets, to maximize chance of detection
556                                 testorigin[0] = lhrandom(entmins[0], entmaxs[0]);
557                                 testorigin[1] = lhrandom(entmins[1], entmaxs[1]);
558                                 testorigin[2] = lhrandom(entmins[2], entmaxs[2]);
559
560                                 sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, testeye, testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
561                                 if (trace.fraction == 1)
562                                         client->visibletime[e] = realtime + 1;
563                                 else
564                                 {
565                                         //test nearest point on bbox
566                                         testorigin[0] = bound(entmins[0], testeye[0], entmaxs[0]);
567                                         testorigin[1] = bound(entmins[1], testeye[1], entmaxs[1]);
568                                         testorigin[2] = bound(entmins[2], testeye[2], entmaxs[2]);
569
570                                         sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, testeye, testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
571                                         if (trace.fraction == 1)
572                                                 client->visibletime[e] = realtime + 1;
573                                         else if (realtime > client->visibletime[e])
574                                         {
575                                                 culled_trace++;
576                                                 continue;
577                                         }
578                                 }
579                         }
580                         visibleentities++;
581                 }
582
583                 alphaf = 255.0f;
584                 scale = 16;
585                 glowcolor = 254;
586                 effects = ent->v->effects;
587
588                 if ((val = GETEDICTFIELDVALUE(ent, eval_alpha)))
589                 if (val->_float != 0)
590                         alphaf = val->_float * 255.0f;
591
592                 // HalfLife support
593                 if ((val = GETEDICTFIELDVALUE(ent, eval_renderamt)))
594                 if (val->_float != 0)
595                         alphaf = val->_float;
596
597                 if (alphaf == 0.0f)
598                         alphaf = 255.0f;
599                 alpha = bound(0, alphaf, 255);
600
601                 if ((val = GETEDICTFIELDVALUE(ent, eval_scale)))
602                 if ((scale = (int) (val->_float * 16.0)) == 0) scale = 16;
603                 if (scale < 0) scale = 0;
604                 if (scale > 255) scale = 255;
605
606                 if ((val = GETEDICTFIELDVALUE(ent, eval_glow_color)))
607                 if (val->_float != 0)
608                         glowcolor = (int) val->_float;
609
610                 if ((val = GETEDICTFIELDVALUE(ent, eval_fullbright)))
611                 if (val->_float != 0)
612                         effects |= EF_FULLBRIGHT;
613
614                 if (ent != clent)
615                 {
616                         if (glowsize == 0 && (bits & U_GLOWTRAIL) == 0) // no effects
617                         {
618                                 if (model) // model
619                                 {
620                                         // don't send if flagged for NODRAW and there are no effects
621                                         if (model->flags == 0 && ((effects & EF_NODRAW) || scale <= 0 || alpha <= 0))
622                                                 continue;
623                                 }
624                                 else // no model and no effects
625                                         continue;
626                         }
627                 }
628
629                 if (msg->maxsize - msg->cursize < 32) // LordHavoc: increased check from 16 to 32
630                 {
631                         Con_Print("packet overflow\n");
632                         // mark the rest of the entities so they can't be delta compressed against this frame
633                         for (;e < sv.num_edicts;e++)
634                         {
635                                 client->nextfullupdate[e] = -1;
636                                 client->visibletime[e] = -1;
637                         }
638                         return;
639                 }
640
641                 if ((val = GETEDICTFIELDVALUE(ent, eval_exteriormodeltoclient)) && val->edict == clentnum)
642                         bits = bits | U_EXTERIORMODEL;
643
644 // send an update
645                 baseline = &ent->e->baseline;
646
647                 if (((int)ent->v->effects & EF_DELTA) && sv_deltacompress.integer)
648                 {
649                         // every half second a full update is forced
650                         if (realtime < client->nextfullupdate[e])
651                         {
652                                 bits |= U_DELTA;
653                                 baseline = &ent->e->deltabaseline;
654                         }
655                         else
656                                 nextfullupdate = realtime + 0.5f;
657                 }
658                 else
659                         nextfullupdate = realtime + 0.5f;
660
661                 // restore nextfullupdate since this is being sent for real
662                 client->nextfullupdate[e] = nextfullupdate;
663
664                 if (e >= 256)
665                         bits |= U_LONGENTITY;
666
667                 if (ent->v->movetype == MOVETYPE_STEP)
668                         bits |= U_STEP;
669
670                 // LordHavoc: old stuff, but rewritten to have more exact tolerances
671                 if (origin[0] != baseline->origin[0])                                                                                   bits |= U_ORIGIN1;
672                 if (origin[1] != baseline->origin[1])                                                                                   bits |= U_ORIGIN2;
673                 if (origin[2] != baseline->origin[2])                                                                                   bits |= U_ORIGIN3;
674                 if (((int)(angles[0]*(256.0/360.0)) & 255) != ((int)(baseline->angles[0]*(256.0/360.0)) & 255)) bits |= U_ANGLE1;
675                 if (((int)(angles[1]*(256.0/360.0)) & 255) != ((int)(baseline->angles[1]*(256.0/360.0)) & 255)) bits |= U_ANGLE2;
676                 if (((int)(angles[2]*(256.0/360.0)) & 255) != ((int)(baseline->angles[2]*(256.0/360.0)) & 255)) bits |= U_ANGLE3;
677                 if (baseline->colormap != (qbyte) ent->v->colormap)                                                             bits |= U_COLORMAP;
678                 if (baseline->skin != (qbyte) ent->v->skin)                                                                             bits |= U_SKIN;
679                 if ((baseline->frame & 0x00FF) != ((int) ent->v->frame & 0x00FF))                               bits |= U_FRAME;
680                 if ((baseline->effects & 0x00FF) != ((int) ent->v->effects & 0x00FF))                   bits |= U_EFFECTS;
681                 if ((baseline->modelindex & 0x00FF) != ((int) ent->v->modelindex & 0x00FF))             bits |= U_MODEL;
682
683                 // LordHavoc: new stuff
684                 if (baseline->alpha != alpha)                                                                                                   bits |= U_ALPHA;
685                 if (baseline->scale != scale)                                                                                                   bits |= U_SCALE;
686                 if (((int) baseline->effects & 0xFF00) != ((int) ent->v->effects & 0xFF00))             bits |= U_EFFECTS2;
687                 if (baseline->glowsize != glowsize)                                                                                             bits |= U_GLOWSIZE;
688                 if (baseline->glowcolor != glowcolor)                                                                                   bits |= U_GLOWCOLOR;
689                 if (((int) baseline->frame & 0xFF00) != ((int) ent->v->frame & 0xFF00))                 bits |= U_FRAME2;
690                 if (((int) baseline->frame & 0xFF00) != ((int) ent->v->modelindex & 0xFF00))            bits |= U_MODEL2;
691
692                 // update delta baseline
693                 VectorCopy(ent->v->origin, ent->e->deltabaseline.origin);
694                 VectorCopy(ent->v->angles, ent->e->deltabaseline.angles);
695                 ent->e->deltabaseline.colormap = ent->v->colormap;
696                 ent->e->deltabaseline.skin = ent->v->skin;
697                 ent->e->deltabaseline.frame = ent->v->frame;
698                 ent->e->deltabaseline.effects = ent->v->effects;
699                 ent->e->deltabaseline.modelindex = ent->v->modelindex;
700                 ent->e->deltabaseline.alpha = alpha;
701                 ent->e->deltabaseline.scale = scale;
702                 ent->e->deltabaseline.glowsize = glowsize;
703                 ent->e->deltabaseline.glowcolor = glowcolor;
704
705                 // write the message
706                 if (bits >= 16777216)
707                         bits |= U_EXTEND2;
708                 if (bits >= 65536)
709                         bits |= U_EXTEND1;
710                 if (bits >= 256)
711                         bits |= U_MOREBITS;
712                 bits |= U_SIGNAL;
713
714                 MSG_WriteByte (msg, bits);
715                 if (bits & U_MOREBITS)
716                         MSG_WriteByte (msg, bits>>8);
717                 // LordHavoc: extend bytes have to be written here due to delta compression
718                 if (bits & U_EXTEND1)
719                         MSG_WriteByte (msg, bits>>16);
720                 if (bits & U_EXTEND2)
721                         MSG_WriteByte (msg, bits>>24);
722
723                 // LordHavoc: old stuff
724                 if (bits & U_LONGENTITY)
725                         MSG_WriteShort (msg,e);
726                 else
727                         MSG_WriteByte (msg,e);
728                 if (bits & U_MODEL)             MSG_WriteByte(msg,      ent->v->modelindex);
729                 if (bits & U_FRAME)             MSG_WriteByte(msg, ent->v->frame);
730                 if (bits & U_COLORMAP)  MSG_WriteByte(msg, ent->v->colormap);
731                 if (bits & U_SKIN)              MSG_WriteByte(msg, ent->v->skin);
732                 if (bits & U_EFFECTS)   MSG_WriteByte(msg, ent->v->effects);
733                 if (bits & U_ORIGIN1)   MSG_WriteCoord13i(msg, origin[0]);
734                 if (bits & U_ANGLE1)    MSG_WriteAngle8i(msg, angles[0]);
735                 if (bits & U_ORIGIN2)   MSG_WriteCoord13i(msg, origin[1]);
736                 if (bits & U_ANGLE2)    MSG_WriteAngle8i(msg, angles[1]);
737                 if (bits & U_ORIGIN3)   MSG_WriteCoord13i(msg, origin[2]);
738                 if (bits & U_ANGLE3)    MSG_WriteAngle8i(msg, angles[2]);
739
740                 // LordHavoc: new stuff
741                 if (bits & U_ALPHA)             MSG_WriteByte(msg, alpha);
742                 if (bits & U_SCALE)             MSG_WriteByte(msg, scale);
743                 if (bits & U_EFFECTS2)  MSG_WriteByte(msg, (int)ent->v->effects >> 8);
744                 if (bits & U_GLOWSIZE)  MSG_WriteByte(msg, glowsize);
745                 if (bits & U_GLOWCOLOR) MSG_WriteByte(msg, glowcolor);
746                 if (bits & U_FRAME2)    MSG_WriteByte(msg, (int)ent->v->frame >> 8);
747                 if (bits & U_MODEL2)    MSG_WriteByte(msg, (int)ent->v->modelindex >> 8);
748         }
749
750         if (sv_cullentities_stats.integer)
751                 Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d trace\n", client->name, totalentities, visibleentities, culled_pvs + culled_trace, culled_pvs, culled_trace);
752 }
753 */
754
755 static int numsendentities;
756 static entity_state_t sendentities[MAX_EDICTS];
757 static entity_state_t *sendentitiesindex[MAX_EDICTS];
758
759 void SV_PrepareEntitiesForSending(void)
760 {
761         int e, i;
762         float f;
763         edict_t *ent;
764         entity_state_t cs;
765         // send all entities that touch the pvs
766         numsendentities = 0;
767         sendentitiesindex[0] = NULL;
768         for (e = 1, ent = NEXT_EDICT(sv.edicts);e < sv.num_edicts;e++, ent = NEXT_EDICT(ent))
769         {
770                 sendentitiesindex[e] = NULL;
771                 if (ent->e->free)
772                         continue;
773
774                 cs = defaultstate;
775                 cs.active = true;
776                 cs.number = e;
777                 VectorCopy(ent->v->origin, cs.origin);
778                 VectorCopy(ent->v->angles, cs.angles);
779                 cs.flags = 0;
780                 cs.effects = (int)ent->v->effects;
781                 cs.colormap = (qbyte)ent->v->colormap;
782                 cs.skin = (qbyte)ent->v->skin;
783                 cs.frame = (qbyte)ent->v->frame;
784                 cs.viewmodelforclient = GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)->edict;
785                 cs.exteriormodelforclient = GETEDICTFIELDVALUE(ent, eval_exteriormodeltoclient)->edict;
786                 cs.nodrawtoclient = GETEDICTFIELDVALUE(ent, eval_nodrawtoclient)->edict;
787                 cs.drawonlytoclient = GETEDICTFIELDVALUE(ent, eval_drawonlytoclient)->edict;
788                 cs.tagentity = GETEDICTFIELDVALUE(ent, eval_tag_entity)->edict;
789                 cs.tagindex = (qbyte)GETEDICTFIELDVALUE(ent, eval_tag_index)->_float;
790                 i = (int)(GETEDICTFIELDVALUE(ent, eval_glow_size)->_float * 0.25f);
791                 cs.glowsize = (qbyte)bound(0, i, 255);
792                 if (GETEDICTFIELDVALUE(ent, eval_glow_trail)->_float)
793                         cs.flags |= RENDER_GLOWTRAIL;
794
795                 cs.modelindex = 0;
796                 i = (int)ent->v->modelindex;
797                 if (i >= 1 && i < MAX_MODELS && *PR_GetString(ent->v->model))
798                         cs.modelindex = i;
799
800                 cs.alpha = 255;
801                 f = (GETEDICTFIELDVALUE(ent, eval_alpha)->_float * 255.0f);
802                 if (f)
803                 {
804                         i = (int)f;
805                         cs.alpha = (qbyte)bound(0, i, 255);
806                 }
807                 // halflife
808                 f = (GETEDICTFIELDVALUE(ent, eval_renderamt)->_float);
809                 if (f)
810                 {
811                         i = (int)f;
812                         cs.alpha = (qbyte)bound(0, i, 255);
813                 }
814
815                 cs.scale = 16;
816                 f = (GETEDICTFIELDVALUE(ent, eval_scale)->_float * 16.0f);
817                 if (f)
818                 {
819                         i = (int)f;
820                         cs.scale = (qbyte)bound(0, i, 255);
821                 }
822
823                 cs.glowcolor = 254;
824                 f = (GETEDICTFIELDVALUE(ent, eval_glow_color)->_float);
825                 if (f)
826                         cs.glowcolor = (int)f;
827
828                 if (GETEDICTFIELDVALUE(ent, eval_fullbright)->_float)
829                         cs.effects |= EF_FULLBRIGHT;
830
831                 if (ent->v->movetype == MOVETYPE_STEP)
832                         cs.flags |= RENDER_STEP;
833                 if ((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)
834                         cs.flags |= RENDER_LOWPRECISION;
835                 if (ent->v->colormap >= 1024)
836                         cs.flags |= RENDER_COLORMAPPED;
837                 if (cs.viewmodelforclient)
838                         cs.flags |= RENDER_VIEWMODEL; // show relative to the view
839
840                 f = GETEDICTFIELDVALUE(ent, eval_color)->vector[0]*256;
841                 cs.light[0] = (unsigned short)bound(0, f, 65535);
842                 f = GETEDICTFIELDVALUE(ent, eval_color)->vector[1]*256;
843                 cs.light[1] = (unsigned short)bound(0, f, 65535);
844                 f = GETEDICTFIELDVALUE(ent, eval_color)->vector[2]*256;
845                 cs.light[2] = (unsigned short)bound(0, f, 65535);
846                 f = GETEDICTFIELDVALUE(ent, eval_light_lev)->_float;
847                 cs.light[3] = (unsigned short)bound(0, f, 65535);
848                 cs.lightstyle = (qbyte)GETEDICTFIELDVALUE(ent, eval_style)->_float;
849                 cs.lightpflags = (qbyte)GETEDICTFIELDVALUE(ent, eval_pflags)->_float;
850
851                 if (gamemode == GAME_TENEBRAE)
852                 {
853                         // tenebrae's EF_FULLDYNAMIC conflicts with Q2's EF_NODRAW
854                         if (cs.effects & 16)
855                         {
856                                 cs.effects &= ~16;
857                                 cs.lightpflags |= PFLAGS_FULLDYNAMIC;
858                         }
859                         // tenebrae's EF_GREEN conflicts with DP's EF_ADDITIVE
860                         if (cs.effects & 32)
861                         {
862                                 cs.effects &= ~32;
863                                 cs.light[0] = 0.2;
864                                 cs.light[1] = 1;
865                                 cs.light[2] = 0.2;
866                                 cs.light[3] = 200;
867                                 cs.lightpflags |= PFLAGS_FULLDYNAMIC;
868                         }
869                 }
870
871                 cs.specialvisibilityradius = 0;
872                 if (cs.lightpflags & PFLAGS_FULLDYNAMIC)
873                         cs.specialvisibilityradius = max(cs.specialvisibilityradius, cs.light[3]);
874                 if (cs.glowsize)
875                         cs.specialvisibilityradius = max(cs.specialvisibilityradius, cs.glowsize * 4);
876                 if (cs.flags & RENDER_GLOWTRAIL)
877                         cs.specialvisibilityradius = max(cs.specialvisibilityradius, 100);
878                 if (cs.effects & (EF_BRIGHTFIELD | EF_MUZZLEFLASH | EF_BRIGHTLIGHT | EF_DIMLIGHT | EF_RED | EF_BLUE | EF_FLAME | EF_STARDUST))
879                 {
880                         if (cs.effects & EF_BRIGHTFIELD)
881                                 cs.specialvisibilityradius = max(cs.specialvisibilityradius, 80);
882                         if (cs.effects & EF_MUZZLEFLASH)
883                                 cs.specialvisibilityradius = max(cs.specialvisibilityradius, 100);
884                         if (cs.effects & EF_BRIGHTLIGHT)
885                                 cs.specialvisibilityradius = max(cs.specialvisibilityradius, 400);
886                         if (cs.effects & EF_DIMLIGHT)
887                                 cs.specialvisibilityradius = max(cs.specialvisibilityradius, 200);
888                         if (cs.effects & EF_RED)
889                                 cs.specialvisibilityradius = max(cs.specialvisibilityradius, 200);
890                         if (cs.effects & EF_BLUE)
891                                 cs.specialvisibilityradius = max(cs.specialvisibilityradius, 200);
892                         if (cs.effects & EF_FLAME)
893                                 cs.specialvisibilityradius = max(cs.specialvisibilityradius, 250);
894                         if (cs.effects & EF_STARDUST)
895                                 cs.specialvisibilityradius = max(cs.specialvisibilityradius, 100);
896                 }
897
898                 if (numsendentities >= MAX_EDICTS)
899                         continue;
900                 // we can omit invisible entities with no effects that are not clients
901                 // LordHavoc: this could kill tags attached to an invisible entity, I
902                 // just hope we never have to support that case
903                 if (cs.number > svs.maxclients && ((cs.effects & EF_NODRAW) || (!cs.modelindex && !cs.specialvisibilityradius)))
904                         continue;
905                 sendentitiesindex[e] = sendentities + numsendentities;
906                 sendentities[numsendentities++] = cs;
907         }
908 }
909
910 static int sententitiesmark = 0;
911 static int sententities[MAX_EDICTS];
912 static int sententitiesconsideration[MAX_EDICTS];
913 static int sv_writeentitiestoclient_culled_pvs;
914 static int sv_writeentitiestoclient_culled_trace;
915 static int sv_writeentitiestoclient_visibleentities;
916 static int sv_writeentitiestoclient_totalentities;
917 //static entity_frame_t sv_writeentitiestoclient_entityframe;
918 static int sv_writeentitiestoclient_clentnum;
919 static vec3_t sv_writeentitiestoclient_testeye;
920 static client_t *sv_writeentitiestoclient_client;
921
922 void SV_MarkWriteEntityStateToClient(entity_state_t *s)
923 {
924         int isbmodel;
925         vec3_t entmins, entmaxs, lightmins, lightmaxs, testorigin;
926         model_t *model;
927         trace_t trace;
928         if (sententitiesconsideration[s->number] == sententitiesmark)
929                 return;
930         sententitiesconsideration[s->number] = sententitiesmark;
931         // viewmodels don't have visibility checking
932         if (s->viewmodelforclient)
933         {
934                 if (s->viewmodelforclient != sv_writeentitiestoclient_clentnum)
935                         return;
936         }
937         // never reject player
938         else if (s->number != sv_writeentitiestoclient_clentnum)
939         {
940                 // check various rejection conditions
941                 if (s->nodrawtoclient == sv_writeentitiestoclient_clentnum)
942                         return;
943                 if (s->drawonlytoclient && s->drawonlytoclient != sv_writeentitiestoclient_clentnum)
944                         return;
945                 if (s->effects & EF_NODRAW)
946                         return;
947                 // LordHavoc: only send entities with a model or important effects
948                 if (!s->modelindex && s->specialvisibilityradius == 0)
949                         return;
950                 if (s->tagentity)
951                 {
952                         // tag attached entities simply check their parent
953                         if (!sendentitiesindex[s->tagentity])
954                                 return;
955                         SV_MarkWriteEntityStateToClient(sendentitiesindex[s->tagentity]);
956                         if (sententities[s->tagentity] != sententitiesmark)
957                                 return;
958                 }
959                 // always send world submodels, they don't generate much traffic
960                 // except in PROTOCOL_QUAKE where they hog bandwidth like crazy
961                 else if (!(isbmodel = (model = sv.models[s->modelindex]) != NULL && model->name[0] == '*') || sv.protocol == PROTOCOL_QUAKE)
962                 {
963                         Mod_CheckLoaded(model);
964                         // entity has survived every check so far, check if visible
965                         // enlarged box to account for prediction (not that there is
966                         // any currently, but still helps the 'run into a room and
967                         // watch items pop up' problem)
968                         entmins[0] = s->origin[0] - 32.0f;
969                         entmins[1] = s->origin[1] - 32.0f;
970                         entmins[2] = s->origin[2] - 32.0f;
971                         entmaxs[0] = s->origin[0] + 32.0f;
972                         entmaxs[1] = s->origin[1] + 32.0f;
973                         entmaxs[2] = s->origin[2] + 32.0f;
974                         // using the model's bounding box to ensure things are visible regardless of their physics box
975                         if (model)
976                         {
977                                 if (s->angles[0] || s->angles[2]) // pitch and roll
978                                 {
979                                         VectorAdd(entmins, model->rotatedmins, entmins);
980                                         VectorAdd(entmaxs, model->rotatedmaxs, entmaxs);
981                                 }
982                                 else if (s->angles[1])
983                                 {
984                                         VectorAdd(entmins, model->yawmins, entmins);
985                                         VectorAdd(entmaxs, model->yawmaxs, entmaxs);
986                                 }
987                                 else
988                                 {
989                                         VectorAdd(entmins, model->normalmins, entmins);
990                                         VectorAdd(entmaxs, model->normalmaxs, entmaxs);
991                                 }
992                         }
993                         lightmins[0] = min(entmins[0], s->origin[0] - s->specialvisibilityradius);
994                         lightmins[1] = min(entmins[1], s->origin[1] - s->specialvisibilityradius);
995                         lightmins[2] = min(entmins[2], s->origin[2] - s->specialvisibilityradius);
996                         lightmaxs[0] = max(entmaxs[0], s->origin[0] + s->specialvisibilityradius);
997                         lightmaxs[1] = max(entmaxs[1], s->origin[1] + s->specialvisibilityradius);
998                         lightmaxs[2] = max(entmaxs[2], s->origin[2] + s->specialvisibilityradius);
999                         sv_writeentitiestoclient_totalentities++;
1000                         // if not touching a visible leaf
1001                         if (sv_cullentities_pvs.integer && sv_writeentitiestoclient_pvsbytes && sv.worldmodel && sv.worldmodel->brush.BoxTouchingPVS && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, sv_writeentitiestoclient_pvs, lightmins, lightmaxs))
1002                         {
1003                                 sv_writeentitiestoclient_culled_pvs++;
1004                                 return;
1005                         }
1006                         // or not seen by random tracelines
1007                         if (sv_cullentities_trace.integer && !isbmodel)
1008                         {
1009                                 // LordHavoc: test center first
1010                                 testorigin[0] = (entmins[0] + entmaxs[0]) * 0.5f;
1011                                 testorigin[1] = (entmins[1] + entmaxs[1]) * 0.5f;
1012                                 testorigin[2] = (entmins[2] + entmaxs[2]) * 0.5f;
1013                                 sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
1014                                 if (trace.fraction == 1 || BoxesOverlap(trace.endpos, trace.endpos, entmins, entmaxs))
1015                                         sv_writeentitiestoclient_client->visibletime[s->number] = realtime + 1;
1016                                 else
1017                                 {
1018                                         // LordHavoc: test random offsets, to maximize chance of detection
1019                                         testorigin[0] = lhrandom(entmins[0], entmaxs[0]);
1020                                         testorigin[1] = lhrandom(entmins[1], entmaxs[1]);
1021                                         testorigin[2] = lhrandom(entmins[2], entmaxs[2]);
1022                                         sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
1023                                         if (trace.fraction == 1 || BoxesOverlap(trace.endpos, trace.endpos, entmins, entmaxs))
1024                                                 sv_writeentitiestoclient_client->visibletime[s->number] = realtime + 1;
1025                                         else
1026                                         {
1027                                                 if (s->specialvisibilityradius)
1028                                                 {
1029                                                         // LordHavoc: test random offsets, to maximize chance of detection
1030                                                         testorigin[0] = lhrandom(lightmins[0], lightmaxs[0]);
1031                                                         testorigin[1] = lhrandom(lightmins[1], lightmaxs[1]);
1032                                                         testorigin[2] = lhrandom(lightmins[2], lightmaxs[2]);
1033                                                         sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
1034                                                         if (trace.fraction == 1 || BoxesOverlap(trace.endpos, trace.endpos, entmins, entmaxs))
1035                                                                 sv_writeentitiestoclient_client->visibletime[s->number] = realtime + 1;
1036                                                 }
1037                                         }
1038                                 }
1039                                 if (realtime > sv_writeentitiestoclient_client->visibletime[s->number])
1040                                 {
1041                                         sv_writeentitiestoclient_culled_trace++;
1042                                         return;
1043                                 }
1044                         }
1045                         sv_writeentitiestoclient_visibleentities++;
1046                 }
1047         }
1048         // this just marks it for sending
1049         // FIXME: it would be more efficient to send here, but the entity
1050         // compressor isn't that flexible
1051         sententities[s->number] = sententitiesmark;
1052 }
1053
1054 entity_state_t sendstates[MAX_EDICTS]; 
1055
1056 /*
1057 // entityframe4 protocol
1058 void SV_WriteEntitiesToClient_EF4(client_t *client, edict_t *clent, sizebuf_t *msg)
1059 {
1060         int i;
1061         vec3_t testorigin;
1062         entity_state_t *s;
1063         entityframe4_database_t *d;
1064         int n, startnumber;
1065         entity_state_t *e, inactiveentitystate;
1066         sizebuf_t buf;
1067         qbyte data[128];
1068
1069         // if there isn't enough space to accomplish anything, skip it
1070         if (msg->cursize + 24 > msg->maxsize)
1071                 return;
1072
1073         // prepare the buffer
1074         memset(&buf, 0, sizeof(buf));
1075         buf.data = data;
1076         buf.maxsize = sizeof(data);
1077
1078         d = client->entitydatabase4;
1079
1080         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
1081                 if (!d->commit[i].numentities)
1082                         break;
1083         // if commit buffer full, just don't bother writing an update this frame
1084         if (i == MAX_ENTITY_HISTORY)
1085                 return;
1086         d->currentcommit = d->commit + i;
1087
1088         // this state's number gets played around with later
1089         inactiveentitystate = defaultstate;
1090
1091         sv_writeentitiestoclient_client = client;
1092
1093         sv_writeentitiestoclient_culled_pvs = 0;
1094         sv_writeentitiestoclient_culled_trace = 0;
1095         sv_writeentitiestoclient_visibleentities = 0;
1096         sv_writeentitiestoclient_totalentities = 0;
1097
1098         Mod_CheckLoaded(sv.worldmodel);
1099
1100 // find the client's PVS
1101         // the real place being tested from
1102         VectorAdd(clent->v->origin, clent->v->view_ofs, sv_writeentitiestoclient_testeye);
1103         sv_writeentitiestoclient_pvsbytes = 0;
1104         if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
1105                 sv_writeentitiestoclient_pvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, sv_writeentitiestoclient_testeye, 8, sv_writeentitiestoclient_pvs, sizeof(sv_writeentitiestoclient_pvs));
1106
1107         sv_writeentitiestoclient_clentnum = EDICT_TO_PROG(clent); // LordHavoc: for comparison purposes
1108
1109         sententitiesmark++;
1110
1111         // the place being reported (to consider the fact the client still
1112         // applies the view_ofs[2], so we have to only send the fractional part
1113         // of view_ofs[2], undoing what the client will redo)
1114         VectorCopy(sv_writeentitiestoclient_testeye, testorigin);
1115         i = (int) clent->v->view_ofs[2] & 255;
1116         if (i >= 128)
1117                 i -= 256;
1118         testorigin[2] -= (float) i;
1119
1120         for (i = 0;i < numsendentities;i++)
1121                 SV_MarkWriteEntityStateToClient(sendentities + i);
1122
1123         d->currentcommit->numentities = 0;
1124         d->currentcommit->framenum = ++d->latestframenumber;
1125         MSG_WriteByte(msg, svc_entities);
1126         MSG_WriteLong(msg, d->referenceframenum);
1127         MSG_WriteLong(msg, d->currentcommit->framenum);
1128         if (developer_networkentities.integer >= 1)
1129         {
1130                 Con_Printf("send svc_entities num:%i ref:%i (database: ref:%i commits:", d->currentcommit->framenum, d->referenceframenum, d->referenceframenum);
1131                 for (i = 0;i < MAX_ENTITY_HISTORY;i++)
1132                         if (d->commit[i].numentities)
1133                                 Con_Printf(" %i", d->commit[i].framenum);
1134                 Con_Print(")\n");
1135         }
1136         if (d->currententitynumber >= sv.max_edicts)
1137                 startnumber = 1;
1138         else
1139                 startnumber = bound(1, d->currententitynumber, sv.max_edicts - 1);
1140         MSG_WriteShort(msg, startnumber);
1141         // reset currententitynumber so if the loop does not break it we will
1142         // start at beginning next frame (if it does break, it will set it)
1143         d->currententitynumber = 1;
1144         for (i = 0, n = startnumber;n < sv.max_edicts;n++)
1145         {
1146                 // find the old state to delta from
1147                 e = EntityFrame4_GetReferenceEntity(d, n);
1148                 // prepare the buffer
1149                 SZ_Clear(&buf);
1150                 // make the message
1151                 if (sententities[n] == sententitiesmark)
1152                 {
1153                         // entity exists, build an update (if empty there is no change)
1154                         // find the state in the list
1155                         for (;i < numsendentities && sendentities[i].number < n;i++);
1156                         s = sendentities + i;
1157                         if (s->number != n)
1158                                 Sys_Error("SV_WriteEntitiesToClient: s->number != n\n");
1159                         // build the update
1160                         if (s->exteriormodelforclient && s->exteriormodelforclient == sv_writeentitiestoclient_clentnum)
1161                         {
1162                                 s->flags |= RENDER_EXTERIORMODEL;
1163                                 EntityState_WriteUpdate(s, &buf, e);
1164                                 s->flags &= ~RENDER_EXTERIORMODEL;
1165                         }
1166                         else
1167                                 EntityState_WriteUpdate(s, &buf, e);
1168                 }
1169                 else
1170                 {
1171                         s = &inactiveentitystate;
1172                         s->number = n;
1173                         if (e->active)
1174                         {
1175                                 // entity used to exist but doesn't anymore, send remove
1176                                 MSG_WriteShort(&buf, n | 0x8000);
1177                         }
1178                 }
1179                 // if the commit is full, we're done this frame
1180                 if (msg->cursize + buf.cursize > msg->maxsize - 4)
1181                 {
1182                         // next frame we will continue where we left off
1183                         break;
1184                 }
1185                 // add the entity to the commit
1186                 EntityFrame4_AddCommitEntity(d, s);
1187                 // if the message is empty, skip out now
1188                 if (buf.cursize)
1189                 {
1190                         // write the message to the packet
1191                         SZ_Write(msg, buf.data, buf.cursize);
1192                 }
1193         }
1194         d->currententitynumber = n;
1195
1196         // remove world message (invalid, and thus a good terminator)
1197         MSG_WriteShort(msg, 0x8000);
1198         // write the number of the end entity
1199         MSG_WriteShort(msg, d->currententitynumber);
1200         // just to be sure
1201         d->currentcommit = NULL;
1202
1203         if (sv_cullentities_stats.integer)
1204                 Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d trace\n", client->name, sv_writeentitiestoclient_totalentities, sv_writeentitiestoclient_visibleentities, sv_writeentitiestoclient_culled_pvs + sv_writeentitiestoclient_culled_trace, sv_writeentitiestoclient_culled_pvs, sv_writeentitiestoclient_culled_trace);
1205 }
1206 */
1207
1208 void SV_WriteEntitiesToClient(client_t *client, edict_t *clent, sizebuf_t *msg)
1209 {
1210         int i, numsendstates;
1211         entity_state_t *s;
1212
1213         // if there isn't enough space to accomplish anything, skip it
1214         if (msg->cursize + 25 > msg->maxsize)
1215                 return;
1216
1217         sv_writeentitiestoclient_client = client;
1218
1219         sv_writeentitiestoclient_culled_pvs = 0;
1220         sv_writeentitiestoclient_culled_trace = 0;
1221         sv_writeentitiestoclient_visibleentities = 0;
1222         sv_writeentitiestoclient_totalentities = 0;
1223
1224         Mod_CheckLoaded(sv.worldmodel);
1225
1226 // find the client's PVS
1227         // the real place being tested from
1228         VectorAdd(clent->v->origin, clent->v->view_ofs, sv_writeentitiestoclient_testeye);
1229         sv_writeentitiestoclient_pvsbytes = 0;
1230         if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
1231                 sv_writeentitiestoclient_pvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, sv_writeentitiestoclient_testeye, 8, sv_writeentitiestoclient_pvs, sizeof(sv_writeentitiestoclient_pvs));
1232
1233         sv_writeentitiestoclient_clentnum = EDICT_TO_PROG(clent); // LordHavoc: for comparison purposes
1234
1235         sententitiesmark++;
1236
1237         for (i = 0;i < numsendentities;i++)
1238                 SV_MarkWriteEntityStateToClient(sendentities + i);
1239
1240         numsendstates = 0;
1241         for (i = 0;i < numsendentities;i++)
1242         {
1243                 if (sententities[sendentities[i].number] == sententitiesmark)
1244                 {
1245                         s = &sendstates[numsendstates++];
1246                         *s = sendentities[i];
1247                         if (s->exteriormodelforclient && s->exteriormodelforclient == sv_writeentitiestoclient_clentnum)
1248                                 s->flags |= RENDER_EXTERIORMODEL;
1249                 }
1250         }
1251
1252         if (sv_cullentities_stats.integer)
1253                 Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d trace\n", client->name, sv_writeentitiestoclient_totalentities, sv_writeentitiestoclient_visibleentities, sv_writeentitiestoclient_culled_pvs + sv_writeentitiestoclient_culled_trace, sv_writeentitiestoclient_culled_pvs, sv_writeentitiestoclient_culled_trace);
1254
1255         if (client->entitydatabase5)
1256                 EntityFrame5_WriteFrame(msg, client->entitydatabase5, numsendstates, sendstates, client - svs.clients + 1);
1257         else if (client->entitydatabase4)
1258                 EntityFrame4_WriteFrame(msg, client->entitydatabase4, numsendstates, sendstates);
1259         else if (client->entitydatabase)
1260                 EntityFrame_WriteFrame(msg, client->entitydatabase, numsendstates, sendstates, client - svs.clients + 1);
1261         else
1262                 EntityFrameQuake_WriteFrame(msg, numsendstates, sendstates);
1263 }
1264
1265 /*
1266 =============
1267 SV_CleanupEnts
1268
1269 =============
1270 */
1271 void SV_CleanupEnts (void)
1272 {
1273         int             e;
1274         edict_t *ent;
1275
1276         ent = NEXT_EDICT(sv.edicts);
1277         for (e=1 ; e<sv.num_edicts ; e++, ent = NEXT_EDICT(ent))
1278                 ent->v->effects = (int)ent->v->effects & ~EF_MUZZLEFLASH;
1279 }
1280
1281 /*
1282 ==================
1283 SV_WriteClientdataToMessage
1284
1285 ==================
1286 */
1287 void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
1288 {
1289         int             bits;
1290         int             i;
1291         edict_t *other;
1292         int             items;
1293         eval_t  *val;
1294         vec3_t  punchvector;
1295         qbyte   viewzoom;
1296
1297 //
1298 // send a damage message
1299 //
1300         if (ent->v->dmg_take || ent->v->dmg_save)
1301         {
1302                 other = PROG_TO_EDICT(ent->v->dmg_inflictor);
1303                 MSG_WriteByte (msg, svc_damage);
1304                 MSG_WriteByte (msg, ent->v->dmg_save);
1305                 MSG_WriteByte (msg, ent->v->dmg_take);
1306                 for (i=0 ; i<3 ; i++)
1307                         MSG_WriteCoord (msg, other->v->origin[i] + 0.5*(other->v->mins[i] + other->v->maxs[i]), sv.protocol);
1308
1309                 ent->v->dmg_take = 0;
1310                 ent->v->dmg_save = 0;
1311         }
1312
1313 //
1314 // send the current viewpos offset from the view entity
1315 //
1316         SV_SetIdealPitch ();            // how much to look up / down ideally
1317
1318 // a fixangle might get lost in a dropped packet.  Oh well.
1319         if ( ent->v->fixangle )
1320         {
1321                 MSG_WriteByte (msg, svc_setangle);
1322                 for (i=0 ; i < 3 ; i++)
1323                 {
1324                         if (sv.protocol == PROTOCOL_DARKPLACES5)
1325                                 MSG_WriteAngle16i (msg, ent->v->angles[i] );
1326                         else
1327                                 MSG_WriteAngle8i (msg, ent->v->angles[i] );
1328                 }
1329                 ent->v->fixangle = 0;
1330         }
1331
1332         bits = 0;
1333
1334         if (ent->v->view_ofs[2] != DEFAULT_VIEWHEIGHT)
1335                 bits |= SU_VIEWHEIGHT;
1336
1337         if (ent->v->idealpitch)
1338                 bits |= SU_IDEALPITCH;
1339
1340 // stuff the sigil bits into the high bits of items for sbar, or else
1341 // mix in items2
1342         val = GETEDICTFIELDVALUE(ent, eval_items2);
1343
1344         if (val)
1345                 items = (int)ent->v->items | ((int)val->_float << 23);
1346         else
1347                 items = (int)ent->v->items | ((int)pr_global_struct->serverflags << 28);
1348
1349         bits |= SU_ITEMS;
1350
1351         if ( (int)ent->v->flags & FL_ONGROUND)
1352                 bits |= SU_ONGROUND;
1353
1354         if ( ent->v->waterlevel >= 2)
1355                 bits |= SU_INWATER;
1356
1357         // PROTOCOL_DARKPLACES
1358         VectorClear(punchvector);
1359         if ((val = GETEDICTFIELDVALUE(ent, eval_punchvector)))
1360                 VectorCopy(val->vector, punchvector);
1361
1362         i = 255;
1363         if ((val = GETEDICTFIELDVALUE(ent, eval_viewzoom)))
1364         {
1365                 i = val->_float * 255.0f;
1366                 if (i == 0)
1367                         i = 255;
1368                 else
1369                         i = bound(0, i, 65535);
1370         }
1371         viewzoom = i;
1372
1373         // FIXME: which protocols support this?  does PROTOCOL_DARKPLACES3 support viewzoom?
1374         if (sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
1375                 if (viewzoom != 255)
1376                         bits |= SU_VIEWZOOM;
1377
1378         for (i=0 ; i<3 ; i++)
1379         {
1380                 if (ent->v->punchangle[i])
1381                         bits |= (SU_PUNCH1<<i);
1382                 if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
1383                         if (punchvector[i])
1384                                 bits |= (SU_PUNCHVEC1<<i);
1385                 if (ent->v->velocity[i])
1386                         bits |= (SU_VELOCITY1<<i);
1387         }
1388
1389         if (ent->v->weaponframe)
1390                 bits |= SU_WEAPONFRAME;
1391
1392         if (ent->v->armorvalue)
1393                 bits |= SU_ARMOR;
1394
1395         bits |= SU_WEAPON;
1396
1397         if (bits >= 65536)
1398                 bits |= SU_EXTEND1;
1399         if (bits >= 16777216)
1400                 bits |= SU_EXTEND2;
1401
1402 // send the data
1403
1404         MSG_WriteByte (msg, svc_clientdata);
1405         MSG_WriteShort (msg, bits);
1406         if (bits & SU_EXTEND1)
1407                 MSG_WriteByte(msg, bits >> 16);
1408         if (bits & SU_EXTEND2)
1409                 MSG_WriteByte(msg, bits >> 24);
1410
1411         if (bits & SU_VIEWHEIGHT)
1412                 MSG_WriteChar (msg, ent->v->view_ofs[2]);
1413
1414         if (bits & SU_IDEALPITCH)
1415                 MSG_WriteChar (msg, ent->v->idealpitch);
1416
1417         for (i=0 ; i<3 ; i++)
1418         {
1419                 if (bits & (SU_PUNCH1<<i))
1420                 {
1421                         if (sv.protocol == PROTOCOL_QUAKE)
1422                                 MSG_WriteChar(msg, ent->v->punchangle[i]);
1423                         else if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
1424                                 MSG_WriteAngle16i(msg, ent->v->punchangle[i]);
1425                 }
1426                 if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
1427                 {
1428                         if (bits & (SU_PUNCHVEC1<<i))
1429                         {
1430                                 if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
1431                                         MSG_WriteCoord16i(msg, punchvector[i]);
1432                                 else if (sv.protocol == PROTOCOL_DARKPLACES5)
1433                                         MSG_WriteCoord32f(msg, punchvector[i]);
1434                         }
1435                 }
1436                 if (bits & (SU_VELOCITY1<<i))
1437                 {
1438                         if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
1439                                 MSG_WriteChar(msg, ent->v->velocity[i] * (1.0f / 16.0f));
1440                         else if (sv.protocol == PROTOCOL_DARKPLACES5)
1441                                 MSG_WriteCoord32f(msg, ent->v->velocity[i]);
1442                 }
1443         }
1444
1445 // [always sent]        if (bits & SU_ITEMS)
1446         MSG_WriteLong (msg, items);
1447
1448         if (sv.protocol == PROTOCOL_DARKPLACES5)
1449         {
1450                 if (bits & SU_WEAPONFRAME)
1451                         MSG_WriteShort (msg, ent->v->weaponframe);
1452                 if (bits & SU_ARMOR)
1453                         MSG_WriteShort (msg, ent->v->armorvalue);
1454                 if (bits & SU_WEAPON)
1455                 {
1456                         i = SV_ModelIndex(PR_GetString(ent->v->weaponmodel));
1457                         if (i < 0)
1458                         {
1459                                 Con_DPrintf("weaponmodel \"%s\" not precached\n", PR_GetString(ent->v->weaponmodel));
1460                                 i = 0;
1461                         }
1462                         MSG_WriteShort (msg, i);
1463                 }
1464
1465                 MSG_WriteShort (msg, ent->v->health);
1466                 MSG_WriteShort (msg, ent->v->currentammo);
1467                 MSG_WriteShort (msg, ent->v->ammo_shells);
1468                 MSG_WriteShort (msg, ent->v->ammo_nails);
1469                 MSG_WriteShort (msg, ent->v->ammo_rockets);
1470                 MSG_WriteShort (msg, ent->v->ammo_cells);
1471
1472                 MSG_WriteShort (msg, ent->v->weapon);
1473         
1474                 if (bits & SU_VIEWZOOM)
1475                         MSG_WriteShort (msg, viewzoom);
1476         }
1477         else
1478         {
1479                 if (bits & SU_WEAPONFRAME)
1480                         MSG_WriteByte (msg, ent->v->weaponframe);
1481                 if (bits & SU_ARMOR)
1482                         MSG_WriteByte (msg, ent->v->armorvalue);
1483                 if (bits & SU_WEAPON)
1484                 {
1485                         i = SV_ModelIndex(PR_GetString(ent->v->weaponmodel));
1486                         if (i < 0)
1487                         {
1488                                 Con_DPrintf("weaponmodel \"%s\" not precached\n", PR_GetString(ent->v->weaponmodel));
1489                                 i = 0;
1490                         }
1491                         MSG_WriteByte (msg, i);
1492                 }
1493
1494                 MSG_WriteShort (msg, ent->v->health);
1495                 MSG_WriteByte (msg, ent->v->currentammo);
1496                 MSG_WriteByte (msg, ent->v->ammo_shells);
1497                 MSG_WriteByte (msg, ent->v->ammo_nails);
1498                 MSG_WriteByte (msg, ent->v->ammo_rockets);
1499                 MSG_WriteByte (msg, ent->v->ammo_cells);
1500
1501                 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE || gamemode == GAME_NEXUIZ)
1502                 {
1503                         for(i=0;i<32;i++)
1504                         {
1505                                 if ( ((int)ent->v->weapon) & (1<<i) )
1506                                 {
1507                                         MSG_WriteByte (msg, i);
1508                                         break;
1509                                 }
1510                         }
1511                 }
1512                 else
1513                 {
1514                         MSG_WriteByte (msg, ent->v->weapon);
1515                 }
1516         
1517                 if (bits & SU_VIEWZOOM)
1518                 {
1519                         if (sv.protocol == PROTOCOL_DARKPLACES4)
1520                         {
1521                                 viewzoom = min(viewzoom, 255);
1522                                 MSG_WriteByte (msg, viewzoom);
1523                         }
1524                         else if (sv.protocol == PROTOCOL_DARKPLACES5)
1525                                 MSG_WriteShort (msg, viewzoom);
1526                 }
1527         }
1528 }
1529
1530 /*
1531 =======================
1532 SV_SendClientDatagram
1533 =======================
1534 */
1535 static qbyte sv_sendclientdatagram_buf[NET_MAXMESSAGE]; // FIXME?
1536 qboolean SV_SendClientDatagram (client_t *client)
1537 {
1538         int rate, maxrate, maxsize, maxsize2;
1539         sizebuf_t msg;
1540
1541         if (LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) == LHNETADDRESSTYPE_LOOP && !sv_ratelimitlocalplayer.integer)
1542         {
1543                 // for good singleplayer, send huge packets
1544                 maxsize = sizeof(sv_sendclientdatagram_buf);
1545                 maxsize2 = sizeof(sv_sendclientdatagram_buf);
1546         }
1547         else if (sv.protocol == PROTOCOL_DARKPLACES5)
1548         {
1549                 // PROTOCOL_DARKPLACES5 supports packet size limiting of updates
1550                 maxrate = bound(NET_MINRATE, sv_maxrate.integer, NET_MAXRATE);
1551                 if (sv_maxrate.integer != maxrate)
1552                         Cvar_SetValueQuick(&sv_maxrate, maxrate);
1553
1554                 rate = bound(NET_MINRATE, client->netconnection->rate, maxrate);
1555                 rate = (int)(client->netconnection->rate * sys_ticrate.value);
1556                 maxsize = bound(100, rate, 1400);
1557                 maxsize2 = 1400;
1558         }
1559         else
1560         {
1561                 // no rate limiting support on older protocols because dp protocols
1562                 // 1-4 kick the client off if they overflow, and quake protocol shows
1563                 // less than the full entity set if rate limited
1564                 maxsize = 1400;
1565                 maxsize2 = 1400;
1566         }
1567
1568         msg.data = sv_sendclientdatagram_buf;
1569         msg.maxsize = maxsize;
1570         msg.cursize = 0;
1571
1572         MSG_WriteByte (&msg, svc_time);
1573         MSG_WriteFloat (&msg, sv.time);
1574
1575         // add the client specific data to the datagram
1576         SV_WriteClientdataToMessage (client->edict, &msg);
1577
1578         SV_WriteEntitiesToClient (client, client->edict, &msg);
1579
1580         // expand packet size to allow effects to go over the rate limit
1581         // (dropping them is FAR too ugly)
1582         msg.maxsize = maxsize2;
1583
1584         // copy the server datagram if there is space
1585         // FIXME: put in delayed queue of effects to send
1586         if (sv.datagram.cursize > 0 && msg.cursize + sv.datagram.cursize <= msg.maxsize)
1587                 SZ_Write (&msg, sv.datagram.data, sv.datagram.cursize);
1588
1589 // send the datagram
1590         if (NetConn_SendUnreliableMessage (client->netconnection, &msg) == -1)
1591         {
1592                 SV_DropClient (true);// if the message couldn't send, kick off
1593                 return false;
1594         }
1595
1596         return true;
1597 }
1598
1599 /*
1600 =======================
1601 SV_UpdateToReliableMessages
1602 =======================
1603 */
1604 void SV_UpdateToReliableMessages (void)
1605 {
1606         int i, j;
1607         client_t *client;
1608         eval_t *val;
1609         char *s;
1610
1611 // check for changes to be sent over the reliable streams
1612         for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
1613         {
1614                 // update the host_client fields we care about according to the entity fields
1615                 sv_player = EDICT_NUM(i+1);
1616                 s = PR_GetString(sv_player->v->netname);
1617                 if (s != host_client->name)
1618                 {
1619                         if (s == NULL)
1620                                 s = "";
1621                         // point the string back at host_client->name to keep it safe
1622                         strlcpy (host_client->name, s, sizeof (host_client->name));
1623                         sv_player->v->netname = PR_SetString(host_client->name);
1624                 }
1625                 if ((val = GETEDICTFIELDVALUE(sv_player, eval_clientcolors)) && host_client->colors != val->_float)
1626                         host_client->colors = val->_float;
1627                 host_client->frags = sv_player->v->frags;
1628                 if (gamemode == GAME_NEHAHRA)
1629                         if ((val = GETEDICTFIELDVALUE(sv_player, eval_pmodel)) && host_client->pmodel != val->_float)
1630                                 host_client->pmodel = val->_float;
1631
1632                 // if the fields changed, send messages about the changes
1633                 if (strcmp(host_client->old_name, host_client->name))
1634                 {
1635                         strcpy(host_client->old_name, host_client->name);
1636                         for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1637                         {
1638                                 if (!client->spawned || !client->netconnection)
1639                                         continue;
1640                                 MSG_WriteByte (&client->message, svc_updatename);
1641                                 MSG_WriteByte (&client->message, i);
1642                                 MSG_WriteString (&client->message, host_client->name);
1643                         }
1644                 }
1645                 if (host_client->old_colors != host_client->colors)
1646                 {
1647                         host_client->old_colors = host_client->colors;
1648                         for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1649                         {
1650                                 if (!client->spawned || !client->netconnection)
1651                                         continue;
1652                                 MSG_WriteByte (&client->message, svc_updatecolors);
1653                                 MSG_WriteByte (&client->message, i);
1654                                 MSG_WriteByte (&client->message, host_client->colors);
1655                         }
1656                 }
1657                 if (host_client->old_frags != host_client->frags)
1658                 {
1659                         host_client->old_frags = host_client->frags;
1660                         for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1661                         {
1662                                 if (!client->spawned || !client->netconnection)
1663                                         continue;
1664                                 MSG_WriteByte (&client->message, svc_updatefrags);
1665                                 MSG_WriteByte (&client->message, i);
1666                                 MSG_WriteShort (&client->message, host_client->frags);
1667                         }
1668                 }
1669         }
1670
1671         for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1672                 if (client->netconnection)
1673                         SZ_Write (&client->message, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
1674
1675         SZ_Clear (&sv.reliable_datagram);
1676 }
1677
1678
1679 /*
1680 =======================
1681 SV_SendNop
1682
1683 Send a nop message without trashing or sending the accumulated client
1684 message buffer
1685 =======================
1686 */
1687 void SV_SendNop (client_t *client)
1688 {
1689         sizebuf_t       msg;
1690         qbyte           buf[4];
1691
1692         msg.data = buf;
1693         msg.maxsize = sizeof(buf);
1694         msg.cursize = 0;
1695
1696         MSG_WriteChar (&msg, svc_nop);
1697
1698         if (NetConn_SendUnreliableMessage (client->netconnection, &msg) == -1)
1699                 SV_DropClient (true);   // if the message couldn't send, kick off
1700         client->last_message = realtime;
1701 }
1702
1703 /*
1704 =======================
1705 SV_SendClientMessages
1706 =======================
1707 */
1708 void SV_SendClientMessages (void)
1709 {
1710         int i, prepared = false;
1711
1712 // update frags, names, etc
1713         SV_UpdateToReliableMessages();
1714
1715 // build individual updates
1716         for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
1717         {
1718                 if (!host_client->active)
1719                         continue;
1720                 if (!host_client->netconnection)
1721                 {
1722                         SZ_Clear(&host_client->message);
1723                         continue;
1724                 }
1725
1726                 if (host_client->deadsocket || host_client->message.overflowed)
1727                 {
1728                         SV_DropClient (true);   // if the message couldn't send, kick off
1729                         continue;
1730                 }
1731
1732                 if (host_client->spawned)
1733                 {
1734                         if (!prepared)
1735                         {
1736                                 prepared = true;
1737                                 // only prepare entities once per frame
1738                                 SV_PrepareEntitiesForSending();
1739                         }
1740                         if (!SV_SendClientDatagram (host_client))
1741                                 continue;
1742                 }
1743                 else
1744                 {
1745                 // the player isn't totally in the game yet
1746                 // send small keepalive messages if too much time has passed
1747                 // send a full message when the next signon stage has been requested
1748                 // some other message data (name changes, etc) may accumulate
1749                 // between signon stages
1750                         if (!host_client->sendsignon)
1751                         {
1752                                 if (realtime - host_client->last_message > 5)
1753                                         SV_SendNop (host_client);
1754                                 continue;       // don't send out non-signon messages
1755                         }
1756                 }
1757
1758                 if (host_client->message.cursize || host_client->dropasap)
1759                 {
1760                         if (!NetConn_CanSendMessage (host_client->netconnection))
1761                                 continue;
1762
1763                         if (host_client->dropasap)
1764                                 SV_DropClient (false);  // went to another level
1765                         else
1766                         {
1767                                 if (NetConn_SendReliableMessage (host_client->netconnection, &host_client->message) == -1)
1768                                         SV_DropClient (true);   // if the message couldn't send, kick off
1769                                 SZ_Clear (&host_client->message);
1770                                 host_client->last_message = realtime;
1771                                 host_client->sendsignon = false;
1772                         }
1773                 }
1774         }
1775
1776 // clear muzzle flashes
1777         SV_CleanupEnts();
1778 }
1779
1780
1781 /*
1782 ==============================================================================
1783
1784 SERVER SPAWNING
1785
1786 ==============================================================================
1787 */
1788
1789 /*
1790 ================
1791 SV_ModelIndex
1792
1793 ================
1794 */
1795 int SV_ModelIndex (const char *name)
1796 {
1797         int i;
1798
1799         if (!name || !name[0])
1800                 return 0;
1801
1802         for (i=0 ; i<MAX_MODELS && sv.model_precache[i] ; i++)
1803                 if (!strcmp(sv.model_precache[i], name))
1804                         return i;
1805         if (i==MAX_MODELS || !sv.model_precache[i])
1806         {
1807                 Con_DPrintf ("SV_ModelIndex: model %s not precached", name);
1808                 return -1;
1809         }
1810         return i;
1811 }
1812
1813 /*
1814 ================
1815 SV_CreateBaseline
1816
1817 ================
1818 */
1819 void SV_CreateBaseline (void)
1820 {
1821         int i, entnum, large;
1822         edict_t *svent;
1823
1824         // LordHavoc: clear *all* states (note just active ones)
1825         for (entnum = 0;entnum < sv.max_edicts;entnum++)
1826         {
1827                 // get the current server version
1828                 svent = EDICT_NUM(entnum);
1829
1830                 // LordHavoc: always clear state values, whether the entity is in use or not
1831                 svent->e->baseline = defaultstate;
1832
1833                 if (svent->e->free)
1834                         continue;
1835                 if (entnum > svs.maxclients && !svent->v->modelindex)
1836                         continue;
1837
1838                 // create entity baseline
1839                 VectorCopy (svent->v->origin, svent->e->baseline.origin);
1840                 VectorCopy (svent->v->angles, svent->e->baseline.angles);
1841                 svent->e->baseline.frame = svent->v->frame;
1842                 svent->e->baseline.skin = svent->v->skin;
1843                 if (entnum > 0 && entnum <= svs.maxclients)
1844                 {
1845                         svent->e->baseline.colormap = entnum;
1846                         i = SV_ModelIndex("progs/player.mdl");
1847                         if (i < 0)
1848                                 i = 0;
1849                         svent->e->baseline.modelindex = i;
1850                 }
1851                 else
1852                 {
1853                         svent->e->baseline.colormap = 0;
1854                         svent->e->baseline.modelindex = svent->v->modelindex;
1855                 }
1856
1857                 large = false;
1858                 if (svent->e->baseline.modelindex & 0xFF00 || svent->e->baseline.frame & 0xFF00)
1859                         large = true;
1860
1861                 // add to the message
1862                 if (large)
1863                         MSG_WriteByte (&sv.signon, svc_spawnbaseline2);
1864                 else
1865                         MSG_WriteByte (&sv.signon, svc_spawnbaseline);
1866                 MSG_WriteShort (&sv.signon, entnum);
1867
1868                 if (large)
1869                 {
1870                         MSG_WriteShort (&sv.signon, svent->e->baseline.modelindex);
1871                         MSG_WriteShort (&sv.signon, svent->e->baseline.frame);
1872                 }
1873                 else
1874                 {
1875                         MSG_WriteByte (&sv.signon, svent->e->baseline.modelindex);
1876                         MSG_WriteByte (&sv.signon, svent->e->baseline.frame);
1877                 }
1878                 MSG_WriteByte (&sv.signon, svent->e->baseline.colormap);
1879                 MSG_WriteByte (&sv.signon, svent->e->baseline.skin);
1880                 for (i=0 ; i<3 ; i++)
1881                 {
1882                         MSG_WriteCoord(&sv.signon, svent->e->baseline.origin[i], sv.protocol);
1883                         MSG_WriteAngle8i(&sv.signon, svent->e->baseline.angles[i]);
1884                 }
1885         }
1886 }
1887
1888
1889 /*
1890 ================
1891 SV_SendReconnect
1892
1893 Tell all the clients that the server is changing levels
1894 ================
1895 */
1896 void SV_SendReconnect (void)
1897 {
1898         char    data[128];
1899         sizebuf_t       msg;
1900
1901         msg.data = data;
1902         msg.cursize = 0;
1903         msg.maxsize = sizeof(data);
1904
1905         MSG_WriteChar (&msg, svc_stufftext);
1906         MSG_WriteString (&msg, "reconnect\n");
1907         NetConn_SendToAll (&msg, 5);
1908
1909         if (cls.state != ca_dedicated)
1910                 Cmd_ExecuteString ("reconnect\n", src_command);
1911 }
1912
1913
1914 /*
1915 ================
1916 SV_SaveSpawnparms
1917
1918 Grabs the current state of each client for saving across the
1919 transition to another level
1920 ================
1921 */
1922 void SV_SaveSpawnparms (void)
1923 {
1924         int             i, j;
1925
1926         svs.serverflags = pr_global_struct->serverflags;
1927
1928         for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
1929         {
1930                 if (!host_client->active)
1931                         continue;
1932
1933         // call the progs to get default spawn parms for the new client
1934                 pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
1935                 PR_ExecuteProgram (pr_global_struct->SetChangeParms, "QC function SetChangeParms is missing");
1936                 for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
1937                         host_client->spawn_parms[j] = (&pr_global_struct->parm1)[j];
1938         }
1939 }
1940
1941 void SV_IncreaseEdicts(void)
1942 {
1943         int i;
1944         edict_t *ent;
1945         int oldmax_edicts = sv.max_edicts;
1946         void *oldedictsengineprivate = sv.edictsengineprivate;
1947         void *oldedictsfields = sv.edictsfields;
1948         void *oldmoved_edicts = sv.moved_edicts;
1949
1950         if (sv.max_edicts >= MAX_EDICTS)
1951                 return;
1952
1953         // links don't survive the transition, so unlink everything
1954         for (i = 0, ent = sv.edicts;i < sv.max_edicts;i++, ent++)
1955         {
1956                 if (!ent->e->free)
1957                         SV_UnlinkEdict(sv.edicts + i);
1958                 memset(&ent->e->areagrid, 0, sizeof(ent->e->areagrid));
1959         }
1960         SV_ClearWorld();
1961
1962         sv.max_edicts   = min(sv.max_edicts + 256, MAX_EDICTS);
1963         sv.edictsengineprivate = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_engineprivate_t));
1964         sv.edictsfields = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size);
1965         sv.moved_edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *));
1966
1967         memcpy(sv.edictsengineprivate, oldedictsengineprivate, oldmax_edicts * sizeof(edict_engineprivate_t));
1968         memcpy(sv.edictsfields, oldedictsfields, oldmax_edicts * pr_edict_size);
1969
1970         for (i = 0, ent = sv.edicts;i < sv.max_edicts;i++, ent++)
1971         {
1972                 ent->e = sv.edictsengineprivate + i;
1973                 ent->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
1974                 // link every entity except world
1975                 if (!ent->e->free)
1976                         SV_LinkEdict(ent, false);
1977         }
1978
1979         Mem_Free(oldedictsengineprivate);
1980         Mem_Free(oldedictsfields);
1981         Mem_Free(oldmoved_edicts);
1982 }
1983
1984 /*
1985 ================
1986 SV_SpawnServer
1987
1988 This is called at the start of each level
1989 ================
1990 */
1991 extern float            scr_centertime_off;
1992
1993 void SV_SpawnServer (const char *server)
1994 {
1995         edict_t *ent;
1996         int i;
1997         qbyte *entities;
1998         model_t *worldmodel;
1999         char modelname[sizeof(sv.modelname)];
2000
2001         Con_DPrintf("SpawnServer: %s\n", server);
2002
2003         snprintf (modelname, sizeof(modelname), "maps/%s.bsp", server);
2004         worldmodel = Mod_ForName(modelname, false, true, true);
2005         if (!worldmodel || !worldmodel->TraceBox)
2006         {
2007                 Con_Printf("Couldn't load map %s\n", modelname);
2008                 return;
2009         }
2010
2011         // let's not have any servers with no name
2012         if (hostname.string[0] == 0)
2013                 Cvar_Set ("hostname", "UNNAMED");
2014         scr_centertime_off = 0;
2015
2016         svs.changelevel_issued = false;         // now safe to issue another
2017
2018 //
2019 // tell all connected clients that we are going to a new level
2020 //
2021         if (sv.active)
2022                 SV_SendReconnect();
2023         else
2024         {
2025                 // make sure cvars have been checked before opening the ports
2026                 NetConn_ServerFrame();
2027                 NetConn_OpenServerPorts(true);
2028         }
2029
2030 //
2031 // make cvars consistant
2032 //
2033         if (coop.integer)
2034                 Cvar_SetValue ("deathmatch", 0);
2035         current_skill = bound(0, (int)(skill.value + 0.5), 3);
2036
2037         Cvar_SetValue ("skill", (float)current_skill);
2038
2039 //
2040 // set up the new server
2041 //
2042         Host_ClearMemory ();
2043
2044         memset (&sv, 0, sizeof(sv));
2045
2046         strlcpy (sv.name, server, sizeof (sv.name));
2047
2048         // FIXME: cvar
2049         if (!strcasecmp(sv_protocolname.string, "QUAKE"))
2050         {
2051                 sv.protocol = PROTOCOL_QUAKE;
2052                 sv.netquakecompatible = true;
2053         }
2054         else if (!strcasecmp(sv_protocolname.string, "QUAKEDP"))
2055         {
2056                 sv.protocol = PROTOCOL_QUAKE;
2057                 sv.netquakecompatible = false;
2058         }
2059         else if (!strcasecmp(sv_protocolname.string, "DARKPLACES1"))
2060         {
2061                 sv.protocol = PROTOCOL_DARKPLACES1;
2062                 sv.netquakecompatible = false;
2063         }
2064         else if (!strcasecmp(sv_protocolname.string, "DARKPLACES2"))
2065         {
2066                 sv.protocol = PROTOCOL_DARKPLACES2;
2067                 sv.netquakecompatible = false;
2068         }
2069         else if (!strcasecmp(sv_protocolname.string, "DARKPLACES3"))
2070         {
2071                 sv.protocol = PROTOCOL_DARKPLACES3;
2072                 sv.netquakecompatible = false;
2073         }
2074         else if (!strcasecmp(sv_protocolname.string, "DARKPLACES4"))
2075         {
2076                 sv.protocol = PROTOCOL_DARKPLACES4;
2077                 sv.netquakecompatible = false;
2078         }
2079         else if (!strcasecmp(sv_protocolname.string, "DARKPLACES5"))
2080         {
2081                 sv.protocol = PROTOCOL_DARKPLACES5;
2082                 sv.netquakecompatible = false;
2083         }
2084         else
2085         {
2086                 sv.protocol = PROTOCOL_DARKPLACES5;
2087                 sv.netquakecompatible = false;
2088                 Con_Printf("Unknown sv_protocolname \"%s\", valid values are QUAKE, QUAKEDP, DARKPLACES1, DARKPLACES2, DARKPLACES3, DARKPLACES4, DARKPLACES5, falling back to DARKPLACES5 protocol\n", sv_protocolname.string);
2089         }
2090
2091 // load progs to get entity field count
2092         PR_LoadProgs ();
2093
2094 // allocate server memory
2095         // start out with just enough room for clients and a reasonable estimate of entities
2096         sv.max_edicts = max(svs.maxclients + 1, 512);
2097         sv.max_edicts = min(sv.max_edicts, MAX_EDICTS);
2098
2099         // clear the edict memory pool
2100         Mem_EmptyPool(sv_edicts_mempool);
2101         // edict_t structures (hidden from progs)
2102         sv.edicts = Mem_Alloc(sv_edicts_mempool, MAX_EDICTS * sizeof(edict_t));
2103         // engine private structures (hidden from progs)
2104         sv.edictsengineprivate = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_engineprivate_t));
2105         // progs fields, often accessed by server
2106         sv.edictsfields = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size);
2107         // used by PushMove to move back pushed entities
2108         sv.moved_edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *));
2109         for (i = 0;i < sv.max_edicts;i++)
2110         {
2111                 ent = sv.edicts + i;
2112                 ent->e = sv.edictsengineprivate + i;
2113                 ent->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
2114         }
2115
2116         sv.datagram.maxsize = sizeof(sv.datagram_buf);
2117         sv.datagram.cursize = 0;
2118         sv.datagram.data = sv.datagram_buf;
2119
2120         sv.reliable_datagram.maxsize = sizeof(sv.reliable_datagram_buf);
2121         sv.reliable_datagram.cursize = 0;
2122         sv.reliable_datagram.data = sv.reliable_datagram_buf;
2123
2124         sv.signon.maxsize = sizeof(sv.signon_buf);
2125         sv.signon.cursize = 0;
2126         sv.signon.data = sv.signon_buf;
2127
2128 // leave slots at start for clients only
2129         sv.num_edicts = svs.maxclients+1;
2130
2131         sv.state = ss_loading;
2132         sv.paused = false;
2133
2134         sv.time = 1.0;
2135
2136         Mod_ClearUsed();
2137         worldmodel->used = true;
2138
2139         strlcpy (sv.name, server, sizeof (sv.name));
2140         strcpy(sv.modelname, modelname);
2141         sv.worldmodel = worldmodel;
2142         sv.models[1] = sv.worldmodel;
2143
2144 //
2145 // clear world interaction links
2146 //
2147         SV_ClearWorld ();
2148
2149         sv.sound_precache[0] = "";
2150
2151         sv.model_precache[0] = "";
2152         sv.model_precache[1] = sv.modelname;
2153         for (i = 1;i < sv.worldmodel->brush.numsubmodels;i++)
2154         {
2155                 sv.model_precache[i+1] = localmodels[i];
2156                 sv.models[i+1] = Mod_ForName (localmodels[i], false, false, false);
2157         }
2158
2159 //
2160 // load the rest of the entities
2161 //
2162         ent = EDICT_NUM(0);
2163         memset (ent->v, 0, progs->entityfields * 4);
2164         ent->e->free = false;
2165         ent->v->model = PR_SetString(sv.modelname);
2166         ent->v->modelindex = 1;         // world model
2167         ent->v->solid = SOLID_BSP;
2168         ent->v->movetype = MOVETYPE_PUSH;
2169
2170         if (coop.value)
2171                 pr_global_struct->coop = coop.integer;
2172         else
2173                 pr_global_struct->deathmatch = deathmatch.integer;
2174
2175         pr_global_struct->mapname = PR_SetString(sv.name);
2176
2177 // serverflags are for cross level information (sigils)
2178         pr_global_struct->serverflags = svs.serverflags;
2179
2180         // load replacement entity file if found
2181         entities = NULL;
2182         if (sv_entpatch.integer)
2183                 entities = FS_LoadFile(va("maps/%s.ent", sv.name), tempmempool, true);
2184         if (entities)
2185         {
2186                 Con_Printf("Loaded maps/%s.ent\n", sv.name);
2187                 ED_LoadFromFile (entities);
2188                 Mem_Free(entities);
2189         }
2190         else
2191                 ED_LoadFromFile (sv.worldmodel->brush.entities);
2192
2193
2194         // LordHavoc: clear world angles (to fix e3m3.bsp)
2195         VectorClear(sv.edicts->v->angles);
2196
2197         sv.active = true;
2198
2199 // all setup is completed, any further precache statements are errors
2200         sv.state = ss_active;
2201
2202 // run two frames to allow everything to settle
2203         for (i = 0;i < 2;i++)
2204         {
2205                 sv.frametime = pr_global_struct->frametime = host_frametime = 0.1;
2206                 SV_Physics ();
2207         }
2208
2209         Mod_PurgeUnused();
2210
2211 // create a baseline for more efficient communications
2212         if (sv.protocol == PROTOCOL_QUAKE)
2213                 SV_CreateBaseline ();
2214
2215 // send serverinfo to all connected clients
2216         for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
2217                 if (host_client->netconnection)
2218                         SV_SendServerinfo(host_client);
2219
2220         Con_DPrint("Server spawned.\n");
2221         NetConn_Heartbeat (2);
2222 }
2223