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