2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
20 // sv_edict.c -- entity dictionary
25 mfunction_t *pr_functions;
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
35 unsigned short pr_crc;
37 mempool_t *progs_mempool;
38 mempool_t *edictstring_mempool;
40 int type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
42 ddef_t *ED_FieldAtOfs(int ofs);
43 qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s);
45 cvar_t pr_checkextension = {0, "pr_checkextension", "1"};
46 cvar_t nomonsters = {0, "nomonsters", "0"};
47 cvar_t gamecfg = {0, "gamecfg", "0"};
48 cvar_t scratch1 = {0, "scratch1", "0"};
49 cvar_t scratch2 = {0,"scratch2", "0"};
50 cvar_t scratch3 = {0, "scratch3", "0"};
51 cvar_t scratch4 = {0, "scratch4", "0"};
52 cvar_t savedgamecfg = {CVAR_SAVE, "savedgamecfg", "0"};
53 cvar_t saved1 = {CVAR_SAVE, "saved1", "0"};
54 cvar_t saved2 = {CVAR_SAVE, "saved2", "0"};
55 cvar_t saved3 = {CVAR_SAVE, "saved3", "0"};
56 cvar_t saved4 = {CVAR_SAVE, "saved4", "0"};
57 cvar_t decors = {0, "decors", "0"};
58 cvar_t nehx00 = {0, "nehx00", "0"};cvar_t nehx01 = {0, "nehx01", "0"};
59 cvar_t nehx02 = {0, "nehx02", "0"};cvar_t nehx03 = {0, "nehx03", "0"};
60 cvar_t nehx04 = {0, "nehx04", "0"};cvar_t nehx05 = {0, "nehx05", "0"};
61 cvar_t nehx06 = {0, "nehx06", "0"};cvar_t nehx07 = {0, "nehx07", "0"};
62 cvar_t nehx08 = {0, "nehx08", "0"};cvar_t nehx09 = {0, "nehx09", "0"};
63 cvar_t nehx10 = {0, "nehx10", "0"};cvar_t nehx11 = {0, "nehx11", "0"};
64 cvar_t nehx12 = {0, "nehx12", "0"};cvar_t nehx13 = {0, "nehx13", "0"};
65 cvar_t nehx14 = {0, "nehx14", "0"};cvar_t nehx15 = {0, "nehx15", "0"};
66 cvar_t nehx16 = {0, "nehx16", "0"};cvar_t nehx17 = {0, "nehx17", "0"};
67 cvar_t nehx18 = {0, "nehx18", "0"};cvar_t nehx19 = {0, "nehx19", "0"};
68 cvar_t cutscene = {0, "cutscene", "1"};
69 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
70 cvar_t pr_boundscheck = {0, "pr_boundscheck", "1"};
71 // LordHavoc: prints every opcode as it executes - warning: this is significant spew
72 cvar_t pr_traceqc = {0, "pr_traceqc", "0"};
74 #define MAX_FIELD_LEN 64
75 #define GEFV_CACHESIZE 2
79 char field[MAX_FIELD_LEN];
82 static gefv_cache gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
84 ddef_t *ED_FindField (const char *name);
85 mfunction_t *ED_FindFunction (const char *name);
87 // LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue... these are defined as externs in progs.h
101 int eval_renderamt; // HalfLife support
102 int eval_rendermode; // HalfLife support
104 int eval_ammo_shells1;
105 int eval_ammo_nails1;
106 int eval_ammo_lava_nails;
107 int eval_ammo_rockets1;
108 int eval_ammo_multi_rockets;
109 int eval_ammo_cells1;
110 int eval_ammo_plasma;
112 int eval_pitch_speed;
113 int eval_viewmodelforclient;
114 int eval_nodrawtoclient;
115 int eval_exteriormodeltoclient;
116 int eval_drawonlytoclient;
120 int eval_punchvector;
122 int eval_clientcolors;
126 mfunction_t *SV_PlayerPhysicsQC;
127 mfunction_t *EndFrameQC;
128 //KrimZon - SERVER COMMANDS IN QUAKEC
129 mfunction_t *SV_ParseClientCommandQC;
131 int FindFieldOffset(const char *field)
134 d = ED_FindField(field);
140 void FindEdictFieldOffsets(void)
142 eval_gravity = FindFieldOffset("gravity");
143 eval_button3 = FindFieldOffset("button3");
144 eval_button4 = FindFieldOffset("button4");
145 eval_button5 = FindFieldOffset("button5");
146 eval_button6 = FindFieldOffset("button6");
147 eval_button7 = FindFieldOffset("button7");
148 eval_button8 = FindFieldOffset("button8");
149 eval_glow_size = FindFieldOffset("glow_size");
150 eval_glow_trail = FindFieldOffset("glow_trail");
151 eval_glow_color = FindFieldOffset("glow_color");
152 eval_items2 = FindFieldOffset("items2");
153 eval_scale = FindFieldOffset("scale");
154 eval_alpha = FindFieldOffset("alpha");
155 eval_renderamt = FindFieldOffset("renderamt"); // HalfLife support
156 eval_rendermode = FindFieldOffset("rendermode"); // HalfLife support
157 eval_fullbright = FindFieldOffset("fullbright");
158 eval_ammo_shells1 = FindFieldOffset("ammo_shells1");
159 eval_ammo_nails1 = FindFieldOffset("ammo_nails1");
160 eval_ammo_lava_nails = FindFieldOffset("ammo_lava_nails");
161 eval_ammo_rockets1 = FindFieldOffset("ammo_rockets1");
162 eval_ammo_multi_rockets = FindFieldOffset("ammo_multi_rockets");
163 eval_ammo_cells1 = FindFieldOffset("ammo_cells1");
164 eval_ammo_plasma = FindFieldOffset("ammo_plasma");
165 eval_idealpitch = FindFieldOffset("idealpitch");
166 eval_pitch_speed = FindFieldOffset("pitch_speed");
167 eval_viewmodelforclient = FindFieldOffset("viewmodelforclient");
168 eval_nodrawtoclient = FindFieldOffset("nodrawtoclient");
169 eval_exteriormodeltoclient = FindFieldOffset("exteriormodeltoclient");
170 eval_drawonlytoclient = FindFieldOffset("drawonlytoclient");
171 eval_ping = FindFieldOffset("ping");
172 eval_movement = FindFieldOffset("movement");
173 eval_pmodel = FindFieldOffset("pmodel");
174 eval_punchvector = FindFieldOffset("punchvector");
175 eval_viewzoom = FindFieldOffset("viewzoom");
176 eval_clientcolors = FindFieldOffset("clientcolors");
177 eval_tag_entity = FindFieldOffset("tag_entity");
178 eval_tag_index = FindFieldOffset("tag_index");
180 // LordHavoc: allowing QuakeC to override the player movement code
181 SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
182 // LordHavoc: support for endframe
183 EndFrameQC = ED_FindFunction ("EndFrame");
184 //KrimZon - SERVER COMMANDS IN QUAKEC
185 SV_ParseClientCommandQC = ED_FindFunction ("SV_ParseClientCommand");
192 Sets everything to NULL
195 void ED_ClearEdict (edict_t *e)
198 memset (e->v, 0, progs->entityfields * 4);
200 // LordHavoc: for consistency set these here
201 num = NUM_FOR_EDICT(e) - 1;
202 if (num >= 0 && num < svs.maxclients)
204 e->v->colormap = num + 1;
205 e->v->team = (svs.clients[num].colors & 15) + 1;
206 e->v->netname = PR_SetString(svs.clients[num].name);
214 Either finds a free edict, or allocates a new one.
215 Try to avoid reusing an entity that was recently freed, because it
216 can cause the client to think the entity morphed into something else
217 instead of being removed and recreated, which can cause interpolated
218 angles and bad trails.
221 edict_t *ED_Alloc (void)
226 for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
229 // the first couple seconds of server time can involve a lot of
230 // freeing and allocating, so relax the replacement policy
231 if (e->e->free && ( e->e->freetime < 2 || sv.time - e->e->freetime > 0.5 ) )
239 Host_Error ("ED_Alloc: no free edicts");
242 if (sv.num_edicts >= sv.max_edicts)
254 Marks the edict as free
255 FIXME: walk all entities and NULL out references to this entity
258 void ED_Free (edict_t *ed)
260 SV_UnlinkEdict (ed); // unlink from world bsp
264 ed->v->takedamage = 0;
265 ed->v->modelindex = 0;
269 VectorClear(ed->v->origin);
270 VectorClear(ed->v->angles);
271 ed->v->nextthink = -1;
274 ed->e->freetime = sv.time;
277 //===========================================================================
284 ddef_t *ED_GlobalAtOfs (int ofs)
289 for (i=0 ; i<progs->numglobaldefs ; i++)
291 def = &pr_globaldefs[i];
303 ddef_t *ED_FieldAtOfs (int ofs)
308 for (i=0 ; i<progs->numfielddefs ; i++)
310 def = &pr_fielddefs[i];
322 ddef_t *ED_FindField (const char *name)
327 for (i=0 ; i<progs->numfielddefs ; i++)
329 def = &pr_fielddefs[i];
330 if (!strcmp(PR_GetString(def->s_name), name))
341 ddef_t *ED_FindGlobal (const char *name)
346 for (i=0 ; i<progs->numglobaldefs ; i++)
348 def = &pr_globaldefs[i];
349 if (!strcmp(PR_GetString(def->s_name), name))
361 mfunction_t *ED_FindFunction (const char *name)
366 for (i=0 ; i<progs->numfunctions ; i++)
368 func = &pr_functions[i];
369 if (!strcmp(PR_GetString(func->s_name), name))
380 Returns a string describing *data in a type specific manner
383 //int NoCrash_NUM_FOR_EDICT(edict_t *e);
384 char *PR_ValueString (etype_t type, eval_t *val)
386 static char line[1024]; // LordHavoc: enlarged a bit (was 256)
391 type &= ~DEF_SAVEGLOBAL;
396 snprintf (line, sizeof (line), "%s", PR_GetString(val->string));
399 //n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict));
401 if (n < 0 || n >= MAX_EDICTS)
402 snprintf (line, sizeof (line), "entity %i (invalid!)", n);
404 snprintf (line, sizeof (line), "entity %i", n);
407 f = pr_functions + val->function;
408 snprintf (line, sizeof (line), "%s()", PR_GetString(f->s_name));
411 def = ED_FieldAtOfs ( val->_int );
412 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
415 snprintf (line, sizeof (line), "void");
418 // LordHavoc: changed from %5.1f to %10.4f
419 snprintf (line, sizeof (line), "%10.4f", val->_float);
422 // LordHavoc: changed from %5.1f to %10.4f
423 snprintf (line, sizeof (line), "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
426 snprintf (line, sizeof (line), "pointer");
429 snprintf (line, sizeof (line), "bad type %i", type);
440 Returns a string describing *data in a type specific manner
441 Easier to parse than PR_ValueString
444 char *PR_UglyValueString (etype_t type, eval_t *val)
446 static char line[4096];
452 type &= ~DEF_SAVEGLOBAL;
457 // Parse the string a bit to turn special characters
458 // (like newline, specifically) into escape codes,
459 // this fixes saving games from various mods
460 s = PR_GetString (val->string);
461 for (i = 0;i < (int)sizeof(line) - 2 && *s;)
480 snprintf (line, sizeof (line), "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
483 f = pr_functions + val->function;
484 snprintf (line, sizeof (line), "%s", PR_GetString(f->s_name));
487 def = ED_FieldAtOfs ( val->_int );
488 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
491 snprintf (line, sizeof (line), "void");
494 snprintf (line, sizeof (line), "%f", val->_float);
497 snprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
500 snprintf (line, sizeof (line), "bad type %i", type);
511 Returns a string with a description and the contents of a global,
512 padded to 20 field width
515 char *PR_GlobalString (int ofs)
521 static char line[128];
523 val = (void *)&pr_globals[ofs];
524 def = ED_GlobalAtOfs(ofs);
526 snprintf (line, sizeof (line), "%i(?)", ofs);
529 s = PR_ValueString (def->type, val);
530 snprintf (line, sizeof (line), "%i(%s)%s", ofs, PR_GetString(def->s_name), s);
535 strlcat (line, " ", sizeof (line));
536 strlcat (line, " ", sizeof (line));
541 char *PR_GlobalStringNoContents (int ofs)
545 static char line[128];
547 def = ED_GlobalAtOfs(ofs);
549 snprintf (line, sizeof (line), "%i(?)", ofs);
551 snprintf (line, sizeof (line), "%i(%s)", ofs, PR_GetString(def->s_name));
555 strlcat (line, " ", sizeof (line));
556 strlcat (line, " ", sizeof (line));
569 // LordHavoc: optimized this to print out much more quickly (tempstring)
570 // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
571 void ED_Print (edict_t *ed)
579 char tempstring[8192], tempstring2[260]; // temporary string buffers
583 Con_Printf ("FREE\n");
588 snprintf (tempstring, sizeof (tempstring), "\nEDICT %i:\n", NUM_FOR_EDICT(ed));
589 for (i=1 ; i<progs->numfielddefs ; i++)
591 d = &pr_fielddefs[i];
592 name = PR_GetString(d->s_name);
593 if (name[strlen(name)-2] == '_')
594 continue; // skip _x, _y, _z vars
596 v = (int *)((char *)ed->v + d->ofs*4);
598 // if the value is still all 0, skip the field
599 type = d->type & ~DEF_SAVEGLOBAL;
601 for (j=0 ; j<type_size[type] ; j++)
604 if (j == type_size[type])
607 if (strlen(name) > 256)
609 strncpy(tempstring2, name, 256);
610 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
611 tempstring2[259] = 0;
614 strlcat (tempstring, name, sizeof (tempstring));
615 for (l = strlen(name);l < 14;l++)
616 strcat(tempstring, " ");
617 strcat(tempstring, " ");
619 name = PR_ValueString(d->type, (eval_t *)v);
620 if (strlen(name) > 256)
622 strncpy(tempstring2, name, 256);
623 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
624 tempstring2[259] = 0;
627 strlcat (tempstring, name, sizeof (tempstring));
628 strlcat (tempstring, "\n", sizeof (tempstring));
629 if (strlen(tempstring) >= 4096)
631 Con_Printf("%s", tempstring);
636 Con_Printf("%s", tempstring);
646 void ED_Write (qfile_t *f, edict_t *ed)
654 FS_Printf (f, "{\n");
658 FS_Printf (f, "}\n");
662 for (i=1 ; i<progs->numfielddefs ; i++)
664 d = &pr_fielddefs[i];
665 name = PR_GetString(d->s_name);
666 if (name[strlen(name)-2] == '_')
667 continue; // skip _x, _y, _z vars
669 v = (int *)((char *)ed->v + d->ofs*4);
671 // if the value is still all 0, skip the field
672 type = d->type & ~DEF_SAVEGLOBAL;
673 for (j=0 ; j<type_size[type] ; j++)
676 if (j == type_size[type])
679 FS_Printf (f,"\"%s\" ",name);
680 FS_Printf (f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
683 FS_Printf (f, "}\n");
686 void ED_PrintNum (int ent)
688 ED_Print (EDICT_NUM(ent));
695 For debugging, prints all the entities in the current server
698 void ED_PrintEdicts (void)
702 Con_Printf ("%i entities\n", sv.num_edicts);
703 for (i=0 ; i<sv.num_edicts ; i++)
711 For debugging, prints a single edict
714 void ED_PrintEdict_f (void)
718 i = atoi (Cmd_Argv(1));
719 if (i >= sv.num_edicts)
721 Con_Printf("Bad edict number\n");
738 int active, models, solid, step;
740 active = models = solid = step = 0;
741 for (i=0 ; i<sv.num_edicts ; i++)
751 if (ent->v->movetype == MOVETYPE_STEP)
755 Con_Printf ("num_edicts:%3i\n", sv.num_edicts);
756 Con_Printf ("active :%3i\n", active);
757 Con_Printf ("view :%3i\n", models);
758 Con_Printf ("touch :%3i\n", solid);
759 Con_Printf ("step :%3i\n", step);
764 ==============================================================================
768 FIXME: need to tag constants, doesn't really work
769 ==============================================================================
777 void ED_WriteGlobals (qfile_t *f)
785 for (i=0 ; i<progs->numglobaldefs ; i++)
787 def = &pr_globaldefs[i];
789 if ( !(def->type & DEF_SAVEGLOBAL) )
791 type &= ~DEF_SAVEGLOBAL;
793 if (type != ev_string && type != ev_float && type != ev_entity)
796 name = PR_GetString(def->s_name);
797 FS_Printf (f,"\"%s\" ", name);
798 FS_Printf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
808 void ED_ParseGlobals (const char *data)
810 char keyname[1024]; // LordHavoc: good idea? bad idea? was 64
816 if (!COM_ParseToken(&data, false))
817 Host_Error ("ED_ParseEntity: EOF without closing brace");
818 if (com_token[0] == '}')
821 strcpy (keyname, com_token);
824 if (!COM_ParseToken(&data, false))
825 Host_Error ("ED_ParseEntity: EOF without closing brace");
827 if (com_token[0] == '}')
828 Host_Error ("ED_ParseEntity: closing brace without data");
830 key = ED_FindGlobal (keyname);
833 Con_DPrintf ("'%s' is not a global\n", keyname);
837 if (!ED_ParseEpair(NULL, key, com_token))
838 Host_Error ("ED_ParseGlobals: parse error");
842 //============================================================================
850 char *ED_NewString (const char *string)
855 l = strlen(string) + 1;
856 new = Mem_Alloc(edictstring_mempool, l);
859 for (i=0 ; i< l ; i++)
861 if (string[i] == '\\' && i < l-1)
864 if (string[i] == 'n')
870 *new_p++ = string[i];
881 Can parse either fields or globals
882 returns false if error
885 qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
893 val = (eval_t *)((int *)ent->v + key->ofs);
895 val = (eval_t *)((int *)pr_globals + key->ofs);
896 switch (key->type & ~DEF_SAVEGLOBAL)
899 val->string = PR_SetString(ED_NewString(s));
903 while (*s && *s <= ' ')
905 val->_float = atof(s);
909 for (i = 0;i < 3;i++)
911 while (*s && *s <= ' ')
915 val->vector[i] = atof(s);
924 while (*s && *s <= ' ')
927 if (i < 0 || i >= MAX_EDICTS)
928 Con_Printf("ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i)\n", i, MAX_EDICTS);
929 while (i >= sv.max_edicts)
931 // if SV_IncreaseEdicts was called the base pointer needs to be updated
933 val = (eval_t *)((int *)ent->v + key->ofs);
934 val->edict = EDICT_TO_PROG(EDICT_NUM(i));
938 def = ED_FindField(s);
941 Con_DPrintf("ED_ParseEpair: Can't find field %s\n", s);
944 val->_int = G_INT(def->ofs);
948 func = ED_FindFunction(s);
951 Con_Printf ("ED_ParseEpair: Can't find function %s\n", s);
954 val->function = func - pr_functions;
958 Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PR_GetString(key->s_name));
968 Parses an edict out of the given string, returning the new position
969 ed should be a properly initialized empty edict.
970 Used for initial level load and for savegames.
973 const char *ED_ParseEdict (const char *data, edict_t *ent)
984 if (ent != sv.edicts) // hack
985 memset (ent->v, 0, progs->entityfields * 4);
987 // go through all the dictionary pairs
991 if (!COM_ParseToken(&data, false))
992 Host_Error ("ED_ParseEntity: EOF without closing brace");
993 if (com_token[0] == '}')
996 // anglehack is to allow QuakeEd to write single scalar angles
997 // and allow them to be turned into vectors. (FIXME...)
998 anglehack = !strcmp (com_token, "angle");
1000 strlcpy (com_token, "angles", sizeof (com_token));
1002 // FIXME: change light to _light to get rid of this hack
1003 if (!strcmp(com_token, "light"))
1004 strlcpy (com_token, "light_lev", sizeof (com_token)); // hack for single light def
1006 strlcpy (keyname, com_token, sizeof (keyname));
1008 // another hack to fix heynames with trailing spaces
1009 n = strlen(keyname);
1010 while (n && keyname[n-1] == ' ')
1017 if (!COM_ParseToken(&data, false))
1018 Host_Error ("ED_ParseEntity: EOF without closing brace");
1020 if (com_token[0] == '}')
1021 Host_Error ("ED_ParseEntity: closing brace without data");
1025 // keynames with a leading underscore are used for utility comments,
1026 // and are immediately discarded by quake
1027 if (keyname[0] == '_')
1030 key = ED_FindField (keyname);
1033 Con_DPrintf ("'%s' is not a field\n", keyname);
1040 strlcpy (temp, com_token, sizeof (temp));
1041 snprintf (com_token, sizeof (com_token), "0 %s 0", temp);
1044 if (!ED_ParseEpair(ent, key, com_token))
1045 Host_Error ("ED_ParseEdict: parse error");
1049 ent->e->free = true;
1059 The entities are directly placed in the array, rather than allocated with
1060 ED_Alloc, because otherwise an error loading the map would have entity
1061 number references out of order.
1063 Creates a server's entity / program execution context by
1064 parsing textual entity definitions out of an ent file.
1066 Used for both fresh maps and savegame loads. A fresh map would also need
1067 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1070 void ED_LoadFromFile (const char *data)
1073 int parsed, inhibited, spawned, died;
1081 pr_global_struct->time = sv.time;
1086 // parse the opening brace
1087 if (!COM_ParseToken(&data, false))
1089 if (com_token[0] != '{')
1090 Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
1096 data = ED_ParseEdict (data, ent);
1099 // remove things from different skill levels or deathmatch
1100 if (deathmatch.integer)
1102 if (((int)ent->v->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
1109 else if ((current_skill == 0 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_EASY ))
1110 || (current_skill == 1 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_MEDIUM))
1111 || (current_skill >= 2 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_HARD )))
1119 // immediately call spawn function
1121 if (!ent->v->classname)
1123 Con_Printf ("No classname for:\n");
1129 // look for the spawn function
1130 func = ED_FindFunction (PR_GetString(ent->v->classname));
1134 if (developer.integer) // don't confuse non-developers with errors
1136 Con_Printf ("No spawn function for:\n");
1143 pr_global_struct->self = EDICT_TO_PROG(ent);
1144 PR_ExecuteProgram (func - pr_functions, "");
1150 Con_DPrintf ("%i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", parsed, inhibited, spawned, died, spawned - died);
1154 typedef struct dpfield_s
1161 #define DPFIELDS (sizeof(dpfields) / sizeof(dpfield_t))
1163 dpfield_t dpfields[] =
1165 {ev_float, "gravity"},
1166 {ev_float, "button3"},
1167 {ev_float, "button4"},
1168 {ev_float, "button5"},
1169 {ev_float, "button6"},
1170 {ev_float, "button7"},
1171 {ev_float, "button8"},
1172 {ev_float, "glow_size"},
1173 {ev_float, "glow_trail"},
1174 {ev_float, "glow_color"},
1175 {ev_float, "items2"},
1176 {ev_float, "scale"},
1177 {ev_float, "alpha"},
1178 {ev_float, "renderamt"},
1179 {ev_float, "rendermode"},
1180 {ev_float, "fullbright"},
1181 {ev_float, "ammo_shells1"},
1182 {ev_float, "ammo_nails1"},
1183 {ev_float, "ammo_lava_nails"},
1184 {ev_float, "ammo_rockets1"},
1185 {ev_float, "ammo_multi_rockets"},
1186 {ev_float, "ammo_cells1"},
1187 {ev_float, "ammo_plasma"},
1188 {ev_float, "idealpitch"},
1189 {ev_float, "pitch_speed"},
1190 {ev_entity, "viewmodelforclient"},
1191 {ev_entity, "nodrawtoclient"},
1192 {ev_entity, "exteriormodeltoclient"},
1193 {ev_entity, "drawonlytoclient"},
1195 {ev_vector, "movement"},
1196 {ev_float, "pmodel"},
1197 {ev_vector, "punchvector"},
1198 {ev_float, "clientcolors"},
1199 {ev_entity, "tag_entity"},
1200 {ev_float, "tag_index"}
1208 extern void PR_Cmd_Reset (void);
1209 void PR_LoadProgs (void)
1213 ddef_t *infielddefs;
1215 dfunction_t *dfunctions;
1217 // flush the non-C variable lookup cache
1218 for (i=0 ; i<GEFV_CACHESIZE ; i++)
1219 gefvCache[i].field[0] = 0;
1221 Mem_EmptyPool(progs_mempool);
1222 Mem_EmptyPool(edictstring_mempool);
1224 temp = FS_LoadFile ("progs.dat", false);
1226 Host_Error ("PR_LoadProgs: couldn't load progs.dat");
1228 progs = (dprograms_t *)Mem_Alloc(progs_mempool, fs_filesize);
1230 memcpy(progs, temp, fs_filesize);
1233 Con_DPrintf ("Programs occupy %iK.\n", fs_filesize/1024);
1235 pr_crc = CRC_Block((qbyte *)progs, fs_filesize);
1237 // byte swap the header
1238 for (i = 0;i < (int) sizeof(*progs) / 4;i++)
1239 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1241 if (progs->version != PROG_VERSION)
1242 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1243 if (progs->crc != PROGHEADER_CRC)
1244 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1246 //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1247 dfunctions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1248 pr_strings = (char *)progs + progs->ofs_strings;
1249 pr_globaldefs = (ddef_t *)((qbyte *)progs + progs->ofs_globaldefs);
1251 // we need to expand the fielddefs list to include all the engine fields,
1252 // so allocate a new place for it
1253 infielddefs = (ddef_t *)((qbyte *)progs + progs->ofs_fielddefs);
1254 pr_fielddefs = Mem_Alloc(progs_mempool, (progs->numfielddefs + DPFIELDS) * sizeof(ddef_t));
1256 pr_statements = (dstatement_t *)((qbyte *)progs + progs->ofs_statements);
1258 // moved edict_size calculation down below field adding code
1260 pr_global_struct = (globalvars_t *)((qbyte *)progs + progs->ofs_globals);
1261 pr_globals = (float *)pr_global_struct;
1263 // byte swap the lumps
1264 for (i=0 ; i<progs->numstatements ; i++)
1266 pr_statements[i].op = LittleShort(pr_statements[i].op);
1267 pr_statements[i].a = LittleShort(pr_statements[i].a);
1268 pr_statements[i].b = LittleShort(pr_statements[i].b);
1269 pr_statements[i].c = LittleShort(pr_statements[i].c);
1272 pr_functions = Mem_Alloc(progs_mempool, sizeof(mfunction_t) * progs->numfunctions);
1273 for (i = 0;i < progs->numfunctions;i++)
1275 pr_functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
1276 pr_functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
1277 pr_functions[i].s_name = LittleLong (dfunctions[i].s_name);
1278 pr_functions[i].s_file = LittleLong (dfunctions[i].s_file);
1279 pr_functions[i].numparms = LittleLong (dfunctions[i].numparms);
1280 pr_functions[i].locals = LittleLong (dfunctions[i].locals);
1281 memcpy(pr_functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
1284 for (i=0 ; i<progs->numglobaldefs ; i++)
1286 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1287 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1288 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1291 // copy the progs fields to the new fields list
1292 for (i = 0;i < progs->numfielddefs;i++)
1294 pr_fielddefs[i].type = LittleShort (infielddefs[i].type);
1295 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1296 Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1297 pr_fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
1298 pr_fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
1301 // append the darkplaces fields
1302 for (i = 0;i < (int) DPFIELDS;i++)
1304 pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
1305 pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
1306 pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string);
1307 if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
1308 progs->entityfields += 3;
1310 progs->entityfields++;
1311 progs->numfielddefs++;
1314 for (i=0 ; i<progs->numglobals ; i++)
1315 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1317 // moved edict_size calculation down here, below field adding code
1318 // LordHavoc: this no longer includes the edict_t header
1319 pr_edict_size = progs->entityfields * 4;
1320 pr_edictareasize = pr_edict_size * MAX_EDICTS;
1322 // LordHavoc: bounds check anything static
1323 for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1329 if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1330 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1333 if (st->a + i < 0 || st->a + i >= progs->numstatements)
1334 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1336 // global global global
1371 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1372 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1374 // global none global
1380 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1381 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1397 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1398 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1412 if ((unsigned short) st->a >= progs->numglobals)
1413 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1416 Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1421 FindEdictFieldOffsets(); // LordHavoc: update field offset list
1422 PR_Execute_ProgsLoaded();
1427 void PR_Fields_f (void)
1429 int i, j, ednum, used, usedamount;
1431 char tempstring[5000], tempstring2[260], *name;
1437 Con_Printf("no progs loaded\n");
1440 counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
1441 for (ednum = 0;ednum < sv.max_edicts;ednum++)
1443 ed = EDICT_NUM(ednum);
1446 for (i = 1;i < progs->numfielddefs;i++)
1448 d = &pr_fielddefs[i];
1449 name = PR_GetString(d->s_name);
1450 if (name[strlen(name)-2] == '_')
1451 continue; // skip _x, _y, _z vars
1452 v = (int *)((char *)ed->v + d->ofs*4);
1453 // if the value is still all 0, skip the field
1454 for (j = 0;j < type_size[d->type & ~DEF_SAVEGLOBAL];j++)
1467 for (i = 0;i < progs->numfielddefs;i++)
1469 d = &pr_fielddefs[i];
1470 name = PR_GetString(d->s_name);
1471 if (name[strlen(name)-2] == '_')
1472 continue; // skip _x, _y, _z vars
1473 switch(d->type & ~DEF_SAVEGLOBAL)
1476 strlcat (tempstring, "string ", sizeof (tempstring));
1479 strlcat (tempstring, "entity ", sizeof (tempstring));
1482 strlcat (tempstring, "function ", sizeof (tempstring));
1485 strlcat (tempstring, "field ", sizeof (tempstring));
1488 strlcat (tempstring, "void ", sizeof (tempstring));
1491 strlcat (tempstring, "float ", sizeof (tempstring));
1494 strlcat (tempstring, "vector ", sizeof (tempstring));
1497 strlcat (tempstring, "pointer ", sizeof (tempstring));
1500 snprintf (tempstring2, sizeof (tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
1501 strlcat (tempstring, tempstring2, sizeof (tempstring));
1504 if (strlen(name) > 256)
1506 strncpy(tempstring2, name, 256);
1507 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
1508 tempstring2[259] = 0;
1511 strcat (tempstring, name);
1512 for (j = strlen(name);j < 25;j++)
1513 strcat(tempstring, " ");
1514 snprintf (tempstring2, sizeof (tempstring2), "%5d", counts[i]);
1515 strlcat (tempstring, tempstring2, sizeof (tempstring));
1516 strlcat (tempstring, "\n", sizeof (tempstring));
1517 if (strlen(tempstring) >= 4096)
1519 Con_Printf("%s", tempstring);
1525 usedamount += type_size[d->type & ~DEF_SAVEGLOBAL];
1529 Con_Printf("%i entity fields (%i in use), totalling %i bytes per edict (%i in use), %i edicts allocated, %i bytes total spent on edict fields (%i needed)\n", progs->entityfields, used, progs->entityfields * 4, usedamount * 4, sv.max_edicts, progs->entityfields * 4 * sv.max_edicts, usedamount * 4 * sv.max_edicts);
1532 void PR_Globals_f (void)
1537 Con_Printf("no progs loaded\n");
1540 for (i = 0;i < progs->numglobaldefs;i++)
1541 Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name));
1542 Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
1550 extern void PR_Cmd_Init(void);
1553 Cmd_AddCommand ("edict", ED_PrintEdict_f);
1554 Cmd_AddCommand ("edicts", ED_PrintEdicts);
1555 Cmd_AddCommand ("edictcount", ED_Count);
1556 Cmd_AddCommand ("profile", PR_Profile_f);
1557 Cmd_AddCommand ("pr_fields", PR_Fields_f);
1558 Cmd_AddCommand ("pr_globals", PR_Globals_f);
1559 Cvar_RegisterVariable (&pr_checkextension);
1560 Cvar_RegisterVariable (&nomonsters);
1561 Cvar_RegisterVariable (&gamecfg);
1562 Cvar_RegisterVariable (&scratch1);
1563 Cvar_RegisterVariable (&scratch2);
1564 Cvar_RegisterVariable (&scratch3);
1565 Cvar_RegisterVariable (&scratch4);
1566 Cvar_RegisterVariable (&savedgamecfg);
1567 Cvar_RegisterVariable (&saved1);
1568 Cvar_RegisterVariable (&saved2);
1569 Cvar_RegisterVariable (&saved3);
1570 Cvar_RegisterVariable (&saved4);
1571 // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1572 Cvar_RegisterVariable (&decors);
1573 // LordHavoc: Nehahra uses these to pass data around cutscene demos
1574 if (gamemode == GAME_NEHAHRA)
1576 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1577 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1578 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1579 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1580 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1581 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1582 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1583 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1584 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1585 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1587 Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1588 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1589 Cvar_RegisterVariable (&pr_boundscheck);
1590 Cvar_RegisterVariable (&pr_traceqc);
1592 progs_mempool = Mem_AllocPool("progs.dat");
1593 edictstring_mempool = Mem_AllocPool("edict strings");
1598 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1599 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
1601 Host_Error ("EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
1606 int NUM_FOR_EDICT_ERROR(edict_t *e)
1608 Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
1612 int NUM_FOR_EDICT(edict_t *e)
1616 if ((unsigned int)n >= MAX_EDICTS)
1617 Host_Error ("NUM_FOR_EDICT: bad pointer");
1621 //int NoCrash_NUM_FOR_EDICT(edict_t *e)
1623 // return e - sv.edicts;
1626 //#define EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
1627 //#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
1628 int EDICT_TO_PROG(edict_t *e)
1632 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1633 Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
1634 return n;// EXPERIMENTAL
1635 //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
1637 edict_t *PROG_TO_EDICT(int n)
1639 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1640 Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
1641 return sv.edicts + n; // EXPERIMENTAL
1642 //return sv.edicts + ((n) / (progs->entityfields * 4));