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
103 int eval_renderamt; // HalfLife support
104 int eval_rendermode; // HalfLife support
106 int eval_ammo_shells1;
107 int eval_ammo_nails1;
108 int eval_ammo_lava_nails;
109 int eval_ammo_rockets1;
110 int eval_ammo_multi_rockets;
111 int eval_ammo_cells1;
112 int eval_ammo_plasma;
114 int eval_pitch_speed;
115 int eval_viewmodelforclient;
116 int eval_nodrawtoclient;
117 int eval_exteriormodeltoclient;
118 int eval_drawonlytoclient;
122 int eval_punchvector;
124 int eval_clientcolors;
131 int eval_cursor_active;
132 int eval_cursor_screen;
133 int eval_cursor_trace_start;
134 int eval_cursor_trace_endpos;
135 int eval_cursor_trace_ent;
138 mfunction_t *SV_PlayerPhysicsQC;
139 mfunction_t *EndFrameQC;
140 //KrimZon - SERVER COMMANDS IN QUAKEC
141 mfunction_t *SV_ParseClientCommandQC;
143 int FindFieldOffset(const char *field)
146 d = ED_FindField(field);
152 void FindEdictFieldOffsets(void)
154 eval_gravity = FindFieldOffset("gravity");
155 eval_button3 = FindFieldOffset("button3");
156 eval_button4 = FindFieldOffset("button4");
157 eval_button5 = FindFieldOffset("button5");
158 eval_button6 = FindFieldOffset("button6");
159 eval_button7 = FindFieldOffset("button7");
160 eval_button8 = FindFieldOffset("button8");
161 eval_buttonuse = FindFieldOffset("buttonuse");
162 eval_buttonchat = FindFieldOffset("buttonchat");
163 eval_glow_size = FindFieldOffset("glow_size");
164 eval_glow_trail = FindFieldOffset("glow_trail");
165 eval_glow_color = FindFieldOffset("glow_color");
166 eval_items2 = FindFieldOffset("items2");
167 eval_scale = FindFieldOffset("scale");
168 eval_alpha = FindFieldOffset("alpha");
169 eval_renderamt = FindFieldOffset("renderamt"); // HalfLife support
170 eval_rendermode = FindFieldOffset("rendermode"); // HalfLife support
171 eval_fullbright = FindFieldOffset("fullbright");
172 eval_ammo_shells1 = FindFieldOffset("ammo_shells1");
173 eval_ammo_nails1 = FindFieldOffset("ammo_nails1");
174 eval_ammo_lava_nails = FindFieldOffset("ammo_lava_nails");
175 eval_ammo_rockets1 = FindFieldOffset("ammo_rockets1");
176 eval_ammo_multi_rockets = FindFieldOffset("ammo_multi_rockets");
177 eval_ammo_cells1 = FindFieldOffset("ammo_cells1");
178 eval_ammo_plasma = FindFieldOffset("ammo_plasma");
179 eval_idealpitch = FindFieldOffset("idealpitch");
180 eval_pitch_speed = FindFieldOffset("pitch_speed");
181 eval_viewmodelforclient = FindFieldOffset("viewmodelforclient");
182 eval_nodrawtoclient = FindFieldOffset("nodrawtoclient");
183 eval_exteriormodeltoclient = FindFieldOffset("exteriormodeltoclient");
184 eval_drawonlytoclient = FindFieldOffset("drawonlytoclient");
185 eval_ping = FindFieldOffset("ping");
186 eval_movement = FindFieldOffset("movement");
187 eval_pmodel = FindFieldOffset("pmodel");
188 eval_punchvector = FindFieldOffset("punchvector");
189 eval_viewzoom = FindFieldOffset("viewzoom");
190 eval_clientcolors = FindFieldOffset("clientcolors");
191 eval_tag_entity = FindFieldOffset("tag_entity");
192 eval_tag_index = FindFieldOffset("tag_index");
193 eval_light_lev = FindFieldOffset("light_lev");
194 eval_color = FindFieldOffset("color");
195 eval_style = FindFieldOffset("style");
196 eval_pflags = FindFieldOffset("pflags");
197 eval_cursor_active = FindFieldOffset("cursor_active");
198 eval_cursor_screen = FindFieldOffset("cursor_screen");
199 eval_cursor_trace_start = FindFieldOffset("cursor_trace_start");
200 eval_cursor_trace_endpos = FindFieldOffset("cursor_trace_endpos");
201 eval_cursor_trace_ent = FindFieldOffset("cursor_trace_ent");
202 eval_colormod = FindFieldOffset("colormod");
204 // LordHavoc: allowing QuakeC to override the player movement code
205 SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
206 // LordHavoc: support for endframe
207 EndFrameQC = ED_FindFunction ("EndFrame");
208 //KrimZon - SERVER COMMANDS IN QUAKEC
209 SV_ParseClientCommandQC = ED_FindFunction ("SV_ParseClientCommand");
216 Sets everything to NULL
219 void ED_ClearEdict (edict_t *e)
222 memset (e->v, 0, progs->entityfields * 4);
224 // LordHavoc: for consistency set these here
225 num = NUM_FOR_EDICT(e) - 1;
226 if (num >= 0 && num < svs.maxclients)
229 // set colormap and team on newly created player entity
230 e->v->colormap = num + 1;
231 e->v->team = (svs.clients[num].colors & 15) + 1;
232 // set netname/clientcolors back to client values so that
233 // DP_SV_CLIENTNAME and DPV_SV_CLIENTCOLORS will not immediately
235 e->v->netname = PR_SetString(svs.clients[num].name);
236 if ((val = GETEDICTFIELDVALUE(e, eval_clientcolors)))
237 val->_float = svs.clients[num].colors;
245 Either finds a free edict, or allocates a new one.
246 Try to avoid reusing an entity that was recently freed, because it
247 can cause the client to think the entity morphed into something else
248 instead of being removed and recreated, which can cause interpolated
249 angles and bad trails.
252 edict_t *ED_Alloc (void)
257 for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
260 // the first couple seconds of server time can involve a lot of
261 // freeing and allocating, so relax the replacement policy
262 if (e->e->free && ( e->e->freetime < 2 || sv.time - e->e->freetime > 0.5 ) )
270 Host_Error ("ED_Alloc: no free edicts");
273 if (sv.num_edicts >= sv.max_edicts)
285 Marks the edict as free
286 FIXME: walk all entities and NULL out references to this entity
289 void ED_Free (edict_t *ed)
291 SV_UnlinkEdict (ed); // unlink from world bsp
295 ed->v->takedamage = 0;
296 ed->v->modelindex = 0;
300 VectorClear(ed->v->origin);
301 VectorClear(ed->v->angles);
302 ed->v->nextthink = -1;
305 ed->e->freetime = sv.time;
308 //===========================================================================
315 ddef_t *ED_GlobalAtOfs (int ofs)
320 for (i=0 ; i<progs->numglobaldefs ; i++)
322 def = &pr_globaldefs[i];
334 ddef_t *ED_FieldAtOfs (int ofs)
339 for (i=0 ; i<progs->numfielddefs ; i++)
341 def = &pr_fielddefs[i];
353 ddef_t *ED_FindField (const char *name)
358 for (i=0 ; i<progs->numfielddefs ; i++)
360 def = &pr_fielddefs[i];
361 if (!strcmp(PR_GetString(def->s_name), name))
372 ddef_t *ED_FindGlobal (const char *name)
377 for (i=0 ; i<progs->numglobaldefs ; i++)
379 def = &pr_globaldefs[i];
380 if (!strcmp(PR_GetString(def->s_name), name))
392 mfunction_t *ED_FindFunction (const char *name)
397 for (i=0 ; i<progs->numfunctions ; i++)
399 func = &pr_functions[i];
400 if (!strcmp(PR_GetString(func->s_name), name))
411 Returns a string describing *data in a type specific manner
414 //int NoCrash_NUM_FOR_EDICT(edict_t *e);
415 char *PR_ValueString (etype_t type, eval_t *val)
417 static char line[1024]; // LordHavoc: enlarged a bit (was 256)
422 type &= ~DEF_SAVEGLOBAL;
427 strlcpy (line, PR_GetString (val->string), sizeof (line));
430 //n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict));
432 if (n < 0 || n >= MAX_EDICTS)
433 snprintf (line, sizeof (line), "entity %i (invalid!)", n);
435 snprintf (line, sizeof (line), "entity %i", n);
438 f = pr_functions + val->function;
439 snprintf (line, sizeof (line), "%s()", PR_GetString(f->s_name));
442 def = ED_FieldAtOfs ( val->_int );
443 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
446 snprintf (line, sizeof (line), "void");
449 // LordHavoc: changed from %5.1f to %10.4f
450 snprintf (line, sizeof (line), "%10.4f", val->_float);
453 // LordHavoc: changed from %5.1f to %10.4f
454 snprintf (line, sizeof (line), "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
457 snprintf (line, sizeof (line), "pointer");
460 snprintf (line, sizeof (line), "bad type %i", type);
471 Returns a string describing *data in a type specific manner
472 Easier to parse than PR_ValueString
475 char *PR_UglyValueString (etype_t type, eval_t *val)
477 static char line[4096];
483 type &= ~DEF_SAVEGLOBAL;
488 // Parse the string a bit to turn special characters
489 // (like newline, specifically) into escape codes,
490 // this fixes saving games from various mods
491 s = PR_GetString (val->string);
492 for (i = 0;i < (int)sizeof(line) - 2 && *s;)
511 snprintf (line, sizeof (line), "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
514 f = pr_functions + val->function;
515 strlcpy (line, PR_GetString (f->s_name), sizeof (line));
518 def = ED_FieldAtOfs ( val->_int );
519 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
522 snprintf (line, sizeof (line), "void");
525 snprintf (line, sizeof (line), "%f", val->_float);
528 snprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
531 snprintf (line, sizeof (line), "bad type %i", type);
542 Returns a string with a description and the contents of a global,
543 padded to 20 field width
546 char *PR_GlobalString (int ofs)
552 static char line[128];
554 val = (void *)&pr_globals[ofs];
555 def = ED_GlobalAtOfs(ofs);
557 snprintf (line, sizeof (line), "%i(?)", ofs);
560 s = PR_ValueString (def->type, val);
561 snprintf (line, sizeof (line), "%i(%s)%s", ofs, PR_GetString(def->s_name), s);
566 strlcat (line, " ", sizeof (line));
567 strlcat (line, " ", sizeof (line));
572 char *PR_GlobalStringNoContents (int ofs)
576 static char line[128];
578 def = ED_GlobalAtOfs(ofs);
580 snprintf (line, sizeof (line), "%i(?)", ofs);
582 snprintf (line, sizeof (line), "%i(%s)", ofs, PR_GetString(def->s_name));
586 strlcat (line, " ", sizeof (line));
587 strlcat (line, " ", sizeof (line));
600 // LordHavoc: optimized this to print out much more quickly (tempstring)
601 // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
602 void ED_Print(edict_t *ed)
610 char tempstring[8192], tempstring2[260]; // temporary string buffers
619 snprintf (tempstring, sizeof (tempstring), "\nEDICT %i:\n", NUM_FOR_EDICT(ed));
620 for (i=1 ; i<progs->numfielddefs ; i++)
622 d = &pr_fielddefs[i];
623 name = PR_GetString(d->s_name);
624 if (name[strlen(name)-2] == '_')
625 continue; // skip _x, _y, _z vars
627 v = (int *)((char *)ed->v + d->ofs*4);
629 // if the value is still all 0, skip the field
630 type = d->type & ~DEF_SAVEGLOBAL;
632 for (j=0 ; j<type_size[type] ; j++)
635 if (j == type_size[type])
638 if (strlen(name) > 256)
640 memcpy (tempstring2, name, 256);
641 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
642 tempstring2[259] = 0;
645 strlcat (tempstring, name, sizeof (tempstring));
646 for (l = strlen(name);l < 14;l++)
647 strcat(tempstring, " ");
648 strcat(tempstring, " ");
650 name = PR_ValueString(d->type, (eval_t *)v);
651 if (strlen(name) > 256)
653 memcpy(tempstring2, name, 256);
654 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
655 tempstring2[259] = 0;
658 strlcat (tempstring, name, sizeof (tempstring));
659 strlcat (tempstring, "\n", sizeof (tempstring));
660 if (strlen(tempstring) >= 4096)
662 Con_Print(tempstring);
667 Con_Print(tempstring);
677 void ED_Write (qfile_t *f, edict_t *ed)
693 for (i=1 ; i<progs->numfielddefs ; i++)
695 d = &pr_fielddefs[i];
696 name = PR_GetString(d->s_name);
697 if (name[strlen(name)-2] == '_')
698 continue; // skip _x, _y, _z vars
700 v = (int *)((char *)ed->v + d->ofs*4);
702 // if the value is still all 0, skip the field
703 type = d->type & ~DEF_SAVEGLOBAL;
704 for (j=0 ; j<type_size[type] ; j++)
707 if (j == type_size[type])
710 FS_Printf(f,"\"%s\" ",name);
711 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
717 void ED_PrintNum (int ent)
719 ED_Print(EDICT_NUM(ent));
726 For debugging, prints all the entities in the current server
729 void ED_PrintEdicts (void)
733 Con_Printf("%i entities\n", sv.num_edicts);
734 for (i=0 ; i<sv.num_edicts ; i++)
742 For debugging, prints a single edict
745 void ED_PrintEdict_f (void)
749 i = atoi (Cmd_Argv(1));
750 if (i < 0 || i >= sv.num_edicts)
752 Con_Print("Bad edict number\n");
769 int active, models, solid, step;
771 active = models = solid = step = 0;
772 for (i=0 ; i<sv.num_edicts ; i++)
782 if (ent->v->movetype == MOVETYPE_STEP)
786 Con_Printf("num_edicts:%3i\n", sv.num_edicts);
787 Con_Printf("active :%3i\n", active);
788 Con_Printf("view :%3i\n", models);
789 Con_Printf("touch :%3i\n", solid);
790 Con_Printf("step :%3i\n", step);
795 ==============================================================================
799 FIXME: need to tag constants, doesn't really work
800 ==============================================================================
808 void ED_WriteGlobals (qfile_t *f)
816 for (i=0 ; i<progs->numglobaldefs ; i++)
818 def = &pr_globaldefs[i];
820 if ( !(def->type & DEF_SAVEGLOBAL) )
822 type &= ~DEF_SAVEGLOBAL;
824 if (type != ev_string && type != ev_float && type != ev_entity)
827 name = PR_GetString(def->s_name);
828 FS_Printf(f,"\"%s\" ", name);
829 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
838 Console command to set a field of a specified edict
841 void ED_EdictSet_f(void)
848 Con_Print("edictset <edict number> <field> <value>\n");
851 ed = EDICT_NUM(atoi(Cmd_Argv(1)));
853 if((key = ED_FindField(Cmd_Argv(2))) == 0)
855 Con_Printf("Key %s not found !\n", Cmd_Argv(2));
859 ED_ParseEpair(ed, key, Cmd_Argv(3));
867 void ED_ParseGlobals (const char *data)
869 char keyname[1024]; // LordHavoc: good idea? bad idea? was 64
875 if (!COM_ParseToken(&data, false))
876 Host_Error ("ED_ParseEntity: EOF without closing brace");
877 if (com_token[0] == '}')
880 strcpy (keyname, com_token);
883 if (!COM_ParseToken(&data, false))
884 Host_Error ("ED_ParseEntity: EOF without closing brace");
886 if (com_token[0] == '}')
887 Host_Error ("ED_ParseEntity: closing brace without data");
889 key = ED_FindGlobal (keyname);
892 Con_DPrintf("'%s' is not a global\n", keyname);
896 if (!ED_ParseEpair(NULL, key, com_token))
897 Host_Error ("ED_ParseGlobals: parse error");
901 //============================================================================
909 char *ED_NewString (const char *string)
914 l = strlen(string) + 1;
915 new = Mem_Alloc(edictstring_mempool, l);
918 for (i=0 ; i< l ; i++)
920 if (string[i] == '\\' && i < l-1)
923 if (string[i] == 'n')
929 *new_p++ = string[i];
940 Can parse either fields or globals
941 returns false if error
944 qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
952 val = (eval_t *)((int *)ent->v + key->ofs);
954 val = (eval_t *)((int *)pr_globals + key->ofs);
955 switch (key->type & ~DEF_SAVEGLOBAL)
958 val->string = PR_SetString(ED_NewString(s));
962 while (*s && *s <= ' ')
964 val->_float = atof(s);
968 for (i = 0;i < 3;i++)
970 while (*s && *s <= ' ')
973 val->vector[i] = atof(s);
982 while (*s && *s <= ' ')
985 if (i < 0 || i >= MAX_EDICTS)
986 Con_Printf("ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i)\n", i, MAX_EDICTS);
987 while (i >= sv.max_edicts)
989 // if SV_IncreaseEdicts was called the base pointer needs to be updated
991 val = (eval_t *)((int *)ent->v + key->ofs);
992 val->edict = EDICT_TO_PROG(EDICT_NUM(i));
996 def = ED_FindField(s);
999 Con_DPrintf("ED_ParseEpair: Can't find field %s\n", s);
1002 //val->_int = G_INT(def->ofs); AK Please check this - seems to be an org. quake bug
1003 val->_int = def->ofs;
1007 func = ED_FindFunction(s);
1010 Con_Printf("ED_ParseEpair: Can't find function %s\n", s);
1013 val->function = func - pr_functions;
1017 Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PR_GetString(key->s_name));
1024 ====================
1027 Parses an edict out of the given string, returning the new position
1028 ed should be a properly initialized empty edict.
1029 Used for initial level load and for savegames.
1030 ====================
1032 const char *ED_ParseEdict (const char *data, edict_t *ent)
1043 if (ent != sv.edicts) // hack
1044 memset (ent->v, 0, progs->entityfields * 4);
1046 // go through all the dictionary pairs
1050 if (!COM_ParseToken(&data, false))
1051 Host_Error ("ED_ParseEntity: EOF without closing brace");
1052 if (com_token[0] == '}')
1055 // anglehack is to allow QuakeEd to write single scalar angles
1056 // and allow them to be turned into vectors. (FIXME...)
1057 anglehack = !strcmp (com_token, "angle");
1059 strlcpy (com_token, "angles", sizeof (com_token));
1061 // FIXME: change light to _light to get rid of this hack
1062 if (!strcmp(com_token, "light"))
1063 strlcpy (com_token, "light_lev", sizeof (com_token)); // hack for single light def
1065 strlcpy (keyname, com_token, sizeof (keyname));
1067 // another hack to fix heynames with trailing spaces
1068 n = strlen(keyname);
1069 while (n && keyname[n-1] == ' ')
1076 if (!COM_ParseToken(&data, false))
1077 Host_Error ("ED_ParseEntity: EOF without closing brace");
1079 if (com_token[0] == '}')
1080 Host_Error ("ED_ParseEntity: closing brace without data");
1084 // keynames with a leading underscore are used for utility comments,
1085 // and are immediately discarded by quake
1086 if (keyname[0] == '_')
1089 key = ED_FindField (keyname);
1092 Con_DPrintf("'%s' is not a field\n", keyname);
1099 strlcpy (temp, com_token, sizeof (temp));
1100 snprintf (com_token, sizeof (com_token), "0 %s 0", temp);
1103 if (!ED_ParseEpair(ent, key, com_token))
1104 Host_Error ("ED_ParseEdict: parse error");
1108 ent->e->free = true;
1118 The entities are directly placed in the array, rather than allocated with
1119 ED_Alloc, because otherwise an error loading the map would have entity
1120 number references out of order.
1122 Creates a server's entity / program execution context by
1123 parsing textual entity definitions out of an ent file.
1125 Used for both fresh maps and savegame loads. A fresh map would also need
1126 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1129 void ED_LoadFromFile (const char *data)
1132 int parsed, inhibited, spawned, died;
1140 pr_global_struct->time = sv.time;
1145 // parse the opening brace
1146 if (!COM_ParseToken(&data, false))
1148 if (com_token[0] != '{')
1149 Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
1155 data = ED_ParseEdict (data, ent);
1158 // remove things from different skill levels or deathmatch
1159 if (deathmatch.integer)
1161 if (((int)ent->v->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
1168 else if ((current_skill == 0 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_EASY ))
1169 || (current_skill == 1 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_MEDIUM))
1170 || (current_skill >= 2 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_HARD )))
1178 // immediately call spawn function
1180 if (!ent->v->classname)
1182 Con_Print("No classname for:\n");
1188 // look for the spawn function
1189 func = ED_FindFunction (PR_GetString(ent->v->classname));
1193 if (developer.integer) // don't confuse non-developers with errors
1195 Con_Print("No spawn function for:\n");
1202 pr_global_struct->self = EDICT_TO_PROG(ent);
1203 PR_ExecuteProgram (func - pr_functions, "QC function spawn is missing");
1209 Con_DPrintf("%i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", parsed, inhibited, spawned, died, spawned - died);
1213 typedef struct dpfield_s
1220 #define DPFIELDS (sizeof(dpfields) / sizeof(dpfield_t))
1222 dpfield_t dpfields[] =
1224 {ev_entity, "cursor_trace_ent"},
1225 {ev_entity, "drawonlytoclient"},
1226 {ev_entity, "exteriormodeltoclient"},
1227 {ev_entity, "nodrawtoclient"},
1228 {ev_entity, "tag_entity"},
1229 {ev_entity, "viewmodelforclient"},
1230 {ev_float, "alpha"},
1231 {ev_float, "ammo_cells1"},
1232 {ev_float, "ammo_lava_nails"},
1233 {ev_float, "ammo_multi_rockets"},
1234 {ev_float, "ammo_nails1"},
1235 {ev_float, "ammo_plasma"},
1236 {ev_float, "ammo_rockets1"},
1237 {ev_float, "ammo_shells1"},
1238 {ev_float, "button3"},
1239 {ev_float, "button4"},
1240 {ev_float, "button5"},
1241 {ev_float, "button6"},
1242 {ev_float, "button7"},
1243 {ev_float, "button8"},
1244 {ev_float, "buttonchat"},
1245 {ev_float, "buttonuse"},
1246 {ev_float, "clientcolors"},
1247 {ev_float, "cursor_active"},
1248 {ev_float, "fullbright"},
1249 {ev_float, "glow_color"},
1250 {ev_float, "glow_size"},
1251 {ev_float, "glow_trail"},
1252 {ev_float, "gravity"},
1253 {ev_float, "idealpitch"},
1254 {ev_float, "items2"},
1255 {ev_float, "light_lev"},
1256 {ev_float, "pflags"},
1258 {ev_float, "pitch_speed"},
1259 {ev_float, "pmodel"},
1260 {ev_float, "renderamt"}, // HalfLife support
1261 {ev_float, "rendermode"}, // HalfLife support
1262 {ev_float, "scale"},
1263 {ev_float, "style"},
1264 {ev_float, "tag_index"},
1265 {ev_float, "viewzoom"},
1266 {ev_vector, "color"},
1267 {ev_vector, "colormod"},
1268 {ev_vector, "cursor_screen"},
1269 {ev_vector, "cursor_trace_endpos"},
1270 {ev_vector, "cursor_trace_start"},
1271 {ev_vector, "movement"},
1272 {ev_vector, "punchvector"}
1280 extern void PR_Cmd_Reset (void);
1281 void PR_LoadProgs (void)
1285 ddef_t *infielddefs;
1286 dfunction_t *dfunctions;
1288 // flush the non-C variable lookup cache
1289 for (i=0 ; i<GEFV_CACHESIZE ; i++)
1290 gefvCache[i].field[0] = 0;
1292 Mem_EmptyPool(progs_mempool);
1293 Mem_EmptyPool(edictstring_mempool);
1295 progs = (dprograms_t *)FS_LoadFile ("progs.dat", progs_mempool, false);
1297 Host_Error ("PR_LoadProgs: couldn't load progs.dat");
1299 Con_DPrintf("Programs occupy %iK.\n", fs_filesize/1024);
1301 pr_crc = CRC_Block((qbyte *)progs, fs_filesize);
1303 // byte swap the header
1304 for (i = 0;i < (int) sizeof(*progs) / 4;i++)
1305 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1307 if (progs->version != PROG_VERSION)
1308 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1309 if (progs->crc != PROGHEADER_CRC && progs->crc != 32401) // tenebrae crc also allowed
1310 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1312 //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1313 dfunctions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1314 pr_strings = (char *)progs + progs->ofs_strings;
1315 pr_globaldefs = (ddef_t *)((qbyte *)progs + progs->ofs_globaldefs);
1317 // we need to expand the fielddefs list to include all the engine fields,
1318 // so allocate a new place for it
1319 infielddefs = (ddef_t *)((qbyte *)progs + progs->ofs_fielddefs);
1320 pr_fielddefs = Mem_Alloc(progs_mempool, (progs->numfielddefs + DPFIELDS) * sizeof(ddef_t));
1322 pr_statements = (dstatement_t *)((qbyte *)progs + progs->ofs_statements);
1324 // moved edict_size calculation down below field adding code
1326 pr_global_struct = (globalvars_t *)((qbyte *)progs + progs->ofs_globals);
1327 pr_globals = (float *)pr_global_struct;
1329 // byte swap the lumps
1330 for (i=0 ; i<progs->numstatements ; i++)
1332 pr_statements[i].op = LittleShort(pr_statements[i].op);
1333 pr_statements[i].a = LittleShort(pr_statements[i].a);
1334 pr_statements[i].b = LittleShort(pr_statements[i].b);
1335 pr_statements[i].c = LittleShort(pr_statements[i].c);
1338 pr_functions = Mem_Alloc(progs_mempool, sizeof(mfunction_t) * progs->numfunctions);
1339 for (i = 0;i < progs->numfunctions;i++)
1341 pr_functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
1342 pr_functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
1343 pr_functions[i].s_name = LittleLong (dfunctions[i].s_name);
1344 pr_functions[i].s_file = LittleLong (dfunctions[i].s_file);
1345 pr_functions[i].numparms = LittleLong (dfunctions[i].numparms);
1346 pr_functions[i].locals = LittleLong (dfunctions[i].locals);
1347 memcpy(pr_functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
1350 for (i=0 ; i<progs->numglobaldefs ; i++)
1352 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1353 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1354 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1357 // copy the progs fields to the new fields list
1358 for (i = 0;i < progs->numfielddefs;i++)
1360 pr_fielddefs[i].type = LittleShort (infielddefs[i].type);
1361 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1362 Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1363 pr_fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
1364 pr_fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
1367 // append the darkplaces fields
1368 for (i = 0;i < (int) DPFIELDS;i++)
1370 pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
1371 pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
1372 pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string);
1373 if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
1374 progs->entityfields += 3;
1376 progs->entityfields++;
1377 progs->numfielddefs++;
1380 for (i=0 ; i<progs->numglobals ; i++)
1381 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1383 // moved edict_size calculation down here, below field adding code
1384 // LordHavoc: this no longer includes the edict_t header
1385 pr_edict_size = progs->entityfields * 4;
1386 pr_edictareasize = pr_edict_size * MAX_EDICTS;
1388 // LordHavoc: bounds check anything static
1389 for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1395 if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1396 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1399 if (st->a + i < 0 || st->a + i >= progs->numstatements)
1400 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1402 // global global global
1437 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1438 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1440 // global none global
1446 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1447 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1463 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1464 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1478 if ((unsigned short) st->a >= progs->numglobals)
1479 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1482 Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1487 FindEdictFieldOffsets(); // LordHavoc: update field offset list
1488 PR_Execute_ProgsLoaded();
1493 void PR_Fields_f (void)
1495 int i, j, ednum, used, usedamount;
1497 char tempstring[5000], tempstring2[260], *name;
1503 Con_Print("no progs loaded\n");
1506 counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
1507 for (ednum = 0;ednum < sv.max_edicts;ednum++)
1509 ed = EDICT_NUM(ednum);
1512 for (i = 1;i < progs->numfielddefs;i++)
1514 d = &pr_fielddefs[i];
1515 name = PR_GetString(d->s_name);
1516 if (name[strlen(name)-2] == '_')
1517 continue; // skip _x, _y, _z vars
1518 v = (int *)((char *)ed->v + d->ofs*4);
1519 // if the value is still all 0, skip the field
1520 for (j = 0;j < type_size[d->type & ~DEF_SAVEGLOBAL];j++)
1533 for (i = 0;i < progs->numfielddefs;i++)
1535 d = &pr_fielddefs[i];
1536 name = PR_GetString(d->s_name);
1537 if (name[strlen(name)-2] == '_')
1538 continue; // skip _x, _y, _z vars
1539 switch(d->type & ~DEF_SAVEGLOBAL)
1542 strlcat (tempstring, "string ", sizeof (tempstring));
1545 strlcat (tempstring, "entity ", sizeof (tempstring));
1548 strlcat (tempstring, "function ", sizeof (tempstring));
1551 strlcat (tempstring, "field ", sizeof (tempstring));
1554 strlcat (tempstring, "void ", sizeof (tempstring));
1557 strlcat (tempstring, "float ", sizeof (tempstring));
1560 strlcat (tempstring, "vector ", sizeof (tempstring));
1563 strlcat (tempstring, "pointer ", sizeof (tempstring));
1566 snprintf (tempstring2, sizeof (tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
1567 strlcat (tempstring, tempstring2, sizeof (tempstring));
1570 if (strlen(name) > 256)
1572 memcpy(tempstring2, name, 256);
1573 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
1574 tempstring2[259] = 0;
1577 strcat (tempstring, name);
1578 for (j = strlen(name);j < 25;j++)
1579 strcat(tempstring, " ");
1580 snprintf (tempstring2, sizeof (tempstring2), "%5d", counts[i]);
1581 strlcat (tempstring, tempstring2, sizeof (tempstring));
1582 strlcat (tempstring, "\n", sizeof (tempstring));
1583 if (strlen(tempstring) >= 4096)
1585 Con_Print(tempstring);
1591 usedamount += type_size[d->type & ~DEF_SAVEGLOBAL];
1595 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);
1598 void PR_Globals_f (void)
1603 Con_Print("no progs loaded\n");
1606 for (i = 0;i < progs->numglobaldefs;i++)
1607 Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name));
1608 Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
1616 extern void PR_Cmd_Init(void);
1619 Cmd_AddCommand ("edict", ED_PrintEdict_f);
1620 Cmd_AddCommand ("edicts", ED_PrintEdicts);
1621 Cmd_AddCommand ("edictcount", ED_Count);
1622 Cmd_AddCommand ("edictset", ED_EdictSet_f);
1623 Cmd_AddCommand ("profile", PR_Profile_f);
1624 Cmd_AddCommand ("pr_fields", PR_Fields_f);
1625 Cmd_AddCommand ("pr_globals", PR_Globals_f);
1626 Cvar_RegisterVariable (&pr_checkextension);
1627 Cvar_RegisterVariable (&nomonsters);
1628 Cvar_RegisterVariable (&gamecfg);
1629 Cvar_RegisterVariable (&scratch1);
1630 Cvar_RegisterVariable (&scratch2);
1631 Cvar_RegisterVariable (&scratch3);
1632 Cvar_RegisterVariable (&scratch4);
1633 Cvar_RegisterVariable (&savedgamecfg);
1634 Cvar_RegisterVariable (&saved1);
1635 Cvar_RegisterVariable (&saved2);
1636 Cvar_RegisterVariable (&saved3);
1637 Cvar_RegisterVariable (&saved4);
1638 // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1639 Cvar_RegisterVariable (&decors);
1640 // LordHavoc: Nehahra uses these to pass data around cutscene demos
1641 if (gamemode == GAME_NEHAHRA)
1643 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1644 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1645 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1646 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1647 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1648 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1649 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1650 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1651 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1652 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1654 Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1655 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1656 Cvar_RegisterVariable (&pr_boundscheck);
1657 Cvar_RegisterVariable (&pr_traceqc);
1659 progs_mempool = Mem_AllocPool("progs.dat", 0, NULL);
1660 edictstring_mempool = Mem_AllocPool("edict strings", 0, NULL);
1665 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1666 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
1668 Host_Error ("EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
1673 int NUM_FOR_EDICT_ERROR(edict_t *e)
1675 Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
1679 int NUM_FOR_EDICT(edict_t *e)
1683 if ((unsigned int)n >= MAX_EDICTS)
1684 Host_Error ("NUM_FOR_EDICT: bad pointer");
1688 //int NoCrash_NUM_FOR_EDICT(edict_t *e)
1690 // return e - sv.edicts;
1693 //#define EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
1694 //#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
1695 int EDICT_TO_PROG(edict_t *e)
1699 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1700 Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
1701 return n;// EXPERIMENTAL
1702 //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
1704 edict_t *PROG_TO_EDICT(int n)
1706 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1707 Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
1708 return sv.edicts + n; // EXPERIMENTAL
1709 //return sv.edicts + ((n) / (progs->entityfields * 4));