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