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 = {CVAR_READONLY, "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;
130 mfunction_t *SV_PlayerPhysicsQC;
131 mfunction_t *EndFrameQC;
132 //KrimZon - SERVER COMMANDS IN QUAKEC
133 mfunction_t *SV_ParseClientCommandQC;
135 int FindFieldOffset(const char *field)
138 d = ED_FindField(field);
144 void FindEdictFieldOffsets(void)
146 eval_gravity = FindFieldOffset("gravity");
147 eval_button3 = FindFieldOffset("button3");
148 eval_button4 = FindFieldOffset("button4");
149 eval_button5 = FindFieldOffset("button5");
150 eval_button6 = FindFieldOffset("button6");
151 eval_button7 = FindFieldOffset("button7");
152 eval_button8 = FindFieldOffset("button8");
153 eval_glow_size = FindFieldOffset("glow_size");
154 eval_glow_trail = FindFieldOffset("glow_trail");
155 eval_glow_color = FindFieldOffset("glow_color");
156 eval_items2 = FindFieldOffset("items2");
157 eval_scale = FindFieldOffset("scale");
158 eval_alpha = FindFieldOffset("alpha");
159 eval_renderamt = FindFieldOffset("renderamt"); // HalfLife support
160 eval_rendermode = FindFieldOffset("rendermode"); // HalfLife support
161 eval_fullbright = FindFieldOffset("fullbright");
162 eval_ammo_shells1 = FindFieldOffset("ammo_shells1");
163 eval_ammo_nails1 = FindFieldOffset("ammo_nails1");
164 eval_ammo_lava_nails = FindFieldOffset("ammo_lava_nails");
165 eval_ammo_rockets1 = FindFieldOffset("ammo_rockets1");
166 eval_ammo_multi_rockets = FindFieldOffset("ammo_multi_rockets");
167 eval_ammo_cells1 = FindFieldOffset("ammo_cells1");
168 eval_ammo_plasma = FindFieldOffset("ammo_plasma");
169 eval_idealpitch = FindFieldOffset("idealpitch");
170 eval_pitch_speed = FindFieldOffset("pitch_speed");
171 eval_viewmodelforclient = FindFieldOffset("viewmodelforclient");
172 eval_nodrawtoclient = FindFieldOffset("nodrawtoclient");
173 eval_exteriormodeltoclient = FindFieldOffset("exteriormodeltoclient");
174 eval_drawonlytoclient = FindFieldOffset("drawonlytoclient");
175 eval_ping = FindFieldOffset("ping");
176 eval_movement = FindFieldOffset("movement");
177 eval_pmodel = FindFieldOffset("pmodel");
178 eval_punchvector = FindFieldOffset("punchvector");
179 eval_viewzoom = FindFieldOffset("viewzoom");
180 eval_clientcolors = FindFieldOffset("clientcolors");
181 eval_tag_entity = FindFieldOffset("tag_entity");
182 eval_tag_index = FindFieldOffset("tag_index");
183 eval_light_lev = FindFieldOffset("light_lev");
184 eval_color = FindFieldOffset("color");
185 eval_style = FindFieldOffset("style");
186 eval_pflags = FindFieldOffset("pflags");
188 // LordHavoc: allowing QuakeC to override the player movement code
189 SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
190 // LordHavoc: support for endframe
191 EndFrameQC = ED_FindFunction ("EndFrame");
192 //KrimZon - SERVER COMMANDS IN QUAKEC
193 SV_ParseClientCommandQC = ED_FindFunction ("SV_ParseClientCommand");
200 Sets everything to NULL
203 void ED_ClearEdict (edict_t *e)
206 memset (e->v, 0, progs->entityfields * 4);
208 // LordHavoc: for consistency set these here
209 num = NUM_FOR_EDICT(e) - 1;
210 if (num >= 0 && num < svs.maxclients)
213 // set colormap and team on newly created player entity
214 e->v->colormap = num + 1;
215 e->v->team = (svs.clients[num].colors & 15) + 1;
216 // set netname/clientcolors back to client values so that
217 // DP_SV_CLIENTNAME and DPV_SV_CLIENTCOLORS will not immediately
219 e->v->netname = PR_SetString(svs.clients[num].name);
220 if ((val = GETEDICTFIELDVALUE(e, eval_clientcolors)))
221 val->_float = svs.clients[num].colors;
229 Either finds a free edict, or allocates a new one.
230 Try to avoid reusing an entity that was recently freed, because it
231 can cause the client to think the entity morphed into something else
232 instead of being removed and recreated, which can cause interpolated
233 angles and bad trails.
236 edict_t *ED_Alloc (void)
241 for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
244 // the first couple seconds of server time can involve a lot of
245 // freeing and allocating, so relax the replacement policy
246 if (e->e->free && ( e->e->freetime < 2 || sv.time - e->e->freetime > 0.5 ) )
254 Host_Error ("ED_Alloc: no free edicts");
257 if (sv.num_edicts >= sv.max_edicts)
269 Marks the edict as free
270 FIXME: walk all entities and NULL out references to this entity
273 void ED_Free (edict_t *ed)
275 SV_UnlinkEdict (ed); // unlink from world bsp
279 ed->v->takedamage = 0;
280 ed->v->modelindex = 0;
284 VectorClear(ed->v->origin);
285 VectorClear(ed->v->angles);
286 ed->v->nextthink = -1;
289 ed->e->freetime = sv.time;
292 //===========================================================================
299 ddef_t *ED_GlobalAtOfs (int ofs)
304 for (i=0 ; i<progs->numglobaldefs ; i++)
306 def = &pr_globaldefs[i];
318 ddef_t *ED_FieldAtOfs (int ofs)
323 for (i=0 ; i<progs->numfielddefs ; i++)
325 def = &pr_fielddefs[i];
337 ddef_t *ED_FindField (const char *name)
342 for (i=0 ; i<progs->numfielddefs ; i++)
344 def = &pr_fielddefs[i];
345 if (!strcmp(PR_GetString(def->s_name), name))
356 ddef_t *ED_FindGlobal (const char *name)
361 for (i=0 ; i<progs->numglobaldefs ; i++)
363 def = &pr_globaldefs[i];
364 if (!strcmp(PR_GetString(def->s_name), name))
376 mfunction_t *ED_FindFunction (const char *name)
381 for (i=0 ; i<progs->numfunctions ; i++)
383 func = &pr_functions[i];
384 if (!strcmp(PR_GetString(func->s_name), name))
395 Returns a string describing *data in a type specific manner
398 //int NoCrash_NUM_FOR_EDICT(edict_t *e);
399 char *PR_ValueString (etype_t type, eval_t *val)
401 static char line[1024]; // LordHavoc: enlarged a bit (was 256)
406 type &= ~DEF_SAVEGLOBAL;
411 strlcpy (line, PR_GetString (val->string), sizeof (line));
414 //n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict));
416 if (n < 0 || n >= MAX_EDICTS)
417 snprintf (line, sizeof (line), "entity %i (invalid!)", n);
419 snprintf (line, sizeof (line), "entity %i", n);
422 f = pr_functions + val->function;
423 snprintf (line, sizeof (line), "%s()", PR_GetString(f->s_name));
426 def = ED_FieldAtOfs ( val->_int );
427 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
430 snprintf (line, sizeof (line), "void");
433 // LordHavoc: changed from %5.1f to %10.4f
434 snprintf (line, sizeof (line), "%10.4f", val->_float);
437 // LordHavoc: changed from %5.1f to %10.4f
438 snprintf (line, sizeof (line), "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
441 snprintf (line, sizeof (line), "pointer");
444 snprintf (line, sizeof (line), "bad type %i", type);
455 Returns a string describing *data in a type specific manner
456 Easier to parse than PR_ValueString
459 char *PR_UglyValueString (etype_t type, eval_t *val)
461 static char line[4096];
467 type &= ~DEF_SAVEGLOBAL;
472 // Parse the string a bit to turn special characters
473 // (like newline, specifically) into escape codes,
474 // this fixes saving games from various mods
475 s = PR_GetString (val->string);
476 for (i = 0;i < (int)sizeof(line) - 2 && *s;)
495 snprintf (line, sizeof (line), "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
498 f = pr_functions + val->function;
499 strlcpy (line, PR_GetString (f->s_name), sizeof (line));
502 def = ED_FieldAtOfs ( val->_int );
503 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
506 snprintf (line, sizeof (line), "void");
509 snprintf (line, sizeof (line), "%f", val->_float);
512 snprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
515 snprintf (line, sizeof (line), "bad type %i", type);
526 Returns a string with a description and the contents of a global,
527 padded to 20 field width
530 char *PR_GlobalString (int ofs)
536 static char line[128];
538 val = (void *)&pr_globals[ofs];
539 def = ED_GlobalAtOfs(ofs);
541 snprintf (line, sizeof (line), "%i(?)", ofs);
544 s = PR_ValueString (def->type, val);
545 snprintf (line, sizeof (line), "%i(%s)%s", ofs, PR_GetString(def->s_name), s);
550 strlcat (line, " ", sizeof (line));
551 strlcat (line, " ", sizeof (line));
556 char *PR_GlobalStringNoContents (int ofs)
560 static char line[128];
562 def = ED_GlobalAtOfs(ofs);
564 snprintf (line, sizeof (line), "%i(?)", ofs);
566 snprintf (line, sizeof (line), "%i(%s)", ofs, PR_GetString(def->s_name));
570 strlcat (line, " ", sizeof (line));
571 strlcat (line, " ", sizeof (line));
584 // LordHavoc: optimized this to print out much more quickly (tempstring)
585 // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
586 void ED_Print(edict_t *ed)
594 char tempstring[8192], tempstring2[260]; // temporary string buffers
603 snprintf (tempstring, sizeof (tempstring), "\nEDICT %i:\n", NUM_FOR_EDICT(ed));
604 for (i=1 ; i<progs->numfielddefs ; i++)
606 d = &pr_fielddefs[i];
607 name = PR_GetString(d->s_name);
608 if (name[strlen(name)-2] == '_')
609 continue; // skip _x, _y, _z vars
611 v = (int *)((char *)ed->v + d->ofs*4);
613 // if the value is still all 0, skip the field
614 type = d->type & ~DEF_SAVEGLOBAL;
616 for (j=0 ; j<type_size[type] ; j++)
619 if (j == type_size[type])
622 if (strlen(name) > 256)
624 memcpy (tempstring2, name, 256);
625 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
626 tempstring2[259] = 0;
629 strlcat (tempstring, name, sizeof (tempstring));
630 for (l = strlen(name);l < 14;l++)
631 strcat(tempstring, " ");
632 strcat(tempstring, " ");
634 name = PR_ValueString(d->type, (eval_t *)v);
635 if (strlen(name) > 256)
637 memcpy(tempstring2, name, 256);
638 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
639 tempstring2[259] = 0;
642 strlcat (tempstring, name, sizeof (tempstring));
643 strlcat (tempstring, "\n", sizeof (tempstring));
644 if (strlen(tempstring) >= 4096)
646 Con_Print(tempstring);
651 Con_Print(tempstring);
661 void ED_Write (qfile_t *f, edict_t *ed)
677 for (i=1 ; i<progs->numfielddefs ; i++)
679 d = &pr_fielddefs[i];
680 name = PR_GetString(d->s_name);
681 if (name[strlen(name)-2] == '_')
682 continue; // skip _x, _y, _z vars
684 v = (int *)((char *)ed->v + d->ofs*4);
686 // if the value is still all 0, skip the field
687 type = d->type & ~DEF_SAVEGLOBAL;
688 for (j=0 ; j<type_size[type] ; j++)
691 if (j == type_size[type])
694 FS_Printf(f,"\"%s\" ",name);
695 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
701 void ED_PrintNum (int ent)
703 ED_Print(EDICT_NUM(ent));
710 For debugging, prints all the entities in the current server
713 void ED_PrintEdicts (void)
717 Con_Printf("%i entities\n", sv.num_edicts);
718 for (i=0 ; i<sv.num_edicts ; i++)
726 For debugging, prints a single edict
729 void ED_PrintEdict_f (void)
733 i = atoi (Cmd_Argv(1));
734 if (i < 0 || i >= sv.num_edicts)
736 Con_Print("Bad edict number\n");
753 int active, models, solid, step;
755 active = models = solid = step = 0;
756 for (i=0 ; i<sv.num_edicts ; i++)
766 if (ent->v->movetype == MOVETYPE_STEP)
770 Con_Printf("num_edicts:%3i\n", sv.num_edicts);
771 Con_Printf("active :%3i\n", active);
772 Con_Printf("view :%3i\n", models);
773 Con_Printf("touch :%3i\n", solid);
774 Con_Printf("step :%3i\n", step);
779 ==============================================================================
783 FIXME: need to tag constants, doesn't really work
784 ==============================================================================
792 void ED_WriteGlobals (qfile_t *f)
800 for (i=0 ; i<progs->numglobaldefs ; i++)
802 def = &pr_globaldefs[i];
804 if ( !(def->type & DEF_SAVEGLOBAL) )
806 type &= ~DEF_SAVEGLOBAL;
808 if (type != ev_string && type != ev_float && type != ev_entity)
811 name = PR_GetString(def->s_name);
812 FS_Printf(f,"\"%s\" ", name);
813 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
822 Console command to set a field of a specified edict
825 void ED_EdictSet_f(void)
832 Con_Print("edictset <edict number> <field> <value>\n");
835 ed = EDICT_NUM(atoi(Cmd_Argv(1)));
837 if((key = ED_FindField(Cmd_Argv(2))) == 0)
839 Con_Printf("Key %s not found !\n", Cmd_Argv(2));
843 ED_ParseEpair(ed, key, Cmd_Argv(3));
851 void ED_ParseGlobals (const char *data)
853 char keyname[1024]; // LordHavoc: good idea? bad idea? was 64
859 if (!COM_ParseToken(&data, false))
860 Host_Error ("ED_ParseEntity: EOF without closing brace");
861 if (com_token[0] == '}')
864 strcpy (keyname, com_token);
867 if (!COM_ParseToken(&data, false))
868 Host_Error ("ED_ParseEntity: EOF without closing brace");
870 if (com_token[0] == '}')
871 Host_Error ("ED_ParseEntity: closing brace without data");
873 key = ED_FindGlobal (keyname);
876 Con_DPrintf("'%s' is not a global\n", keyname);
880 if (!ED_ParseEpair(NULL, key, com_token))
881 Host_Error ("ED_ParseGlobals: parse error");
885 //============================================================================
893 char *ED_NewString (const char *string)
898 l = strlen(string) + 1;
899 new = Mem_Alloc(edictstring_mempool, l);
902 for (i=0 ; i< l ; i++)
904 if (string[i] == '\\' && i < l-1)
907 if (string[i] == 'n')
913 *new_p++ = string[i];
924 Can parse either fields or globals
925 returns false if error
928 qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
936 val = (eval_t *)((int *)ent->v + key->ofs);
938 val = (eval_t *)((int *)pr_globals + key->ofs);
939 switch (key->type & ~DEF_SAVEGLOBAL)
942 val->string = PR_SetString(ED_NewString(s));
946 while (*s && *s <= ' ')
948 val->_float = atof(s);
952 for (i = 0;i < 3;i++)
954 while (*s && *s <= ' ')
957 val->vector[i] = atof(s);
966 while (*s && *s <= ' ')
969 if (i < 0 || i >= MAX_EDICTS)
970 Con_Printf("ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i)\n", i, MAX_EDICTS);
971 while (i >= sv.max_edicts)
973 // if SV_IncreaseEdicts was called the base pointer needs to be updated
975 val = (eval_t *)((int *)ent->v + key->ofs);
976 val->edict = EDICT_TO_PROG(EDICT_NUM(i));
980 def = ED_FindField(s);
983 Con_DPrintf("ED_ParseEpair: Can't find field %s\n", s);
986 val->_int = G_INT(def->ofs);
990 func = ED_FindFunction(s);
993 Con_Printf("ED_ParseEpair: Can't find function %s\n", s);
996 val->function = func - pr_functions;
1000 Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PR_GetString(key->s_name));
1007 ====================
1010 Parses an edict out of the given string, returning the new position
1011 ed should be a properly initialized empty edict.
1012 Used for initial level load and for savegames.
1013 ====================
1015 const char *ED_ParseEdict (const char *data, edict_t *ent)
1026 if (ent != sv.edicts) // hack
1027 memset (ent->v, 0, progs->entityfields * 4);
1029 // go through all the dictionary pairs
1033 if (!COM_ParseToken(&data, false))
1034 Host_Error ("ED_ParseEntity: EOF without closing brace");
1035 if (com_token[0] == '}')
1038 // anglehack is to allow QuakeEd to write single scalar angles
1039 // and allow them to be turned into vectors. (FIXME...)
1040 anglehack = !strcmp (com_token, "angle");
1042 strlcpy (com_token, "angles", sizeof (com_token));
1044 // FIXME: change light to _light to get rid of this hack
1045 if (!strcmp(com_token, "light"))
1046 strlcpy (com_token, "light_lev", sizeof (com_token)); // hack for single light def
1048 strlcpy (keyname, com_token, sizeof (keyname));
1050 // another hack to fix heynames with trailing spaces
1051 n = strlen(keyname);
1052 while (n && keyname[n-1] == ' ')
1059 if (!COM_ParseToken(&data, false))
1060 Host_Error ("ED_ParseEntity: EOF without closing brace");
1062 if (com_token[0] == '}')
1063 Host_Error ("ED_ParseEntity: closing brace without data");
1067 // keynames with a leading underscore are used for utility comments,
1068 // and are immediately discarded by quake
1069 if (keyname[0] == '_')
1072 key = ED_FindField (keyname);
1075 Con_DPrintf("'%s' is not a field\n", keyname);
1082 strlcpy (temp, com_token, sizeof (temp));
1083 snprintf (com_token, sizeof (com_token), "0 %s 0", temp);
1086 if (!ED_ParseEpair(ent, key, com_token))
1087 Host_Error ("ED_ParseEdict: parse error");
1091 ent->e->free = true;
1101 The entities are directly placed in the array, rather than allocated with
1102 ED_Alloc, because otherwise an error loading the map would have entity
1103 number references out of order.
1105 Creates a server's entity / program execution context by
1106 parsing textual entity definitions out of an ent file.
1108 Used for both fresh maps and savegame loads. A fresh map would also need
1109 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1112 void ED_LoadFromFile (const char *data)
1115 int parsed, inhibited, spawned, died;
1123 pr_global_struct->time = sv.time;
1128 // parse the opening brace
1129 if (!COM_ParseToken(&data, false))
1131 if (com_token[0] != '{')
1132 Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
1138 data = ED_ParseEdict (data, ent);
1141 // remove things from different skill levels or deathmatch
1142 if (deathmatch.integer)
1144 if (((int)ent->v->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
1151 else if ((current_skill == 0 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_EASY ))
1152 || (current_skill == 1 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_MEDIUM))
1153 || (current_skill >= 2 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_HARD )))
1161 // immediately call spawn function
1163 if (!ent->v->classname)
1165 Con_Print("No classname for:\n");
1171 // look for the spawn function
1172 func = ED_FindFunction (PR_GetString(ent->v->classname));
1176 if (developer.integer) // don't confuse non-developers with errors
1178 Con_Print("No spawn function for:\n");
1185 pr_global_struct->self = EDICT_TO_PROG(ent);
1186 PR_ExecuteProgram (func - pr_functions, "QC function spawn is missing");
1192 Con_DPrintf("%i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", parsed, inhibited, spawned, died, spawned - died);
1196 typedef struct dpfield_s
1203 #define DPFIELDS (sizeof(dpfields) / sizeof(dpfield_t))
1205 dpfield_t dpfields[] =
1207 {ev_float, "gravity"},
1208 {ev_float, "button3"},
1209 {ev_float, "button4"},
1210 {ev_float, "button5"},
1211 {ev_float, "button6"},
1212 {ev_float, "button7"},
1213 {ev_float, "button8"},
1214 {ev_float, "glow_size"},
1215 {ev_float, "glow_trail"},
1216 {ev_float, "glow_color"},
1217 {ev_float, "items2"},
1218 {ev_float, "scale"},
1219 {ev_float, "alpha"},
1220 {ev_float, "renderamt"},
1221 {ev_float, "rendermode"},
1222 {ev_float, "fullbright"},
1223 {ev_float, "ammo_shells1"},
1224 {ev_float, "ammo_nails1"},
1225 {ev_float, "ammo_lava_nails"},
1226 {ev_float, "ammo_rockets1"},
1227 {ev_float, "ammo_multi_rockets"},
1228 {ev_float, "ammo_cells1"},
1229 {ev_float, "ammo_plasma"},
1230 {ev_float, "idealpitch"},
1231 {ev_float, "pitch_speed"},
1232 {ev_entity, "viewmodelforclient"},
1233 {ev_entity, "nodrawtoclient"},
1234 {ev_entity, "exteriormodeltoclient"},
1235 {ev_entity, "drawonlytoclient"},
1237 {ev_vector, "movement"},
1238 {ev_float, "pmodel"},
1239 {ev_vector, "punchvector"},
1240 {ev_float, "clientcolors"},
1241 {ev_entity, "tag_entity"},
1242 {ev_float, "tag_index"},
1243 {ev_float, "light_lev"},
1244 {ev_vector, "color"},
1245 {ev_float, "style"},
1246 {ev_float, "pflags"}
1254 extern void PR_Cmd_Reset (void);
1255 void PR_LoadProgs (void)
1259 ddef_t *infielddefs;
1260 dfunction_t *dfunctions;
1262 // flush the non-C variable lookup cache
1263 for (i=0 ; i<GEFV_CACHESIZE ; i++)
1264 gefvCache[i].field[0] = 0;
1266 Mem_EmptyPool(progs_mempool);
1267 Mem_EmptyPool(edictstring_mempool);
1269 progs = (dprograms_t *)FS_LoadFile ("progs.dat", progs_mempool, false);
1271 Host_Error ("PR_LoadProgs: couldn't load progs.dat");
1273 Con_DPrintf("Programs occupy %iK.\n", fs_filesize/1024);
1275 pr_crc = CRC_Block((qbyte *)progs, fs_filesize);
1277 // byte swap the header
1278 for (i = 0;i < (int) sizeof(*progs) / 4;i++)
1279 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1281 if (progs->version != PROG_VERSION)
1282 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1283 if (progs->crc != PROGHEADER_CRC && progs->crc != 32401) // tenebrae crc also allowed
1284 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1286 //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1287 dfunctions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1288 pr_strings = (char *)progs + progs->ofs_strings;
1289 pr_globaldefs = (ddef_t *)((qbyte *)progs + progs->ofs_globaldefs);
1291 // we need to expand the fielddefs list to include all the engine fields,
1292 // so allocate a new place for it
1293 infielddefs = (ddef_t *)((qbyte *)progs + progs->ofs_fielddefs);
1294 pr_fielddefs = Mem_Alloc(progs_mempool, (progs->numfielddefs + DPFIELDS) * sizeof(ddef_t));
1296 pr_statements = (dstatement_t *)((qbyte *)progs + progs->ofs_statements);
1298 // moved edict_size calculation down below field adding code
1300 pr_global_struct = (globalvars_t *)((qbyte *)progs + progs->ofs_globals);
1301 pr_globals = (float *)pr_global_struct;
1303 // byte swap the lumps
1304 for (i=0 ; i<progs->numstatements ; i++)
1306 pr_statements[i].op = LittleShort(pr_statements[i].op);
1307 pr_statements[i].a = LittleShort(pr_statements[i].a);
1308 pr_statements[i].b = LittleShort(pr_statements[i].b);
1309 pr_statements[i].c = LittleShort(pr_statements[i].c);
1312 pr_functions = Mem_Alloc(progs_mempool, sizeof(mfunction_t) * progs->numfunctions);
1313 for (i = 0;i < progs->numfunctions;i++)
1315 pr_functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
1316 pr_functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
1317 pr_functions[i].s_name = LittleLong (dfunctions[i].s_name);
1318 pr_functions[i].s_file = LittleLong (dfunctions[i].s_file);
1319 pr_functions[i].numparms = LittleLong (dfunctions[i].numparms);
1320 pr_functions[i].locals = LittleLong (dfunctions[i].locals);
1321 memcpy(pr_functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
1324 for (i=0 ; i<progs->numglobaldefs ; i++)
1326 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1327 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1328 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1331 // copy the progs fields to the new fields list
1332 for (i = 0;i < progs->numfielddefs;i++)
1334 pr_fielddefs[i].type = LittleShort (infielddefs[i].type);
1335 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1336 Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1337 pr_fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
1338 pr_fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
1341 // append the darkplaces fields
1342 for (i = 0;i < (int) DPFIELDS;i++)
1344 pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
1345 pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
1346 pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string);
1347 if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
1348 progs->entityfields += 3;
1350 progs->entityfields++;
1351 progs->numfielddefs++;
1354 for (i=0 ; i<progs->numglobals ; i++)
1355 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1357 // moved edict_size calculation down here, below field adding code
1358 // LordHavoc: this no longer includes the edict_t header
1359 pr_edict_size = progs->entityfields * 4;
1360 pr_edictareasize = pr_edict_size * MAX_EDICTS;
1362 // LordHavoc: bounds check anything static
1363 for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1369 if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1370 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1373 if (st->a + i < 0 || st->a + i >= progs->numstatements)
1374 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1376 // global global global
1411 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1412 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1414 // global none global
1420 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1421 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1437 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1438 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1452 if ((unsigned short) st->a >= progs->numglobals)
1453 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1456 Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1461 FindEdictFieldOffsets(); // LordHavoc: update field offset list
1462 PR_Execute_ProgsLoaded();
1467 void PR_Fields_f (void)
1469 int i, j, ednum, used, usedamount;
1471 char tempstring[5000], tempstring2[260], *name;
1477 Con_Print("no progs loaded\n");
1480 counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
1481 for (ednum = 0;ednum < sv.max_edicts;ednum++)
1483 ed = EDICT_NUM(ednum);
1486 for (i = 1;i < progs->numfielddefs;i++)
1488 d = &pr_fielddefs[i];
1489 name = PR_GetString(d->s_name);
1490 if (name[strlen(name)-2] == '_')
1491 continue; // skip _x, _y, _z vars
1492 v = (int *)((char *)ed->v + d->ofs*4);
1493 // if the value is still all 0, skip the field
1494 for (j = 0;j < type_size[d->type & ~DEF_SAVEGLOBAL];j++)
1507 for (i = 0;i < progs->numfielddefs;i++)
1509 d = &pr_fielddefs[i];
1510 name = PR_GetString(d->s_name);
1511 if (name[strlen(name)-2] == '_')
1512 continue; // skip _x, _y, _z vars
1513 switch(d->type & ~DEF_SAVEGLOBAL)
1516 strlcat (tempstring, "string ", sizeof (tempstring));
1519 strlcat (tempstring, "entity ", sizeof (tempstring));
1522 strlcat (tempstring, "function ", sizeof (tempstring));
1525 strlcat (tempstring, "field ", sizeof (tempstring));
1528 strlcat (tempstring, "void ", sizeof (tempstring));
1531 strlcat (tempstring, "float ", sizeof (tempstring));
1534 strlcat (tempstring, "vector ", sizeof (tempstring));
1537 strlcat (tempstring, "pointer ", sizeof (tempstring));
1540 snprintf (tempstring2, sizeof (tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
1541 strlcat (tempstring, tempstring2, sizeof (tempstring));
1544 if (strlen(name) > 256)
1546 memcpy(tempstring2, name, 256);
1547 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
1548 tempstring2[259] = 0;
1551 strcat (tempstring, name);
1552 for (j = strlen(name);j < 25;j++)
1553 strcat(tempstring, " ");
1554 snprintf (tempstring2, sizeof (tempstring2), "%5d", counts[i]);
1555 strlcat (tempstring, tempstring2, sizeof (tempstring));
1556 strlcat (tempstring, "\n", sizeof (tempstring));
1557 if (strlen(tempstring) >= 4096)
1559 Con_Print(tempstring);
1565 usedamount += type_size[d->type & ~DEF_SAVEGLOBAL];
1569 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);
1572 void PR_Globals_f (void)
1577 Con_Print("no progs loaded\n");
1580 for (i = 0;i < progs->numglobaldefs;i++)
1581 Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name));
1582 Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
1590 extern void PR_Cmd_Init(void);
1593 Cmd_AddCommand ("edict", ED_PrintEdict_f);
1594 Cmd_AddCommand ("edicts", ED_PrintEdicts);
1595 Cmd_AddCommand ("edictcount", ED_Count);
1596 Cmd_AddCommand ("edictset", ED_EdictSet_f);
1597 Cmd_AddCommand ("profile", PR_Profile_f);
1598 Cmd_AddCommand ("pr_fields", PR_Fields_f);
1599 Cmd_AddCommand ("pr_globals", PR_Globals_f);
1600 Cvar_RegisterVariable (&pr_checkextension);
1601 Cvar_RegisterVariable (&nomonsters);
1602 Cvar_RegisterVariable (&gamecfg);
1603 Cvar_RegisterVariable (&scratch1);
1604 Cvar_RegisterVariable (&scratch2);
1605 Cvar_RegisterVariable (&scratch3);
1606 Cvar_RegisterVariable (&scratch4);
1607 Cvar_RegisterVariable (&savedgamecfg);
1608 Cvar_RegisterVariable (&saved1);
1609 Cvar_RegisterVariable (&saved2);
1610 Cvar_RegisterVariable (&saved3);
1611 Cvar_RegisterVariable (&saved4);
1612 // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1613 Cvar_RegisterVariable (&decors);
1614 // LordHavoc: Nehahra uses these to pass data around cutscene demos
1615 if (gamemode == GAME_NEHAHRA)
1617 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1618 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1619 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1620 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1621 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1622 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1623 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1624 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1625 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1626 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1628 Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1629 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1630 Cvar_RegisterVariable (&pr_boundscheck);
1631 Cvar_RegisterVariable (&pr_traceqc);
1633 progs_mempool = Mem_AllocPool("progs.dat", 0, NULL);
1634 edictstring_mempool = Mem_AllocPool("edict strings", 0, NULL);
1639 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1640 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
1642 Host_Error ("EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
1647 int NUM_FOR_EDICT_ERROR(edict_t *e)
1649 Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
1653 int NUM_FOR_EDICT(edict_t *e)
1657 if ((unsigned int)n >= MAX_EDICTS)
1658 Host_Error ("NUM_FOR_EDICT: bad pointer");
1662 //int NoCrash_NUM_FOR_EDICT(edict_t *e)
1664 // return e - sv.edicts;
1667 //#define EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
1668 //#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
1669 int EDICT_TO_PROG(edict_t *e)
1673 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1674 Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
1675 return n;// EXPERIMENTAL
1676 //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
1678 edict_t *PROG_TO_EDICT(int n)
1680 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1681 Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
1682 return sv.edicts + n; // EXPERIMENTAL
1683 //return sv.edicts + ((n) / (progs->entityfields * 4));