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;
238 // NEXUIZ_PLAYERMODEL and NEXUIZ_PLAYERSKIN
239 e->v->playermodel = PR_SetString(svs.clients[num].playermodel);
240 e->v->playerskin = PR_SetString(svs.clients[num].playerskin);
248 Either finds a free edict, or allocates a new one.
249 Try to avoid reusing an entity that was recently freed, because it
250 can cause the client to think the entity morphed into something else
251 instead of being removed and recreated, which can cause interpolated
252 angles and bad trails.
255 edict_t *ED_Alloc (void)
260 for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
263 // the first couple seconds of server time can involve a lot of
264 // freeing and allocating, so relax the replacement policy
265 if (e->e->free && ( e->e->freetime < 2 || sv.time - e->e->freetime > 0.5 ) )
273 Host_Error ("ED_Alloc: no free edicts");
276 if (sv.num_edicts >= sv.max_edicts)
288 Marks the edict as free
289 FIXME: walk all entities and NULL out references to this entity
292 void ED_Free (edict_t *ed)
294 SV_UnlinkEdict (ed); // unlink from world bsp
298 ed->v->takedamage = 0;
299 ed->v->modelindex = 0;
303 VectorClear(ed->v->origin);
304 VectorClear(ed->v->angles);
305 ed->v->nextthink = -1;
308 ed->e->freetime = sv.time;
311 //===========================================================================
318 ddef_t *ED_GlobalAtOfs (int ofs)
323 for (i=0 ; i<progs->numglobaldefs ; i++)
325 def = &pr_globaldefs[i];
337 ddef_t *ED_FieldAtOfs (int ofs)
342 for (i=0 ; i<progs->numfielddefs ; i++)
344 def = &pr_fielddefs[i];
356 ddef_t *ED_FindField (const char *name)
361 for (i=0 ; i<progs->numfielddefs ; i++)
363 def = &pr_fielddefs[i];
364 if (!strcmp(PR_GetString(def->s_name), name))
375 ddef_t *ED_FindGlobal (const char *name)
380 for (i=0 ; i<progs->numglobaldefs ; i++)
382 def = &pr_globaldefs[i];
383 if (!strcmp(PR_GetString(def->s_name), name))
395 mfunction_t *ED_FindFunction (const char *name)
400 for (i=0 ; i<progs->numfunctions ; i++)
402 func = &pr_functions[i];
403 if (!strcmp(PR_GetString(func->s_name), name))
414 Returns a string describing *data in a type specific manner
417 //int NoCrash_NUM_FOR_EDICT(edict_t *e);
418 char *PR_ValueString (etype_t type, eval_t *val)
420 static char line[1024]; // LordHavoc: enlarged a bit (was 256)
425 type &= ~DEF_SAVEGLOBAL;
430 strlcpy (line, PR_GetString (val->string), sizeof (line));
433 //n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict));
435 if (n < 0 || n >= MAX_EDICTS)
436 snprintf (line, sizeof (line), "entity %i (invalid!)", n);
438 snprintf (line, sizeof (line), "entity %i", n);
441 f = pr_functions + val->function;
442 snprintf (line, sizeof (line), "%s()", PR_GetString(f->s_name));
445 def = ED_FieldAtOfs ( val->_int );
446 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
449 snprintf (line, sizeof (line), "void");
452 // LordHavoc: changed from %5.1f to %10.4f
453 snprintf (line, sizeof (line), "%10.4f", val->_float);
456 // LordHavoc: changed from %5.1f to %10.4f
457 snprintf (line, sizeof (line), "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
460 snprintf (line, sizeof (line), "pointer");
463 snprintf (line, sizeof (line), "bad type %i", type);
474 Returns a string describing *data in a type specific manner
475 Easier to parse than PR_ValueString
478 char *PR_UglyValueString (etype_t type, eval_t *val)
480 static char line[4096];
486 type &= ~DEF_SAVEGLOBAL;
491 // Parse the string a bit to turn special characters
492 // (like newline, specifically) into escape codes,
493 // this fixes saving games from various mods
494 s = PR_GetString (val->string);
495 for (i = 0;i < (int)sizeof(line) - 2 && *s;)
514 snprintf (line, sizeof (line), "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
517 f = pr_functions + val->function;
518 strlcpy (line, PR_GetString (f->s_name), sizeof (line));
521 def = ED_FieldAtOfs ( val->_int );
522 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
525 snprintf (line, sizeof (line), "void");
528 snprintf (line, sizeof (line), "%f", val->_float);
531 snprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
534 snprintf (line, sizeof (line), "bad type %i", type);
545 Returns a string with a description and the contents of a global,
546 padded to 20 field width
549 char *PR_GlobalString (int ofs)
555 static char line[128];
557 val = (void *)&pr_globals[ofs];
558 def = ED_GlobalAtOfs(ofs);
560 snprintf (line, sizeof (line), "%i(?)", ofs);
563 s = PR_ValueString (def->type, val);
564 snprintf (line, sizeof (line), "%i(%s)%s", ofs, PR_GetString(def->s_name), s);
569 strlcat (line, " ", sizeof (line));
570 strlcat (line, " ", sizeof (line));
575 char *PR_GlobalStringNoContents (int ofs)
579 static char line[128];
581 def = ED_GlobalAtOfs(ofs);
583 snprintf (line, sizeof (line), "%i(?)", ofs);
585 snprintf (line, sizeof (line), "%i(%s)", ofs, PR_GetString(def->s_name));
589 strlcat (line, " ", sizeof (line));
590 strlcat (line, " ", sizeof (line));
603 // LordHavoc: optimized this to print out much more quickly (tempstring)
604 // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
605 void ED_Print(edict_t *ed)
613 char tempstring[8192], tempstring2[260]; // temporary string buffers
622 snprintf (tempstring, sizeof (tempstring), "\nEDICT %i:\n", NUM_FOR_EDICT(ed));
623 for (i=1 ; i<progs->numfielddefs ; i++)
625 d = &pr_fielddefs[i];
626 name = PR_GetString(d->s_name);
627 if (name[strlen(name)-2] == '_')
628 continue; // skip _x, _y, _z vars
630 v = (int *)((char *)ed->v + d->ofs*4);
632 // if the value is still all 0, skip the field
633 type = d->type & ~DEF_SAVEGLOBAL;
635 for (j=0 ; j<type_size[type] ; j++)
638 if (j == type_size[type])
641 if (strlen(name) > 256)
643 memcpy (tempstring2, name, 256);
644 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
645 tempstring2[259] = 0;
648 strlcat (tempstring, name, sizeof (tempstring));
649 for (l = strlen(name);l < 14;l++)
650 strcat(tempstring, " ");
651 strcat(tempstring, " ");
653 name = PR_ValueString(d->type, (eval_t *)v);
654 if (strlen(name) > 256)
656 memcpy(tempstring2, name, 256);
657 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
658 tempstring2[259] = 0;
661 strlcat (tempstring, name, sizeof (tempstring));
662 strlcat (tempstring, "\n", sizeof (tempstring));
663 if (strlen(tempstring) >= 4096)
665 Con_Print(tempstring);
670 Con_Print(tempstring);
680 void ED_Write (qfile_t *f, edict_t *ed)
696 for (i=1 ; i<progs->numfielddefs ; i++)
698 d = &pr_fielddefs[i];
699 name = PR_GetString(d->s_name);
700 if (name[strlen(name)-2] == '_')
701 continue; // skip _x, _y, _z vars
703 v = (int *)((char *)ed->v + d->ofs*4);
705 // if the value is still all 0, skip the field
706 type = d->type & ~DEF_SAVEGLOBAL;
707 for (j=0 ; j<type_size[type] ; j++)
710 if (j == type_size[type])
713 FS_Printf(f,"\"%s\" ",name);
714 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
720 void ED_PrintNum (int ent)
722 ED_Print(EDICT_NUM(ent));
729 For debugging, prints all the entities in the current server
732 void ED_PrintEdicts (void)
736 Con_Printf("%i entities\n", sv.num_edicts);
737 for (i=0 ; i<sv.num_edicts ; i++)
745 For debugging, prints a single edict
748 void ED_PrintEdict_f (void)
752 i = atoi (Cmd_Argv(1));
753 if (i < 0 || i >= sv.num_edicts)
755 Con_Print("Bad edict number\n");
772 int active, models, solid, step;
774 active = models = solid = step = 0;
775 for (i=0 ; i<sv.num_edicts ; i++)
785 if (ent->v->movetype == MOVETYPE_STEP)
789 Con_Printf("num_edicts:%3i\n", sv.num_edicts);
790 Con_Printf("active :%3i\n", active);
791 Con_Printf("view :%3i\n", models);
792 Con_Printf("touch :%3i\n", solid);
793 Con_Printf("step :%3i\n", step);
798 ==============================================================================
802 FIXME: need to tag constants, doesn't really work
803 ==============================================================================
811 void ED_WriteGlobals (qfile_t *f)
819 for (i=0 ; i<progs->numglobaldefs ; i++)
821 def = &pr_globaldefs[i];
823 if ( !(def->type & DEF_SAVEGLOBAL) )
825 type &= ~DEF_SAVEGLOBAL;
827 if (type != ev_string && type != ev_float && type != ev_entity)
830 name = PR_GetString(def->s_name);
831 FS_Printf(f,"\"%s\" ", name);
832 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
841 Console command to set a field of a specified edict
844 void ED_EdictSet_f(void)
851 Con_Print("edictset <edict number> <field> <value>\n");
854 ed = EDICT_NUM(atoi(Cmd_Argv(1)));
856 if((key = ED_FindField(Cmd_Argv(2))) == 0)
858 Con_Printf("Key %s not found !\n", Cmd_Argv(2));
862 ED_ParseEpair(ed, key, Cmd_Argv(3));
870 void ED_ParseGlobals (const char *data)
872 char keyname[1024]; // LordHavoc: good idea? bad idea? was 64
878 if (!COM_ParseToken(&data, false))
879 Host_Error ("ED_ParseEntity: EOF without closing brace");
880 if (com_token[0] == '}')
883 strcpy (keyname, com_token);
886 if (!COM_ParseToken(&data, false))
887 Host_Error ("ED_ParseEntity: EOF without closing brace");
889 if (com_token[0] == '}')
890 Host_Error ("ED_ParseEntity: closing brace without data");
892 key = ED_FindGlobal (keyname);
895 Con_DPrintf("'%s' is not a global\n", keyname);
899 if (!ED_ParseEpair(NULL, key, com_token))
900 Host_Error ("ED_ParseGlobals: parse error");
904 //============================================================================
912 char *ED_NewString (const char *string)
917 l = strlen(string) + 1;
918 new = Mem_Alloc(edictstring_mempool, l);
921 for (i=0 ; i< l ; i++)
923 if (string[i] == '\\' && i < l-1)
926 if (string[i] == 'n')
932 *new_p++ = string[i];
943 Can parse either fields or globals
944 returns false if error
947 qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
955 val = (eval_t *)((int *)ent->v + key->ofs);
957 val = (eval_t *)((int *)pr_globals + key->ofs);
958 switch (key->type & ~DEF_SAVEGLOBAL)
961 val->string = PR_SetString(ED_NewString(s));
965 while (*s && *s <= ' ')
967 val->_float = atof(s);
971 for (i = 0;i < 3;i++)
973 while (*s && *s <= ' ')
976 val->vector[i] = atof(s);
985 while (*s && *s <= ' ')
988 if (i < 0 || i >= MAX_EDICTS)
989 Con_Printf("ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i)\n", i, MAX_EDICTS);
990 while (i >= sv.max_edicts)
992 // if SV_IncreaseEdicts was called the base pointer needs to be updated
994 val = (eval_t *)((int *)ent->v + key->ofs);
995 val->edict = EDICT_TO_PROG(EDICT_NUM(i));
999 def = ED_FindField(s);
1002 Con_DPrintf("ED_ParseEpair: Can't find field %s\n", s);
1005 //val->_int = G_INT(def->ofs); AK Please check this - seems to be an org. quake bug
1006 val->_int = def->ofs;
1010 func = ED_FindFunction(s);
1013 Con_Printf("ED_ParseEpair: Can't find function %s\n", s);
1016 val->function = func - pr_functions;
1020 Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PR_GetString(key->s_name));
1027 ====================
1030 Parses an edict out of the given string, returning the new position
1031 ed should be a properly initialized empty edict.
1032 Used for initial level load and for savegames.
1033 ====================
1035 const char *ED_ParseEdict (const char *data, edict_t *ent)
1046 if (ent != sv.edicts) // hack
1047 memset (ent->v, 0, progs->entityfields * 4);
1049 // go through all the dictionary pairs
1053 if (!COM_ParseToken(&data, false))
1054 Host_Error ("ED_ParseEntity: EOF without closing brace");
1055 if (com_token[0] == '}')
1058 // anglehack is to allow QuakeEd to write single scalar angles
1059 // and allow them to be turned into vectors. (FIXME...)
1060 anglehack = !strcmp (com_token, "angle");
1062 strlcpy (com_token, "angles", sizeof (com_token));
1064 // FIXME: change light to _light to get rid of this hack
1065 if (!strcmp(com_token, "light"))
1066 strlcpy (com_token, "light_lev", sizeof (com_token)); // hack for single light def
1068 strlcpy (keyname, com_token, sizeof (keyname));
1070 // another hack to fix heynames with trailing spaces
1071 n = strlen(keyname);
1072 while (n && keyname[n-1] == ' ')
1079 if (!COM_ParseToken(&data, false))
1080 Host_Error ("ED_ParseEntity: EOF without closing brace");
1082 if (com_token[0] == '}')
1083 Host_Error ("ED_ParseEntity: closing brace without data");
1087 // keynames with a leading underscore are used for utility comments,
1088 // and are immediately discarded by quake
1089 if (keyname[0] == '_')
1092 key = ED_FindField (keyname);
1095 Con_DPrintf("'%s' is not a field\n", keyname);
1102 strlcpy (temp, com_token, sizeof (temp));
1103 snprintf (com_token, sizeof (com_token), "0 %s 0", temp);
1106 if (!ED_ParseEpair(ent, key, com_token))
1107 Host_Error ("ED_ParseEdict: parse error");
1111 ent->e->free = true;
1121 The entities are directly placed in the array, rather than allocated with
1122 ED_Alloc, because otherwise an error loading the map would have entity
1123 number references out of order.
1125 Creates a server's entity / program execution context by
1126 parsing textual entity definitions out of an ent file.
1128 Used for both fresh maps and savegame loads. A fresh map would also need
1129 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1132 void ED_LoadFromFile (const char *data)
1135 int parsed, inhibited, spawned, died;
1143 pr_global_struct->time = sv.time;
1148 // parse the opening brace
1149 if (!COM_ParseToken(&data, false))
1151 if (com_token[0] != '{')
1152 Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
1158 data = ED_ParseEdict (data, ent);
1161 // remove things from different skill levels or deathmatch
1162 if (deathmatch.integer)
1164 if (((int)ent->v->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
1171 else if ((current_skill == 0 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_EASY ))
1172 || (current_skill == 1 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_MEDIUM))
1173 || (current_skill >= 2 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_HARD )))
1181 // immediately call spawn function
1183 if (!ent->v->classname)
1185 Con_Print("No classname for:\n");
1191 // look for the spawn function
1192 func = ED_FindFunction (PR_GetString(ent->v->classname));
1196 if (developer.integer) // don't confuse non-developers with errors
1198 Con_Print("No spawn function for:\n");
1205 pr_global_struct->self = EDICT_TO_PROG(ent);
1206 PR_ExecuteProgram (func - pr_functions, "QC function spawn is missing");
1212 Con_DPrintf("%i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", parsed, inhibited, spawned, died, spawned - died);
1216 typedef struct dpfield_s
1223 #define DPFIELDS (sizeof(dpfields) / sizeof(dpfield_t))
1225 dpfield_t dpfields[] =
1227 {ev_entity, "cursor_trace_ent"},
1228 {ev_entity, "drawonlytoclient"},
1229 {ev_entity, "exteriormodeltoclient"},
1230 {ev_entity, "nodrawtoclient"},
1231 {ev_entity, "tag_entity"},
1232 {ev_entity, "viewmodelforclient"},
1233 {ev_float, "alpha"},
1234 {ev_float, "ammo_cells1"},
1235 {ev_float, "ammo_lava_nails"},
1236 {ev_float, "ammo_multi_rockets"},
1237 {ev_float, "ammo_nails1"},
1238 {ev_float, "ammo_plasma"},
1239 {ev_float, "ammo_rockets1"},
1240 {ev_float, "ammo_shells1"},
1241 {ev_float, "button3"},
1242 {ev_float, "button4"},
1243 {ev_float, "button5"},
1244 {ev_float, "button6"},
1245 {ev_float, "button7"},
1246 {ev_float, "button8"},
1247 {ev_float, "buttonchat"},
1248 {ev_float, "buttonuse"},
1249 {ev_float, "clientcolors"},
1250 {ev_float, "cursor_active"},
1251 {ev_float, "fullbright"},
1252 {ev_float, "glow_color"},
1253 {ev_float, "glow_size"},
1254 {ev_float, "glow_trail"},
1255 {ev_float, "gravity"},
1256 {ev_float, "idealpitch"},
1257 {ev_float, "items2"},
1258 {ev_float, "light_lev"},
1259 {ev_float, "pflags"},
1261 {ev_float, "pitch_speed"},
1262 {ev_float, "pmodel"},
1263 {ev_float, "renderamt"}, // HalfLife support
1264 {ev_float, "rendermode"}, // HalfLife support
1265 {ev_float, "scale"},
1266 {ev_float, "style"},
1267 {ev_float, "tag_index"},
1268 {ev_float, "viewzoom"},
1269 {ev_vector, "color"},
1270 {ev_vector, "colormod"},
1271 {ev_vector, "cursor_screen"},
1272 {ev_vector, "cursor_trace_endpos"},
1273 {ev_vector, "cursor_trace_start"},
1274 {ev_vector, "movement"},
1275 {ev_vector, "punchvector"},
1276 {ev_string, "playermodel"},
1277 {ev_string, "playerskin"}
1285 extern void PR_Cmd_Reset (void);
1286 void PR_LoadProgs (void)
1290 ddef_t *infielddefs;
1291 dfunction_t *dfunctions;
1293 // flush the non-C variable lookup cache
1294 for (i=0 ; i<GEFV_CACHESIZE ; i++)
1295 gefvCache[i].field[0] = 0;
1297 Mem_EmptyPool(progs_mempool);
1298 Mem_EmptyPool(edictstring_mempool);
1300 progs = (dprograms_t *)FS_LoadFile ("progs.dat", progs_mempool, false);
1302 Host_Error ("PR_LoadProgs: couldn't load progs.dat");
1304 Con_DPrintf("Programs occupy %iK.\n", fs_filesize/1024);
1306 pr_crc = CRC_Block((qbyte *)progs, fs_filesize);
1308 // byte swap the header
1309 for (i = 0;i < (int) sizeof(*progs) / 4;i++)
1310 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1312 if (progs->version != PROG_VERSION)
1313 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1314 if (progs->crc != PROGHEADER_CRC && progs->crc != 32401) // tenebrae crc also allowed
1315 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1317 //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1318 dfunctions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1319 pr_strings = (char *)progs + progs->ofs_strings;
1320 pr_globaldefs = (ddef_t *)((qbyte *)progs + progs->ofs_globaldefs);
1322 // we need to expand the fielddefs list to include all the engine fields,
1323 // so allocate a new place for it
1324 infielddefs = (ddef_t *)((qbyte *)progs + progs->ofs_fielddefs);
1325 pr_fielddefs = Mem_Alloc(progs_mempool, (progs->numfielddefs + DPFIELDS) * sizeof(ddef_t));
1327 pr_statements = (dstatement_t *)((qbyte *)progs + progs->ofs_statements);
1329 // moved edict_size calculation down below field adding code
1331 pr_global_struct = (globalvars_t *)((qbyte *)progs + progs->ofs_globals);
1332 pr_globals = (float *)pr_global_struct;
1334 // byte swap the lumps
1335 for (i=0 ; i<progs->numstatements ; i++)
1337 pr_statements[i].op = LittleShort(pr_statements[i].op);
1338 pr_statements[i].a = LittleShort(pr_statements[i].a);
1339 pr_statements[i].b = LittleShort(pr_statements[i].b);
1340 pr_statements[i].c = LittleShort(pr_statements[i].c);
1343 pr_functions = Mem_Alloc(progs_mempool, sizeof(mfunction_t) * progs->numfunctions);
1344 for (i = 0;i < progs->numfunctions;i++)
1346 pr_functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
1347 pr_functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
1348 pr_functions[i].s_name = LittleLong (dfunctions[i].s_name);
1349 pr_functions[i].s_file = LittleLong (dfunctions[i].s_file);
1350 pr_functions[i].numparms = LittleLong (dfunctions[i].numparms);
1351 pr_functions[i].locals = LittleLong (dfunctions[i].locals);
1352 memcpy(pr_functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
1355 for (i=0 ; i<progs->numglobaldefs ; i++)
1357 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1358 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1359 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1362 // copy the progs fields to the new fields list
1363 for (i = 0;i < progs->numfielddefs;i++)
1365 pr_fielddefs[i].type = LittleShort (infielddefs[i].type);
1366 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1367 Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1368 pr_fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
1369 pr_fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
1372 // append the darkplaces fields
1373 for (i = 0;i < (int) DPFIELDS;i++)
1375 pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
1376 pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
1377 pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string);
1378 if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
1379 progs->entityfields += 3;
1381 progs->entityfields++;
1382 progs->numfielddefs++;
1385 for (i=0 ; i<progs->numglobals ; i++)
1386 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1388 // moved edict_size calculation down here, below field adding code
1389 // LordHavoc: this no longer includes the edict_t header
1390 pr_edict_size = progs->entityfields * 4;
1391 pr_edictareasize = pr_edict_size * MAX_EDICTS;
1393 // LordHavoc: bounds check anything static
1394 for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1400 if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1401 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1404 if (st->a + i < 0 || st->a + i >= progs->numstatements)
1405 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1407 // global global global
1442 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1443 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1445 // global none global
1451 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1452 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1468 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1469 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1483 if ((unsigned short) st->a >= progs->numglobals)
1484 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1487 Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1492 FindEdictFieldOffsets(); // LordHavoc: update field offset list
1493 PR_Execute_ProgsLoaded();
1498 void PR_Fields_f (void)
1500 int i, j, ednum, used, usedamount;
1502 char tempstring[5000], tempstring2[260], *name;
1508 Con_Print("no progs loaded\n");
1511 counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
1512 for (ednum = 0;ednum < sv.max_edicts;ednum++)
1514 ed = EDICT_NUM(ednum);
1517 for (i = 1;i < progs->numfielddefs;i++)
1519 d = &pr_fielddefs[i];
1520 name = PR_GetString(d->s_name);
1521 if (name[strlen(name)-2] == '_')
1522 continue; // skip _x, _y, _z vars
1523 v = (int *)((char *)ed->v + d->ofs*4);
1524 // if the value is still all 0, skip the field
1525 for (j = 0;j < type_size[d->type & ~DEF_SAVEGLOBAL];j++)
1538 for (i = 0;i < progs->numfielddefs;i++)
1540 d = &pr_fielddefs[i];
1541 name = PR_GetString(d->s_name);
1542 if (name[strlen(name)-2] == '_')
1543 continue; // skip _x, _y, _z vars
1544 switch(d->type & ~DEF_SAVEGLOBAL)
1547 strlcat (tempstring, "string ", sizeof (tempstring));
1550 strlcat (tempstring, "entity ", sizeof (tempstring));
1553 strlcat (tempstring, "function ", sizeof (tempstring));
1556 strlcat (tempstring, "field ", sizeof (tempstring));
1559 strlcat (tempstring, "void ", sizeof (tempstring));
1562 strlcat (tempstring, "float ", sizeof (tempstring));
1565 strlcat (tempstring, "vector ", sizeof (tempstring));
1568 strlcat (tempstring, "pointer ", sizeof (tempstring));
1571 snprintf (tempstring2, sizeof (tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
1572 strlcat (tempstring, tempstring2, sizeof (tempstring));
1575 if (strlen(name) > 256)
1577 memcpy(tempstring2, name, 256);
1578 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
1579 tempstring2[259] = 0;
1582 strcat (tempstring, name);
1583 for (j = strlen(name);j < 25;j++)
1584 strcat(tempstring, " ");
1585 snprintf (tempstring2, sizeof (tempstring2), "%5d", counts[i]);
1586 strlcat (tempstring, tempstring2, sizeof (tempstring));
1587 strlcat (tempstring, "\n", sizeof (tempstring));
1588 if (strlen(tempstring) >= 4096)
1590 Con_Print(tempstring);
1596 usedamount += type_size[d->type & ~DEF_SAVEGLOBAL];
1600 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);
1603 void PR_Globals_f (void)
1608 Con_Print("no progs loaded\n");
1611 for (i = 0;i < progs->numglobaldefs;i++)
1612 Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name));
1613 Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
1621 extern void PR_Cmd_Init(void);
1624 Cmd_AddCommand ("edict", ED_PrintEdict_f);
1625 Cmd_AddCommand ("edicts", ED_PrintEdicts);
1626 Cmd_AddCommand ("edictcount", ED_Count);
1627 Cmd_AddCommand ("edictset", ED_EdictSet_f);
1628 Cmd_AddCommand ("profile", PR_Profile_f);
1629 Cmd_AddCommand ("pr_fields", PR_Fields_f);
1630 Cmd_AddCommand ("pr_globals", PR_Globals_f);
1631 Cvar_RegisterVariable (&pr_checkextension);
1632 Cvar_RegisterVariable (&nomonsters);
1633 Cvar_RegisterVariable (&gamecfg);
1634 Cvar_RegisterVariable (&scratch1);
1635 Cvar_RegisterVariable (&scratch2);
1636 Cvar_RegisterVariable (&scratch3);
1637 Cvar_RegisterVariable (&scratch4);
1638 Cvar_RegisterVariable (&savedgamecfg);
1639 Cvar_RegisterVariable (&saved1);
1640 Cvar_RegisterVariable (&saved2);
1641 Cvar_RegisterVariable (&saved3);
1642 Cvar_RegisterVariable (&saved4);
1643 // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1644 Cvar_RegisterVariable (&decors);
1645 // LordHavoc: Nehahra uses these to pass data around cutscene demos
1646 if (gamemode == GAME_NEHAHRA)
1648 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1649 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1650 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1651 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1652 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1653 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1654 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1655 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1656 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1657 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1659 Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1660 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1661 Cvar_RegisterVariable (&pr_boundscheck);
1662 Cvar_RegisterVariable (&pr_traceqc);
1664 progs_mempool = Mem_AllocPool("progs.dat", 0, NULL);
1665 edictstring_mempool = Mem_AllocPool("edict strings", 0, NULL);
1670 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1671 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
1673 Host_Error ("EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
1678 int NUM_FOR_EDICT_ERROR(edict_t *e)
1680 Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
1684 int NUM_FOR_EDICT(edict_t *e)
1688 if ((unsigned int)n >= MAX_EDICTS)
1689 Host_Error ("NUM_FOR_EDICT: bad pointer");
1693 //int NoCrash_NUM_FOR_EDICT(edict_t *e)
1695 // return e - sv.edicts;
1698 //#define EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
1699 //#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
1700 int EDICT_TO_PROG(edict_t *e)
1704 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1705 Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
1706 return n;// EXPERIMENTAL
1707 //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
1709 edict_t *PROG_TO_EDICT(int n)
1711 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1712 Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
1713 return sv.edicts + n; // EXPERIMENTAL
1714 //return sv.edicts + ((n) / (progs->entityfields * 4));