]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - pr_edict.c
2ea21f97ffde0ba94e64756c11d6b2d90e3174cd
[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 (const char *progsname)
1293 {
1294         int i;
1295         dstatement_t *st;
1296         ddef_t *infielddefs;
1297         dfunction_t *dfunctions;
1298
1299         if (!progsname || !*progsname) 
1300                 Host_Error("PR_LoadProgs: passed empty progsname");
1301
1302 // flush the non-C variable lookup cache
1303         for (i=0 ; i<GEFV_CACHESIZE ; i++)
1304                 gefvCache[i].field[0] = 0;
1305
1306         Mem_EmptyPool(progs_mempool);
1307         Mem_EmptyPool(edictstring_mempool);
1308
1309         progs = (dprograms_t *)FS_LoadFile (progsname, progs_mempool, false);
1310         if (!progs)
1311                 Host_Error ("PR_LoadProgs: couldn't load %s", progsname);
1312
1313         Con_DPrintf("Programs occupy %iK.\n", fs_filesize/1024);
1314
1315         pr_crc = CRC_Block((qbyte *)progs, fs_filesize);
1316
1317 // byte swap the header
1318         for (i = 0;i < (int) sizeof(*progs) / 4;i++)
1319                 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1320
1321         if (progs->version != PROG_VERSION)
1322                 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1323         if (progs->crc != PROGHEADER_CRC && progs->crc != 32401) // tenebrae crc also allowed
1324                 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1325
1326         //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1327         dfunctions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1328         pr_strings = (char *)progs + progs->ofs_strings;
1329         pr_globaldefs = (ddef_t *)((qbyte *)progs + progs->ofs_globaldefs);
1330
1331         // we need to expand the fielddefs list to include all the engine fields,
1332         // so allocate a new place for it
1333         infielddefs = (ddef_t *)((qbyte *)progs + progs->ofs_fielddefs);
1334         pr_fielddefs = Mem_Alloc(progs_mempool, (progs->numfielddefs + DPFIELDS) * sizeof(ddef_t));
1335
1336         pr_statements = (dstatement_t *)((qbyte *)progs + progs->ofs_statements);
1337
1338         // moved edict_size calculation down below field adding code
1339
1340         pr_global_struct = (globalvars_t *)((qbyte *)progs + progs->ofs_globals);
1341         pr_globals = (float *)pr_global_struct;
1342
1343 // byte swap the lumps
1344         for (i=0 ; i<progs->numstatements ; i++)
1345         {
1346                 pr_statements[i].op = LittleShort(pr_statements[i].op);
1347                 pr_statements[i].a = LittleShort(pr_statements[i].a);
1348                 pr_statements[i].b = LittleShort(pr_statements[i].b);
1349                 pr_statements[i].c = LittleShort(pr_statements[i].c);
1350         }
1351
1352         pr_functions = Mem_Alloc(progs_mempool, sizeof(mfunction_t) * progs->numfunctions);
1353         for (i = 0;i < progs->numfunctions;i++)
1354         {
1355                 pr_functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
1356                 pr_functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
1357                 pr_functions[i].s_name = LittleLong (dfunctions[i].s_name);
1358                 pr_functions[i].s_file = LittleLong (dfunctions[i].s_file);
1359                 pr_functions[i].numparms = LittleLong (dfunctions[i].numparms);
1360                 pr_functions[i].locals = LittleLong (dfunctions[i].locals);
1361                 memcpy(pr_functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
1362         }
1363
1364         for (i=0 ; i<progs->numglobaldefs ; i++)
1365         {
1366                 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1367                 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1368                 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1369         }
1370
1371         // copy the progs fields to the new fields list
1372         for (i = 0;i < progs->numfielddefs;i++)
1373         {
1374                 pr_fielddefs[i].type = LittleShort (infielddefs[i].type);
1375                 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1376                         Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1377                 pr_fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
1378                 pr_fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
1379         }
1380
1381         // append the darkplaces fields
1382         for (i = 0;i < (int) DPFIELDS;i++)
1383         {
1384                 pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
1385                 pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
1386                 pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string);
1387                 if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
1388                         progs->entityfields += 3;
1389                 else
1390                         progs->entityfields++;
1391                 progs->numfielddefs++;
1392         }
1393
1394         for (i=0 ; i<progs->numglobals ; i++)
1395                 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1396
1397         // moved edict_size calculation down here, below field adding code
1398         // LordHavoc: this no longer includes the edict_t header
1399         pr_edict_size = progs->entityfields * 4;
1400         pr_edictareasize = pr_edict_size * MAX_EDICTS;
1401
1402         // LordHavoc: bounds check anything static
1403         for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1404         {
1405                 switch (st->op)
1406                 {
1407                 case OP_IF:
1408                 case OP_IFNOT:
1409                         if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1410                                 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1411                         break;
1412                 case OP_GOTO:
1413                         if (st->a + i < 0 || st->a + i >= progs->numstatements)
1414                                 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1415                         break;
1416                 // global global global
1417                 case OP_ADD_F:
1418                 case OP_ADD_V:
1419                 case OP_SUB_F:
1420                 case OP_SUB_V:
1421                 case OP_MUL_F:
1422                 case OP_MUL_V:
1423                 case OP_MUL_FV:
1424                 case OP_MUL_VF:
1425                 case OP_DIV_F:
1426                 case OP_BITAND:
1427                 case OP_BITOR:
1428                 case OP_GE:
1429                 case OP_LE:
1430                 case OP_GT:
1431                 case OP_LT:
1432                 case OP_AND:
1433                 case OP_OR:
1434                 case OP_EQ_F:
1435                 case OP_EQ_V:
1436                 case OP_EQ_S:
1437                 case OP_EQ_E:
1438                 case OP_EQ_FNC:
1439                 case OP_NE_F:
1440                 case OP_NE_V:
1441                 case OP_NE_S:
1442                 case OP_NE_E:
1443                 case OP_NE_FNC:
1444                 case OP_ADDRESS:
1445                 case OP_LOAD_F:
1446                 case OP_LOAD_FLD:
1447                 case OP_LOAD_ENT:
1448                 case OP_LOAD_S:
1449                 case OP_LOAD_FNC:
1450                 case OP_LOAD_V:
1451                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1452                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1453                         break;
1454                 // global none global
1455                 case OP_NOT_F:
1456                 case OP_NOT_V:
1457                 case OP_NOT_S:
1458                 case OP_NOT_FNC:
1459                 case OP_NOT_ENT:
1460                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1461                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1462                         break;
1463                 // 2 globals
1464                 case OP_STOREP_F:
1465                 case OP_STOREP_ENT:
1466                 case OP_STOREP_FLD:
1467                 case OP_STOREP_S:
1468                 case OP_STOREP_FNC:
1469                 case OP_STORE_F:
1470                 case OP_STORE_ENT:
1471                 case OP_STORE_FLD:
1472                 case OP_STORE_S:
1473                 case OP_STORE_FNC:
1474                 case OP_STATE:
1475                 case OP_STOREP_V:
1476                 case OP_STORE_V:
1477                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1478                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1479                         break;
1480                 // 1 global
1481                 case OP_CALL0:
1482                 case OP_CALL1:
1483                 case OP_CALL2:
1484                 case OP_CALL3:
1485                 case OP_CALL4:
1486                 case OP_CALL5:
1487                 case OP_CALL6:
1488                 case OP_CALL7:
1489                 case OP_CALL8:
1490                 case OP_DONE:
1491                 case OP_RETURN:
1492                         if ((unsigned short) st->a >= progs->numglobals)
1493                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1494                         break;
1495                 default:
1496                         Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1497                         break;
1498                 }
1499         }
1500
1501         FindEdictFieldOffsets(); // LordHavoc: update field offset list
1502         PR_Execute_ProgsLoaded();
1503         PR_Cmd_Reset();
1504 }
1505
1506
1507 void PR_Fields_f (void)
1508 {
1509         int i, j, ednum, used, usedamount;
1510         int *counts;
1511         char tempstring[5000], tempstring2[260], *name;
1512         edict_t *ed;
1513         ddef_t *d;
1514         int *v;
1515         if (!sv.active)
1516         {
1517                 Con_Print("no progs loaded\n");
1518                 return;
1519         }
1520         counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
1521         for (ednum = 0;ednum < sv.max_edicts;ednum++)
1522         {
1523                 ed = EDICT_NUM(ednum);
1524                 if (ed->e->free)
1525                         continue;
1526                 for (i = 1;i < progs->numfielddefs;i++)
1527                 {
1528                         d = &pr_fielddefs[i];
1529                         name = PR_GetString(d->s_name);
1530                         if (name[strlen(name)-2] == '_')
1531                                 continue;       // skip _x, _y, _z vars
1532                         v = (int *)((char *)ed->v + d->ofs*4);
1533                         // if the value is still all 0, skip the field
1534                         for (j = 0;j < type_size[d->type & ~DEF_SAVEGLOBAL];j++)
1535                         {
1536                                 if (v[j])
1537                                 {
1538                                         counts[i]++;
1539                                         break;
1540                                 }
1541                         }
1542                 }
1543         }
1544         used = 0;
1545         usedamount = 0;
1546         tempstring[0] = 0;
1547         for (i = 0;i < progs->numfielddefs;i++)
1548         {
1549                 d = &pr_fielddefs[i];
1550                 name = PR_GetString(d->s_name);
1551                 if (name[strlen(name)-2] == '_')
1552                         continue;       // skip _x, _y, _z vars
1553                 switch(d->type & ~DEF_SAVEGLOBAL)
1554                 {
1555                 case ev_string:
1556                         strlcat (tempstring, "string   ", sizeof (tempstring));
1557                         break;
1558                 case ev_entity:
1559                         strlcat (tempstring, "entity   ", sizeof (tempstring));
1560                         break;
1561                 case ev_function:
1562                         strlcat (tempstring, "function ", sizeof (tempstring));
1563                         break;
1564                 case ev_field:
1565                         strlcat (tempstring, "field    ", sizeof (tempstring));
1566                         break;
1567                 case ev_void:
1568                         strlcat (tempstring, "void     ", sizeof (tempstring));
1569                         break;
1570                 case ev_float:
1571                         strlcat (tempstring, "float    ", sizeof (tempstring));
1572                         break;
1573                 case ev_vector:
1574                         strlcat (tempstring, "vector   ", sizeof (tempstring));
1575                         break;
1576                 case ev_pointer:
1577                         strlcat (tempstring, "pointer  ", sizeof (tempstring));
1578                         break;
1579                 default:
1580                         snprintf (tempstring2, sizeof (tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
1581                         strlcat (tempstring, tempstring2, sizeof (tempstring));
1582                         break;
1583                 }
1584                 if (strlen(name) > 256)
1585                 {
1586                         memcpy(tempstring2, name, 256);
1587                         tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
1588                         tempstring2[259] = 0;
1589                         name = tempstring2;
1590                 }
1591                 strcat (tempstring, name);
1592                 for (j = strlen(name);j < 25;j++)
1593                         strcat(tempstring, " ");
1594                 snprintf (tempstring2, sizeof (tempstring2), "%5d", counts[i]);
1595                 strlcat (tempstring, tempstring2, sizeof (tempstring));
1596                 strlcat (tempstring, "\n", sizeof (tempstring));
1597                 if (strlen(tempstring) >= 4096)
1598                 {
1599                         Con_Print(tempstring);
1600                         tempstring[0] = 0;
1601                 }
1602                 if (counts[i])
1603                 {
1604                         used++;
1605                         usedamount += type_size[d->type & ~DEF_SAVEGLOBAL];
1606                 }
1607         }
1608         Mem_Free(counts);
1609         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);
1610 }
1611
1612 void PR_Globals_f (void)
1613 {
1614         int i;
1615         if (!sv.active)
1616         {
1617                 Con_Print("no progs loaded\n");
1618                 return;
1619         }
1620         for (i = 0;i < progs->numglobaldefs;i++)
1621                 Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name));
1622         Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
1623 }
1624
1625 /*
1626 ===============
1627 PR_Init
1628 ===============
1629 */
1630 extern void PR_Cmd_Init(void);
1631 void PR_Init (void)
1632 {
1633         Cmd_AddCommand ("edict", ED_PrintEdict_f);
1634         Cmd_AddCommand ("edicts", ED_PrintEdicts);
1635         Cmd_AddCommand ("edictcount", ED_Count);
1636         Cmd_AddCommand ("edictset", ED_EdictSet_f);
1637         Cmd_AddCommand ("profile", PR_Profile_f);
1638         Cmd_AddCommand ("pr_fields", PR_Fields_f);
1639         Cmd_AddCommand ("pr_globals", PR_Globals_f);
1640         Cvar_RegisterVariable (&pr_checkextension);
1641         Cvar_RegisterVariable (&nomonsters);
1642         Cvar_RegisterVariable (&gamecfg);
1643         Cvar_RegisterVariable (&scratch1);
1644         Cvar_RegisterVariable (&scratch2);
1645         Cvar_RegisterVariable (&scratch3);
1646         Cvar_RegisterVariable (&scratch4);
1647         Cvar_RegisterVariable (&savedgamecfg);
1648         Cvar_RegisterVariable (&saved1);
1649         Cvar_RegisterVariable (&saved2);
1650         Cvar_RegisterVariable (&saved3);
1651         Cvar_RegisterVariable (&saved4);
1652         // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1653         Cvar_RegisterVariable (&decors);
1654         // LordHavoc: Nehahra uses these to pass data around cutscene demos
1655         if (gamemode == GAME_NEHAHRA)
1656         {
1657                 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1658                 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1659                 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1660                 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1661                 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1662                 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1663                 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1664                 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1665                 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1666                 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1667         }
1668         Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1669         // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1670         Cvar_RegisterVariable (&pr_boundscheck);
1671         Cvar_RegisterVariable (&pr_traceqc);
1672
1673         progs_mempool = Mem_AllocPool("progs.dat", 0, NULL);
1674         edictstring_mempool = Mem_AllocPool("edict strings", 0, NULL);
1675
1676         PR_Cmd_Init();
1677 }
1678
1679 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1680 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
1681 {
1682         Host_Error ("EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
1683         return NULL;
1684 }
1685
1686 /*
1687 int NUM_FOR_EDICT_ERROR(edict_t *e)
1688 {
1689         Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
1690         return 0;
1691 }
1692
1693 int NUM_FOR_EDICT(edict_t *e)
1694 {
1695         int n;
1696         n = e - sv.edicts;
1697         if ((unsigned int)n >= MAX_EDICTS)
1698                 Host_Error ("NUM_FOR_EDICT: bad pointer");
1699         return n;
1700 }
1701
1702 //int NoCrash_NUM_FOR_EDICT(edict_t *e)
1703 //{
1704 //      return e - sv.edicts;
1705 //}
1706
1707 //#define       EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
1708 //#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
1709 int EDICT_TO_PROG(edict_t *e)
1710 {
1711         int n;
1712         n = e - sv.edicts;
1713         if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1714                 Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
1715         return n;// EXPERIMENTAL
1716         //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
1717 }
1718 edict_t *PROG_TO_EDICT(int n)
1719 {
1720         if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1721                 Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
1722         return sv.edicts + n; // EXPERIMENTAL
1723         //return sv.edicts + ((n) / (progs->entityfields * 4));
1724 }
1725 */
1726