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); AK Please check this - seems to be an org. quake bug
987 val->_int = def->ofs;
991 func = ED_FindFunction(s);
994 Con_Printf("ED_ParseEpair: Can't find function %s\n", s);
997 val->function = func - pr_functions;
1001 Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PR_GetString(key->s_name));
1008 ====================
1011 Parses an edict out of the given string, returning the new position
1012 ed should be a properly initialized empty edict.
1013 Used for initial level load and for savegames.
1014 ====================
1016 const char *ED_ParseEdict (const char *data, edict_t *ent)
1027 if (ent != sv.edicts) // hack
1028 memset (ent->v, 0, progs->entityfields * 4);
1030 // go through all the dictionary pairs
1034 if (!COM_ParseToken(&data, false))
1035 Host_Error ("ED_ParseEntity: EOF without closing brace");
1036 if (com_token[0] == '}')
1039 // anglehack is to allow QuakeEd to write single scalar angles
1040 // and allow them to be turned into vectors. (FIXME...)
1041 anglehack = !strcmp (com_token, "angle");
1043 strlcpy (com_token, "angles", sizeof (com_token));
1045 // FIXME: change light to _light to get rid of this hack
1046 if (!strcmp(com_token, "light"))
1047 strlcpy (com_token, "light_lev", sizeof (com_token)); // hack for single light def
1049 strlcpy (keyname, com_token, sizeof (keyname));
1051 // another hack to fix heynames with trailing spaces
1052 n = strlen(keyname);
1053 while (n && keyname[n-1] == ' ')
1060 if (!COM_ParseToken(&data, false))
1061 Host_Error ("ED_ParseEntity: EOF without closing brace");
1063 if (com_token[0] == '}')
1064 Host_Error ("ED_ParseEntity: closing brace without data");
1068 // keynames with a leading underscore are used for utility comments,
1069 // and are immediately discarded by quake
1070 if (keyname[0] == '_')
1073 key = ED_FindField (keyname);
1076 Con_DPrintf("'%s' is not a field\n", keyname);
1083 strlcpy (temp, com_token, sizeof (temp));
1084 snprintf (com_token, sizeof (com_token), "0 %s 0", temp);
1087 if (!ED_ParseEpair(ent, key, com_token))
1088 Host_Error ("ED_ParseEdict: parse error");
1092 ent->e->free = true;
1102 The entities are directly placed in the array, rather than allocated with
1103 ED_Alloc, because otherwise an error loading the map would have entity
1104 number references out of order.
1106 Creates a server's entity / program execution context by
1107 parsing textual entity definitions out of an ent file.
1109 Used for both fresh maps and savegame loads. A fresh map would also need
1110 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1113 void ED_LoadFromFile (const char *data)
1116 int parsed, inhibited, spawned, died;
1124 pr_global_struct->time = sv.time;
1129 // parse the opening brace
1130 if (!COM_ParseToken(&data, false))
1132 if (com_token[0] != '{')
1133 Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
1139 data = ED_ParseEdict (data, ent);
1142 // remove things from different skill levels or deathmatch
1143 if (deathmatch.integer)
1145 if (((int)ent->v->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
1152 else if ((current_skill == 0 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_EASY ))
1153 || (current_skill == 1 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_MEDIUM))
1154 || (current_skill >= 2 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_HARD )))
1162 // immediately call spawn function
1164 if (!ent->v->classname)
1166 Con_Print("No classname for:\n");
1172 // look for the spawn function
1173 func = ED_FindFunction (PR_GetString(ent->v->classname));
1177 if (developer.integer) // don't confuse non-developers with errors
1179 Con_Print("No spawn function for:\n");
1186 pr_global_struct->self = EDICT_TO_PROG(ent);
1187 PR_ExecuteProgram (func - pr_functions, "QC function spawn is missing");
1193 Con_DPrintf("%i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", parsed, inhibited, spawned, died, spawned - died);
1197 typedef struct dpfield_s
1204 #define DPFIELDS (sizeof(dpfields) / sizeof(dpfield_t))
1206 dpfield_t dpfields[] =
1208 {ev_float, "gravity"},
1209 {ev_float, "button3"},
1210 {ev_float, "button4"},
1211 {ev_float, "button5"},
1212 {ev_float, "button6"},
1213 {ev_float, "button7"},
1214 {ev_float, "button8"},
1215 {ev_float, "glow_size"},
1216 {ev_float, "glow_trail"},
1217 {ev_float, "glow_color"},
1218 {ev_float, "items2"},
1219 {ev_float, "scale"},
1220 {ev_float, "alpha"},
1221 {ev_float, "renderamt"},
1222 {ev_float, "rendermode"},
1223 {ev_float, "fullbright"},
1224 {ev_float, "ammo_shells1"},
1225 {ev_float, "ammo_nails1"},
1226 {ev_float, "ammo_lava_nails"},
1227 {ev_float, "ammo_rockets1"},
1228 {ev_float, "ammo_multi_rockets"},
1229 {ev_float, "ammo_cells1"},
1230 {ev_float, "ammo_plasma"},
1231 {ev_float, "idealpitch"},
1232 {ev_float, "pitch_speed"},
1233 {ev_entity, "viewmodelforclient"},
1234 {ev_entity, "nodrawtoclient"},
1235 {ev_entity, "exteriormodeltoclient"},
1236 {ev_entity, "drawonlytoclient"},
1238 {ev_vector, "movement"},
1239 {ev_float, "pmodel"},
1240 {ev_vector, "punchvector"},
1241 {ev_float, "clientcolors"},
1242 {ev_entity, "tag_entity"},
1243 {ev_float, "tag_index"},
1244 {ev_float, "light_lev"},
1245 {ev_vector, "color"},
1246 {ev_float, "style"},
1247 {ev_float, "pflags"}
1255 extern void PR_Cmd_Reset (void);
1256 void PR_LoadProgs (void)
1260 ddef_t *infielddefs;
1261 dfunction_t *dfunctions;
1263 // flush the non-C variable lookup cache
1264 for (i=0 ; i<GEFV_CACHESIZE ; i++)
1265 gefvCache[i].field[0] = 0;
1267 Mem_EmptyPool(progs_mempool);
1268 Mem_EmptyPool(edictstring_mempool);
1270 progs = (dprograms_t *)FS_LoadFile ("progs.dat", progs_mempool, false);
1272 Host_Error ("PR_LoadProgs: couldn't load progs.dat");
1274 Con_DPrintf("Programs occupy %iK.\n", fs_filesize/1024);
1276 pr_crc = CRC_Block((qbyte *)progs, fs_filesize);
1278 // byte swap the header
1279 for (i = 0;i < (int) sizeof(*progs) / 4;i++)
1280 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1282 if (progs->version != PROG_VERSION)
1283 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1284 if (progs->crc != PROGHEADER_CRC && progs->crc != 32401) // tenebrae crc also allowed
1285 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1287 //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1288 dfunctions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1289 pr_strings = (char *)progs + progs->ofs_strings;
1290 pr_globaldefs = (ddef_t *)((qbyte *)progs + progs->ofs_globaldefs);
1292 // we need to expand the fielddefs list to include all the engine fields,
1293 // so allocate a new place for it
1294 infielddefs = (ddef_t *)((qbyte *)progs + progs->ofs_fielddefs);
1295 pr_fielddefs = Mem_Alloc(progs_mempool, (progs->numfielddefs + DPFIELDS) * sizeof(ddef_t));
1297 pr_statements = (dstatement_t *)((qbyte *)progs + progs->ofs_statements);
1299 // moved edict_size calculation down below field adding code
1301 pr_global_struct = (globalvars_t *)((qbyte *)progs + progs->ofs_globals);
1302 pr_globals = (float *)pr_global_struct;
1304 // byte swap the lumps
1305 for (i=0 ; i<progs->numstatements ; i++)
1307 pr_statements[i].op = LittleShort(pr_statements[i].op);
1308 pr_statements[i].a = LittleShort(pr_statements[i].a);
1309 pr_statements[i].b = LittleShort(pr_statements[i].b);
1310 pr_statements[i].c = LittleShort(pr_statements[i].c);
1313 pr_functions = Mem_Alloc(progs_mempool, sizeof(mfunction_t) * progs->numfunctions);
1314 for (i = 0;i < progs->numfunctions;i++)
1316 pr_functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
1317 pr_functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
1318 pr_functions[i].s_name = LittleLong (dfunctions[i].s_name);
1319 pr_functions[i].s_file = LittleLong (dfunctions[i].s_file);
1320 pr_functions[i].numparms = LittleLong (dfunctions[i].numparms);
1321 pr_functions[i].locals = LittleLong (dfunctions[i].locals);
1322 memcpy(pr_functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
1325 for (i=0 ; i<progs->numglobaldefs ; i++)
1327 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1328 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1329 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1332 // copy the progs fields to the new fields list
1333 for (i = 0;i < progs->numfielddefs;i++)
1335 pr_fielddefs[i].type = LittleShort (infielddefs[i].type);
1336 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1337 Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1338 pr_fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
1339 pr_fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
1342 // append the darkplaces fields
1343 for (i = 0;i < (int) DPFIELDS;i++)
1345 pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
1346 pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
1347 pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string);
1348 if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
1349 progs->entityfields += 3;
1351 progs->entityfields++;
1352 progs->numfielddefs++;
1355 for (i=0 ; i<progs->numglobals ; i++)
1356 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1358 // moved edict_size calculation down here, below field adding code
1359 // LordHavoc: this no longer includes the edict_t header
1360 pr_edict_size = progs->entityfields * 4;
1361 pr_edictareasize = pr_edict_size * MAX_EDICTS;
1363 // LordHavoc: bounds check anything static
1364 for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1370 if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1371 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1374 if (st->a + i < 0 || st->a + i >= progs->numstatements)
1375 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1377 // global global global
1412 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1413 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1415 // global none global
1421 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1422 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1438 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1439 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1453 if ((unsigned short) st->a >= progs->numglobals)
1454 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1457 Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1462 FindEdictFieldOffsets(); // LordHavoc: update field offset list
1463 PR_Execute_ProgsLoaded();
1468 void PR_Fields_f (void)
1470 int i, j, ednum, used, usedamount;
1472 char tempstring[5000], tempstring2[260], *name;
1478 Con_Print("no progs loaded\n");
1481 counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
1482 for (ednum = 0;ednum < sv.max_edicts;ednum++)
1484 ed = EDICT_NUM(ednum);
1487 for (i = 1;i < progs->numfielddefs;i++)
1489 d = &pr_fielddefs[i];
1490 name = PR_GetString(d->s_name);
1491 if (name[strlen(name)-2] == '_')
1492 continue; // skip _x, _y, _z vars
1493 v = (int *)((char *)ed->v + d->ofs*4);
1494 // if the value is still all 0, skip the field
1495 for (j = 0;j < type_size[d->type & ~DEF_SAVEGLOBAL];j++)
1508 for (i = 0;i < progs->numfielddefs;i++)
1510 d = &pr_fielddefs[i];
1511 name = PR_GetString(d->s_name);
1512 if (name[strlen(name)-2] == '_')
1513 continue; // skip _x, _y, _z vars
1514 switch(d->type & ~DEF_SAVEGLOBAL)
1517 strlcat (tempstring, "string ", sizeof (tempstring));
1520 strlcat (tempstring, "entity ", sizeof (tempstring));
1523 strlcat (tempstring, "function ", sizeof (tempstring));
1526 strlcat (tempstring, "field ", sizeof (tempstring));
1529 strlcat (tempstring, "void ", sizeof (tempstring));
1532 strlcat (tempstring, "float ", sizeof (tempstring));
1535 strlcat (tempstring, "vector ", sizeof (tempstring));
1538 strlcat (tempstring, "pointer ", sizeof (tempstring));
1541 snprintf (tempstring2, sizeof (tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
1542 strlcat (tempstring, tempstring2, sizeof (tempstring));
1545 if (strlen(name) > 256)
1547 memcpy(tempstring2, name, 256);
1548 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
1549 tempstring2[259] = 0;
1552 strcat (tempstring, name);
1553 for (j = strlen(name);j < 25;j++)
1554 strcat(tempstring, " ");
1555 snprintf (tempstring2, sizeof (tempstring2), "%5d", counts[i]);
1556 strlcat (tempstring, tempstring2, sizeof (tempstring));
1557 strlcat (tempstring, "\n", sizeof (tempstring));
1558 if (strlen(tempstring) >= 4096)
1560 Con_Print(tempstring);
1566 usedamount += type_size[d->type & ~DEF_SAVEGLOBAL];
1570 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);
1573 void PR_Globals_f (void)
1578 Con_Print("no progs loaded\n");
1581 for (i = 0;i < progs->numglobaldefs;i++)
1582 Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name));
1583 Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
1591 extern void PR_Cmd_Init(void);
1594 Cmd_AddCommand ("edict", ED_PrintEdict_f);
1595 Cmd_AddCommand ("edicts", ED_PrintEdicts);
1596 Cmd_AddCommand ("edictcount", ED_Count);
1597 Cmd_AddCommand ("edictset", ED_EdictSet_f);
1598 Cmd_AddCommand ("profile", PR_Profile_f);
1599 Cmd_AddCommand ("pr_fields", PR_Fields_f);
1600 Cmd_AddCommand ("pr_globals", PR_Globals_f);
1601 Cvar_RegisterVariable (&pr_checkextension);
1602 Cvar_RegisterVariable (&nomonsters);
1603 Cvar_RegisterVariable (&gamecfg);
1604 Cvar_RegisterVariable (&scratch1);
1605 Cvar_RegisterVariable (&scratch2);
1606 Cvar_RegisterVariable (&scratch3);
1607 Cvar_RegisterVariable (&scratch4);
1608 Cvar_RegisterVariable (&savedgamecfg);
1609 Cvar_RegisterVariable (&saved1);
1610 Cvar_RegisterVariable (&saved2);
1611 Cvar_RegisterVariable (&saved3);
1612 Cvar_RegisterVariable (&saved4);
1613 // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1614 Cvar_RegisterVariable (&decors);
1615 // LordHavoc: Nehahra uses these to pass data around cutscene demos
1616 if (gamemode == GAME_NEHAHRA)
1618 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1619 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1620 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1621 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1622 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1623 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1624 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1625 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1626 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1627 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1629 Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1630 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1631 Cvar_RegisterVariable (&pr_boundscheck);
1632 Cvar_RegisterVariable (&pr_traceqc);
1634 progs_mempool = Mem_AllocPool("progs.dat", 0, NULL);
1635 edictstring_mempool = Mem_AllocPool("edict strings", 0, NULL);
1640 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1641 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
1643 Host_Error ("EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
1648 int NUM_FOR_EDICT_ERROR(edict_t *e)
1650 Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
1654 int NUM_FOR_EDICT(edict_t *e)
1658 if ((unsigned int)n >= MAX_EDICTS)
1659 Host_Error ("NUM_FOR_EDICT: bad pointer");
1663 //int NoCrash_NUM_FOR_EDICT(edict_t *e)
1665 // return e - sv.edicts;
1668 //#define EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
1669 //#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
1670 int EDICT_TO_PROG(edict_t *e)
1674 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1675 Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
1676 return n;// EXPERIMENTAL
1677 //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
1679 edict_t *PROG_TO_EDICT(int n)
1681 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1682 Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
1683 return sv.edicts + n; // EXPERIMENTAL
1684 //return sv.edicts + ((n) / (progs->entityfields * 4));