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