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;
126 mfunction_t *SV_PlayerPhysicsQC;
127 mfunction_t *EndFrameQC;
128 //KrimZon - SERVER COMMANDS IN QUAKEC
129 mfunction_t *SV_ParseClientCommandQC;
131 int FindFieldOffset(const char *field)
134 d = ED_FindField(field);
140 void FindEdictFieldOffsets(void)
142 eval_gravity = FindFieldOffset("gravity");
143 eval_button3 = FindFieldOffset("button3");
144 eval_button4 = FindFieldOffset("button4");
145 eval_button5 = FindFieldOffset("button5");
146 eval_button6 = FindFieldOffset("button6");
147 eval_button7 = FindFieldOffset("button7");
148 eval_button8 = FindFieldOffset("button8");
149 eval_glow_size = FindFieldOffset("glow_size");
150 eval_glow_trail = FindFieldOffset("glow_trail");
151 eval_glow_color = FindFieldOffset("glow_color");
152 eval_items2 = FindFieldOffset("items2");
153 eval_scale = FindFieldOffset("scale");
154 eval_alpha = FindFieldOffset("alpha");
155 eval_renderamt = FindFieldOffset("renderamt"); // HalfLife support
156 eval_rendermode = FindFieldOffset("rendermode"); // HalfLife support
157 eval_fullbright = FindFieldOffset("fullbright");
158 eval_ammo_shells1 = FindFieldOffset("ammo_shells1");
159 eval_ammo_nails1 = FindFieldOffset("ammo_nails1");
160 eval_ammo_lava_nails = FindFieldOffset("ammo_lava_nails");
161 eval_ammo_rockets1 = FindFieldOffset("ammo_rockets1");
162 eval_ammo_multi_rockets = FindFieldOffset("ammo_multi_rockets");
163 eval_ammo_cells1 = FindFieldOffset("ammo_cells1");
164 eval_ammo_plasma = FindFieldOffset("ammo_plasma");
165 eval_idealpitch = FindFieldOffset("idealpitch");
166 eval_pitch_speed = FindFieldOffset("pitch_speed");
167 eval_viewmodelforclient = FindFieldOffset("viewmodelforclient");
168 eval_nodrawtoclient = FindFieldOffset("nodrawtoclient");
169 eval_exteriormodeltoclient = FindFieldOffset("exteriormodeltoclient");
170 eval_drawonlytoclient = FindFieldOffset("drawonlytoclient");
171 eval_ping = FindFieldOffset("ping");
172 eval_movement = FindFieldOffset("movement");
173 eval_pmodel = FindFieldOffset("pmodel");
174 eval_punchvector = FindFieldOffset("punchvector");
175 eval_viewzoom = FindFieldOffset("viewzoom");
176 eval_clientcolors = FindFieldOffset("clientcolors");
177 eval_tag_entity = FindFieldOffset("tag_entity");
178 eval_tag_index = FindFieldOffset("tag_index");
180 // LordHavoc: allowing QuakeC to override the player movement code
181 SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
182 // LordHavoc: support for endframe
183 EndFrameQC = ED_FindFunction ("EndFrame");
184 //KrimZon - SERVER COMMANDS IN QUAKEC
185 SV_ParseClientCommandQC = ED_FindFunction ("SV_ParseClientCommand");
192 Sets everything to NULL
195 void ED_ClearEdict (edict_t *e)
198 memset (e->v, 0, progs->entityfields * 4);
200 // LordHavoc: for consistency set these here
201 num = NUM_FOR_EDICT(e) - 1;
202 if (num >= 0 && num < svs.maxclients)
204 e->v->colormap = num + 1;
205 e->v->team = (svs.clients[num].colors & 15) + 1;
206 e->v->netname = PR_SetString(svs.clients[num].name);
214 Either finds a free edict, or allocates a new one.
215 Try to avoid reusing an entity that was recently freed, because it
216 can cause the client to think the entity morphed into something else
217 instead of being removed and recreated, which can cause interpolated
218 angles and bad trails.
221 edict_t *ED_Alloc (void)
226 for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
229 // the first couple seconds of server time can involve a lot of
230 // freeing and allocating, so relax the replacement policy
231 if (e->e->free && ( e->e->freetime < 2 || sv.time - e->e->freetime > 0.5 ) )
239 Host_Error ("ED_Alloc: no free edicts");
242 if (sv.num_edicts >= sv.max_edicts)
254 Marks the edict as free
255 FIXME: walk all entities and NULL out references to this entity
258 void ED_Free (edict_t *ed)
260 SV_UnlinkEdict (ed); // unlink from world bsp
264 ed->v->takedamage = 0;
265 ed->v->modelindex = 0;
269 VectorClear(ed->v->origin);
270 VectorClear(ed->v->angles);
271 ed->v->nextthink = -1;
274 ed->e->freetime = sv.time;
277 //===========================================================================
284 ddef_t *ED_GlobalAtOfs (int ofs)
289 for (i=0 ; i<progs->numglobaldefs ; i++)
291 def = &pr_globaldefs[i];
303 ddef_t *ED_FieldAtOfs (int ofs)
308 for (i=0 ; i<progs->numfielddefs ; i++)
310 def = &pr_fielddefs[i];
322 ddef_t *ED_FindField (const char *name)
327 for (i=0 ; i<progs->numfielddefs ; i++)
329 def = &pr_fielddefs[i];
330 if (!strcmp(PR_GetString(def->s_name), name))
341 ddef_t *ED_FindGlobal (const char *name)
346 for (i=0 ; i<progs->numglobaldefs ; i++)
348 def = &pr_globaldefs[i];
349 if (!strcmp(PR_GetString(def->s_name), name))
361 mfunction_t *ED_FindFunction (const char *name)
366 for (i=0 ; i<progs->numfunctions ; i++)
368 func = &pr_functions[i];
369 if (!strcmp(PR_GetString(func->s_name), name))
380 Returns a string describing *data in a type specific manner
383 //int NoCrash_NUM_FOR_EDICT(edict_t *e);
384 char *PR_ValueString (etype_t type, eval_t *val)
386 static char line[1024]; // LordHavoc: enlarged a bit (was 256)
391 type &= ~DEF_SAVEGLOBAL;
396 snprintf (line, sizeof (line), "%s", PR_GetString(val->string));
399 //n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict));
401 if (n < 0 || n >= MAX_EDICTS)
402 snprintf (line, sizeof (line), "entity %i (invalid!)", n);
404 snprintf (line, sizeof (line), "entity %i", n);
407 f = pr_functions + val->function;
408 snprintf (line, sizeof (line), "%s()", PR_GetString(f->s_name));
411 def = ED_FieldAtOfs ( val->_int );
412 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
415 snprintf (line, sizeof (line), "void");
418 // LordHavoc: changed from %5.1f to %10.4f
419 snprintf (line, sizeof (line), "%10.4f", val->_float);
422 // LordHavoc: changed from %5.1f to %10.4f
423 snprintf (line, sizeof (line), "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
426 snprintf (line, sizeof (line), "pointer");
429 snprintf (line, sizeof (line), "bad type %i", type);
440 Returns a string describing *data in a type specific manner
441 Easier to parse than PR_ValueString
444 char *PR_UglyValueString (etype_t type, eval_t *val)
446 static char line[4096];
452 type &= ~DEF_SAVEGLOBAL;
457 // Parse the string a bit to turn special characters
458 // (like newline, specifically) into escape codes,
459 // this fixes saving games from various mods
460 s = PR_GetString (val->string);
461 for (i = 0;i < (int)sizeof(line) - 2 && *s;)
480 snprintf (line, sizeof (line), "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
483 f = pr_functions + val->function;
484 snprintf (line, sizeof (line), "%s", PR_GetString(f->s_name));
487 def = ED_FieldAtOfs ( val->_int );
488 snprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
491 snprintf (line, sizeof (line), "void");
494 snprintf (line, sizeof (line), "%f", val->_float);
497 snprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
500 snprintf (line, sizeof (line), "bad type %i", type);
511 Returns a string with a description and the contents of a global,
512 padded to 20 field width
515 char *PR_GlobalString (int ofs)
521 static char line[128];
523 val = (void *)&pr_globals[ofs];
524 def = ED_GlobalAtOfs(ofs);
526 snprintf (line, sizeof (line), "%i(?)", ofs);
529 s = PR_ValueString (def->type, val);
530 snprintf (line, sizeof (line), "%i(%s)%s", ofs, PR_GetString(def->s_name), s);
535 strlcat (line, " ", sizeof (line));
536 strlcat (line, " ", sizeof (line));
541 char *PR_GlobalStringNoContents (int ofs)
545 static char line[128];
547 def = ED_GlobalAtOfs(ofs);
549 snprintf (line, sizeof (line), "%i(?)", ofs);
551 snprintf (line, sizeof (line), "%i(%s)", ofs, PR_GetString(def->s_name));
555 strlcat (line, " ", sizeof (line));
556 strlcat (line, " ", sizeof (line));
569 // LordHavoc: optimized this to print out much more quickly (tempstring)
570 // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
571 void ED_Print (edict_t *ed)
579 char tempstring[8192], tempstring2[260]; // temporary string buffers
583 Con_Printf ("FREE\n");
588 snprintf (tempstring, sizeof (tempstring), "\nEDICT %i:\n", NUM_FOR_EDICT(ed));
589 for (i=1 ; i<progs->numfielddefs ; i++)
591 d = &pr_fielddefs[i];
592 name = PR_GetString(d->s_name);
593 if (name[strlen(name)-2] == '_')
594 continue; // skip _x, _y, _z vars
596 v = (int *)((char *)ed->v + d->ofs*4);
598 // if the value is still all 0, skip the field
599 type = d->type & ~DEF_SAVEGLOBAL;
601 for (j=0 ; j<type_size[type] ; j++)
604 if (j == type_size[type])
607 if (strlen(name) > 256)
609 strncpy(tempstring2, name, 256);
610 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
611 tempstring2[259] = 0;
614 strlcat (tempstring, name, sizeof (tempstring));
615 for (l = strlen(name);l < 14;l++)
616 strcat(tempstring, " ");
617 strcat(tempstring, " ");
619 name = PR_ValueString(d->type, (eval_t *)v);
620 if (strlen(name) > 256)
622 strncpy(tempstring2, name, 256);
623 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
624 tempstring2[259] = 0;
627 strlcat (tempstring, name, sizeof (tempstring));
628 strlcat (tempstring, "\n", sizeof (tempstring));
629 if (strlen(tempstring) >= 4096)
631 Con_Printf("%s", tempstring);
636 Con_Printf("%s", tempstring);
646 void ED_Write (qfile_t *f, edict_t *ed)
654 FS_Printf (f, "{\n");
658 FS_Printf (f, "}\n");
662 for (i=1 ; i<progs->numfielddefs ; i++)
664 d = &pr_fielddefs[i];
665 name = PR_GetString(d->s_name);
666 if (name[strlen(name)-2] == '_')
667 continue; // skip _x, _y, _z vars
669 v = (int *)((char *)ed->v + d->ofs*4);
671 // if the value is still all 0, skip the field
672 type = d->type & ~DEF_SAVEGLOBAL;
673 for (j=0 ; j<type_size[type] ; j++)
676 if (j == type_size[type])
679 FS_Printf (f,"\"%s\" ",name);
680 FS_Printf (f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
683 FS_Printf (f, "}\n");
686 void ED_PrintNum (int ent)
688 ED_Print (EDICT_NUM(ent));
695 For debugging, prints all the entities in the current server
698 void ED_PrintEdicts (void)
702 Con_Printf ("%i entities\n", sv.num_edicts);
703 for (i=0 ; i<sv.num_edicts ; i++)
711 For debugging, prints a single edict
714 void ED_PrintEdict_f (void)
718 i = atoi (Cmd_Argv(1));
719 if (i >= sv.num_edicts)
721 Con_Printf("Bad edict number\n");
738 int active, models, solid, step;
740 active = models = solid = step = 0;
741 for (i=0 ; i<sv.num_edicts ; i++)
751 if (ent->v->movetype == MOVETYPE_STEP)
755 Con_Printf ("num_edicts:%3i\n", sv.num_edicts);
756 Con_Printf ("active :%3i\n", active);
757 Con_Printf ("view :%3i\n", models);
758 Con_Printf ("touch :%3i\n", solid);
759 Con_Printf ("step :%3i\n", step);
764 ==============================================================================
768 FIXME: need to tag constants, doesn't really work
769 ==============================================================================
777 void ED_WriteGlobals (qfile_t *f)
785 for (i=0 ; i<progs->numglobaldefs ; i++)
787 def = &pr_globaldefs[i];
789 if ( !(def->type & DEF_SAVEGLOBAL) )
791 type &= ~DEF_SAVEGLOBAL;
793 if (type != ev_string && type != ev_float && type != ev_entity)
796 name = PR_GetString(def->s_name);
797 FS_Printf (f,"\"%s\" ", name);
798 FS_Printf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
807 Console command to set a field of a specified edict
810 void ED_EdictSet_f(void)
817 Con_Printf("edictset <edict number> <field> <value>\n");
820 ed = EDICT_NUM(atoi(Cmd_Argv(1)));
822 if((key = ED_FindField(Cmd_Argv(2))) == 0)
824 Con_Printf("Key %s not found !\n", Cmd_Argv(2));
828 ED_ParseEpair(ed, key, Cmd_Argv(3));
836 void ED_ParseGlobals (const char *data)
838 char keyname[1024]; // LordHavoc: good idea? bad idea? was 64
844 if (!COM_ParseToken(&data, false))
845 Host_Error ("ED_ParseEntity: EOF without closing brace");
846 if (com_token[0] == '}')
849 strcpy (keyname, com_token);
852 if (!COM_ParseToken(&data, false))
853 Host_Error ("ED_ParseEntity: EOF without closing brace");
855 if (com_token[0] == '}')
856 Host_Error ("ED_ParseEntity: closing brace without data");
858 key = ED_FindGlobal (keyname);
861 Con_DPrintf ("'%s' is not a global\n", keyname);
865 if (!ED_ParseEpair(NULL, key, com_token))
866 Host_Error ("ED_ParseGlobals: parse error");
870 //============================================================================
878 char *ED_NewString (const char *string)
883 l = strlen(string) + 1;
884 new = Mem_Alloc(edictstring_mempool, l);
887 for (i=0 ; i< l ; i++)
889 if (string[i] == '\\' && i < l-1)
892 if (string[i] == 'n')
898 *new_p++ = string[i];
909 Can parse either fields or globals
910 returns false if error
913 qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
921 val = (eval_t *)((int *)ent->v + key->ofs);
923 val = (eval_t *)((int *)pr_globals + key->ofs);
924 switch (key->type & ~DEF_SAVEGLOBAL)
927 val->string = PR_SetString(ED_NewString(s));
931 while (*s && *s <= ' ')
933 val->_float = atof(s);
937 for (i = 0;i < 3;i++)
939 while (*s && *s <= ' ')
943 val->vector[i] = atof(s);
952 while (*s && *s <= ' ')
955 if (i < 0 || i >= MAX_EDICTS)
956 Con_Printf("ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i)\n", i, MAX_EDICTS);
957 while (i >= sv.max_edicts)
959 // if SV_IncreaseEdicts was called the base pointer needs to be updated
961 val = (eval_t *)((int *)ent->v + key->ofs);
962 val->edict = EDICT_TO_PROG(EDICT_NUM(i));
966 def = ED_FindField(s);
969 Con_DPrintf("ED_ParseEpair: Can't find field %s\n", s);
972 val->_int = G_INT(def->ofs);
976 func = ED_FindFunction(s);
979 Con_Printf ("ED_ParseEpair: Can't find function %s\n", s);
982 val->function = func - pr_functions;
986 Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PR_GetString(key->s_name));
996 Parses an edict out of the given string, returning the new position
997 ed should be a properly initialized empty edict.
998 Used for initial level load and for savegames.
1001 const char *ED_ParseEdict (const char *data, edict_t *ent)
1012 if (ent != sv.edicts) // hack
1013 memset (ent->v, 0, progs->entityfields * 4);
1015 // go through all the dictionary pairs
1019 if (!COM_ParseToken(&data, false))
1020 Host_Error ("ED_ParseEntity: EOF without closing brace");
1021 if (com_token[0] == '}')
1024 // anglehack is to allow QuakeEd to write single scalar angles
1025 // and allow them to be turned into vectors. (FIXME...)
1026 anglehack = !strcmp (com_token, "angle");
1028 strlcpy (com_token, "angles", sizeof (com_token));
1030 // FIXME: change light to _light to get rid of this hack
1031 if (!strcmp(com_token, "light"))
1032 strlcpy (com_token, "light_lev", sizeof (com_token)); // hack for single light def
1034 strlcpy (keyname, com_token, sizeof (keyname));
1036 // another hack to fix heynames with trailing spaces
1037 n = strlen(keyname);
1038 while (n && keyname[n-1] == ' ')
1045 if (!COM_ParseToken(&data, false))
1046 Host_Error ("ED_ParseEntity: EOF without closing brace");
1048 if (com_token[0] == '}')
1049 Host_Error ("ED_ParseEntity: closing brace without data");
1053 // keynames with a leading underscore are used for utility comments,
1054 // and are immediately discarded by quake
1055 if (keyname[0] == '_')
1058 key = ED_FindField (keyname);
1061 Con_DPrintf ("'%s' is not a field\n", keyname);
1068 strlcpy (temp, com_token, sizeof (temp));
1069 snprintf (com_token, sizeof (com_token), "0 %s 0", temp);
1072 if (!ED_ParseEpair(ent, key, com_token))
1073 Host_Error ("ED_ParseEdict: parse error");
1077 ent->e->free = true;
1087 The entities are directly placed in the array, rather than allocated with
1088 ED_Alloc, because otherwise an error loading the map would have entity
1089 number references out of order.
1091 Creates a server's entity / program execution context by
1092 parsing textual entity definitions out of an ent file.
1094 Used for both fresh maps and savegame loads. A fresh map would also need
1095 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1098 void ED_LoadFromFile (const char *data)
1101 int parsed, inhibited, spawned, died;
1109 pr_global_struct->time = sv.time;
1114 // parse the opening brace
1115 if (!COM_ParseToken(&data, false))
1117 if (com_token[0] != '{')
1118 Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
1124 data = ED_ParseEdict (data, ent);
1127 // remove things from different skill levels or deathmatch
1128 if (deathmatch.integer)
1130 if (((int)ent->v->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
1137 else if ((current_skill == 0 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_EASY ))
1138 || (current_skill == 1 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_MEDIUM))
1139 || (current_skill >= 2 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_HARD )))
1147 // immediately call spawn function
1149 if (!ent->v->classname)
1151 Con_Printf ("No classname for:\n");
1157 // look for the spawn function
1158 func = ED_FindFunction (PR_GetString(ent->v->classname));
1162 if (developer.integer) // don't confuse non-developers with errors
1164 Con_Printf ("No spawn function for:\n");
1171 pr_global_struct->self = EDICT_TO_PROG(ent);
1172 PR_ExecuteProgram (func - pr_functions, "");
1178 Con_DPrintf ("%i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", parsed, inhibited, spawned, died, spawned - died);
1182 typedef struct dpfield_s
1189 #define DPFIELDS (sizeof(dpfields) / sizeof(dpfield_t))
1191 dpfield_t dpfields[] =
1193 {ev_float, "gravity"},
1194 {ev_float, "button3"},
1195 {ev_float, "button4"},
1196 {ev_float, "button5"},
1197 {ev_float, "button6"},
1198 {ev_float, "button7"},
1199 {ev_float, "button8"},
1200 {ev_float, "glow_size"},
1201 {ev_float, "glow_trail"},
1202 {ev_float, "glow_color"},
1203 {ev_float, "items2"},
1204 {ev_float, "scale"},
1205 {ev_float, "alpha"},
1206 {ev_float, "renderamt"},
1207 {ev_float, "rendermode"},
1208 {ev_float, "fullbright"},
1209 {ev_float, "ammo_shells1"},
1210 {ev_float, "ammo_nails1"},
1211 {ev_float, "ammo_lava_nails"},
1212 {ev_float, "ammo_rockets1"},
1213 {ev_float, "ammo_multi_rockets"},
1214 {ev_float, "ammo_cells1"},
1215 {ev_float, "ammo_plasma"},
1216 {ev_float, "idealpitch"},
1217 {ev_float, "pitch_speed"},
1218 {ev_entity, "viewmodelforclient"},
1219 {ev_entity, "nodrawtoclient"},
1220 {ev_entity, "exteriormodeltoclient"},
1221 {ev_entity, "drawonlytoclient"},
1223 {ev_vector, "movement"},
1224 {ev_float, "pmodel"},
1225 {ev_vector, "punchvector"},
1226 {ev_float, "clientcolors"},
1227 {ev_entity, "tag_entity"},
1228 {ev_float, "tag_index"}
1236 extern void PR_Cmd_Reset (void);
1237 void PR_LoadProgs (void)
1241 ddef_t *infielddefs;
1243 dfunction_t *dfunctions;
1245 // flush the non-C variable lookup cache
1246 for (i=0 ; i<GEFV_CACHESIZE ; i++)
1247 gefvCache[i].field[0] = 0;
1249 Mem_EmptyPool(progs_mempool);
1250 Mem_EmptyPool(edictstring_mempool);
1252 temp = FS_LoadFile ("progs.dat", false);
1254 Host_Error ("PR_LoadProgs: couldn't load progs.dat");
1256 progs = (dprograms_t *)Mem_Alloc(progs_mempool, fs_filesize);
1258 memcpy(progs, temp, fs_filesize);
1261 Con_DPrintf ("Programs occupy %iK.\n", fs_filesize/1024);
1263 pr_crc = CRC_Block((qbyte *)progs, fs_filesize);
1265 // byte swap the header
1266 for (i = 0;i < (int) sizeof(*progs) / 4;i++)
1267 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1269 if (progs->version != PROG_VERSION)
1270 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1271 if (progs->crc != PROGHEADER_CRC)
1272 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1274 //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1275 dfunctions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
1276 pr_strings = (char *)progs + progs->ofs_strings;
1277 pr_globaldefs = (ddef_t *)((qbyte *)progs + progs->ofs_globaldefs);
1279 // we need to expand the fielddefs list to include all the engine fields,
1280 // so allocate a new place for it
1281 infielddefs = (ddef_t *)((qbyte *)progs + progs->ofs_fielddefs);
1282 pr_fielddefs = Mem_Alloc(progs_mempool, (progs->numfielddefs + DPFIELDS) * sizeof(ddef_t));
1284 pr_statements = (dstatement_t *)((qbyte *)progs + progs->ofs_statements);
1286 // moved edict_size calculation down below field adding code
1288 pr_global_struct = (globalvars_t *)((qbyte *)progs + progs->ofs_globals);
1289 pr_globals = (float *)pr_global_struct;
1291 // byte swap the lumps
1292 for (i=0 ; i<progs->numstatements ; i++)
1294 pr_statements[i].op = LittleShort(pr_statements[i].op);
1295 pr_statements[i].a = LittleShort(pr_statements[i].a);
1296 pr_statements[i].b = LittleShort(pr_statements[i].b);
1297 pr_statements[i].c = LittleShort(pr_statements[i].c);
1300 pr_functions = Mem_Alloc(progs_mempool, sizeof(mfunction_t) * progs->numfunctions);
1301 for (i = 0;i < progs->numfunctions;i++)
1303 pr_functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
1304 pr_functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
1305 pr_functions[i].s_name = LittleLong (dfunctions[i].s_name);
1306 pr_functions[i].s_file = LittleLong (dfunctions[i].s_file);
1307 pr_functions[i].numparms = LittleLong (dfunctions[i].numparms);
1308 pr_functions[i].locals = LittleLong (dfunctions[i].locals);
1309 memcpy(pr_functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
1312 for (i=0 ; i<progs->numglobaldefs ; i++)
1314 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1315 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1316 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1319 // copy the progs fields to the new fields list
1320 for (i = 0;i < progs->numfielddefs;i++)
1322 pr_fielddefs[i].type = LittleShort (infielddefs[i].type);
1323 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1324 Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1325 pr_fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
1326 pr_fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
1329 // append the darkplaces fields
1330 for (i = 0;i < (int) DPFIELDS;i++)
1332 pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
1333 pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
1334 pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string);
1335 if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
1336 progs->entityfields += 3;
1338 progs->entityfields++;
1339 progs->numfielddefs++;
1342 for (i=0 ; i<progs->numglobals ; i++)
1343 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1345 // moved edict_size calculation down here, below field adding code
1346 // LordHavoc: this no longer includes the edict_t header
1347 pr_edict_size = progs->entityfields * 4;
1348 pr_edictareasize = pr_edict_size * MAX_EDICTS;
1350 // LordHavoc: bounds check anything static
1351 for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1357 if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1358 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1361 if (st->a + i < 0 || st->a + i >= progs->numstatements)
1362 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1364 // global global global
1399 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1400 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1402 // global none global
1408 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1409 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1425 if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1426 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1440 if ((unsigned short) st->a >= progs->numglobals)
1441 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1444 Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1449 FindEdictFieldOffsets(); // LordHavoc: update field offset list
1450 PR_Execute_ProgsLoaded();
1455 void PR_Fields_f (void)
1457 int i, j, ednum, used, usedamount;
1459 char tempstring[5000], tempstring2[260], *name;
1465 Con_Printf("no progs loaded\n");
1468 counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
1469 for (ednum = 0;ednum < sv.max_edicts;ednum++)
1471 ed = EDICT_NUM(ednum);
1474 for (i = 1;i < progs->numfielddefs;i++)
1476 d = &pr_fielddefs[i];
1477 name = PR_GetString(d->s_name);
1478 if (name[strlen(name)-2] == '_')
1479 continue; // skip _x, _y, _z vars
1480 v = (int *)((char *)ed->v + d->ofs*4);
1481 // if the value is still all 0, skip the field
1482 for (j = 0;j < type_size[d->type & ~DEF_SAVEGLOBAL];j++)
1495 for (i = 0;i < progs->numfielddefs;i++)
1497 d = &pr_fielddefs[i];
1498 name = PR_GetString(d->s_name);
1499 if (name[strlen(name)-2] == '_')
1500 continue; // skip _x, _y, _z vars
1501 switch(d->type & ~DEF_SAVEGLOBAL)
1504 strlcat (tempstring, "string ", sizeof (tempstring));
1507 strlcat (tempstring, "entity ", sizeof (tempstring));
1510 strlcat (tempstring, "function ", sizeof (tempstring));
1513 strlcat (tempstring, "field ", sizeof (tempstring));
1516 strlcat (tempstring, "void ", sizeof (tempstring));
1519 strlcat (tempstring, "float ", sizeof (tempstring));
1522 strlcat (tempstring, "vector ", sizeof (tempstring));
1525 strlcat (tempstring, "pointer ", sizeof (tempstring));
1528 snprintf (tempstring2, sizeof (tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
1529 strlcat (tempstring, tempstring2, sizeof (tempstring));
1532 if (strlen(name) > 256)
1534 strncpy(tempstring2, name, 256);
1535 tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
1536 tempstring2[259] = 0;
1539 strcat (tempstring, name);
1540 for (j = strlen(name);j < 25;j++)
1541 strcat(tempstring, " ");
1542 snprintf (tempstring2, sizeof (tempstring2), "%5d", counts[i]);
1543 strlcat (tempstring, tempstring2, sizeof (tempstring));
1544 strlcat (tempstring, "\n", sizeof (tempstring));
1545 if (strlen(tempstring) >= 4096)
1547 Con_Printf("%s", tempstring);
1553 usedamount += type_size[d->type & ~DEF_SAVEGLOBAL];
1557 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);
1560 void PR_Globals_f (void)
1565 Con_Printf("no progs loaded\n");
1568 for (i = 0;i < progs->numglobaldefs;i++)
1569 Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name));
1570 Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
1578 extern void PR_Cmd_Init(void);
1581 Cmd_AddCommand ("edict", ED_PrintEdict_f);
1582 Cmd_AddCommand ("edicts", ED_PrintEdicts);
1583 Cmd_AddCommand ("edictcount", ED_Count);
1584 Cmd_AddCommand ("edictset", ED_EdictSet_f);
1585 Cmd_AddCommand ("profile", PR_Profile_f);
1586 Cmd_AddCommand ("pr_fields", PR_Fields_f);
1587 Cmd_AddCommand ("pr_globals", PR_Globals_f);
1588 Cvar_RegisterVariable (&pr_checkextension);
1589 Cvar_RegisterVariable (&nomonsters);
1590 Cvar_RegisterVariable (&gamecfg);
1591 Cvar_RegisterVariable (&scratch1);
1592 Cvar_RegisterVariable (&scratch2);
1593 Cvar_RegisterVariable (&scratch3);
1594 Cvar_RegisterVariable (&scratch4);
1595 Cvar_RegisterVariable (&savedgamecfg);
1596 Cvar_RegisterVariable (&saved1);
1597 Cvar_RegisterVariable (&saved2);
1598 Cvar_RegisterVariable (&saved3);
1599 Cvar_RegisterVariable (&saved4);
1600 // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1601 Cvar_RegisterVariable (&decors);
1602 // LordHavoc: Nehahra uses these to pass data around cutscene demos
1603 if (gamemode == GAME_NEHAHRA)
1605 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1606 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1607 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1608 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1609 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1610 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1611 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1612 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1613 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1614 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1616 Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1617 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1618 Cvar_RegisterVariable (&pr_boundscheck);
1619 Cvar_RegisterVariable (&pr_traceqc);
1621 progs_mempool = Mem_AllocPool("progs.dat");
1622 edictstring_mempool = Mem_AllocPool("edict strings");
1627 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1628 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
1630 Host_Error ("EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
1635 int NUM_FOR_EDICT_ERROR(edict_t *e)
1637 Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
1641 int NUM_FOR_EDICT(edict_t *e)
1645 if ((unsigned int)n >= MAX_EDICTS)
1646 Host_Error ("NUM_FOR_EDICT: bad pointer");
1650 //int NoCrash_NUM_FOR_EDICT(edict_t *e)
1652 // return e - sv.edicts;
1655 //#define EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
1656 //#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
1657 int EDICT_TO_PROG(edict_t *e)
1661 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1662 Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
1663 return n;// EXPERIMENTAL
1664 //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
1666 edict_t *PROG_TO_EDICT(int n)
1668 if ((unsigned int)n >= (unsigned int)sv.max_edicts)
1669 Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
1670 return sv.edicts + n; // EXPERIMENTAL
1671 //return sv.edicts + ((n) / (progs->entityfields * 4));