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;
137 int eval_playermodel;
140 mfunction_t *SV_PlayerPhysicsQC;
141 mfunction_t *EndFrameQC;
142 //KrimZon - SERVER COMMANDS IN QUAKEC
143 mfunction_t *SV_ParseClientCommandQC;
145 int FindFieldOffset(const char *field)
148 d = ED_FindField(field);
154 void FindEdictFieldOffsets(void)
156 eval_gravity = FindFieldOffset("gravity");
157 eval_button3 = FindFieldOffset("button3");
158 eval_button4 = FindFieldOffset("button4");
159 eval_button5 = FindFieldOffset("button5");
160 eval_button6 = FindFieldOffset("button6");
161 eval_button7 = FindFieldOffset("button7");
162 eval_button8 = FindFieldOffset("button8");
163 eval_buttonuse = FindFieldOffset("buttonuse");
164 eval_buttonchat = FindFieldOffset("buttonchat");
165 eval_glow_size = FindFieldOffset("glow_size");
166 eval_glow_trail = FindFieldOffset("glow_trail");
167 eval_glow_color = FindFieldOffset("glow_color");
168 eval_items2 = FindFieldOffset("items2");
169 eval_scale = FindFieldOffset("scale");
170 eval_alpha = FindFieldOffset("alpha");
171 eval_renderamt = FindFieldOffset("renderamt"); // HalfLife support
172 eval_rendermode = FindFieldOffset("rendermode"); // HalfLife support
173 eval_fullbright = FindFieldOffset("fullbright");
174 eval_ammo_shells1 = FindFieldOffset("ammo_shells1");
175 eval_ammo_nails1 = FindFieldOffset("ammo_nails1");
176 eval_ammo_lava_nails = FindFieldOffset("ammo_lava_nails");
177 eval_ammo_rockets1 = FindFieldOffset("ammo_rockets1");
178 eval_ammo_multi_rockets = FindFieldOffset("ammo_multi_rockets");
179 eval_ammo_cells1 = FindFieldOffset("ammo_cells1");
180 eval_ammo_plasma = FindFieldOffset("ammo_plasma");
181 eval_idealpitch = FindFieldOffset("idealpitch");
182 eval_pitch_speed = FindFieldOffset("pitch_speed");
183 eval_viewmodelforclient = FindFieldOffset("viewmodelforclient");
184 eval_nodrawtoclient = FindFieldOffset("nodrawtoclient");
185 eval_exteriormodeltoclient = FindFieldOffset("exteriormodeltoclient");
186 eval_drawonlytoclient = FindFieldOffset("drawonlytoclient");
187 eval_ping = FindFieldOffset("ping");
188 eval_movement = FindFieldOffset("movement");
189 eval_pmodel = FindFieldOffset("pmodel");
190 eval_punchvector = FindFieldOffset("punchvector");
191 eval_viewzoom = FindFieldOffset("viewzoom");
192 eval_clientcolors = FindFieldOffset("clientcolors");
193 eval_tag_entity = FindFieldOffset("tag_entity");
194 eval_tag_index = FindFieldOffset("tag_index");
195 eval_light_lev = FindFieldOffset("light_lev");
196 eval_color = FindFieldOffset("color");
197 eval_style = FindFieldOffset("style");
198 eval_pflags = FindFieldOffset("pflags");
199 eval_cursor_active = FindFieldOffset("cursor_active");
200 eval_cursor_screen = FindFieldOffset("cursor_screen");
201 eval_cursor_trace_start = FindFieldOffset("cursor_trace_start");
202 eval_cursor_trace_endpos = FindFieldOffset("cursor_trace_endpos");
203 eval_cursor_trace_ent = FindFieldOffset("cursor_trace_ent");
204 eval_colormod = FindFieldOffset("colormod");
205 eval_playermodel = FindFieldOffset("playermodel");
206 eval_playerskin = FindFieldOffset("playerskin");
208 // LordHavoc: allowing QuakeC to override the player movement code
209 SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
210 // LordHavoc: support for endframe
211 EndFrameQC = ED_FindFunction ("EndFrame");
212 //KrimZon - SERVER COMMANDS IN QUAKEC
213 SV_ParseClientCommandQC = ED_FindFunction ("SV_ParseClientCommand");
220 Sets everything to NULL
223 void ED_ClearEdict (edict_t *e)
226 memset (e->v, 0, progs->entityfields * 4);
228 // LordHavoc: for consistency set these here
229 num = NUM_FOR_EDICT(e) - 1;
230 if (num >= 0 && num < svs.maxclients)
233 // set colormap and team on newly created player entity
234 e->v->colormap = num + 1;
235 e->v->team = (svs.clients[num].colors & 15) + 1;
236 // set netname/clientcolors back to client values so that
237 // DP_SV_CLIENTNAME and DPV_SV_CLIENTCOLORS will not immediately
239 e->v->netname = PR_SetString(svs.clients[num].name);
240 if ((val = GETEDICTFIELDVALUE(e, eval_clientcolors)))
241 val->_float = svs.clients[num].colors;
242 // NEXUIZ_PLAYERMODEL and NEXUIZ_PLAYERSKIN
243 if( eval_playermodel )
244 GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string = PR_SetString(svs.clients[num].playermodel);
245 if( eval_playerskin )
246 GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string = PR_SetString(svs.clients[num].playerskin);
254 Either finds a free edict, or allocates a new one.
255 Try to avoid reusing an entity that was recently freed, because it
256 can cause the client to think the entity morphed into something else
257 instead of being removed and recreated, which can cause interpolated
258 angles and bad trails.
261 edict_t *ED_Alloc (void)
266 for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
269 // the first couple seconds of server time can involve a lot of
270 // freeing and allocating, so relax the replacement policy
271 if (e->e->free && ( e->e->freetime < 2 || sv.time - e->e->freetime > 0.5 ) )
279 Host_Error ("ED_Alloc: no free edicts");
282 if (sv.num_edicts >= sv.max_edicts)
294 Marks the edict as free
295 FIXME: walk all entities and NULL out references to this entity
298 void ED_Free (edict_t *ed)
300 SV_UnlinkEdict (ed); // unlink from world bsp
304 ed->v->takedamage = 0;
305 ed->v->modelindex = 0;
309 VectorClear(ed->v->origin);
310 VectorClear(ed->v->angles);
311 ed->v->nextthink = -1;
314 ed->e->freetime = sv.time;
317 //===========================================================================
324 ddef_t *ED_GlobalAtOfs (int ofs)
329 for (i=0 ; i<progs->numglobaldefs ; i++)
331 def = &pr_globaldefs[i];
343 ddef_t *ED_FieldAtOfs (int ofs)
348 for (i=0 ; i<progs->numfielddefs ; i++)
350 def = &pr_fielddefs[i];
362 ddef_t *ED_FindField (const char *name)
367 for (i=0 ; i<progs->numfielddefs ; i++)
369 def = &pr_fielddefs[i];
370 if (!strcmp(PR_GetString(def->s_name), name))
381 ddef_t *ED_FindGlobal (const char *name)
386 for (i=0 ; i<progs->numglobaldefs ; i++)
388 def = &pr_globaldefs[i];
389 if (!strcmp(PR_GetString(def->s_name), name))
401 mfunction_t *ED_FindFunction (const char *name)
406 for (i=0 ; i<progs->numfunctions ; i++)
408 func = &pr_functions[i];
409 if (!strcmp(PR_GetString(func->s_name), name))
420 Returns a string describing *data in a type specific manner
423 //int NoCrash_NUM_FOR_EDICT(edict_t *e);
424 char *PR_ValueString (etype_t type, eval_t *val)
426 static char line[1024]; // LordHavoc: enlarged a bit (was 256)
431 type &= ~DEF_SAVEGLOBAL;
436 strlcpy (line, PR_GetString (val->string), sizeof (line));
439 //n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict));
441 if (n < 0 || n >= MAX_EDICTS)
442 dpsnprintf (line, sizeof (line), "entity %i (invalid!)", n);
444 dpsnprintf (line, sizeof (line), "entity %i", n);
447 f = pr_functions + val->function;
448 dpsnprintf (line, sizeof (line), "%s()", PR_GetString(f->s_name));
451 def = ED_FieldAtOfs ( val->_int );
452 dpsnprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
455 dpsnprintf (line, sizeof (line), "void");
458 // LordHavoc: changed from %5.1f to %10.4f
459 dpsnprintf (line, sizeof (line), "%10.4f", val->_float);
462 // LordHavoc: changed from %5.1f to %10.4f
463 dpsnprintf (line, sizeof (line), "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
466 dpsnprintf (line, sizeof (line), "pointer");
469 dpsnprintf (line, sizeof (line), "bad type %i", type);
480 Returns a string describing *data in a type specific manner
481 Easier to parse than PR_ValueString
484 char *PR_UglyValueString (etype_t type, eval_t *val)
486 static char line[4096];
492 type &= ~DEF_SAVEGLOBAL;
497 // Parse the string a bit to turn special characters
498 // (like newline, specifically) into escape codes,
499 // this fixes saving games from various mods
500 s = PR_GetString (val->string);
501 for (i = 0;i < (int)sizeof(line) - 2 && *s;)
520 dpsnprintf (line, sizeof (line), "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
523 f = pr_functions + val->function;
524 strlcpy (line, PR_GetString (f->s_name), sizeof (line));
527 def = ED_FieldAtOfs ( val->_int );
528 dpsnprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
531 dpsnprintf (line, sizeof (line), "void");
534 dpsnprintf (line, sizeof (line), "%f", val->_float);
537 dpsnprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
540 dpsnprintf (line, sizeof (line), "bad type %i", type);
551 Returns a string with a description and the contents of a global,
552 padded to 20 field width
555 char *PR_GlobalString (int ofs)
561 static char line[128];
563 val = (void *)&pr_globals[ofs];
564 def = ED_GlobalAtOfs(ofs);
566 dpsnprintf (line, sizeof (line), "%i(?)", ofs);
569 s = PR_ValueString (def->type, val);
570 dpsnprintf (line, sizeof (line), "%i(%s)%s", ofs, PR_GetString(def->s_name), s);
575 strlcat (line, " ", sizeof (line));
576 strlcat (line, " ", sizeof (line));
581 char *PR_GlobalStringNoContents (int ofs)
585 static char line[128];
587 def = ED_GlobalAtOfs(ofs);
589 dpsnprintf (line, sizeof (line), "%i(?)", ofs);
591 dpsnprintf (line, sizeof (line), "%i(%s)", ofs, PR_GetString(def->s_name));
595 strlcat (line, " ", sizeof (line));
596 strlcat (line, " ", sizeof (line));
609 // LordHavoc: optimized this to print out much more quickly (tempstring)
610 // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
611 void ED_Print(edict_t *ed)
619 char tempstring[8192], tempstring2[260]; // temporary string buffers
628 dpsnprintf (tempstring, sizeof (tempstring), "\nEDICT %i:\n", NUM_FOR_EDICT(ed));
629 for (i=1 ; i<progs->numfielddefs ; i++)
631 d = &pr_fielddefs[i];
632 name = PR_GetString(d->s_name);
633 if (name[strlen(name)-2] == '_')
634 continue; // skip _x, _y, _z vars
636 v = (int *)((char *)ed->v + d->ofs*4);
638 // if the value is still all 0, skip the field
639 type = d->type & ~DEF_SAVEGLOBAL;
641 for (j=0 ; j<type_size[type] ; j++)
644 if (j == type_size[type])
647 if (strlen(name) > 256)
649 memcpy (tempstring2, name, 256);
650 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
651 tempstring2[259] = 0;
654 strlcat (tempstring, name, sizeof (tempstring));
655 for (l = strlen(name);l < 14;l++)
656 strcat(tempstring, " ");
657 strcat(tempstring, " ");
659 name = PR_ValueString(d->type, (eval_t *)v);
660 if (strlen(name) > 256)
662 memcpy(tempstring2, name, 256);
663 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
664 tempstring2[259] = 0;
667 strlcat (tempstring, name, sizeof (tempstring));
668 strlcat (tempstring, "\n", sizeof (tempstring));
669 if (strlen(tempstring) >= 4096)
671 Con_Print(tempstring);
676 Con_Print(tempstring);
686 void ED_Write (qfile_t *f, edict_t *ed)
702 for (i=1 ; i<progs->numfielddefs ; i++)
704 d = &pr_fielddefs[i];
705 name = PR_GetString(d->s_name);
706 if (name[strlen(name)-2] == '_')
707 continue; // skip _x, _y, _z vars
709 v = (int *)((char *)ed->v + d->ofs*4);
711 // if the value is still all 0, skip the field
712 type = d->type & ~DEF_SAVEGLOBAL;
713 for (j=0 ; j<type_size[type] ; j++)
716 if (j == type_size[type])
719 FS_Printf(f,"\"%s\" ",name);
720 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
726 void ED_PrintNum (int ent)
728 ED_Print(EDICT_NUM(ent));
735 For debugging, prints all the entities in the current server
738 void ED_PrintEdicts (void)
742 Con_Printf("%i entities\n", sv.num_edicts);
743 for (i=0 ; i<sv.num_edicts ; i++)
751 For debugging, prints a single edict
754 void ED_PrintEdict_f (void)
758 i = atoi (Cmd_Argv(1));
759 if (i < 0 || i >= sv.num_edicts)
761 Con_Print("Bad edict number\n");
778 int active, models, solid, step;
780 active = models = solid = step = 0;
781 for (i=0 ; i<sv.num_edicts ; i++)
791 if (ent->v->movetype == MOVETYPE_STEP)
795 Con_Printf("num_edicts:%3i\n", sv.num_edicts);
796 Con_Printf("active :%3i\n", active);
797 Con_Printf("view :%3i\n", models);
798 Con_Printf("touch :%3i\n", solid);
799 Con_Printf("step :%3i\n", step);
804 ==============================================================================
808 FIXME: need to tag constants, doesn't really work
809 ==============================================================================
817 void ED_WriteGlobals (qfile_t *f)
825 for (i=0 ; i<progs->numglobaldefs ; i++)
827 def = &pr_globaldefs[i];
829 if ( !(def->type & DEF_SAVEGLOBAL) )
831 type &= ~DEF_SAVEGLOBAL;
833 if (type != ev_string && type != ev_float && type != ev_entity)
836 name = PR_GetString(def->s_name);
837 FS_Printf(f,"\"%s\" ", name);
838 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
847 Console command to set a field of a specified edict
850 void ED_EdictSet_f(void)
857 Con_Print("edictset <edict number> <field> <value>\n");
860 ed = EDICT_NUM(atoi(Cmd_Argv(1)));
862 if((key = ED_FindField(Cmd_Argv(2))) == 0)
864 Con_Printf("Key %s not found !\n", Cmd_Argv(2));
868 ED_ParseEpair(ed, key, Cmd_Argv(3));
876 void ED_ParseGlobals (const char *data)
878 char keyname[1024]; // LordHavoc: good idea? bad idea? was 64
884 if (!COM_ParseToken(&data, false))
885 Host_Error ("ED_ParseEntity: EOF without closing brace");
886 if (com_token[0] == '}')
889 strcpy (keyname, com_token);
892 if (!COM_ParseToken(&data, false))
893 Host_Error ("ED_ParseEntity: EOF without closing brace");
895 if (com_token[0] == '}')
896 Host_Error ("ED_ParseEntity: closing brace without data");
898 key = ED_FindGlobal (keyname);
901 Con_DPrintf("'%s' is not a global\n", keyname);
905 if (!ED_ParseEpair(NULL, key, com_token))
906 Host_Error ("ED_ParseGlobals: parse error");
910 //============================================================================
918 char *ED_NewString (const char *string)
923 l = strlen(string) + 1;
924 new = Mem_Alloc(edictstring_mempool, l);
927 for (i=0 ; i< l ; i++)
929 if (string[i] == '\\' && i < l-1)
932 if (string[i] == 'n')
934 else if (string[i] == 'r')
940 *new_p++ = string[i];
951 Can parse either fields or globals
952 returns false if error
955 qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
963 val = (eval_t *)((int *)ent->v + key->ofs);
965 val = (eval_t *)((int *)pr_globals + key->ofs);
966 switch (key->type & ~DEF_SAVEGLOBAL)
969 val->string = PR_SetString(ED_NewString(s));
973 while (*s && *s <= ' ')
975 val->_float = atof(s);
979 for (i = 0;i < 3;i++)
981 while (*s && *s <= ' ')
984 val->vector[i] = atof(s);
993 while (*s && *s <= ' ')
996 if (i < 0 || i >= MAX_EDICTS)
997 Con_Printf("ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i)\n", i, MAX_EDICTS);
998 while (i >= sv.max_edicts)
1000 // if SV_IncreaseEdicts was called the base pointer needs to be updated
1002 val = (eval_t *)((int *)ent->v + key->ofs);
1003 val->edict = EDICT_TO_PROG(EDICT_NUM(i));
1007 def = ED_FindField(s);
1010 Con_DPrintf("ED_ParseEpair: Can't find field %s\n", s);
1013 //val->_int = G_INT(def->ofs); // AK Please check this - seems to be an org. quake bug
1014 val->_int = def->ofs;
1018 func = ED_FindFunction(s);
1021 Con_Printf("ED_ParseEpair: Can't find function %s\n", s);
1024 val->function = func - pr_functions;
1028 Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PR_GetString(key->s_name));
1035 ====================
1038 Parses an edict out of the given string, returning the new position
1039 ed should be a properly initialized empty edict.
1040 Used for initial level load and for savegames.
1041 ====================
1043 const char *ED_ParseEdict (const char *data, edict_t *ent)
1054 if (ent != sv.edicts) // hack
1055 memset (ent->v, 0, progs->entityfields * 4);
1057 // go through all the dictionary pairs
1061 if (!COM_ParseToken(&data, false))
1062 Host_Error ("ED_ParseEntity: EOF without closing brace");
1063 if (com_token[0] == '}')
1066 // anglehack is to allow QuakeEd to write single scalar angles
1067 // and allow them to be turned into vectors. (FIXME...)
1068 anglehack = !strcmp (com_token, "angle");
1070 strlcpy (com_token, "angles", sizeof (com_token));
1072 // FIXME: change light to _light to get rid of this hack
1073 if (!strcmp(com_token, "light"))
1074 strlcpy (com_token, "light_lev", sizeof (com_token)); // hack for single light def
1076 strlcpy (keyname, com_token, sizeof (keyname));
1078 // another hack to fix heynames with trailing spaces
1079 n = strlen(keyname);
1080 while (n && keyname[n-1] == ' ')
1087 if (!COM_ParseToken(&data, false))
1088 Host_Error ("ED_ParseEntity: EOF without closing brace");
1090 if (com_token[0] == '}')
1091 Host_Error ("ED_ParseEntity: closing brace without data");
1095 // keynames with a leading underscore are used for utility comments,
1096 // and are immediately discarded by quake
1097 if (keyname[0] == '_')
1100 key = ED_FindField (keyname);
1103 Con_DPrintf("'%s' is not a field\n", keyname);
1110 strlcpy (temp, com_token, sizeof (temp));
1111 dpsnprintf (com_token, sizeof (com_token), "0 %s 0", temp);
1114 if (!ED_ParseEpair(ent, key, com_token))
1115 Host_Error ("ED_ParseEdict: parse error");
1119 ent->e->free = true;
1129 The entities are directly placed in the array, rather than allocated with
1130 ED_Alloc, because otherwise an error loading the map would have entity
1131 number references out of order.
1133 Creates a server's entity / program execution context by
1134 parsing textual entity definitions out of an ent file.
1136 Used for both fresh maps and savegame loads. A fresh map would also need
1137 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1140 void ED_LoadFromFile (const char *data)
1143 int parsed, inhibited, spawned, died;
1151 pr_global_struct->time = sv.time;
1156 // parse the opening brace
1157 if (!COM_ParseToken(&data, false))
1159 if (com_token[0] != '{')
1160 Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
1166 data = ED_ParseEdict (data, ent);
1169 // remove things from different skill levels or deathmatch
1170 if (gamemode != GAME_TRANSFUSION) //Transfusion does this in QC
1172 if (deathmatch.integer)
1174 if (((int)ent->v->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
1181 else if ((current_skill <= 0 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_EASY ))
1182 || (current_skill == 1 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_MEDIUM))
1183 || (current_skill >= 2 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_HARD )))
1191 // immediately call spawn function
1193 if (!ent->v->classname)
1195 Con_Print("No classname for:\n");
1201 // look for the spawn function
1202 func = ED_FindFunction (PR_GetString(ent->v->classname));
1206 if (developer.integer) // don't confuse non-developers with errors
1208 Con_Print("No spawn function for:\n");
1215 pr_global_struct->self = EDICT_TO_PROG(ent);
1216 PR_ExecuteProgram (func - pr_functions, "QC function spawn is missing");
1222 Con_DPrintf("%i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", parsed, inhibited, spawned, died, spawned - died);
1226 typedef struct dpfield_s
1233 #define DPFIELDS (sizeof(dpfields) / sizeof(dpfield_t))
1235 dpfield_t dpfields[] =
1237 {ev_entity, "cursor_trace_ent"},
1238 {ev_entity, "drawonlytoclient"},
1239 {ev_entity, "exteriormodeltoclient"},
1240 {ev_entity, "nodrawtoclient"},
1241 {ev_entity, "tag_entity"},
1242 {ev_entity, "viewmodelforclient"},
1243 {ev_float, "alpha"},
1244 {ev_float, "ammo_cells1"},
1245 {ev_float, "ammo_lava_nails"},
1246 {ev_float, "ammo_multi_rockets"},
1247 {ev_float, "ammo_nails1"},
1248 {ev_float, "ammo_plasma"},
1249 {ev_float, "ammo_rockets1"},
1250 {ev_float, "ammo_shells1"},
1251 {ev_float, "button3"},
1252 {ev_float, "button4"},
1253 {ev_float, "button5"},
1254 {ev_float, "button6"},
1255 {ev_float, "button7"},
1256 {ev_float, "button8"},
1257 {ev_float, "buttonchat"},
1258 {ev_float, "buttonuse"},
1259 {ev_float, "clientcolors"},
1260 {ev_float, "cursor_active"},
1261 {ev_float, "fullbright"},
1262 {ev_float, "glow_color"},
1263 {ev_float, "glow_size"},
1264 {ev_float, "glow_trail"},
1265 {ev_float, "gravity"},
1266 {ev_float, "idealpitch"},
1267 {ev_float, "items2"},
1268 {ev_float, "light_lev"},
1269 {ev_float, "pflags"},
1271 {ev_float, "pitch_speed"},
1272 {ev_float, "pmodel"},
1273 {ev_float, "renderamt"}, // HalfLife support
1274 {ev_float, "rendermode"}, // HalfLife support
1275 {ev_float, "scale"},
1276 {ev_float, "style"},
1277 {ev_float, "tag_index"},
1278 {ev_float, "viewzoom"},
1279 {ev_vector, "color"},
1280 {ev_vector, "colormod"},
1281 {ev_vector, "cursor_screen"},
1282 {ev_vector, "cursor_trace_endpos"},
1283 {ev_vector, "cursor_trace_start"},
1284 {ev_vector, "movement"},
1285 {ev_vector, "punchvector"},
1286 {ev_string, "playermodel"},
1287 {ev_string, "playerskin"}
1295 extern void PR_Cmd_Reset (void);
1296 void PR_LoadProgs (const char *progsname)
1300 ddef_t *infielddefs;
1301 dfunction_t *dfunctions;
1303 if (!progsname || !*progsname)
1304 Host_Error("PR_LoadProgs: passed empty progsname");
1306 // flush the non-C variable lookup cache
1307 for (i=0 ; i<GEFV_CACHESIZE ; i++)
1308 gefvCache[i].field[0] = 0;
1310 Mem_EmptyPool(progs_mempool);
1311 Mem_EmptyPool(edictstring_mempool);
1313 progs = (dprograms_t *)FS_LoadFile (progsname, progs_mempool, false);
1315 Host_Error ("PR_LoadProgs: couldn't load %s", progsname);
1317 Con_DPrintf("Programs occupy %iK.\n", fs_filesize/1024);
1319 pr_crc = CRC_Block((qbyte *)progs, fs_filesize);
1321 // byte swap the header
1322 for (i = 0;i < (int) sizeof(*progs) / 4;i++)
1323 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1325 if (progs->version != PROG_VERSION)
1326 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1327 if (progs->crc != PROGHEADER_CRC && progs->crc != 32401) // tenebrae crc also allowed
1328 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1330 //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1331 dfunctions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1332 pr_strings = (char *)progs + progs->ofs_strings;
1333 pr_globaldefs = (ddef_t *)((qbyte *)progs + progs->ofs_globaldefs);
1335 // we need to expand the fielddefs list to include all the engine fields,
1336 // so allocate a new place for it
1337 infielddefs = (ddef_t *)((qbyte *)progs + progs->ofs_fielddefs);
1338 pr_fielddefs = Mem_Alloc(progs_mempool, (progs->numfielddefs + DPFIELDS) * sizeof(ddef_t));
1340 pr_statements = (dstatement_t *)((qbyte *)progs + progs->ofs_statements);
1342 // moved edict_size calculation down below field adding code
1344 pr_global_struct = (globalvars_t *)((qbyte *)progs + progs->ofs_globals);
1345 pr_globals = (float *)pr_global_struct;
1347 // byte swap the lumps
1348 for (i=0 ; i<progs->numstatements ; i++)
1350 pr_statements[i].op = LittleShort(pr_statements[i].op);
1351 pr_statements[i].a = LittleShort(pr_statements[i].a);
1352 pr_statements[i].b = LittleShort(pr_statements[i].b);
1353 pr_statements[i].c = LittleShort(pr_statements[i].c);
1356 pr_functions = Mem_Alloc(progs_mempool, sizeof(mfunction_t) * progs->numfunctions);
1357 for (i = 0;i < progs->numfunctions;i++)
1359 pr_functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
1360 pr_functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
1361 pr_functions[i].s_name = LittleLong (dfunctions[i].s_name);
1362 pr_functions[i].s_file = LittleLong (dfunctions[i].s_file);
1363 pr_functions[i].numparms = LittleLong (dfunctions[i].numparms);
1364 pr_functions[i].locals = LittleLong (dfunctions[i].locals);
1365 memcpy(pr_functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
1368 for (i=0 ; i<progs->numglobaldefs ; i++)
1370 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1371 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1372 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1375 // copy the progs fields to the new fields list
1376 for (i = 0;i < progs->numfielddefs;i++)
1378 pr_fielddefs[i].type = LittleShort (infielddefs[i].type);
1379 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1380 Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1381 pr_fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
1382 pr_fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
1385 // append the darkplaces fields
1386 for (i = 0;i < (int) DPFIELDS;i++)
1388 pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
1389 pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
1390 pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string);
1391 if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
1392 progs->entityfields += 3;
1394 progs->entityfields++;
1395 progs->numfielddefs++;
1398 for (i=0 ; i<progs->numglobals ; i++)
1399 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1401 // moved edict_size calculation down here, below field adding code
1402 // LordHavoc: this no longer includes the edict_t header
1403 pr_edict_size = progs->entityfields * 4;
1404 pr_edictareasize = pr_edict_size * MAX_EDICTS;
1406 // LordHavoc: bounds check anything static
1407 for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1413 if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1414 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1417 if (st->a + i < 0 || st->a + i >= progs->numstatements)
1418 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1420 // global global global
1455 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1456 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1458 // global none global
1464 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1465 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1481 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1482 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1496 if ((unsigned short) st->a >= progs->numglobals)
1497 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1500 Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1505 FindEdictFieldOffsets(); // LordHavoc: update field offset list
1506 PR_Execute_ProgsLoaded();
1511 void PR_Fields_f (void)
1513 int i, j, ednum, used, usedamount;
1515 char tempstring[5000], tempstring2[260], *name;
1521 Con_Print("no progs loaded\n");
1524 counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
1525 for (ednum = 0;ednum < sv.max_edicts;ednum++)
1527 ed = EDICT_NUM(ednum);
1530 for (i = 1;i < progs->numfielddefs;i++)
1532 d = &pr_fielddefs[i];
1533 name = PR_GetString(d->s_name);
1534 if (name[strlen(name)-2] == '_')
1535 continue; // skip _x, _y, _z vars
1536 v = (int *)((char *)ed->v + d->ofs*4);
1537 // if the value is still all 0, skip the field
1538 for (j = 0;j < type_size[d->type & ~DEF_SAVEGLOBAL];j++)
1551 for (i = 0;i < progs->numfielddefs;i++)
1553 d = &pr_fielddefs[i];
1554 name = PR_GetString(d->s_name);
1555 if (name[strlen(name)-2] == '_')
1556 continue; // skip _x, _y, _z vars
1557 switch(d->type & ~DEF_SAVEGLOBAL)
1560 strlcat (tempstring, "string ", sizeof (tempstring));
1563 strlcat (tempstring, "entity ", sizeof (tempstring));
1566 strlcat (tempstring, "function ", sizeof (tempstring));
1569 strlcat (tempstring, "field ", sizeof (tempstring));
1572 strlcat (tempstring, "void ", sizeof (tempstring));
1575 strlcat (tempstring, "float ", sizeof (tempstring));
1578 strlcat (tempstring, "vector ", sizeof (tempstring));
1581 strlcat (tempstring, "pointer ", sizeof (tempstring));
1584 dpsnprintf (tempstring2, sizeof (tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
1585 strlcat (tempstring, tempstring2, sizeof (tempstring));
1588 if (strlen(name) > 256)
1590 memcpy(tempstring2, name, 256);
1591 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
1592 tempstring2[259] = 0;
1595 strcat (tempstring, name);
1596 for (j = strlen(name);j < 25;j++)
1597 strcat(tempstring, " ");
1598 dpsnprintf (tempstring2, sizeof (tempstring2), "%5d", counts[i]);
1599 strlcat (tempstring, tempstring2, sizeof (tempstring));
1600 strlcat (tempstring, "\n", sizeof (tempstring));
1601 if (strlen(tempstring) >= 4096)
1603 Con_Print(tempstring);
1609 usedamount += type_size[d->type & ~DEF_SAVEGLOBAL];
1613 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);
1616 void PR_Globals_f (void)
1621 Con_Print("no progs loaded\n");
1624 for (i = 0;i < progs->numglobaldefs;i++)
1625 Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name));
1626 Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
1634 extern void PR_Cmd_Init(void);
1637 Cmd_AddCommand ("edict", ED_PrintEdict_f);
1638 Cmd_AddCommand ("edicts", ED_PrintEdicts);
1639 Cmd_AddCommand ("edictcount", ED_Count);
1640 Cmd_AddCommand ("edictset", ED_EdictSet_f);
1641 Cmd_AddCommand ("profile", PR_Profile_f);
1642 Cmd_AddCommand ("pr_fields", PR_Fields_f);
1643 Cmd_AddCommand ("pr_globals", PR_Globals_f);
1644 Cvar_RegisterVariable (&pr_checkextension);
1645 Cvar_RegisterVariable (&nomonsters);
1646 Cvar_RegisterVariable (&gamecfg);
1647 Cvar_RegisterVariable (&scratch1);
1648 Cvar_RegisterVariable (&scratch2);
1649 Cvar_RegisterVariable (&scratch3);
1650 Cvar_RegisterVariable (&scratch4);
1651 Cvar_RegisterVariable (&savedgamecfg);
1652 Cvar_RegisterVariable (&saved1);
1653 Cvar_RegisterVariable (&saved2);
1654 Cvar_RegisterVariable (&saved3);
1655 Cvar_RegisterVariable (&saved4);
1656 // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1657 Cvar_RegisterVariable (&decors);
1658 // LordHavoc: Nehahra uses these to pass data around cutscene demos
1659 if (gamemode == GAME_NEHAHRA)
1661 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1662 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1663 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1664 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1665 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1666 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1667 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1668 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1669 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1670 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1672 Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1673 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1674 Cvar_RegisterVariable (&pr_boundscheck);
1675 Cvar_RegisterVariable (&pr_traceqc);
1677 progs_mempool = Mem_AllocPool("progs.dat", 0, NULL);
1678 edictstring_mempool = Mem_AllocPool("edict strings", 0, NULL);
1688 extern void PR_Cmd_Shutdown(void);
1689 void PR_Shutdown (void)
1693 Mem_FreePool(&edictstring_mempool);
1694 Mem_FreePool(&progs_mempool);
1697 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1698 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
1700 Host_Error ("EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
1705 int NUM_FOR_EDICT_ERROR(edict_t *e)
1707 Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
1711 int NUM_FOR_EDICT(edict_t *e)
1715 if ((unsigned int)n >= MAX_EDICTS)
1716 Host_Error ("NUM_FOR_EDICT: bad pointer");
1720 //int NoCrash_NUM_FOR_EDICT(edict_t *e)
1722 // return e - sv.edicts;
1725 //#define EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
1726 //#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
1727 int EDICT_TO_PROG(edict_t *e)
1731 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1732 Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
1733 return n;// EXPERIMENTAL
1734 //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
1736 edict_t *PROG_TO_EDICT(int n)
1738 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1739 Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
1740 return sv.edicts + n; // EXPERIMENTAL
1741 //return sv.edicts + ((n) / (progs->entityfields * 4));