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