2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 // sv_edict.c -- entity dictionary
25 mfunction_t *pr_functions;
28 ddef_t *pr_globaldefs;
29 dstatement_t *pr_statements;
30 globalvars_t *pr_global_struct;
31 float *pr_globals; // same as pr_global_struct
32 int pr_edict_size; // in bytes
33 int pr_edictareasize; // LordHavoc: in bytes
35 unsigned short pr_crc;
37 mempool_t *progs_mempool;
38 mempool_t *edictstring_mempool;
40 int type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
42 ddef_t *ED_FieldAtOfs(int ofs);
43 qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s);
45 cvar_t pr_checkextension = {CVAR_READONLY, "pr_checkextension", "1"};
46 cvar_t nomonsters = {0, "nomonsters", "0"};
47 cvar_t gamecfg = {0, "gamecfg", "0"};
48 cvar_t scratch1 = {0, "scratch1", "0"};
49 cvar_t scratch2 = {0,"scratch2", "0"};
50 cvar_t scratch3 = {0, "scratch3", "0"};
51 cvar_t scratch4 = {0, "scratch4", "0"};
52 cvar_t savedgamecfg = {CVAR_SAVE, "savedgamecfg", "0"};
53 cvar_t saved1 = {CVAR_SAVE, "saved1", "0"};
54 cvar_t saved2 = {CVAR_SAVE, "saved2", "0"};
55 cvar_t saved3 = {CVAR_SAVE, "saved3", "0"};
56 cvar_t saved4 = {CVAR_SAVE, "saved4", "0"};
57 cvar_t decors = {0, "decors", "0"};
58 cvar_t nehx00 = {0, "nehx00", "0"};cvar_t nehx01 = {0, "nehx01", "0"};
59 cvar_t nehx02 = {0, "nehx02", "0"};cvar_t nehx03 = {0, "nehx03", "0"};
60 cvar_t nehx04 = {0, "nehx04", "0"};cvar_t nehx05 = {0, "nehx05", "0"};
61 cvar_t nehx06 = {0, "nehx06", "0"};cvar_t nehx07 = {0, "nehx07", "0"};
62 cvar_t nehx08 = {0, "nehx08", "0"};cvar_t nehx09 = {0, "nehx09", "0"};
63 cvar_t nehx10 = {0, "nehx10", "0"};cvar_t nehx11 = {0, "nehx11", "0"};
64 cvar_t nehx12 = {0, "nehx12", "0"};cvar_t nehx13 = {0, "nehx13", "0"};
65 cvar_t nehx14 = {0, "nehx14", "0"};cvar_t nehx15 = {0, "nehx15", "0"};
66 cvar_t nehx16 = {0, "nehx16", "0"};cvar_t nehx17 = {0, "nehx17", "0"};
67 cvar_t nehx18 = {0, "nehx18", "0"};cvar_t nehx19 = {0, "nehx19", "0"};
68 cvar_t cutscene = {0, "cutscene", "1"};
69 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
70 cvar_t pr_boundscheck = {0, "pr_boundscheck", "1"};
71 // LordHavoc: prints every opcode as it executes - warning: this is significant spew
72 cvar_t pr_traceqc = {0, "pr_traceqc", "0"};
74 #define MAX_FIELD_LEN 64
75 #define GEFV_CACHESIZE 2
79 char field[MAX_FIELD_LEN];
82 static gefv_cache gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
84 ddef_t *ED_FindField (const char *name);
85 mfunction_t *ED_FindFunction (const char *name);
87 // LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue... these are defined as externs in progs.h
101 int eval_renderamt; // HalfLife support
102 int eval_rendermode; // HalfLife support
104 int eval_ammo_shells1;
105 int eval_ammo_nails1;
106 int eval_ammo_lava_nails;
107 int eval_ammo_rockets1;
108 int eval_ammo_multi_rockets;
109 int eval_ammo_cells1;
110 int eval_ammo_plasma;
112 int eval_pitch_speed;
113 int eval_viewmodelforclient;
114 int eval_nodrawtoclient;
115 int eval_exteriormodeltoclient;
116 int eval_drawonlytoclient;
120 int eval_punchvector;
122 int eval_clientcolors;
130 mfunction_t *SV_PlayerPhysicsQC;
131 mfunction_t *EndFrameQC;
132 //KrimZon - SERVER COMMANDS IN QUAKEC
133 mfunction_t *SV_ParseClientCommandQC;
135 int FindFieldOffset(const char *field)
138 d = ED_FindField(field);
144 void FindEdictFieldOffsets(void)
146 eval_gravity = FindFieldOffset("gravity");
147 eval_button3 = FindFieldOffset("button3");
148 eval_button4 = FindFieldOffset("button4");
149 eval_button5 = FindFieldOffset("button5");
150 eval_button6 = FindFieldOffset("button6");
151 eval_button7 = FindFieldOffset("button7");
152 eval_button8 = FindFieldOffset("button8");
153 eval_glow_size = FindFieldOffset("glow_size");
154 eval_glow_trail = FindFieldOffset("glow_trail");
155 eval_glow_color = FindFieldOffset("glow_color");
156 eval_items2 = FindFieldOffset("items2");
157 eval_scale = FindFieldOffset("scale");
158 eval_alpha = FindFieldOffset("alpha");
159 eval_renderamt = FindFieldOffset("renderamt"); // HalfLife support
160 eval_rendermode = FindFieldOffset("rendermode"); // HalfLife support
161 eval_fullbright = FindFieldOffset("fullbright");
162 eval_ammo_shells1 = FindFieldOffset("ammo_shells1");
163 eval_ammo_nails1 = FindFieldOffset("ammo_nails1");
164 eval_ammo_lava_nails = FindFieldOffset("ammo_lava_nails");
165 eval_ammo_rockets1 = FindFieldOffset("ammo_rockets1");
166 eval_ammo_multi_rockets = FindFieldOffset("ammo_multi_rockets");
167 eval_ammo_cells1 = FindFieldOffset("ammo_cells1");
168 eval_ammo_plasma = FindFieldOffset("ammo_plasma");
169 eval_idealpitch = FindFieldOffset("idealpitch");
170 eval_pitch_speed = FindFieldOffset("pitch_speed");
171 eval_viewmodelforclient = FindFieldOffset("viewmodelforclient");
172 eval_nodrawtoclient = FindFieldOffset("nodrawtoclient");
173 eval_exteriormodeltoclient = FindFieldOffset("exteriormodeltoclient");
174 eval_drawonlytoclient = FindFieldOffset("drawonlytoclient");
175 eval_ping = FindFieldOffset("ping");
176 eval_movement = FindFieldOffset("movement");
177 eval_pmodel = FindFieldOffset("pmodel");
178 eval_punchvector = FindFieldOffset("punchvector");
179 eval_viewzoom = FindFieldOffset("viewzoom");
180 eval_clientcolors = FindFieldOffset("clientcolors");
181 eval_tag_entity = FindFieldOffset("tag_entity");
182 eval_tag_index = FindFieldOffset("tag_index");
183 eval_light_lev = FindFieldOffset("light_lev");
184 eval_color = FindFieldOffset("color");
185 eval_style = FindFieldOffset("style");
186 eval_pflags = FindFieldOffset("pflags");
188 // LordHavoc: allowing QuakeC to override the player movement code
189 SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
190 // LordHavoc: support for endframe
191 EndFrameQC = ED_FindFunction ("EndFrame");
192 //KrimZon - SERVER COMMANDS IN QUAKEC
193 SV_ParseClientCommandQC = ED_FindFunction ("SV_ParseClientCommand");
200 Sets everything to NULL
203 void ED_ClearEdict (edict_t *e)
206 memset (e->v, 0, progs->entityfields * 4);
208 // LordHavoc: for consistency set these here
209 num = NUM_FOR_EDICT(e) - 1;
210 if (num >= 0 && num < svs.maxclients)
212 e->v->colormap = num + 1;
213 e->v->team = (svs.clients[num].colors & 15) + 1;
214 e->v->netname = PR_SetString(svs.clients[num].name);
222 Either finds a free edict, or allocates a new one.
223 Try to avoid reusing an entity that was recently freed, because it
224 can cause the client to think the entity morphed into something else
225 instead of being removed and recreated, which can cause interpolated
226 angles and bad trails.
229 edict_t *ED_Alloc (void)
234 for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
237 // the first couple seconds of server time can involve a lot of
238 // freeing and allocating, so relax the replacement policy
239 if (e->e->free && ( e->e->freetime < 2 || sv.time - e->e->freetime > 0.5 ) )
247 Host_Error ("ED_Alloc: no free edicts");
250 if (sv.num_edicts >= sv.max_edicts)
262 Marks the edict as free
263 FIXME: walk all entities and NULL out references to this entity
266 void ED_Free (edict_t *ed)
268 SV_UnlinkEdict (ed); // unlink from world bsp
272 ed->v->takedamage = 0;
273 ed->v->modelindex = 0;
277 VectorClear(ed->v->origin);
278 VectorClear(ed->v->angles);
279 ed->v->nextthink = -1;
282 ed->e->freetime = sv.time;
285 //===========================================================================
292 ddef_t *ED_GlobalAtOfs (int ofs)
297 for (i=0 ; i<progs->numglobaldefs ; i++)
299 def = &pr_globaldefs[i];
311 ddef_t *ED_FieldAtOfs (int ofs)
316 for (i=0 ; i<progs->numfielddefs ; i++)
318 def = &pr_fielddefs[i];
330 ddef_t *ED_FindField (const char *name)
335 for (i=0 ; i<progs->numfielddefs ; i++)
337 def = &pr_fielddefs[i];
338 if (!strcmp(PR_GetString(def->s_name), name))
349 ddef_t *ED_FindGlobal (const char *name)
354 for (i=0 ; i<progs->numglobaldefs ; i++)
356 def = &pr_globaldefs[i];
357 if (!strcmp(PR_GetString(def->s_name), name))
369 mfunction_t *ED_FindFunction (const char *name)
374 for (i=0 ; i<progs->numfunctions ; i++)
376 func = &pr_functions[i];
377 if (!strcmp(PR_GetString(func->s_name), name))
388 Returns a string describing *data in a type specific manner
391 //int NoCrash_NUM_FOR_EDICT(edict_t *e);
392 char *PR_ValueString (etype_t type, eval_t *val)
394 static char line[1024]; // LordHavoc: enlarged a bit (was 256)
399 type &= ~DEF_SAVEGLOBAL;
404 strlcpy (line, PR_GetString (val->string), sizeof (line));
407 //n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict));
409 if (n < 0 || n >= MAX_EDICTS)
410 snprintf (line, sizeof (line), "entity %i (invalid!)", n);
412 snprintf (line, sizeof (line), "entity %i", n);
415 f = pr_functions + val->function;
416 snprintf (line, sizeof (line), "%s()", PR_GetString(f->s_name));
419 def = ED_FieldAtOfs ( val->_int );
420 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
423 snprintf (line, sizeof (line), "void");
426 // LordHavoc: changed from %5.1f to %10.4f
427 snprintf (line, sizeof (line), "%10.4f", val->_float);
430 // LordHavoc: changed from %5.1f to %10.4f
431 snprintf (line, sizeof (line), "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
434 snprintf (line, sizeof (line), "pointer");
437 snprintf (line, sizeof (line), "bad type %i", type);
448 Returns a string describing *data in a type specific manner
449 Easier to parse than PR_ValueString
452 char *PR_UglyValueString (etype_t type, eval_t *val)
454 static char line[4096];
460 type &= ~DEF_SAVEGLOBAL;
465 // Parse the string a bit to turn special characters
466 // (like newline, specifically) into escape codes,
467 // this fixes saving games from various mods
468 s = PR_GetString (val->string);
469 for (i = 0;i < (int)sizeof(line) - 2 && *s;)
488 snprintf (line, sizeof (line), "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
491 f = pr_functions + val->function;
492 strlcpy (line, PR_GetString (f->s_name), sizeof (line));
495 def = ED_FieldAtOfs ( val->_int );
496 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
499 snprintf (line, sizeof (line), "void");
502 snprintf (line, sizeof (line), "%f", val->_float);
505 snprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
508 snprintf (line, sizeof (line), "bad type %i", type);
519 Returns a string with a description and the contents of a global,
520 padded to 20 field width
523 char *PR_GlobalString (int ofs)
529 static char line[128];
531 val = (void *)&pr_globals[ofs];
532 def = ED_GlobalAtOfs(ofs);
534 snprintf (line, sizeof (line), "%i(?)", ofs);
537 s = PR_ValueString (def->type, val);
538 snprintf (line, sizeof (line), "%i(%s)%s", ofs, PR_GetString(def->s_name), s);
543 strlcat (line, " ", sizeof (line));
544 strlcat (line, " ", sizeof (line));
549 char *PR_GlobalStringNoContents (int ofs)
553 static char line[128];
555 def = ED_GlobalAtOfs(ofs);
557 snprintf (line, sizeof (line), "%i(?)", ofs);
559 snprintf (line, sizeof (line), "%i(%s)", ofs, PR_GetString(def->s_name));
563 strlcat (line, " ", sizeof (line));
564 strlcat (line, " ", sizeof (line));
577 // LordHavoc: optimized this to print out much more quickly (tempstring)
578 // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
579 void ED_Print(edict_t *ed)
587 char tempstring[8192], tempstring2[260]; // temporary string buffers
596 snprintf (tempstring, sizeof (tempstring), "\nEDICT %i:\n", NUM_FOR_EDICT(ed));
597 for (i=1 ; i<progs->numfielddefs ; i++)
599 d = &pr_fielddefs[i];
600 name = PR_GetString(d->s_name);
601 if (name[strlen(name)-2] == '_')
602 continue; // skip _x, _y, _z vars
604 v = (int *)((char *)ed->v + d->ofs*4);
606 // if the value is still all 0, skip the field
607 type = d->type & ~DEF_SAVEGLOBAL;
609 for (j=0 ; j<type_size[type] ; j++)
612 if (j == type_size[type])
615 if (strlen(name) > 256)
617 memcpy (tempstring2, name, 256);
618 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
619 tempstring2[259] = 0;
622 strlcat (tempstring, name, sizeof (tempstring));
623 for (l = strlen(name);l < 14;l++)
624 strcat(tempstring, " ");
625 strcat(tempstring, " ");
627 name = PR_ValueString(d->type, (eval_t *)v);
628 if (strlen(name) > 256)
630 memcpy(tempstring2, name, 256);
631 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
632 tempstring2[259] = 0;
635 strlcat (tempstring, name, sizeof (tempstring));
636 strlcat (tempstring, "\n", sizeof (tempstring));
637 if (strlen(tempstring) >= 4096)
639 Con_Print(tempstring);
644 Con_Print(tempstring);
654 void ED_Write (qfile_t *f, edict_t *ed)
670 for (i=1 ; i<progs->numfielddefs ; i++)
672 d = &pr_fielddefs[i];
673 name = PR_GetString(d->s_name);
674 if (name[strlen(name)-2] == '_')
675 continue; // skip _x, _y, _z vars
677 v = (int *)((char *)ed->v + d->ofs*4);
679 // if the value is still all 0, skip the field
680 type = d->type & ~DEF_SAVEGLOBAL;
681 for (j=0 ; j<type_size[type] ; j++)
684 if (j == type_size[type])
687 FS_Printf(f,"\"%s\" ",name);
688 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
694 void ED_PrintNum (int ent)
696 ED_Print(EDICT_NUM(ent));
703 For debugging, prints all the entities in the current server
706 void ED_PrintEdicts (void)
710 Con_Printf("%i entities\n", sv.num_edicts);
711 for (i=0 ; i<sv.num_edicts ; i++)
719 For debugging, prints a single edict
722 void ED_PrintEdict_f (void)
726 i = atoi (Cmd_Argv(1));
727 if (i < 0 || i >= sv.num_edicts)
729 Con_Print("Bad edict number\n");
746 int active, models, solid, step;
748 active = models = solid = step = 0;
749 for (i=0 ; i<sv.num_edicts ; i++)
759 if (ent->v->movetype == MOVETYPE_STEP)
763 Con_Printf("num_edicts:%3i\n", sv.num_edicts);
764 Con_Printf("active :%3i\n", active);
765 Con_Printf("view :%3i\n", models);
766 Con_Printf("touch :%3i\n", solid);
767 Con_Printf("step :%3i\n", step);
772 ==============================================================================
776 FIXME: need to tag constants, doesn't really work
777 ==============================================================================
785 void ED_WriteGlobals (qfile_t *f)
793 for (i=0 ; i<progs->numglobaldefs ; i++)
795 def = &pr_globaldefs[i];
797 if ( !(def->type & DEF_SAVEGLOBAL) )
799 type &= ~DEF_SAVEGLOBAL;
801 if (type != ev_string && type != ev_float && type != ev_entity)
804 name = PR_GetString(def->s_name);
805 FS_Printf(f,"\"%s\" ", name);
806 FS_Printf(f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
815 Console command to set a field of a specified edict
818 void ED_EdictSet_f(void)
825 Con_Print("edictset <edict number> <field> <value>\n");
828 ed = EDICT_NUM(atoi(Cmd_Argv(1)));
830 if((key = ED_FindField(Cmd_Argv(2))) == 0)
832 Con_Printf("Key %s not found !\n", Cmd_Argv(2));
836 ED_ParseEpair(ed, key, Cmd_Argv(3));
844 void ED_ParseGlobals (const char *data)
846 char keyname[1024]; // LordHavoc: good idea? bad idea? was 64
852 if (!COM_ParseToken(&data, false))
853 Host_Error ("ED_ParseEntity: EOF without closing brace");
854 if (com_token[0] == '}')
857 strcpy (keyname, com_token);
860 if (!COM_ParseToken(&data, false))
861 Host_Error ("ED_ParseEntity: EOF without closing brace");
863 if (com_token[0] == '}')
864 Host_Error ("ED_ParseEntity: closing brace without data");
866 key = ED_FindGlobal (keyname);
869 Con_DPrintf("'%s' is not a global\n", keyname);
873 if (!ED_ParseEpair(NULL, key, com_token))
874 Host_Error ("ED_ParseGlobals: parse error");
878 //============================================================================
886 char *ED_NewString (const char *string)
891 l = strlen(string) + 1;
892 new = Mem_Alloc(edictstring_mempool, l);
895 for (i=0 ; i< l ; i++)
897 if (string[i] == '\\' && i < l-1)
900 if (string[i] == 'n')
906 *new_p++ = string[i];
917 Can parse either fields or globals
918 returns false if error
921 qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
929 val = (eval_t *)((int *)ent->v + key->ofs);
931 val = (eval_t *)((int *)pr_globals + key->ofs);
932 switch (key->type & ~DEF_SAVEGLOBAL)
935 val->string = PR_SetString(ED_NewString(s));
939 while (*s && *s <= ' ')
941 val->_float = atof(s);
945 for (i = 0;i < 3;i++)
947 while (*s && *s <= ' ')
950 val->vector[i] = atof(s);
959 while (*s && *s <= ' ')
962 if (i < 0 || i >= MAX_EDICTS)
963 Con_Printf("ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i)\n", i, MAX_EDICTS);
964 while (i >= sv.max_edicts)
966 // if SV_IncreaseEdicts was called the base pointer needs to be updated
968 val = (eval_t *)((int *)ent->v + key->ofs);
969 val->edict = EDICT_TO_PROG(EDICT_NUM(i));
973 def = ED_FindField(s);
976 Con_DPrintf("ED_ParseEpair: Can't find field %s\n", s);
979 val->_int = G_INT(def->ofs);
983 func = ED_FindFunction(s);
986 Con_Printf("ED_ParseEpair: Can't find function %s\n", s);
989 val->function = func - pr_functions;
993 Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PR_GetString(key->s_name));
1000 ====================
1003 Parses an edict out of the given string, returning the new position
1004 ed should be a properly initialized empty edict.
1005 Used for initial level load and for savegames.
1006 ====================
1008 const char *ED_ParseEdict (const char *data, edict_t *ent)
1019 if (ent != sv.edicts) // hack
1020 memset (ent->v, 0, progs->entityfields * 4);
1022 // go through all the dictionary pairs
1026 if (!COM_ParseToken(&data, false))
1027 Host_Error ("ED_ParseEntity: EOF without closing brace");
1028 if (com_token[0] == '}')
1031 // anglehack is to allow QuakeEd to write single scalar angles
1032 // and allow them to be turned into vectors. (FIXME...)
1033 anglehack = !strcmp (com_token, "angle");
1035 strlcpy (com_token, "angles", sizeof (com_token));
1037 // FIXME: change light to _light to get rid of this hack
1038 if (!strcmp(com_token, "light"))
1039 strlcpy (com_token, "light_lev", sizeof (com_token)); // hack for single light def
1041 strlcpy (keyname, com_token, sizeof (keyname));
1043 // another hack to fix heynames with trailing spaces
1044 n = strlen(keyname);
1045 while (n && keyname[n-1] == ' ')
1052 if (!COM_ParseToken(&data, false))
1053 Host_Error ("ED_ParseEntity: EOF without closing brace");
1055 if (com_token[0] == '}')
1056 Host_Error ("ED_ParseEntity: closing brace without data");
1060 // keynames with a leading underscore are used for utility comments,
1061 // and are immediately discarded by quake
1062 if (keyname[0] == '_')
1065 key = ED_FindField (keyname);
1068 Con_DPrintf("'%s' is not a field\n", keyname);
1075 strlcpy (temp, com_token, sizeof (temp));
1076 snprintf (com_token, sizeof (com_token), "0 %s 0", temp);
1079 if (!ED_ParseEpair(ent, key, com_token))
1080 Host_Error ("ED_ParseEdict: parse error");
1084 ent->e->free = true;
1094 The entities are directly placed in the array, rather than allocated with
1095 ED_Alloc, because otherwise an error loading the map would have entity
1096 number references out of order.
1098 Creates a server's entity / program execution context by
1099 parsing textual entity definitions out of an ent file.
1101 Used for both fresh maps and savegame loads. A fresh map would also need
1102 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1105 void ED_LoadFromFile (const char *data)
1108 int parsed, inhibited, spawned, died;
1116 pr_global_struct->time = sv.time;
1121 // parse the opening brace
1122 if (!COM_ParseToken(&data, false))
1124 if (com_token[0] != '{')
1125 Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
1131 data = ED_ParseEdict (data, ent);
1134 // remove things from different skill levels or deathmatch
1135 if (deathmatch.integer)
1137 if (((int)ent->v->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
1144 else if ((current_skill == 0 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_EASY ))
1145 || (current_skill == 1 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_MEDIUM))
1146 || (current_skill >= 2 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_HARD )))
1154 // immediately call spawn function
1156 if (!ent->v->classname)
1158 Con_Print("No classname for:\n");
1164 // look for the spawn function
1165 func = ED_FindFunction (PR_GetString(ent->v->classname));
1169 if (developer.integer) // don't confuse non-developers with errors
1171 Con_Print("No spawn function for:\n");
1178 pr_global_struct->self = EDICT_TO_PROG(ent);
1179 PR_ExecuteProgram (func - pr_functions, "QC function spawn is missing");
1185 Con_DPrintf("%i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", parsed, inhibited, spawned, died, spawned - died);
1189 typedef struct dpfield_s
1196 #define DPFIELDS (sizeof(dpfields) / sizeof(dpfield_t))
1198 dpfield_t dpfields[] =
1200 {ev_float, "gravity"},
1201 {ev_float, "button3"},
1202 {ev_float, "button4"},
1203 {ev_float, "button5"},
1204 {ev_float, "button6"},
1205 {ev_float, "button7"},
1206 {ev_float, "button8"},
1207 {ev_float, "glow_size"},
1208 {ev_float, "glow_trail"},
1209 {ev_float, "glow_color"},
1210 {ev_float, "items2"},
1211 {ev_float, "scale"},
1212 {ev_float, "alpha"},
1213 {ev_float, "renderamt"},
1214 {ev_float, "rendermode"},
1215 {ev_float, "fullbright"},
1216 {ev_float, "ammo_shells1"},
1217 {ev_float, "ammo_nails1"},
1218 {ev_float, "ammo_lava_nails"},
1219 {ev_float, "ammo_rockets1"},
1220 {ev_float, "ammo_multi_rockets"},
1221 {ev_float, "ammo_cells1"},
1222 {ev_float, "ammo_plasma"},
1223 {ev_float, "idealpitch"},
1224 {ev_float, "pitch_speed"},
1225 {ev_entity, "viewmodelforclient"},
1226 {ev_entity, "nodrawtoclient"},
1227 {ev_entity, "exteriormodeltoclient"},
1228 {ev_entity, "drawonlytoclient"},
1230 {ev_vector, "movement"},
1231 {ev_float, "pmodel"},
1232 {ev_vector, "punchvector"},
1233 {ev_float, "clientcolors"},
1234 {ev_entity, "tag_entity"},
1235 {ev_float, "tag_index"},
1236 {ev_float, "light_lev"},
1237 {ev_vector, "color"},
1238 {ev_float, "style"},
1239 {ev_float, "pflags"}
1247 extern void PR_Cmd_Reset (void);
1248 void PR_LoadProgs (void)
1252 ddef_t *infielddefs;
1253 dfunction_t *dfunctions;
1255 // flush the non-C variable lookup cache
1256 for (i=0 ; i<GEFV_CACHESIZE ; i++)
1257 gefvCache[i].field[0] = 0;
1259 Mem_EmptyPool(progs_mempool);
1260 Mem_EmptyPool(edictstring_mempool);
1262 progs = (dprograms_t *)FS_LoadFile ("progs.dat", progs_mempool, false);
1264 Host_Error ("PR_LoadProgs: couldn't load progs.dat");
1266 Con_DPrintf("Programs occupy %iK.\n", fs_filesize/1024);
1268 pr_crc = CRC_Block((qbyte *)progs, fs_filesize);
1270 // byte swap the header
1271 for (i = 0;i < (int) sizeof(*progs) / 4;i++)
1272 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1274 if (progs->version != PROG_VERSION)
1275 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1276 if (progs->crc != PROGHEADER_CRC && progs->crc != 32401) // tenebrae crc also allowed
1277 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1279 //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1280 dfunctions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1281 pr_strings = (char *)progs + progs->ofs_strings;
1282 pr_globaldefs = (ddef_t *)((qbyte *)progs + progs->ofs_globaldefs);
1284 // we need to expand the fielddefs list to include all the engine fields,
1285 // so allocate a new place for it
1286 infielddefs = (ddef_t *)((qbyte *)progs + progs->ofs_fielddefs);
1287 pr_fielddefs = Mem_Alloc(progs_mempool, (progs->numfielddefs + DPFIELDS) * sizeof(ddef_t));
1289 pr_statements = (dstatement_t *)((qbyte *)progs + progs->ofs_statements);
1291 // moved edict_size calculation down below field adding code
1293 pr_global_struct = (globalvars_t *)((qbyte *)progs + progs->ofs_globals);
1294 pr_globals = (float *)pr_global_struct;
1296 // byte swap the lumps
1297 for (i=0 ; i<progs->numstatements ; i++)
1299 pr_statements[i].op = LittleShort(pr_statements[i].op);
1300 pr_statements[i].a = LittleShort(pr_statements[i].a);
1301 pr_statements[i].b = LittleShort(pr_statements[i].b);
1302 pr_statements[i].c = LittleShort(pr_statements[i].c);
1305 pr_functions = Mem_Alloc(progs_mempool, sizeof(mfunction_t) * progs->numfunctions);
1306 for (i = 0;i < progs->numfunctions;i++)
1308 pr_functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
1309 pr_functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
1310 pr_functions[i].s_name = LittleLong (dfunctions[i].s_name);
1311 pr_functions[i].s_file = LittleLong (dfunctions[i].s_file);
1312 pr_functions[i].numparms = LittleLong (dfunctions[i].numparms);
1313 pr_functions[i].locals = LittleLong (dfunctions[i].locals);
1314 memcpy(pr_functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
1317 for (i=0 ; i<progs->numglobaldefs ; i++)
1319 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1320 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1321 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1324 // copy the progs fields to the new fields list
1325 for (i = 0;i < progs->numfielddefs;i++)
1327 pr_fielddefs[i].type = LittleShort (infielddefs[i].type);
1328 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1329 Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1330 pr_fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
1331 pr_fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
1334 // append the darkplaces fields
1335 for (i = 0;i < (int) DPFIELDS;i++)
1337 pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
1338 pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
1339 pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string);
1340 if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
1341 progs->entityfields += 3;
1343 progs->entityfields++;
1344 progs->numfielddefs++;
1347 for (i=0 ; i<progs->numglobals ; i++)
1348 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1350 // moved edict_size calculation down here, below field adding code
1351 // LordHavoc: this no longer includes the edict_t header
1352 pr_edict_size = progs->entityfields * 4;
1353 pr_edictareasize = pr_edict_size * MAX_EDICTS;
1355 // LordHavoc: bounds check anything static
1356 for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1362 if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1363 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1366 if (st->a + i < 0 || st->a + i >= progs->numstatements)
1367 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1369 // global global global
1404 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1405 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1407 // global none global
1413 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1414 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1430 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1431 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1445 if ((unsigned short) st->a >= progs->numglobals)
1446 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1449 Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1454 FindEdictFieldOffsets(); // LordHavoc: update field offset list
1455 PR_Execute_ProgsLoaded();
1460 void PR_Fields_f (void)
1462 int i, j, ednum, used, usedamount;
1464 char tempstring[5000], tempstring2[260], *name;
1470 Con_Print("no progs loaded\n");
1473 counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
1474 for (ednum = 0;ednum < sv.max_edicts;ednum++)
1476 ed = EDICT_NUM(ednum);
1479 for (i = 1;i < progs->numfielddefs;i++)
1481 d = &pr_fielddefs[i];
1482 name = PR_GetString(d->s_name);
1483 if (name[strlen(name)-2] == '_')
1484 continue; // skip _x, _y, _z vars
1485 v = (int *)((char *)ed->v + d->ofs*4);
1486 // if the value is still all 0, skip the field
1487 for (j = 0;j < type_size[d->type & ~DEF_SAVEGLOBAL];j++)
1500 for (i = 0;i < progs->numfielddefs;i++)
1502 d = &pr_fielddefs[i];
1503 name = PR_GetString(d->s_name);
1504 if (name[strlen(name)-2] == '_')
1505 continue; // skip _x, _y, _z vars
1506 switch(d->type & ~DEF_SAVEGLOBAL)
1509 strlcat (tempstring, "string ", sizeof (tempstring));
1512 strlcat (tempstring, "entity ", sizeof (tempstring));
1515 strlcat (tempstring, "function ", sizeof (tempstring));
1518 strlcat (tempstring, "field ", sizeof (tempstring));
1521 strlcat (tempstring, "void ", sizeof (tempstring));
1524 strlcat (tempstring, "float ", sizeof (tempstring));
1527 strlcat (tempstring, "vector ", sizeof (tempstring));
1530 strlcat (tempstring, "pointer ", sizeof (tempstring));
1533 snprintf (tempstring2, sizeof (tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
1534 strlcat (tempstring, tempstring2, sizeof (tempstring));
1537 if (strlen(name) > 256)
1539 memcpy(tempstring2, name, 256);
1540 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
1541 tempstring2[259] = 0;
1544 strcat (tempstring, name);
1545 for (j = strlen(name);j < 25;j++)
1546 strcat(tempstring, " ");
1547 snprintf (tempstring2, sizeof (tempstring2), "%5d", counts[i]);
1548 strlcat (tempstring, tempstring2, sizeof (tempstring));
1549 strlcat (tempstring, "\n", sizeof (tempstring));
1550 if (strlen(tempstring) >= 4096)
1552 Con_Print(tempstring);
1558 usedamount += type_size[d->type & ~DEF_SAVEGLOBAL];
1562 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);
1565 void PR_Globals_f (void)
1570 Con_Print("no progs loaded\n");
1573 for (i = 0;i < progs->numglobaldefs;i++)
1574 Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name));
1575 Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
1583 extern void PR_Cmd_Init(void);
1586 Cmd_AddCommand ("edict", ED_PrintEdict_f);
1587 Cmd_AddCommand ("edicts", ED_PrintEdicts);
1588 Cmd_AddCommand ("edictcount", ED_Count);
1589 Cmd_AddCommand ("edictset", ED_EdictSet_f);
1590 Cmd_AddCommand ("profile", PR_Profile_f);
1591 Cmd_AddCommand ("pr_fields", PR_Fields_f);
1592 Cmd_AddCommand ("pr_globals", PR_Globals_f);
1593 Cvar_RegisterVariable (&pr_checkextension);
1594 Cvar_RegisterVariable (&nomonsters);
1595 Cvar_RegisterVariable (&gamecfg);
1596 Cvar_RegisterVariable (&scratch1);
1597 Cvar_RegisterVariable (&scratch2);
1598 Cvar_RegisterVariable (&scratch3);
1599 Cvar_RegisterVariable (&scratch4);
1600 Cvar_RegisterVariable (&savedgamecfg);
1601 Cvar_RegisterVariable (&saved1);
1602 Cvar_RegisterVariable (&saved2);
1603 Cvar_RegisterVariable (&saved3);
1604 Cvar_RegisterVariable (&saved4);
1605 // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1606 Cvar_RegisterVariable (&decors);
1607 // LordHavoc: Nehahra uses these to pass data around cutscene demos
1608 if (gamemode == GAME_NEHAHRA)
1610 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1611 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1612 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1613 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1614 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1615 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1616 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1617 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1618 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1619 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1621 Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1622 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1623 Cvar_RegisterVariable (&pr_boundscheck);
1624 Cvar_RegisterVariable (&pr_traceqc);
1626 progs_mempool = Mem_AllocPool("progs.dat", 0, NULL);
1627 edictstring_mempool = Mem_AllocPool("edict strings", 0, NULL);
1632 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1633 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
1635 Host_Error ("EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
1640 int NUM_FOR_EDICT_ERROR(edict_t *e)
1642 Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
1646 int NUM_FOR_EDICT(edict_t *e)
1650 if ((unsigned int)n >= MAX_EDICTS)
1651 Host_Error ("NUM_FOR_EDICT: bad pointer");
1655 //int NoCrash_NUM_FOR_EDICT(edict_t *e)
1657 // return e - sv.edicts;
1660 //#define EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
1661 //#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
1662 int EDICT_TO_PROG(edict_t *e)
1666 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1667 Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
1668 return n;// EXPERIMENTAL
1669 //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
1671 edict_t *PROG_TO_EDICT(int n)
1673 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1674 Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
1675 return sv.edicts + n; // EXPERIMENTAL
1676 //return sv.edicts + ((n) / (progs->entityfields * 4));