]> icculus.org git repositories - divverent/darkplaces.git/blob - sv_main.c
made quakec stuffed quake1 protocol entities work alongside newer protocols, to attem...
[divverent/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_WriteCoord(msg, origin[0], sv.protocol);
734                 if (bits & U_ANGLE1)    MSG_WriteAngle(msg, angles[0], sv.protocol);
735                 if (bits & U_ORIGIN2)   MSG_WriteCoord(msg, origin[1], sv.protocol);
736                 if (bits & U_ANGLE2)    MSG_WriteAngle(msg, angles[1], sv.protocol);
737                 if (bits & U_ORIGIN3)   MSG_WriteCoord(msg, origin[2], sv.protocol);
738                 if (bits & U_ANGLE3)    MSG_WriteAngle(msg, angles[2], sv.protocol);
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                         MSG_WriteAngle (msg, ent->v->angles[i], sv.protocol);
1324                 ent->v->fixangle = 0;
1325         }
1326
1327         bits = 0;
1328
1329         if (ent->v->view_ofs[2] != DEFAULT_VIEWHEIGHT)
1330                 bits |= SU_VIEWHEIGHT;
1331
1332         if (ent->v->idealpitch)
1333                 bits |= SU_IDEALPITCH;
1334
1335 // stuff the sigil bits into the high bits of items for sbar, or else
1336 // mix in items2
1337         val = GETEDICTFIELDVALUE(ent, eval_items2);
1338
1339         if (val)
1340                 items = (int)ent->v->items | ((int)val->_float << 23);
1341         else
1342                 items = (int)ent->v->items | ((int)pr_global_struct->serverflags << 28);
1343
1344         bits |= SU_ITEMS;
1345
1346         if ( (int)ent->v->flags & FL_ONGROUND)
1347                 bits |= SU_ONGROUND;
1348
1349         if ( ent->v->waterlevel >= 2)
1350                 bits |= SU_INWATER;
1351
1352         // PROTOCOL_DARKPLACES
1353         VectorClear(punchvector);
1354         if ((val = GETEDICTFIELDVALUE(ent, eval_punchvector)))
1355                 VectorCopy(val->vector, punchvector);
1356
1357         i = 255;
1358         if ((val = GETEDICTFIELDVALUE(ent, eval_viewzoom)))
1359         {
1360                 i = val->_float * 255.0f;
1361                 if (i == 0)
1362                         i = 255;
1363                 else
1364                         i = bound(0, i, 65535);
1365         }
1366         viewzoom = i;
1367
1368         // FIXME: which protocols support this?  does PROTOCOL_DARKPLACES3 support viewzoom?
1369         if (sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
1370                 if (viewzoom != 255)
1371                         bits |= SU_VIEWZOOM;
1372
1373         for (i=0 ; i<3 ; i++)
1374         {
1375                 if (ent->v->punchangle[i])
1376                         bits |= (SU_PUNCH1<<i);
1377                 if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
1378                         if (punchvector[i])
1379                                 bits |= (SU_PUNCHVEC1<<i);
1380                 if (ent->v->velocity[i])
1381                         bits |= (SU_VELOCITY1<<i);
1382         }
1383
1384         if (ent->v->weaponframe)
1385                 bits |= SU_WEAPONFRAME;
1386
1387         if (ent->v->armorvalue)
1388                 bits |= SU_ARMOR;
1389
1390         bits |= SU_WEAPON;
1391
1392         if (bits >= 65536)
1393                 bits |= SU_EXTEND1;
1394         if (bits >= 16777216)
1395                 bits |= SU_EXTEND2;
1396
1397 // send the data
1398
1399         MSG_WriteByte (msg, svc_clientdata);
1400         MSG_WriteShort (msg, bits);
1401         if (bits & SU_EXTEND1)
1402                 MSG_WriteByte(msg, bits >> 16);
1403         if (bits & SU_EXTEND2)
1404                 MSG_WriteByte(msg, bits >> 24);
1405
1406         if (bits & SU_VIEWHEIGHT)
1407                 MSG_WriteChar (msg, ent->v->view_ofs[2]);
1408
1409         if (bits & SU_IDEALPITCH)
1410                 MSG_WriteChar (msg, ent->v->idealpitch);
1411
1412         for (i=0 ; i<3 ; i++)
1413         {
1414                 if (bits & (SU_PUNCH1<<i))
1415                 {
1416                         if (sv.protocol == PROTOCOL_QUAKE)
1417                                 MSG_WriteChar(msg, ent->v->punchangle[i]);
1418                         else if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
1419                                 MSG_WriteAngle16i(msg, ent->v->punchangle[i]);
1420                 }
1421                 if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
1422                 {
1423                         if (bits & (SU_PUNCHVEC1<<i))
1424                         {
1425                                 if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
1426                                         MSG_WriteCoord16i(msg, punchvector[i]);
1427                                 else if (sv.protocol == PROTOCOL_DARKPLACES5)
1428                                         MSG_WriteCoord32f(msg, punchvector[i]);
1429                         }
1430                 }
1431                 if (bits & (SU_VELOCITY1<<i))
1432                 {
1433                         if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
1434                                 MSG_WriteChar(msg, ent->v->velocity[i] * (1.0f / 16.0f));
1435                         else if (sv.protocol == PROTOCOL_DARKPLACES5)
1436                                 MSG_WriteCoord32f(msg, ent->v->velocity[i]);
1437                 }
1438         }
1439
1440 // [always sent]        if (bits & SU_ITEMS)
1441         MSG_WriteLong (msg, items);
1442
1443         if (sv.protocol == PROTOCOL_DARKPLACES5)
1444         {
1445                 if (bits & SU_WEAPONFRAME)
1446                         MSG_WriteShort (msg, ent->v->weaponframe);
1447                 if (bits & SU_ARMOR)
1448                         MSG_WriteShort (msg, ent->v->armorvalue);
1449                 if (bits & SU_WEAPON)
1450                 {
1451                         i = SV_ModelIndex(PR_GetString(ent->v->weaponmodel));
1452                         if (i < 0)
1453                         {
1454                                 Con_DPrintf("weaponmodel \"%s\" not precached\n", PR_GetString(ent->v->weaponmodel));
1455                                 i = 0;
1456                         }
1457                         MSG_WriteShort (msg, i);
1458                 }
1459
1460                 MSG_WriteShort (msg, ent->v->health);
1461                 MSG_WriteShort (msg, ent->v->currentammo);
1462                 MSG_WriteShort (msg, ent->v->ammo_shells);
1463                 MSG_WriteShort (msg, ent->v->ammo_nails);
1464                 MSG_WriteShort (msg, ent->v->ammo_rockets);
1465                 MSG_WriteShort (msg, ent->v->ammo_cells);
1466
1467                 MSG_WriteShort (msg, ent->v->weapon);
1468         
1469                 if (bits & SU_VIEWZOOM)
1470                         MSG_WriteShort (msg, viewzoom);
1471         }
1472         else
1473         {
1474                 if (bits & SU_WEAPONFRAME)
1475                         MSG_WriteByte (msg, ent->v->weaponframe);
1476                 if (bits & SU_ARMOR)
1477                         MSG_WriteByte (msg, ent->v->armorvalue);
1478                 if (bits & SU_WEAPON)
1479                 {
1480                         i = SV_ModelIndex(PR_GetString(ent->v->weaponmodel));
1481                         if (i < 0)
1482                         {
1483                                 Con_DPrintf("weaponmodel \"%s\" not precached\n", PR_GetString(ent->v->weaponmodel));
1484                                 i = 0;
1485                         }
1486                         MSG_WriteByte (msg, i);
1487                 }
1488
1489                 MSG_WriteShort (msg, ent->v->health);
1490                 MSG_WriteByte (msg, ent->v->currentammo);
1491                 MSG_WriteByte (msg, ent->v->ammo_shells);
1492                 MSG_WriteByte (msg, ent->v->ammo_nails);
1493                 MSG_WriteByte (msg, ent->v->ammo_rockets);
1494                 MSG_WriteByte (msg, ent->v->ammo_cells);
1495
1496                 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE || gamemode == GAME_NEXUIZ)
1497                 {
1498                         for(i=0;i<32;i++)
1499                         {
1500                                 if ( ((int)ent->v->weapon) & (1<<i) )
1501                                 {
1502                                         MSG_WriteByte (msg, i);
1503                                         break;
1504                                 }
1505                         }
1506                 }
1507                 else
1508                 {
1509                         MSG_WriteByte (msg, ent->v->weapon);
1510                 }
1511         
1512                 if (bits & SU_VIEWZOOM)
1513                 {
1514                         if (sv.protocol == PROTOCOL_DARKPLACES4)
1515                         {
1516                                 viewzoom = min(viewzoom, 255);
1517                                 MSG_WriteByte (msg, viewzoom);
1518                         }
1519                         else if (sv.protocol == PROTOCOL_DARKPLACES5)
1520                                 MSG_WriteShort (msg, viewzoom);
1521                 }
1522         }
1523 }
1524
1525 /*
1526 =======================
1527 SV_SendClientDatagram
1528 =======================
1529 */
1530 static qbyte sv_sendclientdatagram_buf[NET_MAXMESSAGE]; // FIXME?
1531 qboolean SV_SendClientDatagram (client_t *client)
1532 {
1533         int rate, maxrate, maxsize, maxsize2;
1534         sizebuf_t msg;
1535
1536         if (LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) == LHNETADDRESSTYPE_LOOP && !sv_ratelimitlocalplayer.integer)
1537         {
1538                 // for good singleplayer, send huge packets
1539                 maxsize = sizeof(sv_sendclientdatagram_buf);
1540                 maxsize2 = sizeof(sv_sendclientdatagram_buf);
1541         }
1542         else if (sv.protocol == PROTOCOL_DARKPLACES5)
1543         {
1544                 // PROTOCOL_DARKPLACES5 supports packet size limiting of updates
1545                 maxrate = bound(NET_MINRATE, sv_maxrate.integer, NET_MAXRATE);
1546                 if (sv_maxrate.integer != maxrate)
1547                         Cvar_SetValueQuick(&sv_maxrate, maxrate);
1548
1549                 rate = bound(NET_MINRATE, client->netconnection->rate, maxrate);
1550                 rate = (int)(client->netconnection->rate * sys_ticrate.value);
1551                 maxsize = bound(100, rate, 1400);
1552                 maxsize2 = 1400;
1553         }
1554         else
1555         {
1556                 // no rate limiting support on older protocols because dp protocols
1557                 // 1-4 kick the client off if they overflow, and quake protocol shows
1558                 // less than the full entity set if rate limited
1559                 maxsize = 1400;
1560                 maxsize2 = 1400;
1561         }
1562
1563         msg.data = sv_sendclientdatagram_buf;
1564         msg.maxsize = maxsize;
1565         msg.cursize = 0;
1566
1567         MSG_WriteByte (&msg, svc_time);
1568         MSG_WriteFloat (&msg, sv.time);
1569
1570         // add the client specific data to the datagram
1571         SV_WriteClientdataToMessage (client->edict, &msg);
1572
1573         SV_WriteEntitiesToClient (client, client->edict, &msg);
1574
1575         // expand packet size to allow effects to go over the rate limit
1576         // (dropping them is FAR too ugly)
1577         msg.maxsize = maxsize2;
1578
1579         // copy the server datagram if there is space
1580         // FIXME: put in delayed queue of effects to send
1581         if (sv.datagram.cursize > 0 && msg.cursize + sv.datagram.cursize <= msg.maxsize)
1582                 SZ_Write (&msg, sv.datagram.data, sv.datagram.cursize);
1583
1584 // send the datagram
1585         if (NetConn_SendUnreliableMessage (client->netconnection, &msg) == -1)
1586         {
1587                 SV_DropClient (true);// if the message couldn't send, kick off
1588                 return false;
1589         }
1590
1591         return true;
1592 }
1593
1594 /*
1595 =======================
1596 SV_UpdateToReliableMessages
1597 =======================
1598 */
1599 void SV_UpdateToReliableMessages (void)
1600 {
1601         int i, j;
1602         client_t *client;
1603         eval_t *val;
1604         char *s;
1605
1606 // check for changes to be sent over the reliable streams
1607         for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
1608         {
1609                 // update the host_client fields we care about according to the entity fields
1610                 sv_player = EDICT_NUM(i+1);
1611                 s = PR_GetString(sv_player->v->netname);
1612                 if (s != host_client->name)
1613                 {
1614                         if (s == NULL)
1615                                 s = "";
1616                         // point the string back at host_client->name to keep it safe
1617                         strlcpy (host_client->name, s, sizeof (host_client->name));
1618                         sv_player->v->netname = PR_SetString(host_client->name);
1619                 }
1620                 if ((val = GETEDICTFIELDVALUE(sv_player, eval_clientcolors)) && host_client->colors != val->_float)
1621                         host_client->colors = val->_float;
1622                 host_client->frags = sv_player->v->frags;
1623                 if (gamemode == GAME_NEHAHRA)
1624                         if ((val = GETEDICTFIELDVALUE(sv_player, eval_pmodel)) && host_client->pmodel != val->_float)
1625                                 host_client->pmodel = val->_float;
1626
1627                 // if the fields changed, send messages about the changes
1628                 if (strcmp(host_client->old_name, host_client->name))
1629                 {
1630                         strcpy(host_client->old_name, host_client->name);
1631                         for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1632                         {
1633                                 if (!client->spawned || !client->netconnection)
1634                                         continue;
1635                                 MSG_WriteByte (&client->message, svc_updatename);
1636                                 MSG_WriteByte (&client->message, i);
1637                                 MSG_WriteString (&client->message, host_client->name);
1638                         }
1639                 }
1640                 if (host_client->old_colors != host_client->colors)
1641                 {
1642                         host_client->old_colors = host_client->colors;
1643                         for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1644                         {
1645                                 if (!client->spawned || !client->netconnection)
1646                                         continue;
1647                                 MSG_WriteByte (&client->message, svc_updatecolors);
1648                                 MSG_WriteByte (&client->message, i);
1649                                 MSG_WriteByte (&client->message, host_client->colors);
1650                         }
1651                 }
1652                 if (host_client->old_frags != host_client->frags)
1653                 {
1654                         host_client->old_frags = host_client->frags;
1655                         for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1656                         {
1657                                 if (!client->spawned || !client->netconnection)
1658                                         continue;
1659                                 MSG_WriteByte (&client->message, svc_updatefrags);
1660                                 MSG_WriteByte (&client->message, i);
1661                                 MSG_WriteShort (&client->message, host_client->frags);
1662                         }
1663                 }
1664         }
1665
1666         for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1667                 if (client->netconnection)
1668                         SZ_Write (&client->message, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
1669
1670         SZ_Clear (&sv.reliable_datagram);
1671 }
1672
1673
1674 /*
1675 =======================
1676 SV_SendNop
1677
1678 Send a nop message without trashing or sending the accumulated client
1679 message buffer
1680 =======================
1681 */
1682 void SV_SendNop (client_t *client)
1683 {
1684         sizebuf_t       msg;
1685         qbyte           buf[4];
1686
1687         msg.data = buf;
1688         msg.maxsize = sizeof(buf);
1689         msg.cursize = 0;
1690
1691         MSG_WriteChar (&msg, svc_nop);
1692
1693         if (NetConn_SendUnreliableMessage (client->netconnection, &msg) == -1)
1694                 SV_DropClient (true);   // if the message couldn't send, kick off
1695         client->last_message = realtime;
1696 }
1697
1698 /*
1699 =======================
1700 SV_SendClientMessages
1701 =======================
1702 */
1703 void SV_SendClientMessages (void)
1704 {
1705         int i, prepared = false;
1706
1707 // update frags, names, etc
1708         SV_UpdateToReliableMessages();
1709
1710 // build individual updates
1711         for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
1712         {
1713                 if (!host_client->active)
1714                         continue;
1715                 if (!host_client->netconnection)
1716                 {
1717                         SZ_Clear(&host_client->message);
1718                         continue;
1719                 }
1720
1721                 if (host_client->deadsocket || host_client->message.overflowed)
1722                 {
1723                         SV_DropClient (true);   // if the message couldn't send, kick off
1724                         continue;
1725                 }
1726
1727                 if (host_client->spawned)
1728                 {
1729                         if (!prepared)
1730                         {
1731                                 prepared = true;
1732                                 // only prepare entities once per frame
1733                                 SV_PrepareEntitiesForSending();
1734                         }
1735                         if (!SV_SendClientDatagram (host_client))
1736                                 continue;
1737                 }
1738                 else
1739                 {
1740                 // the player isn't totally in the game yet
1741                 // send small keepalive messages if too much time has passed
1742                 // send a full message when the next signon stage has been requested
1743                 // some other message data (name changes, etc) may accumulate
1744                 // between signon stages
1745                         if (!host_client->sendsignon)
1746                         {
1747                                 if (realtime - host_client->last_message > 5)
1748                                         SV_SendNop (host_client);
1749                                 continue;       // don't send out non-signon messages
1750                         }
1751                 }
1752
1753                 if (host_client->message.cursize || host_client->dropasap)
1754                 {
1755                         if (!NetConn_CanSendMessage (host_client->netconnection))
1756                                 continue;
1757
1758                         if (host_client->dropasap)
1759                                 SV_DropClient (false);  // went to another level
1760                         else
1761                         {
1762                                 if (NetConn_SendReliableMessage (host_client->netconnection, &host_client->message) == -1)
1763                                         SV_DropClient (true);   // if the message couldn't send, kick off
1764                                 SZ_Clear (&host_client->message);
1765                                 host_client->last_message = realtime;
1766                                 host_client->sendsignon = false;
1767                         }
1768                 }
1769         }
1770
1771 // clear muzzle flashes
1772         SV_CleanupEnts();
1773 }
1774
1775
1776 /*
1777 ==============================================================================
1778
1779 SERVER SPAWNING
1780
1781 ==============================================================================
1782 */
1783
1784 /*
1785 ================
1786 SV_ModelIndex
1787
1788 ================
1789 */
1790 int SV_ModelIndex (const char *name)
1791 {
1792         int i;
1793
1794         if (!name || !name[0])
1795                 return 0;
1796
1797         for (i=0 ; i<MAX_MODELS && sv.model_precache[i] ; i++)
1798                 if (!strcmp(sv.model_precache[i], name))
1799                         return i;
1800         if (i==MAX_MODELS || !sv.model_precache[i])
1801         {
1802                 Con_DPrintf ("SV_ModelIndex: model %s not precached", name);
1803                 return -1;
1804         }
1805         return i;
1806 }
1807
1808 /*
1809 ================
1810 SV_CreateBaseline
1811
1812 ================
1813 */
1814 void SV_CreateBaseline (void)
1815 {
1816         int i, entnum, large;
1817         edict_t *svent;
1818
1819         // LordHavoc: clear *all* states (note just active ones)
1820         for (entnum = 0;entnum < sv.max_edicts;entnum++)
1821         {
1822                 // get the current server version
1823                 svent = EDICT_NUM(entnum);
1824
1825                 // LordHavoc: always clear state values, whether the entity is in use or not
1826                 svent->e->baseline = defaultstate;
1827
1828                 if (svent->e->free)
1829                         continue;
1830                 if (entnum > svs.maxclients && !svent->v->modelindex)
1831                         continue;
1832
1833                 // create entity baseline
1834                 VectorCopy (svent->v->origin, svent->e->baseline.origin);
1835                 VectorCopy (svent->v->angles, svent->e->baseline.angles);
1836                 svent->e->baseline.frame = svent->v->frame;
1837                 svent->e->baseline.skin = svent->v->skin;
1838                 if (entnum > 0 && entnum <= svs.maxclients)
1839                 {
1840                         svent->e->baseline.colormap = entnum;
1841                         i = SV_ModelIndex("progs/player.mdl");
1842                         if (i < 0)
1843                                 i = 0;
1844                         svent->e->baseline.modelindex = i;
1845                 }
1846                 else
1847                 {
1848                         svent->e->baseline.colormap = 0;
1849                         svent->e->baseline.modelindex = svent->v->modelindex;
1850                 }
1851
1852                 large = false;
1853                 if (svent->e->baseline.modelindex & 0xFF00 || svent->e->baseline.frame & 0xFF00)
1854                         large = true;
1855
1856                 // add to the message
1857                 if (large)
1858                         MSG_WriteByte (&sv.signon, svc_spawnbaseline2);
1859                 else
1860                         MSG_WriteByte (&sv.signon, svc_spawnbaseline);
1861                 MSG_WriteShort (&sv.signon, entnum);
1862
1863                 if (large)
1864                 {
1865                         MSG_WriteShort (&sv.signon, svent->e->baseline.modelindex);
1866                         MSG_WriteShort (&sv.signon, svent->e->baseline.frame);
1867                 }
1868                 else
1869                 {
1870                         MSG_WriteByte (&sv.signon, svent->e->baseline.modelindex);
1871                         MSG_WriteByte (&sv.signon, svent->e->baseline.frame);
1872                 }
1873                 MSG_WriteByte (&sv.signon, svent->e->baseline.colormap);
1874                 MSG_WriteByte (&sv.signon, svent->e->baseline.skin);
1875                 for (i=0 ; i<3 ; i++)
1876                 {
1877                         MSG_WriteCoord(&sv.signon, svent->e->baseline.origin[i], sv.protocol);
1878                         MSG_WriteAngle(&sv.signon, svent->e->baseline.angles[i], sv.protocol);
1879                 }
1880         }
1881 }
1882
1883
1884 /*
1885 ================
1886 SV_SendReconnect
1887
1888 Tell all the clients that the server is changing levels
1889 ================
1890 */
1891 void SV_SendReconnect (void)
1892 {
1893         char    data[128];
1894         sizebuf_t       msg;
1895
1896         msg.data = data;
1897         msg.cursize = 0;
1898         msg.maxsize = sizeof(data);
1899
1900         MSG_WriteChar (&msg, svc_stufftext);
1901         MSG_WriteString (&msg, "reconnect\n");
1902         NetConn_SendToAll (&msg, 5);
1903
1904         if (cls.state != ca_dedicated)
1905                 Cmd_ExecuteString ("reconnect\n", src_command);
1906 }
1907
1908
1909 /*
1910 ================
1911 SV_SaveSpawnparms
1912
1913 Grabs the current state of each client for saving across the
1914 transition to another level
1915 ================
1916 */
1917 void SV_SaveSpawnparms (void)
1918 {
1919         int             i, j;
1920
1921         svs.serverflags = pr_global_struct->serverflags;
1922
1923         for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
1924         {
1925                 if (!host_client->active)
1926                         continue;
1927
1928         // call the progs to get default spawn parms for the new client
1929                 pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
1930                 PR_ExecuteProgram (pr_global_struct->SetChangeParms, "QC function SetChangeParms is missing");
1931                 for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
1932                         host_client->spawn_parms[j] = (&pr_global_struct->parm1)[j];
1933         }
1934 }
1935
1936 void SV_IncreaseEdicts(void)
1937 {
1938         int i;
1939         edict_t *ent;
1940         int oldmax_edicts = sv.max_edicts;
1941         void *oldedictsengineprivate = sv.edictsengineprivate;
1942         void *oldedictsfields = sv.edictsfields;
1943         void *oldmoved_edicts = sv.moved_edicts;
1944
1945         if (sv.max_edicts >= MAX_EDICTS)
1946                 return;
1947
1948         // links don't survive the transition, so unlink everything
1949         for (i = 0, ent = sv.edicts;i < sv.max_edicts;i++, ent++)
1950         {
1951                 if (!ent->e->free)
1952                         SV_UnlinkEdict(sv.edicts + i);
1953                 memset(&ent->e->areagrid, 0, sizeof(ent->e->areagrid));
1954         }
1955         SV_ClearWorld();
1956
1957         sv.max_edicts   = min(sv.max_edicts + 256, MAX_EDICTS);
1958         sv.edictsengineprivate = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_engineprivate_t));
1959         sv.edictsfields = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size);
1960         sv.moved_edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *));
1961
1962         memcpy(sv.edictsengineprivate, oldedictsengineprivate, oldmax_edicts * sizeof(edict_engineprivate_t));
1963         memcpy(sv.edictsfields, oldedictsfields, oldmax_edicts * pr_edict_size);
1964
1965         for (i = 0, ent = sv.edicts;i < sv.max_edicts;i++, ent++)
1966         {
1967                 ent->e = sv.edictsengineprivate + i;
1968                 ent->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
1969                 // link every entity except world
1970                 if (!ent->e->free)
1971                         SV_LinkEdict(ent, false);
1972         }
1973
1974         Mem_Free(oldedictsengineprivate);
1975         Mem_Free(oldedictsfields);
1976         Mem_Free(oldmoved_edicts);
1977 }
1978
1979 /*
1980 ================
1981 SV_SpawnServer
1982
1983 This is called at the start of each level
1984 ================
1985 */
1986 extern float            scr_centertime_off;
1987
1988 void SV_SpawnServer (const char *server)
1989 {
1990         edict_t *ent;
1991         int i;
1992         qbyte *entities;
1993         model_t *worldmodel;
1994         char modelname[sizeof(sv.modelname)];
1995
1996         Con_DPrintf("SpawnServer: %s\n", server);
1997
1998         snprintf (modelname, sizeof(modelname), "maps/%s.bsp", server);
1999         worldmodel = Mod_ForName(modelname, false, true, true);
2000         if (!worldmodel || !worldmodel->TraceBox)
2001         {
2002                 Con_Printf("Couldn't load map %s\n", modelname);
2003                 return;
2004         }
2005
2006         // let's not have any servers with no name
2007         if (hostname.string[0] == 0)
2008                 Cvar_Set ("hostname", "UNNAMED");
2009         scr_centertime_off = 0;
2010
2011         svs.changelevel_issued = false;         // now safe to issue another
2012
2013 //
2014 // tell all connected clients that we are going to a new level
2015 //
2016         if (sv.active)
2017                 SV_SendReconnect();
2018         else
2019         {
2020                 // make sure cvars have been checked before opening the ports
2021                 NetConn_ServerFrame();
2022                 NetConn_OpenServerPorts(true);
2023         }
2024
2025 //
2026 // make cvars consistant
2027 //
2028         if (coop.integer)
2029                 Cvar_SetValue ("deathmatch", 0);
2030         current_skill = bound(0, (int)(skill.value + 0.5), 3);
2031
2032         Cvar_SetValue ("skill", (float)current_skill);
2033
2034 //
2035 // set up the new server
2036 //
2037         Host_ClearMemory ();
2038
2039         memset (&sv, 0, sizeof(sv));
2040
2041         strlcpy (sv.name, server, sizeof (sv.name));
2042
2043         // FIXME: cvar
2044         if (!strcasecmp(sv_protocolname.string, "QUAKE"))
2045         {
2046                 sv.protocol = PROTOCOL_QUAKE;
2047                 sv.netquakecompatible = true;
2048         }
2049         else if (!strcasecmp(sv_protocolname.string, "QUAKEDP"))
2050         {
2051                 sv.protocol = PROTOCOL_QUAKE;
2052                 sv.netquakecompatible = false;
2053         }
2054         else if (!strcasecmp(sv_protocolname.string, "DARKPLACES1"))
2055         {
2056                 sv.protocol = PROTOCOL_DARKPLACES1;
2057                 sv.netquakecompatible = false;
2058         }
2059         else if (!strcasecmp(sv_protocolname.string, "DARKPLACES2"))
2060         {
2061                 sv.protocol = PROTOCOL_DARKPLACES2;
2062                 sv.netquakecompatible = false;
2063         }
2064         else if (!strcasecmp(sv_protocolname.string, "DARKPLACES3"))
2065         {
2066                 sv.protocol = PROTOCOL_DARKPLACES3;
2067                 sv.netquakecompatible = false;
2068         }
2069         else if (!strcasecmp(sv_protocolname.string, "DARKPLACES4"))
2070         {
2071                 sv.protocol = PROTOCOL_DARKPLACES4;
2072                 sv.netquakecompatible = false;
2073         }
2074         else if (!strcasecmp(sv_protocolname.string, "DARKPLACES5"))
2075         {
2076                 sv.protocol = PROTOCOL_DARKPLACES5;
2077                 sv.netquakecompatible = false;
2078         }
2079         else
2080         {
2081                 sv.protocol = PROTOCOL_DARKPLACES5;
2082                 sv.netquakecompatible = false;
2083                 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);
2084         }
2085
2086 // load progs to get entity field count
2087         PR_LoadProgs ();
2088
2089 // allocate server memory
2090         // start out with just enough room for clients and a reasonable estimate of entities
2091         sv.max_edicts = max(svs.maxclients + 1, 512);
2092         sv.max_edicts = min(sv.max_edicts, MAX_EDICTS);
2093
2094         // clear the edict memory pool
2095         Mem_EmptyPool(sv_edicts_mempool);
2096         // edict_t structures (hidden from progs)
2097         sv.edicts = Mem_Alloc(sv_edicts_mempool, MAX_EDICTS * sizeof(edict_t));
2098         // engine private structures (hidden from progs)
2099         sv.edictsengineprivate = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_engineprivate_t));
2100         // progs fields, often accessed by server
2101         sv.edictsfields = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size);
2102         // used by PushMove to move back pushed entities
2103         sv.moved_edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *));
2104         for (i = 0;i < sv.max_edicts;i++)
2105         {
2106                 ent = sv.edicts + i;
2107                 ent->e = sv.edictsengineprivate + i;
2108                 ent->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
2109         }
2110
2111         sv.datagram.maxsize = sizeof(sv.datagram_buf);
2112         sv.datagram.cursize = 0;
2113         sv.datagram.data = sv.datagram_buf;
2114
2115         sv.reliable_datagram.maxsize = sizeof(sv.reliable_datagram_buf);
2116         sv.reliable_datagram.cursize = 0;
2117         sv.reliable_datagram.data = sv.reliable_datagram_buf;
2118
2119         sv.signon.maxsize = sizeof(sv.signon_buf);
2120         sv.signon.cursize = 0;
2121         sv.signon.data = sv.signon_buf;
2122
2123 // leave slots at start for clients only
2124         sv.num_edicts = svs.maxclients+1;
2125
2126         sv.state = ss_loading;
2127         sv.paused = false;
2128
2129         sv.time = 1.0;
2130
2131         Mod_ClearUsed();
2132         worldmodel->used = true;
2133
2134         strlcpy (sv.name, server, sizeof (sv.name));
2135         strcpy(sv.modelname, modelname);
2136         sv.worldmodel = worldmodel;
2137         sv.models[1] = sv.worldmodel;
2138
2139 //
2140 // clear world interaction links
2141 //
2142         SV_ClearWorld ();
2143
2144         sv.sound_precache[0] = "";
2145
2146         sv.model_precache[0] = "";
2147         sv.model_precache[1] = sv.modelname;
2148         for (i = 1;i < sv.worldmodel->brush.numsubmodels;i++)
2149         {
2150                 sv.model_precache[i+1] = localmodels[i];
2151                 sv.models[i+1] = Mod_ForName (localmodels[i], false, false, false);
2152         }
2153
2154 //
2155 // load the rest of the entities
2156 //
2157         ent = EDICT_NUM(0);
2158         memset (ent->v, 0, progs->entityfields * 4);
2159         ent->e->free = false;
2160         ent->v->model = PR_SetString(sv.modelname);
2161         ent->v->modelindex = 1;         // world model
2162         ent->v->solid = SOLID_BSP;
2163         ent->v->movetype = MOVETYPE_PUSH;
2164
2165         if (coop.value)
2166                 pr_global_struct->coop = coop.integer;
2167         else
2168                 pr_global_struct->deathmatch = deathmatch.integer;
2169
2170         pr_global_struct->mapname = PR_SetString(sv.name);
2171
2172 // serverflags are for cross level information (sigils)
2173         pr_global_struct->serverflags = svs.serverflags;
2174
2175         // load replacement entity file if found
2176         entities = NULL;
2177         if (sv_entpatch.integer)
2178                 entities = FS_LoadFile(va("maps/%s.ent", sv.name), tempmempool, true);
2179         if (entities)
2180         {
2181                 Con_Printf("Loaded maps/%s.ent\n", sv.name);
2182                 ED_LoadFromFile (entities);
2183                 Mem_Free(entities);
2184         }
2185         else
2186                 ED_LoadFromFile (sv.worldmodel->brush.entities);
2187
2188
2189         // LordHavoc: clear world angles (to fix e3m3.bsp)
2190         VectorClear(sv.edicts->v->angles);
2191
2192         sv.active = true;
2193
2194 // all setup is completed, any further precache statements are errors
2195         sv.state = ss_active;
2196
2197 // run two frames to allow everything to settle
2198         for (i = 0;i < 2;i++)
2199         {
2200                 sv.frametime = pr_global_struct->frametime = host_frametime = 0.1;
2201                 SV_Physics ();
2202         }
2203
2204         Mod_PurgeUnused();
2205
2206 // create a baseline for more efficient communications
2207         if (sv.protocol == PROTOCOL_QUAKE)
2208                 SV_CreateBaseline ();
2209
2210 // send serverinfo to all connected clients
2211         for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
2212                 if (host_client->netconnection)
2213                         SV_SendServerinfo(host_client);
2214
2215         Con_DPrint("Server spawned.\n");
2216         NetConn_Heartbeat (2);
2217 }
2218