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