]> icculus.org git repositories - divverent/darkplaces.git/blob - pr_edict.c
-Changed the SDL window icon back to DP's icon.
[divverent/darkplaces.git] / pr_edict.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_edict.c -- entity dictionary
21
22 #include "quakedef.h"
23
24 dprograms_t             *progs;
25 mfunction_t             *pr_functions;
26 char                    *pr_strings;
27 ddef_t                  *pr_fielddefs;
28 ddef_t                  *pr_globaldefs;
29 dstatement_t    *pr_statements;
30 globalvars_t    *pr_global_struct;
31 float                   *pr_globals;                    // same as pr_global_struct
32 int                             pr_edict_size;                  // in bytes
33 int                             pr_edictareasize;               // LordHavoc: in bytes
34
35 unsigned short  pr_crc;
36
37 mempool_t               *serverprogs_mempool;
38
39 int             type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
40
41 ddef_t *ED_FieldAtOfs(int ofs);
42 qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s);
43
44 cvar_t  pr_checkextension = {CVAR_READONLY, "pr_checkextension", "1"};
45 cvar_t  nomonsters = {0, "nomonsters", "0"};
46 cvar_t  gamecfg = {0, "gamecfg", "0"};
47 cvar_t  scratch1 = {0, "scratch1", "0"};
48 cvar_t  scratch2 = {0,"scratch2", "0"};
49 cvar_t  scratch3 = {0, "scratch3", "0"};
50 cvar_t  scratch4 = {0, "scratch4", "0"};
51 cvar_t  savedgamecfg = {CVAR_SAVE, "savedgamecfg", "0"};
52 cvar_t  saved1 = {CVAR_SAVE, "saved1", "0"};
53 cvar_t  saved2 = {CVAR_SAVE, "saved2", "0"};
54 cvar_t  saved3 = {CVAR_SAVE, "saved3", "0"};
55 cvar_t  saved4 = {CVAR_SAVE, "saved4", "0"};
56 cvar_t  decors = {0, "decors", "0"};
57 cvar_t  nehx00 = {0, "nehx00", "0"};cvar_t      nehx01 = {0, "nehx01", "0"};
58 cvar_t  nehx02 = {0, "nehx02", "0"};cvar_t      nehx03 = {0, "nehx03", "0"};
59 cvar_t  nehx04 = {0, "nehx04", "0"};cvar_t      nehx05 = {0, "nehx05", "0"};
60 cvar_t  nehx06 = {0, "nehx06", "0"};cvar_t      nehx07 = {0, "nehx07", "0"};
61 cvar_t  nehx08 = {0, "nehx08", "0"};cvar_t      nehx09 = {0, "nehx09", "0"};
62 cvar_t  nehx10 = {0, "nehx10", "0"};cvar_t      nehx11 = {0, "nehx11", "0"};
63 cvar_t  nehx12 = {0, "nehx12", "0"};cvar_t      nehx13 = {0, "nehx13", "0"};
64 cvar_t  nehx14 = {0, "nehx14", "0"};cvar_t      nehx15 = {0, "nehx15", "0"};
65 cvar_t  nehx16 = {0, "nehx16", "0"};cvar_t      nehx17 = {0, "nehx17", "0"};
66 cvar_t  nehx18 = {0, "nehx18", "0"};cvar_t      nehx19 = {0, "nehx19", "0"};
67 cvar_t  cutscene = {0, "cutscene", "1"};
68 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
69 cvar_t  pr_boundscheck = {0, "pr_boundscheck", "1"};
70 // LordHavoc: prints every opcode as it executes - warning: this is significant spew
71 cvar_t  pr_traceqc = {0, "pr_traceqc", "0"};
72
73 #define MAX_FIELD_LEN   64
74 #define GEFV_CACHESIZE  2
75
76 typedef struct {
77         ddef_t  *pcache;
78         char    field[MAX_FIELD_LEN];
79 } gefv_cache;
80
81 static gefv_cache       gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
82
83 ddef_t *ED_FindField (const char *name);
84 mfunction_t *ED_FindFunction (const char *name);
85
86 // LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue...  these are defined as externs in progs.h
87 int eval_gravity;
88 int eval_button3;
89 int eval_button4;
90 int eval_button5;
91 int eval_button6;
92 int eval_button7;
93 int eval_button8;
94 int eval_buttonuse;
95 int eval_buttonchat;
96 int eval_glow_size;
97 int eval_glow_trail;
98 int eval_glow_color;
99 int eval_items2;
100 int eval_scale;
101 int eval_alpha;
102 int eval_renderamt; // HalfLife support
103 int eval_rendermode; // HalfLife support
104 int eval_fullbright;
105 int eval_ammo_shells1;
106 int eval_ammo_nails1;
107 int eval_ammo_lava_nails;
108 int eval_ammo_rockets1;
109 int eval_ammo_multi_rockets;
110 int eval_ammo_cells1;
111 int eval_ammo_plasma;
112 int eval_idealpitch;
113 int eval_pitch_speed;
114 int eval_viewmodelforclient;
115 int eval_nodrawtoclient;
116 int eval_exteriormodeltoclient;
117 int eval_drawonlytoclient;
118 int eval_ping;
119 int eval_movement;
120 int eval_pmodel;
121 int eval_punchvector;
122 int eval_viewzoom;
123 int eval_clientcolors;
124 int eval_tag_entity;
125 int eval_tag_index;
126 int eval_light_lev;
127 int eval_color;
128 int eval_style;
129 int eval_pflags;
130 int eval_cursor_active;
131 int eval_cursor_screen;
132 int eval_cursor_trace_start;
133 int eval_cursor_trace_endpos;
134 int eval_cursor_trace_ent;
135 int eval_colormod;
136 int eval_playermodel;
137 int eval_playerskin;
138
139 mfunction_t *SV_PlayerPhysicsQC;
140 mfunction_t *EndFrameQC;
141 //KrimZon - SERVER COMMANDS IN QUAKEC
142 mfunction_t *SV_ParseClientCommandQC;
143
144 int FindFieldOffset(const char *field)
145 {
146         ddef_t *d;
147         d = ED_FindField(field);
148         if (!d)
149                 return 0;
150         return d->ofs*4;
151 }
152
153 void FindEdictFieldOffsets(void)
154 {
155         eval_gravity = FindFieldOffset("gravity");
156         eval_button3 = FindFieldOffset("button3");
157         eval_button4 = FindFieldOffset("button4");
158         eval_button5 = FindFieldOffset("button5");
159         eval_button6 = FindFieldOffset("button6");
160         eval_button7 = FindFieldOffset("button7");
161         eval_button8 = FindFieldOffset("button8");
162         eval_buttonuse = FindFieldOffset("buttonuse");
163         eval_buttonchat = FindFieldOffset("buttonchat");
164         eval_glow_size = FindFieldOffset("glow_size");
165         eval_glow_trail = FindFieldOffset("glow_trail");
166         eval_glow_color = FindFieldOffset("glow_color");
167         eval_items2 = FindFieldOffset("items2");
168         eval_scale = FindFieldOffset("scale");
169         eval_alpha = FindFieldOffset("alpha");
170         eval_renderamt = FindFieldOffset("renderamt"); // HalfLife support
171         eval_rendermode = FindFieldOffset("rendermode"); // HalfLife support
172         eval_fullbright = FindFieldOffset("fullbright");
173         eval_ammo_shells1 = FindFieldOffset("ammo_shells1");
174         eval_ammo_nails1 = FindFieldOffset("ammo_nails1");
175         eval_ammo_lava_nails = FindFieldOffset("ammo_lava_nails");
176         eval_ammo_rockets1 = FindFieldOffset("ammo_rockets1");
177         eval_ammo_multi_rockets = FindFieldOffset("ammo_multi_rockets");
178         eval_ammo_cells1 = FindFieldOffset("ammo_cells1");
179         eval_ammo_plasma = FindFieldOffset("ammo_plasma");
180         eval_idealpitch = FindFieldOffset("idealpitch");
181         eval_pitch_speed = FindFieldOffset("pitch_speed");
182         eval_viewmodelforclient = FindFieldOffset("viewmodelforclient");
183         eval_nodrawtoclient = FindFieldOffset("nodrawtoclient");
184         eval_exteriormodeltoclient = FindFieldOffset("exteriormodeltoclient");
185         eval_drawonlytoclient = FindFieldOffset("drawonlytoclient");
186         eval_ping = FindFieldOffset("ping");
187         eval_movement = FindFieldOffset("movement");
188         eval_pmodel = FindFieldOffset("pmodel");
189         eval_punchvector = FindFieldOffset("punchvector");
190         eval_viewzoom = FindFieldOffset("viewzoom");
191         eval_clientcolors = FindFieldOffset("clientcolors");
192         eval_tag_entity = FindFieldOffset("tag_entity");
193         eval_tag_index = FindFieldOffset("tag_index");
194         eval_light_lev = FindFieldOffset("light_lev");
195         eval_color = FindFieldOffset("color");
196         eval_style = FindFieldOffset("style");
197         eval_pflags = FindFieldOffset("pflags");
198         eval_cursor_active = FindFieldOffset("cursor_active");
199         eval_cursor_screen = FindFieldOffset("cursor_screen");
200         eval_cursor_trace_start = FindFieldOffset("cursor_trace_start");
201         eval_cursor_trace_endpos = FindFieldOffset("cursor_trace_endpos");
202         eval_cursor_trace_ent = FindFieldOffset("cursor_trace_ent");
203         eval_colormod = FindFieldOffset("colormod");
204         eval_playermodel = FindFieldOffset("playermodel");
205         eval_playerskin = FindFieldOffset("playerskin");
206
207         // LordHavoc: allowing QuakeC to override the player movement code
208         SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
209         // LordHavoc: support for endframe
210         EndFrameQC = ED_FindFunction ("EndFrame");
211         //KrimZon - SERVER COMMANDS IN QUAKEC
212         SV_ParseClientCommandQC = ED_FindFunction ("SV_ParseClientCommand");
213 }
214
215 /*
216 =================
217 ED_ClearEdict
218
219 Sets everything to NULL
220 =================
221 */
222 void ED_ClearEdict (edict_t *e)
223 {
224         int num;
225         memset (e->v, 0, progs->entityfields * 4);
226         e->e->free = false;
227         // LordHavoc: for consistency set these here
228         num = NUM_FOR_EDICT(e) - 1;
229         if (num >= 0 && num < svs.maxclients)
230         {
231                 eval_t *val;
232                 // set colormap and team on newly created player entity
233                 e->v->colormap = num + 1;
234                 e->v->team = (svs.clients[num].colors & 15) + 1;
235                 // set netname/clientcolors back to client values so that
236                 // DP_SV_CLIENTNAME and DPV_SV_CLIENTCOLORS will not immediately
237                 // reset them
238                 e->v->netname = PR_SetString(svs.clients[num].name);
239                 if ((val = GETEDICTFIELDVALUE(e, eval_clientcolors)))
240                         val->_float = svs.clients[num].colors;
241                 // NEXUIZ_PLAYERMODEL and NEXUIZ_PLAYERSKIN
242                 if( eval_playermodel )
243                         GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string = PR_SetString(svs.clients[num].playermodel);
244                 if( eval_playerskin )
245                         GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string = PR_SetString(svs.clients[num].playerskin);
246         }
247 }
248
249 /*
250 =================
251 ED_Alloc
252
253 Either finds a free edict, or allocates a new one.
254 Try to avoid reusing an entity that was recently freed, because it
255 can cause the client to think the entity morphed into something else
256 instead of being removed and recreated, which can cause interpolated
257 angles and bad trails.
258 =================
259 */
260 edict_t *ED_Alloc (void)
261 {
262         int                     i;
263         edict_t         *e;
264
265         for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
266         {
267                 e = EDICT_NUM(i);
268                 // the first couple seconds of server time can involve a lot of
269                 // freeing and allocating, so relax the replacement policy
270                 if (e->e->free && ( e->e->freetime < 2 || sv.time - e->e->freetime > 0.5 ) )
271                 {
272                         ED_ClearEdict (e);
273                         return e;
274                 }
275         }
276
277         if (i == MAX_EDICTS)
278                 Host_Error ("ED_Alloc: no free edicts");
279
280         sv.num_edicts++;
281         if (sv.num_edicts >= sv.max_edicts)
282                 SV_IncreaseEdicts();
283         e = EDICT_NUM(i);
284         ED_ClearEdict (e);
285
286         return e;
287 }
288
289 /*
290 =================
291 ED_Free
292
293 Marks the edict as free
294 FIXME: walk all entities and NULL out references to this entity
295 =================
296 */
297 void ED_Free (edict_t *ed)
298 {
299         SV_UnlinkEdict (ed);            // unlink from world bsp
300
301         ed->e->free = true;
302         ed->v->model = 0;
303         ed->v->takedamage = 0;
304         ed->v->modelindex = 0;
305         ed->v->colormap = 0;
306         ed->v->skin = 0;
307         ed->v->frame = 0;
308         VectorClear(ed->v->origin);
309         VectorClear(ed->v->angles);
310         ed->v->nextthink = -1;
311         ed->v->solid = 0;
312
313         ed->e->freetime = sv.time;
314 }
315
316 //===========================================================================
317
318 /*
319 ============
320 ED_GlobalAtOfs
321 ============
322 */
323 ddef_t *ED_GlobalAtOfs (int ofs)
324 {
325         ddef_t          *def;
326         int                     i;
327
328         for (i=0 ; i<progs->numglobaldefs ; i++)
329         {
330                 def = &pr_globaldefs[i];
331                 if (def->ofs == ofs)
332                         return def;
333         }
334         return NULL;
335 }
336
337 /*
338 ============
339 ED_FieldAtOfs
340 ============
341 */
342 ddef_t *ED_FieldAtOfs (int ofs)
343 {
344         ddef_t          *def;
345         int                     i;
346
347         for (i=0 ; i<progs->numfielddefs ; i++)
348         {
349                 def = &pr_fielddefs[i];
350                 if (def->ofs == ofs)
351                         return def;
352         }
353         return NULL;
354 }
355
356 /*
357 ============
358 ED_FindField
359 ============
360 */
361 ddef_t *ED_FindField (const char *name)
362 {
363         ddef_t *def;
364         int i;
365
366         for (i=0 ; i<progs->numfielddefs ; i++)
367         {
368                 def = &pr_fielddefs[i];
369                 if (!strcmp(PR_GetString(def->s_name), name))
370                         return def;
371         }
372         return NULL;
373 }
374
375 /*
376 ============
377 ED_FindGlobal
378 ============
379 */
380 ddef_t *ED_FindGlobal (const char *name)
381 {
382         ddef_t *def;
383         int i;
384
385         for (i=0 ; i<progs->numglobaldefs ; i++)
386         {
387                 def = &pr_globaldefs[i];
388                 if (!strcmp(PR_GetString(def->s_name), name))
389                         return def;
390         }
391         return NULL;
392 }
393
394
395 /*
396 ============
397 ED_FindFunction
398 ============
399 */
400 mfunction_t *ED_FindFunction (const char *name)
401 {
402         mfunction_t             *func;
403         int                             i;
404
405         for (i=0 ; i<progs->numfunctions ; i++)
406         {
407                 func = &pr_functions[i];
408                 if (!strcmp(PR_GetString(func->s_name), name))
409                         return func;
410         }
411         return NULL;
412 }
413
414
415 /*
416 ============
417 PR_ValueString
418
419 Returns a string describing *data in a type specific manner
420 =============
421 */
422 //int NoCrash_NUM_FOR_EDICT(edict_t *e);
423 char *PR_ValueString (etype_t type, eval_t *val)
424 {
425         static char line[1024]; // LordHavoc: enlarged a bit (was 256)
426         ddef_t *def;
427         mfunction_t *f;
428         int n;
429
430         type &= ~DEF_SAVEGLOBAL;
431
432         switch (type)
433         {
434         case ev_string:
435                 strlcpy (line, PR_GetString (val->string), sizeof (line));
436                 break;
437         case ev_entity:
438                 //n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict));
439                 n = val->edict;
440                 if (n < 0 || n >= MAX_EDICTS)
441                         dpsnprintf (line, sizeof (line), "entity %i (invalid!)", n);
442                 else
443                         dpsnprintf (line, sizeof (line), "entity %i", n);
444                 break;
445         case ev_function:
446                 f = pr_functions + val->function;
447                 dpsnprintf (line, sizeof (line), "%s()", PR_GetString(f->s_name));
448                 break;
449         case ev_field:
450                 def = ED_FieldAtOfs ( val->_int );
451                 dpsnprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
452                 break;
453         case ev_void:
454                 dpsnprintf (line, sizeof (line), "void");
455                 break;
456         case ev_float:
457                 // LordHavoc: changed from %5.1f to %10.4f
458                 dpsnprintf (line, sizeof (line), "%10.4f", val->_float);
459                 break;
460         case ev_vector:
461                 // LordHavoc: changed from %5.1f to %10.4f
462                 dpsnprintf (line, sizeof (line), "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
463                 break;
464         case ev_pointer:
465                 dpsnprintf (line, sizeof (line), "pointer");
466                 break;
467         default:
468                 dpsnprintf (line, sizeof (line), "bad type %i", type);
469                 break;
470         }
471
472         return line;
473 }
474
475 /*
476 ============
477 PR_UglyValueString
478
479 Returns a string describing *data in a type specific manner
480 Easier to parse than PR_ValueString
481 =============
482 */
483 char *PR_UglyValueString (etype_t type, eval_t *val)
484 {
485         static char line[4096];
486         int i;
487         char *s;
488         ddef_t *def;
489         mfunction_t *f;
490
491         type &= ~DEF_SAVEGLOBAL;
492
493         switch (type)
494         {
495         case ev_string:
496                 // Parse the string a bit to turn special characters
497                 // (like newline, specifically) into escape codes,
498                 // this fixes saving games from various mods
499                 s = PR_GetString (val->string);
500                 for (i = 0;i < (int)sizeof(line) - 2 && *s;)
501                 {
502                         if (*s == '\n')
503                         {
504                                 line[i++] = '\\';
505                                 line[i++] = 'n';
506                         }
507                         else if (*s == '\r')
508                         {
509                                 line[i++] = '\\';
510                                 line[i++] = 'r';
511                         }
512                         else
513                                 line[i++] = *s;
514                         s++;
515                 }
516                 line[i] = '\0';
517                 break;
518         case ev_entity:
519                 dpsnprintf (line, sizeof (line), "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
520                 break;
521         case ev_function:
522                 f = pr_functions + val->function;
523                 strlcpy (line, PR_GetString (f->s_name), sizeof (line));
524                 break;
525         case ev_field:
526                 def = ED_FieldAtOfs ( val->_int );
527                 dpsnprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
528                 break;
529         case ev_void:
530                 dpsnprintf (line, sizeof (line), "void");
531                 break;
532         case ev_float:
533                 dpsnprintf (line, sizeof (line), "%f", val->_float);
534                 break;
535         case ev_vector:
536                 dpsnprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
537                 break;
538         default:
539                 dpsnprintf (line, sizeof (line), "bad type %i", type);
540                 break;
541         }
542
543         return line;
544 }
545
546 /*
547 ============
548 PR_GlobalString
549
550 Returns a string with a description and the contents of a global,
551 padded to 20 field width
552 ============
553 */
554 char *PR_GlobalString (int ofs)
555 {
556         char    *s;
557         int             i;
558         ddef_t  *def;
559         void    *val;
560         static char     line[128];
561
562         val = (void *)&pr_globals[ofs];
563         def = ED_GlobalAtOfs(ofs);
564         if (!def)
565                 dpsnprintf (line, sizeof (line), "%i(?)", ofs);
566         else
567         {
568                 s = PR_ValueString (def->type, val);
569                 dpsnprintf (line, sizeof (line), "%i(%s)%s", ofs, PR_GetString(def->s_name), s);
570         }
571
572         i = strlen(line);
573         for ( ; i<20 ; i++)
574                 strlcat (line, " ", sizeof (line));
575         strlcat (line, " ", sizeof (line));
576
577         return line;
578 }
579
580 char *PR_GlobalStringNoContents (int ofs)
581 {
582         int             i;
583         ddef_t  *def;
584         static char     line[128];
585
586         def = ED_GlobalAtOfs(ofs);
587         if (!def)
588                 dpsnprintf (line, sizeof (line), "%i(?)", ofs);
589         else
590                 dpsnprintf (line, sizeof (line), "%i(%s)", ofs, PR_GetString(def->s_name));
591
592         i = strlen(line);
593         for ( ; i<20 ; i++)
594                 strlcat (line, " ", sizeof (line));
595         strlcat (line, " ", sizeof (line));
596
597         return line;
598 }
599
600
601 /*
602 =============
603 ED_Print
604
605 For debugging
606 =============
607 */
608 // LordHavoc: optimized this to print out much more quickly (tempstring)
609 // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
610 void ED_Print(edict_t *ed)
611 {
612         int             l;
613         ddef_t  *d;
614         int             *v;
615         int             i, j;
616         char    *name;
617         int             type;
618         char    tempstring[8192], tempstring2[260]; // temporary string buffers
619
620         if (ed->e->free)
621         {
622                 Con_Print("FREE\n");
623                 return;
624         }
625
626         tempstring[0] = 0;
627         dpsnprintf (tempstring, sizeof (tempstring), "\nEDICT %i:\n", NUM_FOR_EDICT(ed));
628         for (i=1 ; i<progs->numfielddefs ; i++)
629         {
630                 d = &pr_fielddefs[i];
631                 name = PR_GetString(d->s_name);
632                 if (name[strlen(name)-2] == '_')
633                         continue;       // skip _x, _y, _z vars
634
635                 v = (int *)((char *)ed->v + d->ofs*4);
636
637         // if the value is still all 0, skip the field
638                 type = d->type & ~DEF_SAVEGLOBAL;
639
640                 for (j=0 ; j<type_size[type] ; j++)
641                         if (v[j])
642                                 break;
643                 if (j == type_size[type])
644                         continue;
645
646                 if (strlen(name) > 256)
647                 {
648                         memcpy (tempstring2, name, 256);
649                         tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
650                         tempstring2[259] = 0;
651                         name = tempstring2;
652                 }
653                 strlcat (tempstring, name, sizeof (tempstring));
654                 for (l = strlen(name);l < 14;l++)
655                         strcat(tempstring, " ");
656                 strcat(tempstring, " ");
657
658                 name = PR_ValueString(d->type, (eval_t *)v);
659                 if (strlen(name) > 256)
660                 {
661                         memcpy(tempstring2, name, 256);
662                         tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
663                         tempstring2[259] = 0;
664                         name = tempstring2;
665                 }
666                 strlcat (tempstring, name, sizeof (tempstring));
667                 strlcat (tempstring, "\n", sizeof (tempstring));
668                 if (strlen(tempstring) >= 4096)
669                 {
670                         Con_Print(tempstring);
671                         tempstring[0] = 0;
672                 }
673         }
674         if (tempstring[0])
675                 Con_Print(tempstring);
676 }
677
678 /*
679 =============
680 ED_Write
681
682 For savegames
683 =============
684 */
685 void ED_Write (qfile_t *f, edict_t *ed)
686 {
687         ddef_t  *d;
688         int             *v;
689         int             i, j;
690         char    *name;
691         int             type;
692
693         FS_Print(f, "{\n");
694
695         if (ed->e->free)
696         {
697                 FS_Print(f, "}\n");
698                 return;
699         }
700
701         for (i=1 ; i<progs->numfielddefs ; i++)
702         {
703                 d = &pr_fielddefs[i];
704                 name = PR_GetString(d->s_name);
705                 if (name[strlen(name)-2] == '_')
706                         continue;       // skip _x, _y, _z vars
707
708                 v = (int *)((char *)ed->v + d->ofs*4);
709
710         // if the value is still all 0, skip the field
711                 type = d->type & ~DEF_SAVEGLOBAL;
712                 for (j=0 ; j<type_size[type] ; j++)
713                         if (v[j])
714                                 break;
715                 if (j == type_size[type])
716                         continue;
717
718                 FS_Printf(f,"\"%s\" ",name);
719                 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
720         }
721
722         FS_Print(f, "}\n");
723 }
724
725 void ED_PrintNum (int ent)
726 {
727         ED_Print(EDICT_NUM(ent));
728 }
729
730 /*
731 =============
732 ED_PrintEdicts
733
734 For debugging, prints all the entities in the current server
735 =============
736 */
737 void ED_PrintEdicts (void)
738 {
739         int             i;
740
741         Con_Printf("%i entities\n", sv.num_edicts);
742         for (i=0 ; i<sv.num_edicts ; i++)
743                 ED_PrintNum (i);
744 }
745
746 /*
747 =============
748 ED_PrintEdict_f
749
750 For debugging, prints a single edict
751 =============
752 */
753 void ED_PrintEdict_f (void)
754 {
755         int             i;
756
757         i = atoi (Cmd_Argv(1));
758         if (i < 0 || i >= sv.num_edicts)
759         {
760                 Con_Print("Bad edict number\n");
761                 return;
762         }
763         ED_PrintNum (i);
764 }
765
766 /*
767 =============
768 ED_Count
769
770 For debugging
771 =============
772 */
773 void ED_Count (void)
774 {
775         int             i;
776         edict_t *ent;
777         int             active, models, solid, step;
778
779         active = models = solid = step = 0;
780         for (i=0 ; i<sv.num_edicts ; i++)
781         {
782                 ent = EDICT_NUM(i);
783                 if (ent->e->free)
784                         continue;
785                 active++;
786                 if (ent->v->solid)
787                         solid++;
788                 if (ent->v->model)
789                         models++;
790                 if (ent->v->movetype == MOVETYPE_STEP)
791                         step++;
792         }
793
794         Con_Printf("num_edicts:%3i\n", sv.num_edicts);
795         Con_Printf("active    :%3i\n", active);
796         Con_Printf("view      :%3i\n", models);
797         Con_Printf("touch     :%3i\n", solid);
798         Con_Printf("step      :%3i\n", step);
799
800 }
801
802 /*
803 ==============================================================================
804
805                                         ARCHIVING GLOBALS
806
807 FIXME: need to tag constants, doesn't really work
808 ==============================================================================
809 */
810
811 /*
812 =============
813 ED_WriteGlobals
814 =============
815 */
816 void ED_WriteGlobals (qfile_t *f)
817 {
818         ddef_t          *def;
819         int                     i;
820         char            *name;
821         int                     type;
822
823         FS_Print(f,"{\n");
824         for (i=0 ; i<progs->numglobaldefs ; i++)
825         {
826                 def = &pr_globaldefs[i];
827                 type = def->type;
828                 if ( !(def->type & DEF_SAVEGLOBAL) )
829                         continue;
830                 type &= ~DEF_SAVEGLOBAL;
831
832                 if (type != ev_string && type != ev_float && type != ev_entity)
833                         continue;
834
835                 name = PR_GetString(def->s_name);
836                 FS_Printf(f,"\"%s\" ", name);
837                 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
838         }
839         FS_Print(f,"}\n");
840 }
841
842 /*
843 =============
844 ED_EdictSet_f
845
846 Console command to set a field of a specified edict
847 =============
848 */
849 void ED_EdictSet_f(void)
850 {
851         edict_t *ed;
852         ddef_t *key;
853
854         if(Cmd_Argc() != 4)
855         {
856                 Con_Print("edictset <edict number> <field> <value>\n");
857                 return;
858         }
859         ed = EDICT_NUM(atoi(Cmd_Argv(1)));
860
861         if((key = ED_FindField(Cmd_Argv(2))) == 0)
862         {
863                 Con_Printf("Key %s not found !\n", Cmd_Argv(2));
864                 return;
865         }
866
867         ED_ParseEpair(ed, key, Cmd_Argv(3));
868 }
869
870 /*
871 =============
872 ED_ParseGlobals
873 =============
874 */
875 void ED_ParseGlobals (const char *data)
876 {
877         char keyname[1024]; // LordHavoc: good idea? bad idea?  was 64
878         ddef_t *key;
879
880         while (1)
881         {
882                 // parse key
883                 if (!COM_ParseToken(&data, false))
884                         Host_Error ("ED_ParseEntity: EOF without closing brace");
885                 if (com_token[0] == '}')
886                         break;
887
888                 strcpy (keyname, com_token);
889
890                 // parse value
891                 if (!COM_ParseToken(&data, false))
892                         Host_Error ("ED_ParseEntity: EOF without closing brace");
893
894                 if (com_token[0] == '}')
895                         Host_Error ("ED_ParseEntity: closing brace without data");
896
897                 key = ED_FindGlobal (keyname);
898                 if (!key)
899                 {
900                         Con_DPrintf("'%s' is not a global\n", keyname);
901                         continue;
902                 }
903
904                 if (!ED_ParseEpair(NULL, key, com_token))
905                         Host_Error ("ED_ParseGlobals: parse error");
906         }
907 }
908
909 //============================================================================
910
911
912 /*
913 =============
914 ED_NewString
915 =============
916 */
917 char *ED_NewString (const char *string)
918 {
919         char *new, *new_p;
920         int i,l;
921
922         l = strlen(string) + 1;
923         new = PR_Alloc(l);
924         new_p = new;
925
926         for (i=0 ; i< l ; i++)
927         {
928                 if (string[i] == '\\' && i < l-1)
929                 {
930                         i++;
931                         if (string[i] == 'n')
932                                 *new_p++ = '\n';
933                         else if (string[i] == 'r')
934                                 *new_p++ = '\r';
935                         else
936                                 *new_p++ = '\\';
937                 }
938                 else
939                         *new_p++ = string[i];
940         }
941
942         return new;
943 }
944
945
946 /*
947 =============
948 ED_ParseEval
949
950 Can parse either fields or globals
951 returns false if error
952 =============
953 */
954 qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
955 {
956         int i;
957         ddef_t *def;
958         eval_t *val;
959         mfunction_t *func;
960
961         if (ent)
962                 val = (eval_t *)((int *)ent->v + key->ofs);
963         else
964                 val = (eval_t *)((int *)pr_globals + key->ofs);
965         switch (key->type & ~DEF_SAVEGLOBAL)
966         {
967         case ev_string:
968                 val->string = PR_SetString(ED_NewString(s));
969                 break;
970
971         case ev_float:
972                 while (*s && *s <= ' ')
973                         s++;
974                 val->_float = atof(s);
975                 break;
976
977         case ev_vector:
978                 for (i = 0;i < 3;i++)
979                 {
980                         while (*s && *s <= ' ')
981                                 s++;
982                         if (*s)
983                                 val->vector[i] = atof(s);
984                         else
985                                 val->vector[i] = 0;
986                         while (*s > ' ')
987                                 s++;
988                 }
989                 break;
990
991         case ev_entity:
992                 while (*s && *s <= ' ')
993                         s++;
994                 i = atoi(s);
995                 if (i < 0 || i >= MAX_EDICTS)
996                         Con_Printf("ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i)\n", i, MAX_EDICTS);
997                 while (i >= sv.max_edicts)
998                         SV_IncreaseEdicts();
999                 // if SV_IncreaseEdicts was called the base pointer needs to be updated
1000                 if (ent)
1001                         val = (eval_t *)((int *)ent->v + key->ofs);
1002                 val->edict = EDICT_TO_PROG(EDICT_NUM(i));
1003                 break;
1004
1005         case ev_field:
1006                 def = ED_FindField(s);
1007                 if (!def)
1008                 {
1009                         Con_DPrintf("ED_ParseEpair: Can't find field %s\n", s);
1010                         return false;
1011                 }
1012                 //val->_int = G_INT(def->ofs); // AK Please check this - seems to be an org. quake bug
1013                 val->_int = def->ofs;
1014                 break;
1015
1016         case ev_function:
1017                 func = ED_FindFunction(s);
1018                 if (!func)
1019                 {
1020                         Con_Printf("ED_ParseEpair: Can't find function %s\n", s);
1021                         return false;
1022                 }
1023                 val->function = func - pr_functions;
1024                 break;
1025
1026         default:
1027                 Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PR_GetString(key->s_name));
1028                 return false;
1029         }
1030         return true;
1031 }
1032
1033 /*
1034 ====================
1035 ED_ParseEdict
1036
1037 Parses an edict out of the given string, returning the new position
1038 ed should be a properly initialized empty edict.
1039 Used for initial level load and for savegames.
1040 ====================
1041 */
1042 const char *ED_ParseEdict (const char *data, edict_t *ent)
1043 {
1044         ddef_t *key;
1045         qboolean anglehack;
1046         qboolean init;
1047         char keyname[256];
1048         int n;
1049
1050         init = false;
1051
1052 // clear it
1053         if (ent != sv.edicts)   // hack
1054                 memset (ent->v, 0, progs->entityfields * 4);
1055
1056 // go through all the dictionary pairs
1057         while (1)
1058         {
1059         // parse key
1060                 if (!COM_ParseToken(&data, false))
1061                         Host_Error ("ED_ParseEntity: EOF without closing brace");
1062                 if (com_token[0] == '}')
1063                         break;
1064
1065                 // anglehack is to allow QuakeEd to write single scalar angles
1066                 // and allow them to be turned into vectors. (FIXME...)
1067                 anglehack = !strcmp (com_token, "angle");
1068                 if (anglehack)
1069                         strlcpy (com_token, "angles", sizeof (com_token));
1070
1071                 // FIXME: change light to _light to get rid of this hack
1072                 if (!strcmp(com_token, "light"))
1073                         strlcpy (com_token, "light_lev", sizeof (com_token));   // hack for single light def
1074
1075                 strlcpy (keyname, com_token, sizeof (keyname));
1076
1077                 // another hack to fix heynames with trailing spaces
1078                 n = strlen(keyname);
1079                 while (n && keyname[n-1] == ' ')
1080                 {
1081                         keyname[n-1] = 0;
1082                         n--;
1083                 }
1084
1085         // parse value
1086                 if (!COM_ParseToken(&data, false))
1087                         Host_Error ("ED_ParseEntity: EOF without closing brace");
1088
1089                 if (com_token[0] == '}')
1090                         Host_Error ("ED_ParseEntity: closing brace without data");
1091
1092                 init = true;
1093
1094 // keynames with a leading underscore are used for utility comments,
1095 // and are immediately discarded by quake
1096                 if (keyname[0] == '_')
1097                         continue;
1098
1099                 key = ED_FindField (keyname);
1100                 if (!key)
1101                 {
1102                         Con_DPrintf("'%s' is not a field\n", keyname);
1103                         continue;
1104                 }
1105
1106                 if (anglehack)
1107                 {
1108                         char    temp[32];
1109                         strlcpy (temp, com_token, sizeof (temp));
1110                         dpsnprintf (com_token, sizeof (com_token), "0 %s 0", temp);
1111                 }
1112
1113                 if (!ED_ParseEpair(ent, key, com_token))
1114                         Host_Error ("ED_ParseEdict: parse error");
1115         }
1116
1117         if (!init)
1118                 ent->e->free = true;
1119
1120         return data;
1121 }
1122
1123
1124 /*
1125 ================
1126 ED_LoadFromFile
1127
1128 The entities are directly placed in the array, rather than allocated with
1129 ED_Alloc, because otherwise an error loading the map would have entity
1130 number references out of order.
1131
1132 Creates a server's entity / program execution context by
1133 parsing textual entity definitions out of an ent file.
1134
1135 Used for both fresh maps and savegame loads.  A fresh map would also need
1136 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1137 ================
1138 */
1139 void ED_LoadFromFile (const char *data)
1140 {
1141         edict_t *ent;
1142         int parsed, inhibited, spawned, died;
1143         mfunction_t *func;
1144
1145         ent = NULL;
1146         parsed = 0;
1147         inhibited = 0;
1148         spawned = 0;
1149         died = 0;
1150         pr_global_struct->time = sv.time;
1151
1152 // parse ents
1153         while (1)
1154         {
1155 // parse the opening brace
1156                 if (!COM_ParseToken(&data, false))
1157                         break;
1158                 if (com_token[0] != '{')
1159                         Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
1160
1161                 if (!ent)
1162                         ent = EDICT_NUM(0);
1163                 else
1164                         ent = ED_Alloc ();
1165                 data = ED_ParseEdict (data, ent);
1166                 parsed++;
1167
1168 // remove things from different skill levels or deathmatch
1169                 if (gamemode != GAME_TRANSFUSION) //Transfusion does this in QC
1170                 {
1171                         if (deathmatch.integer)
1172                         {
1173                                 if (((int)ent->v->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
1174                                 {
1175                                         ED_Free (ent);
1176                                         inhibited++;
1177                                         continue;
1178                                 }
1179                         }
1180                         else if ((current_skill <= 0 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_EASY  ))
1181                                 || (current_skill == 1 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_MEDIUM))
1182                                 || (current_skill >= 2 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_HARD  )))
1183                         {
1184                                 ED_Free (ent);
1185                                 inhibited++;
1186                                 continue;
1187                         }
1188                 }
1189 //
1190 // immediately call spawn function
1191 //
1192                 if (!ent->v->classname)
1193                 {
1194                         Con_Print("No classname for:\n");
1195                         ED_Print(ent);
1196                         ED_Free (ent);
1197                         continue;
1198                 }
1199
1200         // look for the spawn function
1201                 func = ED_FindFunction (PR_GetString(ent->v->classname));
1202
1203                 if (!func)
1204                 {
1205                         if (developer.integer) // don't confuse non-developers with errors
1206                         {
1207                                 Con_Print("No spawn function for:\n");
1208                                 ED_Print(ent);
1209                         }
1210                         ED_Free (ent);
1211                         continue;
1212                 }
1213
1214                 pr_global_struct->self = EDICT_TO_PROG(ent);
1215                 PR_ExecuteProgram (func - pr_functions, "QC function spawn is missing");
1216                 spawned++;
1217                 if (ent->e->free)
1218                         died++;
1219         }
1220
1221         Con_DPrintf("%i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", parsed, inhibited, spawned, died, spawned - died);
1222 }
1223
1224
1225 typedef struct dpfield_s
1226 {
1227         int type;
1228         char *string;
1229 }
1230 dpfield_t;
1231
1232 #define DPFIELDS (sizeof(dpfields) / sizeof(dpfield_t))
1233
1234 dpfield_t dpfields[] =
1235 {
1236         {ev_entity, "cursor_trace_ent"},
1237         {ev_entity, "drawonlytoclient"},
1238         {ev_entity, "exteriormodeltoclient"},
1239         {ev_entity, "nodrawtoclient"},
1240         {ev_entity, "tag_entity"},
1241         {ev_entity, "viewmodelforclient"},
1242         {ev_float, "alpha"},
1243         {ev_float, "ammo_cells1"},
1244         {ev_float, "ammo_lava_nails"},
1245         {ev_float, "ammo_multi_rockets"},
1246         {ev_float, "ammo_nails1"},
1247         {ev_float, "ammo_plasma"},
1248         {ev_float, "ammo_rockets1"},
1249         {ev_float, "ammo_shells1"},
1250         {ev_float, "button3"},
1251         {ev_float, "button4"},
1252         {ev_float, "button5"},
1253         {ev_float, "button6"},
1254         {ev_float, "button7"},
1255         {ev_float, "button8"},
1256         {ev_float, "buttonchat"},
1257         {ev_float, "buttonuse"},
1258         {ev_float, "clientcolors"},
1259         {ev_float, "cursor_active"},
1260         {ev_float, "fullbright"},
1261         {ev_float, "glow_color"},
1262         {ev_float, "glow_size"},
1263         {ev_float, "glow_trail"},
1264         {ev_float, "gravity"},
1265         {ev_float, "idealpitch"},
1266         {ev_float, "items2"},
1267         {ev_float, "light_lev"},
1268         {ev_float, "pflags"},
1269         {ev_float, "ping"},
1270         {ev_float, "pitch_speed"},
1271         {ev_float, "pmodel"},
1272         {ev_float, "renderamt"}, // HalfLife support
1273         {ev_float, "rendermode"}, // HalfLife support
1274         {ev_float, "scale"},
1275         {ev_float, "style"},
1276         {ev_float, "tag_index"},
1277         {ev_float, "viewzoom"},
1278         {ev_vector, "color"},
1279         {ev_vector, "colormod"},
1280         {ev_vector, "cursor_screen"},
1281         {ev_vector, "cursor_trace_endpos"},
1282         {ev_vector, "cursor_trace_start"},
1283         {ev_vector, "movement"},
1284         {ev_vector, "punchvector"},
1285         {ev_string, "playermodel"},
1286         {ev_string, "playerskin"}
1287 };
1288
1289 /*
1290 ===============
1291 PR_LoadProgs
1292 ===============
1293 */
1294 extern void PR_Cmd_Reset (void);
1295 void PR_LoadProgs (const char *progsname)
1296 {
1297         int i;
1298         dstatement_t *st;
1299         ddef_t *infielddefs;
1300         dfunction_t *dfunctions;
1301
1302         if (!progsname || !*progsname)
1303                 Host_Error("PR_LoadProgs: passed empty progsname");
1304
1305 // flush the non-C variable lookup cache
1306         for (i=0 ; i<GEFV_CACHESIZE ; i++)
1307                 gefvCache[i].field[0] = 0;
1308
1309         PR_FreeAll();
1310
1311         progs = (dprograms_t *)FS_LoadFile (progsname, serverprogs_mempool, false);
1312         if (!progs)
1313                 Host_Error ("PR_LoadProgs: couldn't load %s", progsname);
1314
1315         Con_DPrintf("Programs occupy %iK.\n", fs_filesize/1024);
1316
1317         pr_crc = CRC_Block((qbyte *)progs, fs_filesize);
1318
1319 // byte swap the header
1320         for (i = 0;i < (int) sizeof(*progs) / 4;i++)
1321                 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1322
1323         if (progs->version != PROG_VERSION)
1324                 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1325         if (progs->crc != PROGHEADER_CRC && progs->crc != 32401) // tenebrae crc also allowed
1326                 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1327
1328         //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1329         dfunctions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1330         pr_strings = (char *)progs + progs->ofs_strings;
1331         pr_globaldefs = (ddef_t *)((qbyte *)progs + progs->ofs_globaldefs);
1332
1333         // we need to expand the fielddefs list to include all the engine fields,
1334         // so allocate a new place for it
1335         infielddefs = (ddef_t *)((qbyte *)progs + progs->ofs_fielddefs);
1336         pr_fielddefs = PR_Alloc((progs->numfielddefs + DPFIELDS) * sizeof(ddef_t));
1337         pr_functions = PR_Alloc(sizeof(mfunction_t) * progs->numfunctions);
1338
1339         pr_statements = (dstatement_t *)((qbyte *)progs + progs->ofs_statements);
1340
1341         // moved edict_size calculation down below field adding code
1342
1343         pr_global_struct = (globalvars_t *)((qbyte *)progs + progs->ofs_globals);
1344         pr_globals = (float *)pr_global_struct;
1345
1346 // byte swap the lumps
1347         for (i=0 ; i<progs->numstatements ; i++)
1348         {
1349                 pr_statements[i].op = LittleShort(pr_statements[i].op);
1350                 pr_statements[i].a = LittleShort(pr_statements[i].a);
1351                 pr_statements[i].b = LittleShort(pr_statements[i].b);
1352                 pr_statements[i].c = LittleShort(pr_statements[i].c);
1353         }
1354
1355         for (i = 0;i < progs->numfunctions;i++)
1356         {
1357                 pr_functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
1358                 pr_functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
1359                 pr_functions[i].s_name = LittleLong (dfunctions[i].s_name);
1360                 pr_functions[i].s_file = LittleLong (dfunctions[i].s_file);
1361                 pr_functions[i].numparms = LittleLong (dfunctions[i].numparms);
1362                 pr_functions[i].locals = LittleLong (dfunctions[i].locals);
1363                 memcpy(pr_functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
1364         }
1365
1366         for (i=0 ; i<progs->numglobaldefs ; i++)
1367         {
1368                 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1369                 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1370                 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1371         }
1372
1373         // copy the progs fields to the new fields list
1374         for (i = 0;i < progs->numfielddefs;i++)
1375         {
1376                 pr_fielddefs[i].type = LittleShort (infielddefs[i].type);
1377                 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1378                         Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1379                 pr_fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
1380                 pr_fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
1381         }
1382
1383         // append the darkplaces fields
1384         for (i = 0;i < (int) DPFIELDS;i++)
1385         {
1386                 pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
1387                 pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
1388                 pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string);
1389                 if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
1390                         progs->entityfields += 3;
1391                 else
1392                         progs->entityfields++;
1393                 progs->numfielddefs++;
1394         }
1395
1396         for (i=0 ; i<progs->numglobals ; i++)
1397                 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1398
1399         // moved edict_size calculation down here, below field adding code
1400         // LordHavoc: this no longer includes the edict_t header
1401         pr_edict_size = progs->entityfields * 4;
1402         pr_edictareasize = pr_edict_size * MAX_EDICTS;
1403
1404         // LordHavoc: bounds check anything static
1405         for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1406         {
1407                 switch (st->op)
1408                 {
1409                 case OP_IF:
1410                 case OP_IFNOT:
1411                         if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1412                                 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1413                         break;
1414                 case OP_GOTO:
1415                         if (st->a + i < 0 || st->a + i >= progs->numstatements)
1416                                 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1417                         break;
1418                 // global global global
1419                 case OP_ADD_F:
1420                 case OP_ADD_V:
1421                 case OP_SUB_F:
1422                 case OP_SUB_V:
1423                 case OP_MUL_F:
1424                 case OP_MUL_V:
1425                 case OP_MUL_FV:
1426                 case OP_MUL_VF:
1427                 case OP_DIV_F:
1428                 case OP_BITAND:
1429                 case OP_BITOR:
1430                 case OP_GE:
1431                 case OP_LE:
1432                 case OP_GT:
1433                 case OP_LT:
1434                 case OP_AND:
1435                 case OP_OR:
1436                 case OP_EQ_F:
1437                 case OP_EQ_V:
1438                 case OP_EQ_S:
1439                 case OP_EQ_E:
1440                 case OP_EQ_FNC:
1441                 case OP_NE_F:
1442                 case OP_NE_V:
1443                 case OP_NE_S:
1444                 case OP_NE_E:
1445                 case OP_NE_FNC:
1446                 case OP_ADDRESS:
1447                 case OP_LOAD_F:
1448                 case OP_LOAD_FLD:
1449                 case OP_LOAD_ENT:
1450                 case OP_LOAD_S:
1451                 case OP_LOAD_FNC:
1452                 case OP_LOAD_V:
1453                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1454                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1455                         break;
1456                 // global none global
1457                 case OP_NOT_F:
1458                 case OP_NOT_V:
1459                 case OP_NOT_S:
1460                 case OP_NOT_FNC:
1461                 case OP_NOT_ENT:
1462                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1463                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1464                         break;
1465                 // 2 globals
1466                 case OP_STOREP_F:
1467                 case OP_STOREP_ENT:
1468                 case OP_STOREP_FLD:
1469                 case OP_STOREP_S:
1470                 case OP_STOREP_FNC:
1471                 case OP_STORE_F:
1472                 case OP_STORE_ENT:
1473                 case OP_STORE_FLD:
1474                 case OP_STORE_S:
1475                 case OP_STORE_FNC:
1476                 case OP_STATE:
1477                 case OP_STOREP_V:
1478                 case OP_STORE_V:
1479                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1480                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1481                         break;
1482                 // 1 global
1483                 case OP_CALL0:
1484                 case OP_CALL1:
1485                 case OP_CALL2:
1486                 case OP_CALL3:
1487                 case OP_CALL4:
1488                 case OP_CALL5:
1489                 case OP_CALL6:
1490                 case OP_CALL7:
1491                 case OP_CALL8:
1492                 case OP_DONE:
1493                 case OP_RETURN:
1494                         if ((unsigned short) st->a >= progs->numglobals)
1495                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1496                         break;
1497                 default:
1498                         Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1499                         break;
1500                 }
1501         }
1502
1503         FindEdictFieldOffsets(); // LordHavoc: update field offset list
1504         PR_Execute_ProgsLoaded();
1505         PR_Cmd_Reset();
1506 }
1507
1508
1509 void PR_Fields_f (void)
1510 {
1511         int i, j, ednum, used, usedamount;
1512         int *counts;
1513         char tempstring[5000], tempstring2[260], *name;
1514         edict_t *ed;
1515         ddef_t *d;
1516         int *v;
1517         if (!sv.active)
1518         {
1519                 Con_Print("no progs loaded\n");
1520                 return;
1521         }
1522         counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
1523         for (ednum = 0;ednum < sv.max_edicts;ednum++)
1524         {
1525                 ed = EDICT_NUM(ednum);
1526                 if (ed->e->free)
1527                         continue;
1528                 for (i = 1;i < progs->numfielddefs;i++)
1529                 {
1530                         d = &pr_fielddefs[i];
1531                         name = PR_GetString(d->s_name);
1532                         if (name[strlen(name)-2] == '_')
1533                                 continue;       // skip _x, _y, _z vars
1534                         v = (int *)((char *)ed->v + d->ofs*4);
1535                         // if the value is still all 0, skip the field
1536                         for (j = 0;j < type_size[d->type & ~DEF_SAVEGLOBAL];j++)
1537                         {
1538                                 if (v[j])
1539                                 {
1540                                         counts[i]++;
1541                                         break;
1542                                 }
1543                         }
1544                 }
1545         }
1546         used = 0;
1547         usedamount = 0;
1548         tempstring[0] = 0;
1549         for (i = 0;i < progs->numfielddefs;i++)
1550         {
1551                 d = &pr_fielddefs[i];
1552                 name = PR_GetString(d->s_name);
1553                 if (name[strlen(name)-2] == '_')
1554                         continue;       // skip _x, _y, _z vars
1555                 switch(d->type & ~DEF_SAVEGLOBAL)
1556                 {
1557                 case ev_string:
1558                         strlcat (tempstring, "string   ", sizeof (tempstring));
1559                         break;
1560                 case ev_entity:
1561                         strlcat (tempstring, "entity   ", sizeof (tempstring));
1562                         break;
1563                 case ev_function:
1564                         strlcat (tempstring, "function ", sizeof (tempstring));
1565                         break;
1566                 case ev_field:
1567                         strlcat (tempstring, "field    ", sizeof (tempstring));
1568                         break;
1569                 case ev_void:
1570                         strlcat (tempstring, "void     ", sizeof (tempstring));
1571                         break;
1572                 case ev_float:
1573                         strlcat (tempstring, "float    ", sizeof (tempstring));
1574                         break;
1575                 case ev_vector:
1576                         strlcat (tempstring, "vector   ", sizeof (tempstring));
1577                         break;
1578                 case ev_pointer:
1579                         strlcat (tempstring, "pointer  ", sizeof (tempstring));
1580                         break;
1581                 default:
1582                         dpsnprintf (tempstring2, sizeof (tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
1583                         strlcat (tempstring, tempstring2, sizeof (tempstring));
1584                         break;
1585                 }
1586                 if (strlen(name) > 256)
1587                 {
1588                         memcpy(tempstring2, name, 256);
1589                         tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
1590                         tempstring2[259] = 0;
1591                         name = tempstring2;
1592                 }
1593                 strcat (tempstring, name);
1594                 for (j = strlen(name);j < 25;j++)
1595                         strcat(tempstring, " ");
1596                 dpsnprintf (tempstring2, sizeof (tempstring2), "%5d", counts[i]);
1597                 strlcat (tempstring, tempstring2, sizeof (tempstring));
1598                 strlcat (tempstring, "\n", sizeof (tempstring));
1599                 if (strlen(tempstring) >= 4096)
1600                 {
1601                         Con_Print(tempstring);
1602                         tempstring[0] = 0;
1603                 }
1604                 if (counts[i])
1605                 {
1606                         used++;
1607                         usedamount += type_size[d->type & ~DEF_SAVEGLOBAL];
1608                 }
1609         }
1610         Mem_Free(counts);
1611         Con_Printf("%i entity fields (%i in use), totalling %i bytes per edict (%i in use), %i edicts allocated, %i bytes total spent on edict fields (%i needed)\n", progs->entityfields, used, progs->entityfields * 4, usedamount * 4, sv.max_edicts, progs->entityfields * 4 * sv.max_edicts, usedamount * 4 * sv.max_edicts);
1612 }
1613
1614 void PR_Globals_f (void)
1615 {
1616         int i;
1617         if (!sv.active)
1618         {
1619                 Con_Print("no progs loaded\n");
1620                 return;
1621         }
1622         for (i = 0;i < progs->numglobaldefs;i++)
1623                 Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name));
1624         Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
1625 }
1626
1627 /*
1628 ===============
1629 PR_Init
1630 ===============
1631 */
1632 extern void PR_Cmd_Init(void);
1633 void PR_Init (void)
1634 {
1635         Cmd_AddCommand ("edict", ED_PrintEdict_f);
1636         Cmd_AddCommand ("edicts", ED_PrintEdicts);
1637         Cmd_AddCommand ("edictcount", ED_Count);
1638         Cmd_AddCommand ("edictset", ED_EdictSet_f);
1639         Cmd_AddCommand ("profile", PR_Profile_f);
1640         Cmd_AddCommand ("pr_fields", PR_Fields_f);
1641         Cmd_AddCommand ("pr_globals", PR_Globals_f);
1642         Cvar_RegisterVariable (&pr_checkextension);
1643         Cvar_RegisterVariable (&nomonsters);
1644         Cvar_RegisterVariable (&gamecfg);
1645         Cvar_RegisterVariable (&scratch1);
1646         Cvar_RegisterVariable (&scratch2);
1647         Cvar_RegisterVariable (&scratch3);
1648         Cvar_RegisterVariable (&scratch4);
1649         Cvar_RegisterVariable (&savedgamecfg);
1650         Cvar_RegisterVariable (&saved1);
1651         Cvar_RegisterVariable (&saved2);
1652         Cvar_RegisterVariable (&saved3);
1653         Cvar_RegisterVariable (&saved4);
1654         // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1655         Cvar_RegisterVariable (&decors);
1656         // LordHavoc: Nehahra uses these to pass data around cutscene demos
1657         if (gamemode == GAME_NEHAHRA)
1658         {
1659                 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1660                 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1661                 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1662                 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1663                 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1664                 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1665                 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1666                 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1667                 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1668                 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1669         }
1670         Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1671         // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1672         Cvar_RegisterVariable (&pr_boundscheck);
1673         Cvar_RegisterVariable (&pr_traceqc);
1674
1675         serverprogs_mempool = Mem_AllocPool("server progs", 0, NULL);
1676
1677         PR_Cmd_Init();
1678 }
1679
1680 /*
1681 ===============
1682 PR_Shutdown
1683 ===============
1684 */
1685 extern void PR_Cmd_Shutdown(void);
1686 void PR_Shutdown (void)
1687 {
1688         PR_Cmd_Shutdown();
1689
1690         Mem_FreePool(&serverprogs_mempool);
1691 }
1692
1693 void *PR_Alloc(size_t buffersize)
1694 {
1695         return Mem_Alloc(serverprogs_mempool, buffersize);
1696 }
1697
1698 void PR_Free(void *buffer)
1699 {
1700         Mem_Free(buffer);
1701 }
1702
1703 void PR_FreeAll(void)
1704 {
1705         progs = NULL;
1706         pr_fielddefs = NULL;
1707         pr_functions = NULL;
1708         Mem_EmptyPool(serverprogs_mempool);
1709 }
1710
1711 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1712 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
1713 {
1714         Host_Error ("EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
1715         return NULL;
1716 }
1717
1718 /*
1719 int NUM_FOR_EDICT_ERROR(edict_t *e)
1720 {
1721         Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
1722         return 0;
1723 }
1724
1725 int NUM_FOR_EDICT(edict_t *e)
1726 {
1727         int n;
1728         n = e - sv.edicts;
1729         if ((unsigned int)n >= MAX_EDICTS)
1730                 Host_Error ("NUM_FOR_EDICT: bad pointer");
1731         return n;
1732 }
1733
1734 //int NoCrash_NUM_FOR_EDICT(edict_t *e)
1735 //{
1736 //      return e - sv.edicts;
1737 //}
1738
1739 //#define       EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
1740 //#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
1741 int EDICT_TO_PROG(edict_t *e)
1742 {
1743         int n;
1744         n = e - sv.edicts;
1745         if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1746                 Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
1747         return n;// EXPERIMENTAL
1748         //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
1749 }
1750 edict_t *PROG_TO_EDICT(int n)
1751 {
1752         if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1753                 Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
1754         return sv.edicts + n; // EXPERIMENTAL
1755         //return sv.edicts + ((n) / (progs->entityfields * 4));
1756 }
1757 */
1758