]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - pr_edict.c
particle effect changes and code cleanup
[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 dfunction_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 int             type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
38
39 ddef_t *ED_FieldAtOfs (int ofs);
40 qboolean        ED_ParseEpair (void *base, ddef_t *key, char *s);
41
42 cvar_t  nomonsters = {"nomonsters", "0"};
43 cvar_t  gamecfg = {"gamecfg", "0"};
44 cvar_t  scratch1 = {"scratch1", "0"};
45 cvar_t  scratch2 = {"scratch2", "0"};
46 cvar_t  scratch3 = {"scratch3", "0"};
47 cvar_t  scratch4 = {"scratch4", "0"};
48 cvar_t  savedgamecfg = {"savedgamecfg", "0", true};
49 cvar_t  saved1 = {"saved1", "0", true};
50 cvar_t  saved2 = {"saved2", "0", true};
51 cvar_t  saved3 = {"saved3", "0", true};
52 cvar_t  saved4 = {"saved4", "0", true};
53 cvar_t  decors = {"decors", "0"};
54 cvar_t  nehx00 = {"nehx00", "0"};cvar_t nehx01 = {"nehx01", "0"};
55 cvar_t  nehx02 = {"nehx02", "0"};cvar_t nehx03 = {"nehx03", "0"};
56 cvar_t  nehx04 = {"nehx04", "0"};cvar_t nehx05 = {"nehx05", "0"};
57 cvar_t  nehx06 = {"nehx06", "0"};cvar_t nehx07 = {"nehx07", "0"};
58 cvar_t  nehx08 = {"nehx08", "0"};cvar_t nehx09 = {"nehx09", "0"};
59 cvar_t  nehx10 = {"nehx10", "0"};cvar_t nehx11 = {"nehx11", "0"};
60 cvar_t  nehx12 = {"nehx12", "0"};cvar_t nehx13 = {"nehx13", "0"};
61 cvar_t  nehx14 = {"nehx14", "0"};cvar_t nehx15 = {"nehx15", "0"};
62 cvar_t  nehx16 = {"nehx16", "0"};cvar_t nehx17 = {"nehx17", "0"};
63 cvar_t  nehx18 = {"nehx18", "0"};cvar_t nehx19 = {"nehx19", "0"};
64 cvar_t  cutscene = {"cutscene", "1"};
65 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
66 cvar_t  pr_boundscheck = {"pr_boundscheck", "1"};
67
68 #define MAX_FIELD_LEN   64
69 #define GEFV_CACHESIZE  2
70
71 typedef struct {
72         ddef_t  *pcache;
73         char    field[MAX_FIELD_LEN];
74 } gefv_cache;
75
76 static gefv_cache       gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
77
78 ddef_t *ED_FindField (char *name);
79 dfunction_t *ED_FindFunction (char *name);
80
81 // LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue...  these are defined as externs in progs.h
82 int eval_gravity;
83 int eval_button3;
84 int eval_button4;
85 int eval_button5;
86 int eval_button6;
87 int eval_button7;
88 int eval_button8;
89 int eval_glow_size;
90 int eval_glow_trail;
91 int eval_glow_color;
92 int eval_items2;
93 int eval_scale;
94 int eval_alpha;
95 int eval_renderamt; // HalfLife support
96 int eval_rendermode; // HalfLife support
97 int eval_fullbright;
98 int eval_ammo_shells1;
99 int eval_ammo_nails1;
100 int eval_ammo_lava_nails;
101 int eval_ammo_rockets1;
102 int eval_ammo_multi_rockets;
103 int eval_ammo_cells1;
104 int eval_ammo_plasma;
105 int eval_idealpitch;
106 int eval_pitch_speed;
107 int eval_viewmodelforclient;
108 int eval_nodrawtoclient;
109 int eval_drawonlytoclient;
110 int eval_colormod;
111 int eval_ping;
112 int eval_movement;
113 int eval_pmodel;
114
115 dfunction_t *SV_PlayerPhysicsQC;
116 dfunction_t *EndFrameQC;
117
118 int FindFieldOffset(char *field)
119 {
120         ddef_t *d;
121         d = ED_FindField(field);
122         if (!d)
123                 return 0;
124         return d->ofs*4;
125 }
126
127 void FindEdictFieldOffsets()
128 {
129         eval_gravity = FindFieldOffset("gravity");
130         eval_button3 = FindFieldOffset("button3");
131         eval_button4 = FindFieldOffset("button4");
132         eval_button5 = FindFieldOffset("button5");
133         eval_button6 = FindFieldOffset("button6");
134         eval_button7 = FindFieldOffset("button7");
135         eval_button8 = FindFieldOffset("button8");
136         eval_glow_size = FindFieldOffset("glow_size");
137         eval_glow_trail = FindFieldOffset("glow_trail");
138         eval_glow_color = FindFieldOffset("glow_color");
139         eval_items2 = FindFieldOffset("items2");
140         eval_scale = FindFieldOffset("scale");
141         eval_alpha = FindFieldOffset("alpha");
142         eval_renderamt = FindFieldOffset("renderamt"); // HalfLife support
143         eval_rendermode = FindFieldOffset("rendermode"); // HalfLife support
144         eval_fullbright = FindFieldOffset("fullbright");
145         eval_ammo_shells1 = FindFieldOffset("ammo_shells1");
146         eval_ammo_nails1 = FindFieldOffset("ammo_nails1");
147         eval_ammo_lava_nails = FindFieldOffset("ammo_lava_nails");
148         eval_ammo_rockets1 = FindFieldOffset("ammo_rockets1");
149         eval_ammo_multi_rockets = FindFieldOffset("ammo_multi_rockets");
150         eval_ammo_cells1 = FindFieldOffset("ammo_cells1");
151         eval_ammo_plasma = FindFieldOffset("ammo_plasma");
152         eval_idealpitch = FindFieldOffset("idealpitch");
153         eval_pitch_speed = FindFieldOffset("pitch_speed");
154         eval_viewmodelforclient = FindFieldOffset("viewmodelforclient");
155         eval_nodrawtoclient = FindFieldOffset("nodrawtoclient");
156         eval_drawonlytoclient = FindFieldOffset("drawonlytoclient");
157         eval_colormod = FindFieldOffset("colormod");
158         eval_ping = FindFieldOffset("ping");
159         eval_movement = FindFieldOffset("movement");
160         eval_pmodel = FindFieldOffset("pmodel");
161
162         // LordHavoc: allowing QuakeC to override the player movement code
163         SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
164         // LordHavoc: support for endframe
165         EndFrameQC = ED_FindFunction ("EndFrame");
166 };
167
168 /*
169 =================
170 ED_ClearEdict
171
172 Sets everything to NULL
173 =================
174 */
175 void ED_ClearEdict (edict_t *e)
176 {
177         memset (&e->v, 0, progs->entityfields * 4);
178         e->free = false;
179 }
180
181 /*
182 =================
183 ED_Alloc
184
185 Either finds a free edict, or allocates a new one.
186 Try to avoid reusing an entity that was recently freed, because it
187 can cause the client to think the entity morphed into something else
188 instead of being removed and recreated, which can cause interpolated
189 angles and bad trails.
190 =================
191 */
192 edict_t *ED_Alloc (void)
193 {
194         int                     i;
195         edict_t         *e;
196
197         for ( i=svs.maxclients+1 ; i<sv.num_edicts ; i++)
198         {
199                 e = EDICT_NUM(i);
200                 // the first couple seconds of server time can involve a lot of
201                 // freeing and allocating, so relax the replacement policy
202                 if (e->free && ( e->freetime < 2 || sv.time - e->freetime > 0.5 ) )
203                 {
204                         ED_ClearEdict (e);
205                         return e;
206                 }
207         }
208         
209         if (i == MAX_EDICTS)
210                 Host_Error ("ED_Alloc: no free edicts");
211                 
212         sv.num_edicts++;
213         e = EDICT_NUM(i);
214         ED_ClearEdict (e);
215
216         return e;
217 }
218
219 /*
220 =================
221 ED_Free
222
223 Marks the edict as free
224 FIXME: walk all entities and NULL out references to this entity
225 =================
226 */
227 void ED_Free (edict_t *ed)
228 {
229         SV_UnlinkEdict (ed);            // unlink from world bsp
230
231         ed->free = true;
232         ed->v.model = 0;
233         ed->v.takedamage = 0;
234         ed->v.modelindex = 0;
235         ed->v.colormap = 0;
236         ed->v.skin = 0;
237         ed->v.frame = 0;
238         VectorCopy (vec3_origin, ed->v.origin);
239         VectorCopy (vec3_origin, ed->v.angles);
240         ed->v.nextthink = -1;
241         ed->v.solid = 0;
242         
243         ed->freetime = sv.time;
244 }
245
246 //===========================================================================
247
248 /*
249 ============
250 ED_GlobalAtOfs
251 ============
252 */
253 ddef_t *ED_GlobalAtOfs (int ofs)
254 {
255         ddef_t          *def;
256         int                     i;
257         
258         for (i=0 ; i<progs->numglobaldefs ; i++)
259         {
260                 def = &pr_globaldefs[i];
261                 if (def->ofs == ofs)
262                         return def;
263         }
264         return NULL;
265 }
266
267 /*
268 ============
269 ED_FieldAtOfs
270 ============
271 */
272 ddef_t *ED_FieldAtOfs (int ofs)
273 {
274         ddef_t          *def;
275         int                     i;
276         
277         for (i=0 ; i<progs->numfielddefs ; i++)
278         {
279                 def = &pr_fielddefs[i];
280                 if (def->ofs == ofs)
281                         return def;
282         }
283         return NULL;
284 }
285
286 /*
287 ============
288 ED_FindField
289 ============
290 */
291 ddef_t *ED_FindField (char *name)
292 {
293         ddef_t          *def;
294         int                     i;
295         
296         for (i=0 ; i<progs->numfielddefs ; i++)
297         {
298                 def = &pr_fielddefs[i];
299                 if (!strcmp(pr_strings + def->s_name,name) )
300                         return def;
301         }
302         return NULL;
303 }
304
305
306 /*
307 ============
308 ED_FindGlobal
309 ============
310 */
311 ddef_t *ED_FindGlobal (char *name)
312 {
313         ddef_t          *def;
314         int                     i;
315         
316         for (i=0 ; i<progs->numglobaldefs ; i++)
317         {
318                 def = &pr_globaldefs[i];
319                 if (!strcmp(pr_strings + def->s_name,name) )
320                         return def;
321         }
322         return NULL;
323 }
324
325
326 /*
327 ============
328 ED_FindFunction
329 ============
330 */
331 dfunction_t *ED_FindFunction (char *name)
332 {
333         dfunction_t             *func;
334         int                             i;
335         
336         for (i=0 ; i<progs->numfunctions ; i++)
337         {
338                 func = &pr_functions[i];
339                 if (!strcmp(pr_strings + func->s_name,name) )
340                         return func;
341         }
342         return NULL;
343 }
344
345
346 /*
347 eval_t *GetEdictFieldValue(edict_t *ed, char *field)
348 {
349         ddef_t                  *def = NULL;
350         int                             i;
351         static int              rep = 0;
352
353         for (i=0 ; i<GEFV_CACHESIZE ; i++)
354         {
355                 if (!strcmp(field, gefvCache[i].field))
356                 {
357                         def = gefvCache[i].pcache;
358                         goto Done;
359                 }
360         }
361
362         def = ED_FindField (field);
363
364         if (strlen(field) < MAX_FIELD_LEN)
365         {
366                 gefvCache[rep].pcache = def;
367                 strcpy (gefvCache[rep].field, field);
368                 rep ^= 1;
369         }
370
371 Done:
372         if (!def)
373                 return NULL;
374
375         return (eval_t *)((char *)&ed->v + def->ofs*4);
376 }
377 */
378
379 /*
380 ============
381 PR_ValueString
382
383 Returns a string describing *data in a type specific manner
384 =============
385 */
386 char *PR_ValueString (etype_t type, eval_t *val)
387 {
388         static char     line[256];
389         ddef_t          *def;
390         dfunction_t     *f;
391         
392         type &= ~DEF_SAVEGLOBAL;
393
394         switch (type)
395         {
396         case ev_string:
397                 sprintf (line, "%s", pr_strings + val->string);
398                 break;
399         case ev_entity: 
400                 sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) );
401                 break;
402         case ev_function:
403                 f = pr_functions + val->function;
404                 sprintf (line, "%s()", pr_strings + f->s_name);
405                 break;
406         case ev_field:
407                 def = ED_FieldAtOfs ( val->_int );
408                 sprintf (line, ".%s", pr_strings + def->s_name);
409                 break;
410         case ev_void:
411                 sprintf (line, "void");
412                 break;
413         case ev_float:
414                 sprintf (line, "%5.1f", val->_float);
415                 break;
416         case ev_vector:
417                 sprintf (line, "'%5.1f %5.1f %5.1f'", val->vector[0], val->vector[1], val->vector[2]);
418                 break;
419         case ev_pointer:
420                 sprintf (line, "pointer");
421                 break;
422         default:
423                 sprintf (line, "bad type %i", type);
424                 break;
425         }
426         
427         return line;
428 }
429
430 /*
431 ============
432 PR_UglyValueString
433
434 Returns a string describing *data in a type specific manner
435 Easier to parse than PR_ValueString
436 =============
437 */
438 char *PR_UglyValueString (etype_t type, eval_t *val)
439 {
440         static char     line[256];
441         ddef_t          *def;
442         dfunction_t     *f;
443         
444         type &= ~DEF_SAVEGLOBAL;
445
446         switch (type)
447         {
448         case ev_string:
449                 sprintf (line, "%s", pr_strings + val->string);
450                 break;
451         case ev_entity: 
452                 sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
453                 break;
454         case ev_function:
455                 f = pr_functions + val->function;
456                 sprintf (line, "%s", pr_strings + f->s_name);
457                 break;
458         case ev_field:
459                 def = ED_FieldAtOfs ( val->_int );
460                 sprintf (line, "%s", pr_strings + def->s_name);
461                 break;
462         case ev_void:
463                 sprintf (line, "void");
464                 break;
465         case ev_float:
466                 sprintf (line, "%f", val->_float);
467                 break;
468         case ev_vector:
469                 sprintf (line, "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
470                 break;
471         default:
472                 sprintf (line, "bad type %i", type);
473                 break;
474         }
475         
476         return line;
477 }
478
479 /*
480 ============
481 PR_GlobalString
482
483 Returns a string with a description and the contents of a global,
484 padded to 20 field width
485 ============
486 */
487 char *PR_GlobalString (int ofs)
488 {
489         char    *s;
490         int             i;
491         ddef_t  *def;
492         void    *val;
493         static char     line[128];
494         
495         val = (void *)&pr_globals[ofs];
496         def = ED_GlobalAtOfs(ofs);
497         if (!def)
498                 sprintf (line,"%i(???)", ofs);
499         else
500         {
501                 s = PR_ValueString (def->type, val);
502                 sprintf (line,"%i(%s)%s", ofs, pr_strings + def->s_name, s);
503         }
504         
505         i = strlen(line);
506         for ( ; i<20 ; i++)
507                 strcat (line," ");
508         strcat (line," ");
509                 
510         return line;
511 }
512
513 char *PR_GlobalStringNoContents (int ofs)
514 {
515         int             i;
516         ddef_t  *def;
517         static char     line[128];
518         
519         def = ED_GlobalAtOfs(ofs);
520         if (!def)
521                 sprintf (line,"%i(???)", ofs);
522         else
523                 sprintf (line,"%i(%s)", ofs, pr_strings + def->s_name);
524         
525         i = strlen(line);
526         for ( ; i<20 ; i++)
527                 strcat (line," ");
528         strcat (line," ");
529                 
530         return line;
531 }
532
533
534 /*
535 =============
536 ED_Print
537
538 For debugging
539 =============
540 */
541 // LordHavoc: optimized this to print out much more quickly
542 void ED_Print (edict_t *ed)
543 {
544         int             l;
545         ddef_t  *d;
546         int             *v;
547         int             i, j;
548         char    *name;
549         int             type;
550         char    tempstring[8192]; // temporary string buffer
551
552         if (ed->free)
553         {
554                 Con_Printf ("FREE\n");
555                 return;
556         }
557
558         tempstring[0] = 0;
559         sprintf(tempstring, "\nEDICT %i:\n", NUM_FOR_EDICT(ed));
560         for (i=1 ; i<progs->numfielddefs ; i++)
561         {
562                 d = &pr_fielddefs[i];
563                 name = pr_strings + d->s_name;
564                 if (name[strlen(name)-2] == '_')
565                         continue;       // skip _x, _y, _z vars
566                         
567                 v = (int *)((char *)&ed->v + d->ofs*4);
568
569         // if the value is still all 0, skip the field
570                 type = d->type & ~DEF_SAVEGLOBAL;
571                 
572                 for (j=0 ; j<type_size[type] ; j++)
573                         if (v[j])
574                                 break;
575                 if (j == type_size[type])
576                         continue;
577
578                 strcat(tempstring, name);
579                 l = strlen (name);
580                 while (l++ < 15)
581                         strcat(tempstring, " ");
582
583                 strcat(tempstring, PR_ValueString(d->type, (eval_t *)v));
584                 strcat(tempstring, "\n");
585         }
586         Con_Printf(tempstring);
587 }
588
589 /*
590 =============
591 ED_Write
592
593 For savegames
594 =============
595 */
596 void ED_Write (FILE *f, edict_t *ed)
597 {
598         ddef_t  *d;
599         int             *v;
600         int             i, j;
601         char    *name;
602         int             type;
603
604         fprintf (f, "{\n");
605
606         if (ed->free)
607         {
608                 fprintf (f, "}\n");
609                 return;
610         }
611         
612         for (i=1 ; i<progs->numfielddefs ; i++)
613         {
614                 d = &pr_fielddefs[i];
615                 name = pr_strings + d->s_name;
616                 if (name[strlen(name)-2] == '_')
617                         continue;       // skip _x, _y, _z vars
618                         
619                 v = (int *)((char *)&ed->v + d->ofs*4);
620
621         // if the value is still all 0, skip the field
622                 type = d->type & ~DEF_SAVEGLOBAL;
623                 for (j=0 ; j<type_size[type] ; j++)
624                         if (v[j])
625                                 break;
626                 if (j == type_size[type])
627                         continue;
628         
629                 fprintf (f,"\"%s\" ",name);
630                 fprintf (f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));               
631         }
632
633         fprintf (f, "}\n");
634 }
635
636 void ED_PrintNum (int ent)
637 {
638         ED_Print (EDICT_NUM(ent));
639 }
640
641 /*
642 =============
643 ED_PrintEdicts
644
645 For debugging, prints all the entities in the current server
646 =============
647 */
648 void ED_PrintEdicts (void)
649 {
650         int             i;
651         
652         Con_Printf ("%i entities\n", sv.num_edicts);
653         for (i=0 ; i<sv.num_edicts ; i++)
654                 ED_PrintNum (i);
655 }
656
657 /*
658 =============
659 ED_PrintEdict_f
660
661 For debugging, prints a single edicy
662 =============
663 */
664 void ED_PrintEdict_f (void)
665 {
666         int             i;
667         
668         i = atoi (Cmd_Argv(1));
669         if (i >= sv.num_edicts)
670         {
671                 Con_Printf("Bad edict number\n");
672                 return;
673         }
674         ED_PrintNum (i);
675 }
676
677 /*
678 =============
679 ED_Count
680
681 For debugging
682 =============
683 */
684 void ED_Count (void)
685 {
686         int             i;
687         edict_t *ent;
688         int             active, models, solid, step;
689
690         active = models = solid = step = 0;
691         for (i=0 ; i<sv.num_edicts ; i++)
692         {
693                 ent = EDICT_NUM(i);
694                 if (ent->free)
695                         continue;
696                 active++;
697                 if (ent->v.solid)
698                         solid++;
699                 if (ent->v.model)
700                         models++;
701                 if (ent->v.movetype == MOVETYPE_STEP)
702                         step++;
703         }
704
705         Con_Printf ("num_edicts:%3i\n", sv.num_edicts);
706         Con_Printf ("active    :%3i\n", active);
707         Con_Printf ("view      :%3i\n", models);
708         Con_Printf ("touch     :%3i\n", solid);
709         Con_Printf ("step      :%3i\n", step);
710
711 }
712
713 /*
714 ==============================================================================
715
716                                         ARCHIVING GLOBALS
717
718 FIXME: need to tag constants, doesn't really work
719 ==============================================================================
720 */
721
722 /*
723 =============
724 ED_WriteGlobals
725 =============
726 */
727 void ED_WriteGlobals (FILE *f)
728 {
729         ddef_t          *def;
730         int                     i;
731         char            *name;
732         int                     type;
733
734         fprintf (f,"{\n");
735         for (i=0 ; i<progs->numglobaldefs ; i++)
736         {
737                 def = &pr_globaldefs[i];
738                 type = def->type;
739                 if ( !(def->type & DEF_SAVEGLOBAL) )
740                         continue;
741                 type &= ~DEF_SAVEGLOBAL;
742
743                 if (type != ev_string
744                 && type != ev_float
745                 && type != ev_entity)
746                         continue;
747
748                 name = pr_strings + def->s_name;                
749                 fprintf (f,"\"%s\" ", name);
750                 fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));              
751         }
752         fprintf (f,"}\n");
753 }
754
755 /*
756 =============
757 ED_ParseGlobals
758 =============
759 */
760 void ED_ParseGlobals (char *data)
761 {
762         char    keyname[64];
763         ddef_t  *key;
764
765         while (1)
766         {       
767         // parse key
768                 data = COM_Parse (data);
769                 if (com_token[0] == '}')
770                         break;
771                 if (!data)
772                         Host_Error ("ED_ParseEntity: EOF without closing brace");
773
774                 strcpy (keyname, com_token);
775
776         // parse value  
777                 data = COM_Parse (data);
778                 if (!data)
779                         Host_Error ("ED_ParseEntity: EOF without closing brace");
780
781                 if (com_token[0] == '}')
782                         Host_Error ("ED_ParseEntity: closing brace without data");
783
784                 key = ED_FindGlobal (keyname);
785                 if (!key)
786                 {
787                         Con_DPrintf ("'%s' is not a global\n", keyname);
788                         continue;
789                 }
790
791                 if (!ED_ParseEpair ((void *)pr_globals, key, com_token))
792                         Host_Error ("ED_ParseGlobals: parse error");
793         }
794 }
795
796 //============================================================================
797
798
799 /*
800 =============
801 ED_NewString
802 =============
803 */
804 char *ED_NewString (char *string)
805 {
806         char    *new, *new_p;
807         int             i,l;
808         
809         l = strlen(string) + 1;
810         new = Hunk_Alloc (l);
811         new_p = new;
812
813         for (i=0 ; i< l ; i++)
814         {
815                 if (string[i] == '\\' && i < l-1)
816                 {
817                         i++;
818                         if (string[i] == 'n')
819                                 *new_p++ = '\n';
820                         else
821                                 *new_p++ = '\\';
822                 }
823                 else
824                         *new_p++ = string[i];
825         }
826         
827         return new;
828 }
829
830
831 /*
832 =============
833 ED_ParseEval
834
835 Can parse either fields or globals
836 returns false if error
837 =============
838 */
839 qboolean        ED_ParseEpair (void *base, ddef_t *key, char *s)
840 {
841         int             i;
842         char    string[128];
843         ddef_t  *def;
844         char    *v, *w;
845         void    *d;
846         dfunction_t     *func;
847         
848         d = (void *)((int *)base + key->ofs);
849         
850         switch (key->type & ~DEF_SAVEGLOBAL)
851         {
852         case ev_string:
853                 *(string_t *)d = ED_NewString (s) - pr_strings;
854                 break;
855                 
856         case ev_float:
857                 *(float *)d = atof (s);
858                 break;
859                 
860         case ev_vector:
861                 strcpy (string, s);
862                 v = string;
863                 w = string;
864                 for (i=0 ; i<3 ; i++)
865                 {
866                         while (*v && *v != ' ')
867                                 v++;
868                         *v = 0;
869                         ((float *)d)[i] = atof (w);
870                         w = v = v+1;
871                 }
872                 break;
873                 
874         case ev_entity:
875                 *(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s)));
876                 break;
877                 
878         case ev_field:
879                 def = ED_FindField (s);
880                 if (!def)
881                 {
882                         // LordHavoc: don't warn about worldspawn sky/fog fields because they don't require mod support
883                         if (strcmp(s, "sky") && strcmp(s, "fog") && strncmp(s, "fog_", 4) && strcmp(s, "farclip"))
884                                 Con_DPrintf ("Can't find field %s\n", s);
885                         return false;
886                 }
887                 *(int *)d = G_INT(def->ofs);
888                 break;
889         
890         case ev_function:
891                 func = ED_FindFunction (s);
892                 if (!func)
893                 {
894                         Con_DPrintf ("Can't find function %s\n", s);
895                         return false;
896                 }
897                 *(func_t *)d = func - pr_functions;
898                 break;
899                 
900         default:
901                 break;
902         }
903         return true;
904 }
905
906 /*
907 ====================
908 ED_ParseEdict
909
910 Parses an edict out of the given string, returning the new position
911 ed should be a properly initialized empty edict.
912 Used for initial level load and for savegames.
913 ====================
914 */
915 char *ED_ParseEdict (char *data, edict_t *ent)
916 {
917         ddef_t          *key;
918         qboolean        anglehack;
919         qboolean        init;
920         char            keyname[256];
921         int                     n;
922
923         init = false;
924
925 // clear it
926         if (ent != sv.edicts)   // hack
927                 memset (&ent->v, 0, progs->entityfields * 4);
928
929 // go through all the dictionary pairs
930         while (1)
931         {       
932         // parse key
933                 data = COM_Parse (data);
934                 if (com_token[0] == '}')
935                         break;
936                 if (!data)
937                         Host_Error ("ED_ParseEntity: EOF without closing brace");
938                 
939 // anglehack is to allow QuakeEd to write single scalar angles
940 // and allow them to be turned into vectors. (FIXME...)
941 if (!strcmp(com_token, "angle"))
942 {
943         strcpy (com_token, "angles");
944         anglehack = true;
945 }
946 else
947         anglehack = false;
948
949 // FIXME: change light to _light to get rid of this hack
950 if (!strcmp(com_token, "light"))
951         strcpy (com_token, "light_lev");        // hack for single light def
952
953                 strcpy (keyname, com_token);
954
955                 // another hack to fix heynames with trailing spaces
956                 n = strlen(keyname);
957                 while (n && keyname[n-1] == ' ')
958                 {
959                         keyname[n-1] = 0;
960                         n--;
961                 }
962
963         // parse value  
964                 data = COM_Parse (data);
965                 if (!data)
966                         Host_Error ("ED_ParseEntity: EOF without closing brace");
967
968                 if (com_token[0] == '}')
969                         Host_Error ("ED_ParseEntity: closing brace without data");
970
971                 init = true;    
972
973 // keynames with a leading underscore are used for utility comments,
974 // and are immediately discarded by quake
975                 if (keyname[0] == '_')
976                         continue;
977                 
978                 key = ED_FindField (keyname);
979                 if (!key)
980                 {
981                         Con_DPrintf ("'%s' is not a field\n", keyname);
982                         continue;
983                 }
984
985 if (anglehack)
986 {
987 char    temp[32];
988 strcpy (temp, com_token);
989 sprintf (com_token, "0 %s 0", temp);
990 }
991
992                 if (!ED_ParseEpair ((void *)&ent->v, key, com_token))
993                         Host_Error ("ED_ParseEdict: parse error");
994         }
995
996         if (!init)
997                 ent->free = true;
998
999         return data;
1000 }
1001
1002
1003 /*
1004 ================
1005 ED_LoadFromFile
1006
1007 The entities are directly placed in the array, rather than allocated with
1008 ED_Alloc, because otherwise an error loading the map would have entity
1009 number references out of order.
1010
1011 Creates a server's entity / program execution context by
1012 parsing textual entity definitions out of an ent file.
1013
1014 Used for both fresh maps and savegame loads.  A fresh map would also need
1015 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1016 ================
1017 */
1018 void ED_LoadFromFile (char *data)
1019 {       
1020         edict_t         *ent;
1021         int                     inhibit;
1022         dfunction_t     *func;
1023         
1024         ent = NULL;
1025         inhibit = 0;
1026         pr_global_struct->time = sv.time;
1027         
1028 // parse ents
1029         while (1)
1030         {
1031 // parse the opening brace      
1032                 data = COM_Parse (data);
1033                 if (!data)
1034                         break;
1035                 if (com_token[0] != '{')
1036                         Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
1037
1038                 if (!ent)
1039                         ent = EDICT_NUM(0);
1040                 else
1041                         ent = ED_Alloc ();
1042                 data = ED_ParseEdict (data, ent);
1043
1044 // remove things from different skill levels or deathmatch
1045                 if (deathmatch.value)
1046                 {
1047                         if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
1048                         {
1049                                 ED_Free (ent);  
1050                                 inhibit++;
1051                                 continue;
1052                         }
1053                 }
1054                 else if ((current_skill == 0 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_EASY  ))
1055                           || (current_skill == 1 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM))
1056                           || (current_skill >= 2 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_HARD  )))
1057                 {
1058                         ED_Free (ent);  
1059                         inhibit++;
1060                         continue;
1061                 }
1062
1063 //
1064 // immediately call spawn function
1065 //
1066                 if (!ent->v.classname)
1067                 {
1068                         Con_Printf ("No classname for:\n");
1069                         ED_Print (ent);
1070                         ED_Free (ent);
1071                         continue;
1072                 }
1073
1074         // look for the spawn function
1075                 func = ED_FindFunction ( pr_strings + ent->v.classname );
1076
1077                 if (!func)
1078                 {
1079                         if (developer.value) // don't confuse non-developers with errors
1080                         {
1081                                 Con_Printf ("No spawn function for:\n");
1082                                 ED_Print (ent);
1083                         }
1084                         ED_Free (ent);
1085                         continue;
1086                 }
1087
1088                 pr_global_struct->self = EDICT_TO_PROG(ent);
1089                 PR_ExecuteProgram (func - pr_functions);
1090         }       
1091
1092         Con_DPrintf ("%i entities inhibited\n", inhibit);
1093 }
1094
1095
1096 /*
1097 ===============
1098 PR_LoadProgs
1099 ===============
1100 */
1101 void PR_LoadProgs (void)
1102 {
1103         int             i;
1104         dstatement_t *st;
1105
1106 // flush the non-C variable lookup cache
1107         for (i=0 ; i<GEFV_CACHESIZE ; i++)
1108                 gefvCache[i].field[0] = 0;
1109
1110         progs = (dprograms_t *)COM_LoadHunkFile ("progs.dat", false);
1111         if (!progs)
1112                 Host_Error ("PR_LoadProgs: couldn't load progs.dat");
1113         Con_DPrintf ("Programs occupy %iK.\n", com_filesize/1024);
1114
1115         pr_crc = CRC_Block((byte *)progs, com_filesize);
1116
1117 // byte swap the header
1118         for (i=0 ; i<sizeof(*progs)/4 ; i++)
1119                 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );           
1120
1121         if (progs->version != PROG_VERSION)
1122                 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1123         if (progs->crc != PROGHEADER_CRC)
1124                 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1125
1126         pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
1127         pr_strings = (char *)progs + progs->ofs_strings;
1128         pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs);
1129         pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs);
1130         pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements);
1131
1132         pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);
1133         pr_globals = (float *)pr_global_struct;
1134         
1135         pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t);
1136
1137         pr_edictareasize = pr_edict_size * MAX_EDICTS;
1138
1139 // byte swap the lumps
1140         for (i=0 ; i<progs->numstatements ; i++)
1141         {
1142                 pr_statements[i].op = LittleShort(pr_statements[i].op);
1143                 pr_statements[i].a = LittleShort(pr_statements[i].a);
1144                 pr_statements[i].b = LittleShort(pr_statements[i].b);
1145                 pr_statements[i].c = LittleShort(pr_statements[i].c);
1146         }
1147
1148         for (i=0 ; i<progs->numfunctions; i++)
1149         {
1150                 pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement);
1151                 pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start);
1152                 pr_functions[i].s_name = LittleLong (pr_functions[i].s_name);
1153                 pr_functions[i].s_file = LittleLong (pr_functions[i].s_file);
1154                 pr_functions[i].numparms = LittleLong (pr_functions[i].numparms);
1155                 pr_functions[i].locals = LittleLong (pr_functions[i].locals);
1156         }       
1157
1158         for (i=0 ; i<progs->numglobaldefs ; i++)
1159         {
1160                 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1161                 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1162                 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1163         }
1164
1165         for (i=0 ; i<progs->numfielddefs ; i++)
1166         {
1167                 pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type);
1168                 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1169                         Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1170                 pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs);
1171                 pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name);
1172         }
1173
1174         for (i=0 ; i<progs->numglobals ; i++)
1175                 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1176
1177         // LordHavoc: bounds check anything static
1178         for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1179         {
1180                 switch (st->op)
1181                 {
1182                 case OP_IF:
1183                 case OP_IFNOT:
1184                         if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1185                                 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1186                         break;
1187                 case OP_GOTO:
1188                         if (st->a + i < 0 || st->a + i >= progs->numstatements)
1189                                 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1190                         break;
1191                 // global global global
1192                 case OP_ADD_F:
1193                 case OP_ADD_V:
1194                 case OP_SUB_F:
1195                 case OP_SUB_V:
1196                 case OP_MUL_F:
1197                 case OP_MUL_V:
1198                 case OP_MUL_FV:
1199                 case OP_MUL_VF:
1200                 case OP_DIV_F:
1201                 case OP_BITAND:
1202                 case OP_BITOR:
1203                 case OP_GE:
1204                 case OP_LE:
1205                 case OP_GT:
1206                 case OP_LT:
1207                 case OP_AND:
1208                 case OP_OR:
1209                 case OP_EQ_F:
1210                 case OP_EQ_V:
1211                 case OP_EQ_S:
1212                 case OP_EQ_E:
1213                 case OP_EQ_FNC:
1214                 case OP_NE_F:
1215                 case OP_NE_V:
1216                 case OP_NE_S:
1217                 case OP_NE_E:
1218                 case OP_NE_FNC:
1219                 case OP_ADDRESS:
1220                 case OP_LOAD_F:
1221                 case OP_LOAD_FLD:
1222                 case OP_LOAD_ENT:
1223                 case OP_LOAD_S:
1224                 case OP_LOAD_FNC:
1225                 case OP_LOAD_V:
1226                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1227                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1228                         break;
1229                 // global none global
1230                 case OP_NOT_F:
1231                 case OP_NOT_V:
1232                 case OP_NOT_S:
1233                 case OP_NOT_FNC:
1234                 case OP_NOT_ENT:
1235                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1236                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1237                         break;
1238                 // 2 globals
1239                 case OP_STOREP_F:
1240                 case OP_STOREP_ENT:
1241                 case OP_STOREP_FLD:
1242                 case OP_STOREP_S:
1243                 case OP_STOREP_FNC:
1244                 case OP_STORE_F:
1245                 case OP_STORE_ENT:
1246                 case OP_STORE_FLD:
1247                 case OP_STORE_S:
1248                 case OP_STORE_FNC:
1249                 case OP_STATE:
1250                 case OP_STOREP_V:
1251                 case OP_STORE_V:
1252                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1253                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1254                         break;
1255                 // 1 global
1256                 case OP_CALL0:
1257                 case OP_CALL1:
1258                 case OP_CALL2:
1259                 case OP_CALL3:
1260                 case OP_CALL4:
1261                 case OP_CALL5:
1262                 case OP_CALL6:
1263                 case OP_CALL7:
1264                 case OP_CALL8:
1265                 case OP_DONE:
1266                 case OP_RETURN:
1267                         if ((unsigned short) st->a >= progs->numglobals)
1268                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1269                         break;
1270                 default:
1271                         Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1272                         break;
1273                 }
1274         }
1275
1276         FindEdictFieldOffsets(); // LordHavoc: update field offset list
1277 }
1278
1279
1280 /*
1281 ===============
1282 PR_Init
1283 ===============
1284 */
1285 void PR_Init (void)
1286 {
1287         Cmd_AddCommand ("edict", ED_PrintEdict_f);
1288         Cmd_AddCommand ("edicts", ED_PrintEdicts);
1289         Cmd_AddCommand ("edictcount", ED_Count);
1290         Cmd_AddCommand ("profile", PR_Profile_f);
1291         Cvar_RegisterVariable (&nomonsters);
1292         Cvar_RegisterVariable (&gamecfg);
1293         Cvar_RegisterVariable (&scratch1);
1294         Cvar_RegisterVariable (&scratch2);
1295         Cvar_RegisterVariable (&scratch3);
1296         Cvar_RegisterVariable (&scratch4);
1297         Cvar_RegisterVariable (&savedgamecfg);
1298         Cvar_RegisterVariable (&saved1);
1299         Cvar_RegisterVariable (&saved2);
1300         Cvar_RegisterVariable (&saved3);
1301         Cvar_RegisterVariable (&saved4);
1302         // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1303         Cvar_RegisterVariable (&decors);
1304         // LordHavoc: Nehahra uses these to pass data around cutscene demos
1305         if (nehahra)
1306         {
1307                 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1308                 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1309                 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1310                 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1311                 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1312                 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1313                 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1314                 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1315                 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1316                 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1317         }
1318         Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1319         // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1320         Cvar_RegisterVariable (&pr_boundscheck);
1321 }
1322
1323 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1324 edict_t *EDICT_NUM_ERROR(int n)
1325 {
1326         Host_Error ("EDICT_NUM: bad number %i", n);
1327         return NULL;
1328 }
1329 /*
1330 edict_t *EDICT_NUM(int n)
1331 {
1332         if (n < 0 || n >= sv.max_edicts)
1333                 Sys_Error ("EDICT_NUM: bad number %i", n);
1334         return (edict_t *)((byte *)sv.edicts+ (n)*pr_edict_size);
1335 }
1336 */
1337
1338 int NUM_FOR_EDICT(edict_t *e)
1339 {
1340         int             b;
1341         
1342         b = (byte *)e - (byte *)sv.edicts;
1343         b = b / pr_edict_size;
1344         
1345         if (b < 0 || b >= sv.num_edicts)
1346                 Host_Error ("NUM_FOR_EDICT: bad pointer");
1347         return b;
1348 }