2014-04-12 12:19:49 +00:00
/*
2015-09-14 22:01:02 +00:00
Copyright ( C ) 2015 Marco " eukara " Hladik
2014-04-12 12:19:49 +00:00
Copyright ( C ) 1996 - 1997 Id Software , Inc .
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
// sv_edict.c -- entity dictionary
2015-08-20 13:34:12 +00:00
# include "globaldef.h"
2014-04-12 12:19:49 +00:00
dprograms_t * progs ;
dfunction_t * pr_functions ;
char * pr_strings ;
ddef_t * pr_fielddefs ;
ddef_t * pr_globaldefs ;
dstatement_t * pr_statements ;
globalvars_t * pr_global_struct ;
float * pr_globals ; // same as pr_global_struct
int pr_edict_size ; // in bytes
unsigned short pr_crc ;
int type_size [ 8 ] = { 1 , sizeof ( string_t ) / 4 , 1 , 3 , 1 , 1 , sizeof ( func_t ) / 4 , sizeof ( void * ) / 4 } ;
ddef_t * ED_FieldAtOfs ( int ofs ) ;
qboolean ED_ParseEpair ( void * base , ddef_t * key , char * s ) ;
cvar_t * nomonsters ;
cvar_t * gamecfg ;
cvar_t * scratch1 ;
cvar_t * scratch2 ;
cvar_t * scratch3 ;
cvar_t * scratch4 ;
cvar_t * savedgamecfg ;
cvar_t * saved1 ;
cvar_t * saved2 ;
cvar_t * saved3 ;
cvar_t * saved4 ;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start
cvar_t * pr_builtin_find ;
cvar_t * pr_builtin_remap ;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end
cvar_t * pr_checkextension ; // 2001-10-20 Extension System by LordHavoc/Maddes (DP compatibility)
cvar_t * pr_zone_min_strings ; // 2001-09-20 QuakeC string zone by Maddes
# define MAX_FIELD_LEN 64
# define GEFV_CACHESIZE 2
typedef struct {
ddef_t * pcache ;
char field [ MAX_FIELD_LEN ] ;
} gefv_cache ;
static gefv_cache gefvCache [ GEFV_CACHESIZE ] = { { NULL , " " } , { NULL , " " } } ;
func_t pr_func_endframe ; // 2000-01-02 EndFrame function by Maddes/FrikaC
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes start
ddef_t * pr_global_cpu_frametime ;
ddef_t * pr_global_org_frametime ;
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes end
// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes start
ddef_t * pr_field_ammo_shells1 ;
ddef_t * pr_field_ammo_nails1 ;
ddef_t * pr_field_ammo_lava_nails ;
ddef_t * pr_field_ammo_rockets1 ;
ddef_t * pr_field_ammo_multi_rockets ;
ddef_t * pr_field_ammo_cells1 ;
ddef_t * pr_field_ammo_plasma ;
ddef_t * pr_field_idealpitch ;
ddef_t * pr_field_pitch_speed ;
ddef_t * pr_field_items2 ;
ddef_t * pr_field_gravity ;
2014-04-12 12:29:30 +00:00
ddef_t * pr_field_alpha ;
2014-04-12 12:19:49 +00:00
// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes end
2014-04-12 12:29:30 +00:00
ddef_t * pr_field_renderamt ;
ddef_t * pr_field_scale ;
ddef_t * pr_field_glowcolor ;
ddef_t * pr_field_glowsize ;
// leilei
2014-04-12 12:19:49 +00:00
// 2001-10-20 Extension System by LordHavoc/Maddes start
void PR_Extension_List_f ( void )
{
int i ;
char * partial ;
int len ;
int count ;
if ( Cmd_Argc ( ) > 1 )
{
partial = Cmd_Argv ( 1 ) ;
len = strlen ( partial ) ;
}
else
{
partial = NULL ;
len = 0 ;
}
count = 0 ;
for ( i = 0 ; i < pr_numextensions ; i + + )
{
if ( partial & & Q_strncasecmp ( partial , pr_extensions [ i ] , len ) )
{
continue ;
}
count + + ;
Con_Printf ( " %s \n " , pr_extensions [ i ] ) ;
}
Con_Printf ( " ------------ \n " ) ;
if ( partial )
{
Con_Printf ( " %i beginning with \" %s \" out of " , count , partial ) ;
}
Con_Printf ( " %i extensions \n " , i ) ;
}
// 2001-10-20 Extension System by LordHavoc/Maddes end
/*
= = = = = = = = = = = = = = = = =
ED_ClearEdict
Sets everything to NULL
= = = = = = = = = = = = = = = = =
*/
void ED_ClearEdict ( edict_t * e )
{
memset ( & e - > v , 0 , progs - > entityfields * 4 ) ;
e - > free = false ;
}
/*
= = = = = = = = = = = = = = = = =
ED_Alloc
Either finds a free edict , or allocates a new one .
Try to avoid reusing an entity that was recently freed , because it
can cause the client to think the entity morphed into something else
instead of being removed and recreated , which can cause interpolated
angles and bad trails .
= = = = = = = = = = = = = = = = =
*/
edict_t * ED_Alloc ( void )
{
int i ;
edict_t * e ;
for ( i = svs . maxclients + 1 ; i < sv . num_edicts ; i + + )
{
e = EDICT_NUM ( i ) ;
// the first couple seconds of server time can involve a lot of
// freeing and allocating, so relax the replacement policy
if ( e - > free & & ( e - > freetime < 2 | | sv . time - e - > freetime > 0.5 ) )
{
ED_ClearEdict ( e ) ;
return e ;
}
}
// 2001-09-20 Configurable entity limits by Maddes start
// if (i == MAX_EDICTS)
if ( i > = sv . max_edicts )
// 2001-09-20 Configurable entity limits by Maddes end
Sys_Error ( " ED_Alloc: no free edicts " ) ;
sv . num_edicts + + ;
e = EDICT_NUM ( i ) ;
ED_ClearEdict ( e ) ;
return e ;
}
/*
= = = = = = = = = = = = = = = = =
ED_Free
Marks the edict as free
FIXME : walk all entities and NULL out references to this entity
= = = = = = = = = = = = = = = = =
*/
void ED_Free ( edict_t * ed )
{
2014-04-12 12:29:30 +00:00
2014-04-12 12:19:49 +00:00
SV_UnlinkEdict ( ed ) ; // unlink from world bsp
ed - > free = true ;
ed - > v . model = 0 ;
ed - > v . takedamage = 0 ;
ed - > v . modelindex = 0 ;
ed - > v . colormap = 0 ;
ed - > v . skin = 0 ;
ed - > v . frame = 0 ;
VectorCopy ( vec3_origin , ed - > v . origin ) ;
VectorCopy ( vec3_origin , ed - > v . angles ) ;
ed - > v . nextthink = - 1 ;
ed - > v . solid = 0 ;
ed - > freetime = sv . time ;
}
//===========================================================================
/*
= = = = = = = = = = = =
ED_GlobalAtOfs
= = = = = = = = = = = =
*/
ddef_t * ED_GlobalAtOfs ( int ofs )
{
ddef_t * def ;
int i ;
for ( i = 0 ; i < progs - > numglobaldefs ; i + + )
{
def = & pr_globaldefs [ i ] ;
if ( def - > ofs = = ofs )
return def ;
}
return NULL ;
}
/*
= = = = = = = = = = = =
ED_FieldAtOfs
= = = = = = = = = = = =
*/
ddef_t * ED_FieldAtOfs ( int ofs )
{
ddef_t * def ;
int i ;
for ( i = 0 ; i < progs - > numfielddefs ; i + + )
{
def = & pr_fielddefs [ i ] ;
if ( def - > ofs = = ofs )
return def ;
}
return NULL ;
}
/*
= = = = = = = = = = = =
ED_FindField
= = = = = = = = = = = =
*/
ddef_t * ED_FindField ( char * name )
{
ddef_t * def ;
int i ;
for ( i = 0 ; i < progs - > numfielddefs ; i + + )
{
def = & pr_fielddefs [ i ] ;
if ( ! strcmp ( pr_strings + def - > s_name , name ) )
return def ;
}
return NULL ;
}
/*
= = = = = = = = = = = =
ED_FindGlobal
= = = = = = = = = = = =
*/
ddef_t * ED_FindGlobal ( char * name )
{
ddef_t * def ;
int i ;
for ( i = 0 ; i < progs - > numglobaldefs ; i + + )
{
def = & pr_globaldefs [ i ] ;
if ( ! strcmp ( pr_strings + def - > s_name , name ) )
return def ;
}
return NULL ;
}
/*
= = = = = = = = = = = =
ED_FindFunction
= = = = = = = = = = = =
*/
dfunction_t * ED_FindFunction ( char * name )
{
dfunction_t * func ;
int i ;
for ( i = 0 ; i < progs - > numfunctions ; i + + )
{
func = & pr_functions [ i ] ;
if ( ! strcmp ( pr_strings + func - > s_name , name ) )
return func ;
}
return NULL ;
}
eval_t * GetEdictFieldValue ( edict_t * ed , char * field )
{
ddef_t * def = NULL ;
int i ;
static int rep = 0 ;
for ( i = 0 ; i < GEFV_CACHESIZE ; i + + )
{
if ( ! strcmp ( field , gefvCache [ i ] . field ) )
{
def = gefvCache [ i ] . pcache ;
goto Done ;
}
}
def = ED_FindField ( field ) ;
if ( strlen ( field ) < MAX_FIELD_LEN )
{
gefvCache [ rep ] . pcache = def ;
strcpy ( gefvCache [ rep ] . field , field ) ;
rep ^ = 1 ;
}
Done :
if ( ! def )
return NULL ;
return ( eval_t * ) ( ( char * ) & ed - > v + def - > ofs * 4 ) ;
}
/*
= = = = = = = = = = = =
PR_ValueString
Returns a string describing * data in a type specific manner
= = = = = = = = = = = = =
*/
char * PR_ValueString ( etype_t type , eval_t * val )
{
static char line [ 256 ] ;
ddef_t * def ;
dfunction_t * f ;
type & = ~ DEF_SAVEGLOBAL ;
switch ( type )
{
case ev_string :
sprintf ( line , " %s " , pr_strings + val - > string ) ;
break ;
case ev_entity :
sprintf ( line , " entity %i " , NUM_FOR_EDICT ( PROG_TO_EDICT ( val - > edict ) ) ) ;
break ;
case ev_function :
f = pr_functions + val - > function ;
sprintf ( line , " %s() " , pr_strings + f - > s_name ) ;
break ;
case ev_field :
def = ED_FieldAtOfs ( val - > _int ) ;
sprintf ( line , " .%s " , pr_strings + def - > s_name ) ;
break ;
case ev_void :
sprintf ( line , " void " ) ;
break ;
case ev_float :
sprintf ( line , " %5.1f " , val - > _float ) ;
break ;
case ev_vector :
sprintf ( line , " '%5.1f %5.1f %5.1f' " , val - > vector [ 0 ] , val - > vector [ 1 ] , val - > vector [ 2 ] ) ;
break ;
case ev_pointer :
sprintf ( line , " pointer " ) ;
break ;
default :
sprintf ( line , " bad type %i " , type ) ;
break ;
}
return line ;
}
/*
= = = = = = = = = = = =
PR_UglyValueString
Returns a string describing * data in a type specific manner
Easier to parse than PR_ValueString
= = = = = = = = = = = = =
*/
char * PR_UglyValueString ( etype_t type , eval_t * val )
{
static char line [ 256 ] ;
ddef_t * def ;
dfunction_t * f ;
type & = ~ DEF_SAVEGLOBAL ;
switch ( type )
{
case ev_string :
sprintf ( line , " %s " , pr_strings + val - > string ) ;
break ;
case ev_entity :
sprintf ( line , " %i " , NUM_FOR_EDICT ( PROG_TO_EDICT ( val - > edict ) ) ) ;
break ;
case ev_function :
f = pr_functions + val - > function ;
sprintf ( line , " %s " , pr_strings + f - > s_name ) ;
break ;
case ev_field :
def = ED_FieldAtOfs ( val - > _int ) ;
sprintf ( line , " %s " , pr_strings + def - > s_name ) ;
break ;
case ev_void :
sprintf ( line , " void " ) ;
break ;
case ev_float :
sprintf ( line , " %f " , val - > _float ) ;
break ;
case ev_vector :
sprintf ( line , " %f %f %f " , val - > vector [ 0 ] , val - > vector [ 1 ] , val - > vector [ 2 ] ) ;
break ;
default :
sprintf ( line , " bad type %i " , type ) ;
break ;
}
return line ;
}
/*
= = = = = = = = = = = =
PR_GlobalString
Returns a string with a description and the contents of a global ,
padded to 20 field width
= = = = = = = = = = = =
*/
char * PR_GlobalString ( int ofs )
{
char * s ;
int i ;
ddef_t * def ;
void * val ;
static char line [ 128 ] ;
val = ( void * ) & pr_globals [ ofs ] ;
def = ED_GlobalAtOfs ( ofs ) ;
if ( ! def )
sprintf ( line , " %i(???) " , ofs ) ;
else
{
s = PR_ValueString ( def - > type , val ) ;
sprintf ( line , " %i(%s)%s " , ofs , pr_strings + def - > s_name , s ) ;
}
i = strlen ( line ) ;
for ( ; i < 20 ; i + + )
strcat ( line , " " ) ;
strcat ( line , " " ) ;
return line ;
}
char * PR_GlobalStringNoContents ( int ofs )
{
int i ;
ddef_t * def ;
static char line [ 128 ] ;
def = ED_GlobalAtOfs ( ofs ) ;
if ( ! def )
sprintf ( line , " %i(???) " , ofs ) ;
else
sprintf ( line , " %i(%s) " , ofs , pr_strings + def - > s_name ) ;
i = strlen ( line ) ;
for ( ; i < 20 ; i + + )
strcat ( line , " " ) ;
strcat ( line , " " ) ;
return line ;
}
/*
= = = = = = = = = = = = =
ED_Print
For debugging
= = = = = = = = = = = = =
*/
void ED_Print ( edict_t * ed )
{
int l ;
ddef_t * d ;
int * v ;
int i , j ;
char * name ;
int type ;
if ( ed - > free )
{
Con_Printf ( " FREE \n " ) ;
return ;
}
Con_Printf ( " \n EDICT %i: \n " , NUM_FOR_EDICT ( ed ) ) ;
for ( i = 1 ; i < progs - > numfielddefs ; i + + )
{
d = & pr_fielddefs [ i ] ;
name = pr_strings + d - > s_name ;
if ( name [ strlen ( name ) - 2 ] = = ' _ ' )
continue ; // skip _x, _y, _z vars
v = ( int * ) ( ( char * ) & ed - > v + d - > ofs * 4 ) ;
// if the value is still all 0, skip the field
type = d - > type & ~ DEF_SAVEGLOBAL ;
for ( j = 0 ; j < type_size [ type ] ; j + + )
if ( v [ j ] )
break ;
if ( j = = type_size [ type ] )
continue ;
Con_Printf ( " %s " , name ) ;
l = strlen ( name ) ;
while ( l + + < 15 )
Con_Printf ( " " ) ;
Con_Printf ( " %s \n " , PR_ValueString ( d - > type , ( eval_t * ) v ) ) ;
}
}
/*
= = = = = = = = = = = = =
ED_Write
For savegames
= = = = = = = = = = = = =
*/
void ED_Write ( FILE * f , edict_t * ed )
{
ddef_t * d ;
int * v ;
int i , j ;
char * name ;
int type ;
fprintf ( f , " { \n " ) ;
if ( ed - > free )
{
fprintf ( f , " } \n " ) ;
return ;
}
for ( i = 1 ; i < progs - > numfielddefs ; i + + )
{
d = & pr_fielddefs [ i ] ;
name = pr_strings + d - > s_name ;
if ( name [ strlen ( name ) - 2 ] = = ' _ ' )
continue ; // skip _x, _y, _z vars
v = ( int * ) ( ( char * ) & ed - > v + d - > ofs * 4 ) ;
// if the value is still all 0, skip the field
type = d - > type & ~ DEF_SAVEGLOBAL ;
for ( j = 0 ; j < type_size [ type ] ; j + + )
if ( v [ j ] )
break ;
if ( j = = type_size [ type ] )
continue ;
fprintf ( f , " \" %s \" " , name ) ;
fprintf ( f , " \" %s \" \n " , PR_UglyValueString ( d - > type , ( eval_t * ) v ) ) ;
}
fprintf ( f , " } \n " ) ;
}
void ED_PrintNum ( int ent )
{
ED_Print ( EDICT_NUM ( ent ) ) ;
}
/*
= = = = = = = = = = = = =
ED_PrintEdicts
For debugging , prints all the entities in the current server
= = = = = = = = = = = = =
*/
void ED_PrintEdicts ( void )
{
int i ;
Con_Printf ( " %i entities \n " , sv . num_edicts ) ;
for ( i = 0 ; i < sv . num_edicts ; i + + )
ED_PrintNum ( i ) ;
}
/*
= = = = = = = = = = = = =
ED_PrintEdict_f
For debugging , prints a single edict
= = = = = = = = = = = = =
*/
void ED_PrintEdict_f ( void )
{
int i ;
i = Q_atoi ( Cmd_Argv ( 1 ) ) ;
if ( i > = sv . num_edicts )
{
Con_Printf ( " Bad edict number \n " ) ;
return ;
}
ED_PrintNum ( i ) ;
}
/*
= = = = = = = = = = = = =
ED_Count
For debugging
= = = = = = = = = = = = =
*/
void ED_Count ( void )
{
int i ;
edict_t * ent ;
int active , models , solid , step ;
active = models = solid = step = 0 ;
for ( i = 0 ; i < sv . num_edicts ; i + + )
{
ent = EDICT_NUM ( i ) ;
if ( ent - > free )
continue ;
active + + ;
if ( ent - > v . solid )
solid + + ;
if ( ent - > v . model )
models + + ;
if ( ent - > v . movetype = = MOVETYPE_STEP )
step + + ;
}
Con_Printf ( " num_edicts:%3i \n " , sv . num_edicts ) ;
Con_Printf ( " active :%3i \n " , active ) ;
Con_Printf ( " view :%3i \n " , models ) ;
Con_Printf ( " touch :%3i \n " , solid ) ;
Con_Printf ( " step :%3i \n " , step ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
ARCHIVING GLOBALS
FIXME : need to tag constants , doesn ' t really work
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = =
ED_WriteGlobals
= = = = = = = = = = = = =
*/
void ED_WriteGlobals ( FILE * f )
{
ddef_t * def ;
int i ;
char * name ;
int type ;
fprintf ( f , " { \n " ) ;
for ( i = 0 ; i < progs - > numglobaldefs ; i + + )
{
def = & pr_globaldefs [ i ] ;
type = def - > type ;
if ( ! ( def - > type & DEF_SAVEGLOBAL ) )
continue ;
type & = ~ DEF_SAVEGLOBAL ;
if ( type ! = ev_string
& & type ! = ev_float
& & type ! = ev_entity )
continue ;
name = pr_strings + def - > s_name ;
fprintf ( f , " \" %s \" " , name ) ;
fprintf ( f , " \" %s \" \n " , PR_UglyValueString ( type , ( eval_t * ) & pr_globals [ def - > ofs ] ) ) ;
}
fprintf ( f , " } \n " ) ;
}
/*
= = = = = = = = = = = = =
ED_ParseGlobals
= = = = = = = = = = = = =
*/
void ED_ParseGlobals ( char * data )
{
char keyname [ 64 ] ;
ddef_t * key ;
while ( 1 )
{
// parse key
data = COM_Parse ( data ) ;
if ( com_token [ 0 ] = = ' } ' )
break ;
if ( ! data )
Sys_Error ( " ED_ParseEntity: EOF without closing brace " ) ;
strcpy ( keyname , com_token ) ;
// parse value
data = COM_Parse ( data ) ;
if ( ! data )
Sys_Error ( " ED_ParseEntity: EOF without closing brace " ) ;
if ( com_token [ 0 ] = = ' } ' )
Sys_Error ( " ED_ParseEntity: closing brace without data " ) ;
key = ED_FindGlobal ( keyname ) ;
if ( ! key )
{
Con_Printf ( " '%s' is not a global \n " , keyname ) ;
continue ;
}
if ( ! ED_ParseEpair ( ( void * ) pr_globals , key , com_token ) )
Host_Error ( " ED_ParseGlobals: parse error " ) ;
}
}
//============================================================================
/*
= = = = = = = = = = = = =
ED_NewString
= = = = = = = = = = = = =
*/
char * ED_NewString ( char * string )
{
char * new , * new_p ;
int i , l ;
l = strlen ( string ) + 1 ;
new = Hunk_Alloc ( l ) ;
new_p = new ;
for ( i = 0 ; i < l ; i + + )
{
if ( string [ i ] = = ' \\ ' & & i < l - 1 )
{
i + + ;
if ( string [ i ] = = ' n ' )
* new_p + + = ' \n ' ;
else
* new_p + + = ' \\ ' ;
}
else
* new_p + + = string [ i ] ;
}
return new ;
}
/*
= = = = = = = = = = = = =
ED_ParseEval
Can parse either fields or globals
returns false if error
= = = = = = = = = = = = =
*/
qboolean ED_ParseEpair ( void * base , ddef_t * key , char * s )
{
int i ;
char string [ 128 ] ;
ddef_t * def ;
char * v , * w ;
void * d ;
dfunction_t * func ;
d = ( void * ) ( ( int * ) base + key - > ofs ) ;
switch ( key - > type & ~ DEF_SAVEGLOBAL )
{
case ev_string :
* ( string_t * ) d = ED_NewString ( s ) - pr_strings ;
break ;
case ev_float :
* ( float * ) d = atof ( s ) ;
break ;
case ev_vector :
strcpy ( string , s ) ;
v = string ;
w = string ;
for ( i = 0 ; i < 3 ; i + + )
{
while ( * v & & * v ! = ' ' )
v + + ;
* v = 0 ;
( ( float * ) d ) [ i ] = atof ( w ) ;
w = v = v + 1 ;
}
break ;
case ev_entity :
* ( int * ) d = EDICT_TO_PROG ( EDICT_NUM ( atoi ( s ) ) ) ;
break ;
case ev_field :
def = ED_FindField ( s ) ;
if ( ! def )
{
Con_Printf ( " Can't find field %s \n " , s ) ;
return false ;
}
* ( int * ) d = G_INT ( def - > ofs ) ;
break ;
case ev_function :
func = ED_FindFunction ( s ) ;
if ( ! func )
{
Con_Printf ( " Can't find function %s \n " , s ) ;
return false ;
}
* ( func_t * ) d = func - pr_functions ;
break ;
default :
break ;
}
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = =
ED_ParseEdict
Parses an edict out of the given string , returning the new position
ed should be a properly initialized empty edict .
Used for initial level load and for savegames .
= = = = = = = = = = = = = = = = = = = =
*/
char * ED_ParseEdict ( char * data , edict_t * ent )
{
ddef_t * key ;
qboolean anglehack ;
qboolean init ;
char keyname [ 256 ] ;
int n ;
2014-04-12 12:29:30 +00:00
vec3_t col ;
2014-04-12 12:19:49 +00:00
init = false ;
// clear it
if ( ent ! = sv . edicts ) // hack
memset ( & ent - > v , 0 , progs - > entityfields * 4 ) ;
// go through all the dictionary pairs
while ( 1 )
{
// parse key
data = COM_Parse ( data ) ;
if ( com_token [ 0 ] = = ' } ' )
break ;
if ( ! data )
Sys_Error ( " ED_ParseEntity: EOF without closing brace " ) ;
2014-04-12 12:29:30 +00:00
2014-04-12 12:19:49 +00:00
// anglehack is to allow QuakeEd to write single scalar angles
// and allow them to be turned into vectors. (FIXME...)
if ( ! strcmp ( com_token , " angle " ) )
{
strcpy ( com_token , " angles " ) ;
anglehack = true ;
}
else
anglehack = false ;
// FIXME: change light to _light to get rid of this hack
if ( ! strcmp ( com_token , " light " ) )
strcpy ( com_token , " light_lev " ) ; // hack for single light def
2014-04-12 12:29:30 +00:00
2014-04-12 12:19:49 +00:00
strcpy ( keyname , com_token ) ;
2014-04-12 12:29:30 +00:00
2014-04-12 12:19:49 +00:00
// another hack to fix heynames with trailing spaces
n = strlen ( keyname ) ;
while ( n & & keyname [ n - 1 ] = = ' ' )
{
keyname [ n - 1 ] = 0 ;
n - - ;
}
// parse value
data = COM_Parse ( data ) ;
if ( ! data )
Sys_Error ( " ED_ParseEntity: EOF without closing brace " ) ;
if ( com_token [ 0 ] = = ' } ' )
Sys_Error ( " ED_ParseEntity: closing brace without data " ) ;
init = true ;
2014-04-12 12:29:30 +00:00
2014-04-12 12:19:49 +00:00
2014-04-12 12:29:30 +00:00
2014-04-12 12:19:49 +00:00
// keynames with a leading underscore are used for utility comments,
// and are immediately discarded by quake
if ( keyname [ 0 ] = = ' _ ' )
continue ;
key = ED_FindField ( keyname ) ;
if ( ! key )
{
2014-04-12 12:29:30 +00:00
//johnfitz -- HACK -- suppress error becuase fog/sky/alpha fields might not be mentioned in defs.qc
if ( strncmp ( keyname , " sky " , 3 ) & & strcmp ( keyname , " fog " ) & & strcmp ( keyname , " alpha " ) )
Con_DPrintf ( " \" %s \" is not a field \n " , keyname ) ; //johnfitz -- was Con_Printf
//Con_Printf ("'%s' is not a field\n", keyname);
2014-04-12 12:19:49 +00:00
continue ;
}
2014-04-12 12:29:30 +00:00
2014-04-12 12:19:49 +00:00
if ( anglehack )
{
char temp [ 32 ] ;
strcpy ( temp , com_token ) ;
sprintf ( com_token , " 0 %s 0 " , temp ) ;
}
if ( ! ED_ParseEpair ( ( void * ) & ent - > v , key , com_token ) )
Host_Error ( " ED_ParseEdict: parse error " ) ;
2014-04-12 12:29:30 +00:00
// if (!strncmp(keyname, "light_lev", 5)){
// Con_Printf ("\"%s\" your face is a field\n", keyname); //johnfitz -- was Con_Printf
// R_FlareTest(ent->v.origin, 21, 11, 11, 11, 0, NULL);
// }
2014-04-12 12:19:49 +00:00
}
if ( ! init )
ent - > free = true ;
2014-04-12 12:29:30 +00:00
2014-04-12 12:19:49 +00:00
return data ;
}
/*
= = = = = = = = = = = = = = = =
2014-04-12 12:29:30 +00:00
// leilei - allocate a wlight.
//if (data)
{
dlight_t * dl ;
//Con_Printf("light at %f %f %f", ent->v.origin[0],ent->v.origin[1],ent->v.origin[2]);
dl = CL_AllocDlight ( 66 ) ;
dl - > color [ 0 ] = 4.0f ;
dl - > color [ 1 ] = 2.0f ;
dl - > color [ 2 ] = 0.5f ; // TODO: get avg color from model
VectorCopy ( ent - > v . origin , dl - > origin ) ;
dl - > radius = 750 ;
dl - > die = cl . time + 60.5 ;
dl - > decay = 300 ;
2014-04-12 12:19:49 +00:00
ED_LoadFromFile
The entities are directly placed in the array , rather than allocated with
ED_Alloc , because otherwise an error loading the map would have entity
number references out of order .
Creates a server ' s entity / program execution context by
parsing textual entity definitions out of an ent file .
Used for both fresh maps and savegame loads . A fresh map would also need
to call ED_CallSpawnFunctions ( ) to let the objects initialize themselves .
= = = = = = = = = = = = = = = =
*/
2014-04-12 12:29:30 +00:00
# ifdef GLOBOT
void BotInit ( void ) ;
# endif
2014-04-12 12:19:49 +00:00
void ED_LoadFromFile ( char * data )
{
edict_t * ent ;
int inhibit ;
dfunction_t * func ;
ent = NULL ;
inhibit = 0 ;
pr_global_struct - > time = sv . time ;
// parse ents
while ( 1 )
{
// parse the opening brace
data = COM_Parse ( data ) ;
if ( ! data )
break ;
if ( com_token [ 0 ] ! = ' { ' )
Sys_Error ( " ED_LoadFromFile: found %s when expecting { " , com_token ) ;
if ( ! ent )
ent = EDICT_NUM ( 0 ) ;
else
ent = ED_Alloc ( ) ;
data = ED_ParseEdict ( data , ent ) ;
// remove things from different skill levels or deathmatch
if ( deathmatch - > value )
{
if ( ( ( int ) ent - > v . spawnflags & SPAWNFLAG_NOT_DEATHMATCH ) )
{
ED_Free ( ent ) ;
inhibit + + ;
continue ;
}
}
else if ( ( current_skill = = 0 & & ( ( int ) ent - > v . spawnflags & SPAWNFLAG_NOT_EASY ) )
| | ( current_skill = = 1 & & ( ( int ) ent - > v . spawnflags & SPAWNFLAG_NOT_MEDIUM ) )
| | ( current_skill > = 2 & & ( ( int ) ent - > v . spawnflags & SPAWNFLAG_NOT_HARD ) ) )
{
ED_Free ( ent ) ;
inhibit + + ;
continue ;
}
2014-04-12 12:29:30 +00:00
2014-04-12 12:19:49 +00:00
//
// immediately call spawn function
//
if ( ! ent - > v . classname )
{
Con_Printf ( " No classname for: \n " ) ;
ED_Print ( ent ) ;
ED_Free ( ent ) ;
continue ;
}
// look for the spawn function
func = ED_FindFunction ( pr_strings + ent - > v . classname ) ;
if ( ! func )
{
2014-04-12 12:29:30 +00:00
if ( developer - > value > 55 ) {
2014-04-12 12:19:49 +00:00
Con_Printf ( " No spawn function for: \n " ) ;
2014-04-12 12:29:30 +00:00
ED_Print ( ent ) ; // leilei - suppress these messages...
}
2014-04-12 12:19:49 +00:00
ED_Free ( ent ) ;
continue ;
}
pr_global_struct - > self = EDICT_TO_PROG ( ent ) ;
2014-04-12 12:29:30 +00:00
# ifdef GLOBOT
if ( ! strcmp ( pr_strings + ent - > v . classname , " worldspawn " ) )
BotInit ( ) ;
# endif
2014-04-12 12:19:49 +00:00
PR_ExecuteProgram ( func - pr_functions ) ;
}
Con_DPrintf ( " %i entities inhibited \n " , inhibit ) ;
}
qboolean keep_compatibility ; // 1999-10-28 Compatibilty check by Maddes
/*
= = = = = = = = = = = = = = =
PR_LoadProgs
= = = = = = = = = = = = = = =
*/
void PR_LoadProgs ( void )
{
int i ;
dfunction_t * f ; // 2000-01-02 EndFrame function by Maddes/FrikaC
loadedfile_t * fileinfo ; // 2001-09-12 Returning information about loaded file by Maddes
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm start
int j ;
int funcno ;
char * funcname ;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm end
etype_t type ; // 2001-10-20 TIMESCALE extension by Tomaz/Maddes
// flush the non-C variable lookup cache
for ( i = 0 ; i < GEFV_CACHESIZE ; i + + )
gefvCache [ i ] . field [ 0 ] = 0 ;
CRC_Init ( & pr_crc ) ;
// 2001-09-12 Returning information about loaded file by Maddes start
/*
progs = ( dprograms_t * ) COM_LoadHunkFile ( " progs.dat " ) ;
if ( ! progs )
*/
fileinfo = COM_LoadHunkFile ( " progs.dat " ) ;
if ( ! fileinfo )
// 2001-09-12 Returning information about loaded file by Maddes end
Sys_Error ( " PR_LoadProgs: couldn't load progs.dat " ) ;
progs = ( dprograms_t * ) fileinfo - > data ; // 2001-09-12 Returning information about loaded file by Maddes
Con_DPrintf ( " Programs occupy %iK. \n " , com_filesize / 1024 ) ;
for ( i = 0 ; i < com_filesize ; i + + )
CRC_ProcessByte ( & pr_crc , ( ( byte * ) progs ) [ i ] ) ;
// byte swap the header
for ( i = 0 ; i < sizeof ( * progs ) / 4 ; i + + )
( ( int * ) progs ) [ i ] = LittleLong ( ( ( int * ) progs ) [ i ] ) ;
if ( progs - > version ! = PROG_VERSION )
Sys_Error ( " progs.dat has wrong version number (%i should be %i) " , progs - > version , PROG_VERSION ) ;
// 1999-10-28 Compatibilty check by Maddes start
// if (progs->crc != PROGHEADER_CRC)
if ( progs - > crc = = PROGHEADER101_CRC )
{
keep_compatibility = true ;
Con_DPrintf ( " Old progs.dat found, compatibility turned on. \n " ) ;
}
else if ( progs - > crc = = PROGHEADER_CRC )
// || (progs->crc == PROGHEADER107_CRC)
{
keep_compatibility = false ;
Con_DPrintf ( " Enhanced progs.dat found, CRC is %i. \n " , progs - > crc ) ;
}
else
// 1999-10-28 Compatibilty check by Maddes end
2014-04-12 12:29:30 +00:00
Sys_Error ( " progs.dat CRC is %i and no sir i don't like it. \n \n progs.dat system vars have been modified, progdefs.h is out of date " , progs - > crc ) ;
//Sys_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
2014-04-12 12:19:49 +00:00
pr_functions = ( dfunction_t * ) ( ( byte * ) progs + progs - > ofs_functions ) ;
pr_strings = ( char * ) progs + progs - > ofs_strings ;
pr_globaldefs = ( ddef_t * ) ( ( byte * ) progs + progs - > ofs_globaldefs ) ;
pr_fielddefs = ( ddef_t * ) ( ( byte * ) progs + progs - > ofs_fielddefs ) ;
pr_statements = ( dstatement_t * ) ( ( byte * ) progs + progs - > ofs_statements ) ;
2014-04-12 12:29:30 +00:00
//if (qbeta)
// pr_global_struct = pr_global_struct = (globalvarsbeta_t *)((byte *)progs + progs->ofs_globals);
//else
2014-04-12 12:19:49 +00:00
pr_global_struct = ( globalvars_t * ) ( ( byte * ) progs + progs - > ofs_globals ) ;
pr_globals = ( float * ) pr_global_struct ;
pr_edict_size = progs - > entityfields * 4 + sizeof ( edict_t ) - sizeof ( entvars_t ) ;
// byte swap the lumps
for ( i = 0 ; i < progs - > numstatements ; i + + )
{
pr_statements [ i ] . op = LittleShort ( pr_statements [ i ] . op ) ;
pr_statements [ i ] . a = LittleShort ( pr_statements [ i ] . a ) ;
pr_statements [ i ] . b = LittleShort ( pr_statements [ i ] . b ) ;
pr_statements [ i ] . c = LittleShort ( pr_statements [ i ] . c ) ;
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm start
// initialize function numbers for PROGS.DAT
pr_numbuiltins = 0 ;
pr_builtins = NULL ;
if ( pr_builtin_remap - > value )
{
// remove all previous assigned function numbers
for ( j = 1 ; j < pr_ebfs_numbuiltins ; j + + )
{
pr_ebfs_builtins [ j ] . funcno = 0 ;
}
}
else
{
// use default function numbers
for ( j = 1 ; j < pr_ebfs_numbuiltins ; j + + )
{
pr_ebfs_builtins [ j ] . funcno = pr_ebfs_builtins [ j ] . default_funcno ;
// determine highest builtin number (when NOT remapped)
if ( pr_ebfs_builtins [ j ] . funcno > pr_numbuiltins )
{
pr_numbuiltins = pr_ebfs_builtins [ j ] . funcno ;
}
}
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm end
for ( i = 0 ; i < progs - > numfunctions ; i + + )
{
pr_functions [ i ] . first_statement = LittleLong ( pr_functions [ i ] . first_statement ) ;
pr_functions [ i ] . parm_start = LittleLong ( pr_functions [ i ] . parm_start ) ;
pr_functions [ i ] . s_name = LittleLong ( pr_functions [ i ] . s_name ) ;
pr_functions [ i ] . s_file = LittleLong ( pr_functions [ i ] . s_file ) ;
pr_functions [ i ] . numparms = LittleLong ( pr_functions [ i ] . numparms ) ;
pr_functions [ i ] . locals = LittleLong ( pr_functions [ i ] . locals ) ;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm start
if ( pr_builtin_remap - > value )
{
if ( pr_functions [ i ] . first_statement < 0 ) // builtin function
{
funcno = - pr_functions [ i ] . first_statement ;
funcname = pr_strings + pr_functions [ i ] . s_name ;
// search function name
for ( j = 1 ; j < pr_ebfs_numbuiltins ; j + + )
{
if ( ! ( Q_strcasecmp ( funcname , pr_ebfs_builtins [ j ] . funcname ) ) )
{
break ; // found
}
}
if ( j < pr_ebfs_numbuiltins ) // found
{
pr_ebfs_builtins [ j ] . funcno = funcno ;
}
else
{
Con_DPrintf ( " Can not assign builtin number #%i to %s - function unknown \n " , funcno , funcname ) ;
}
}
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm end
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm start
if ( pr_builtin_remap - > value )
{
// check for unassigned functions and try to assign their default function number
for ( i = 1 ; i < pr_ebfs_numbuiltins ; i + + )
{
if ( ( ! pr_ebfs_builtins [ i ] . funcno ) & & ( pr_ebfs_builtins [ i ] . default_funcno ) ) // unassigned and has a default number
{
// check if default number is already assigned to another function
for ( j = 1 ; j < pr_ebfs_numbuiltins ; j + + )
{
if ( pr_ebfs_builtins [ j ] . funcno = = pr_ebfs_builtins [ i ] . default_funcno )
{
break ; // number already assigned to another builtin function
}
}
if ( j < pr_ebfs_numbuiltins ) // already assigned
{
Con_DPrintf ( " Can not assign default builtin number #%i to %s - number is already assigned to %s \n " , pr_ebfs_builtins [ i ] . default_funcno , pr_ebfs_builtins [ i ] . funcname , pr_ebfs_builtins [ j ] . funcname ) ;
}
else
{
pr_ebfs_builtins [ i ] . funcno = pr_ebfs_builtins [ i ] . default_funcno ;
}
}
// determine highest builtin number (when remapped)
if ( pr_ebfs_builtins [ i ] . funcno > pr_numbuiltins )
{
pr_numbuiltins = pr_ebfs_builtins [ i ] . funcno ;
}
}
}
pr_numbuiltins + + ;
// allocate and initialize builtin list for execution time
pr_builtins = Hunk_AllocName ( pr_numbuiltins * sizeof ( builtin_t ) , " builtins " ) ;
for ( i = 0 ; i < pr_numbuiltins ; i + + )
{
pr_builtins [ i ] = pr_ebfs_builtins [ 0 ] . function ;
}
// create builtin list for execution time and set cvars accordingly
Cvar_Set ( pr_builtin_find , " 0 " ) ;
Cvar_Set ( pr_checkextension , " 0 " ) ; // 2001-10-20 Extension System by LordHavoc/Maddes (DP compatibility)
for ( j = 1 ; j < pr_ebfs_numbuiltins ; j + + )
{
if ( pr_ebfs_builtins [ j ] . funcno ) // only put assigned functions into builtin list
{
pr_builtins [ pr_ebfs_builtins [ j ] . funcno ] = pr_ebfs_builtins [ j ] . function ;
}
if ( pr_ebfs_builtins [ j ] . default_funcno = = PR_DEFAULT_FUNCNO_BUILTIN_FIND )
{
Cvar_SetValue ( pr_builtin_find , pr_ebfs_builtins [ j ] . funcno ) ;
}
// 2001-10-20 Extension System by LordHavoc/Maddes (DP compatibility) start
if ( pr_ebfs_builtins [ j ] . default_funcno = = PR_DEFAULT_FUNCNO_EXTENSION_FIND )
{
Cvar_SetValue ( pr_checkextension , pr_ebfs_builtins [ j ] . funcno ) ;
}
// 2001-10-20 Extension System by LordHavoc/Maddes (DP compatibility) end
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm end
for ( i = 0 ; i < progs - > numglobaldefs ; i + + )
{
pr_globaldefs [ i ] . type = LittleShort ( pr_globaldefs [ i ] . type ) ;
pr_globaldefs [ i ] . ofs = LittleShort ( pr_globaldefs [ i ] . ofs ) ;
pr_globaldefs [ i ] . s_name = LittleLong ( pr_globaldefs [ i ] . s_name ) ;
}
for ( i = 0 ; i < progs - > numfielddefs ; i + + )
{
pr_fielddefs [ i ] . type = LittleShort ( pr_fielddefs [ i ] . type ) ;
if ( pr_fielddefs [ i ] . type & DEF_SAVEGLOBAL )
Sys_Error ( " PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL " ) ;
pr_fielddefs [ i ] . ofs = LittleShort ( pr_fielddefs [ i ] . ofs ) ;
pr_fielddefs [ i ] . s_name = LittleLong ( pr_fielddefs [ i ] . s_name ) ;
}
for ( i = 0 ; i < progs - > numglobals ; i + + )
( ( int * ) pr_globals ) [ i ] = LittleLong ( ( ( int * ) pr_globals ) [ i ] ) ;
// 2000-04-30 NVS HANDSHAKE SRV<->CL/QC<->CL by Maddes start
// check if the QuakeC code wants to know the NVS versions of the server and clients
pr_field_nvs_svc = ED_FindField ( " nvs_svc " ) ;
if ( pr_field_nvs_svc )
{
type = pr_field_nvs_svc - > type ;
type & = ~ DEF_SAVEGLOBAL ;
if ( type ! = ev_float )
{
pr_field_nvs_svc = NULL ;
}
}
// 2000-04-30 NVS HANDSHAKE SRV<->CL/QC<->CL by Maddes ent
// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes start
// search for the definition only once
pr_field_ammo_shells1 = ED_FindField ( " ammo_shells1 " ) ;
pr_field_ammo_nails1 = ED_FindField ( " ammo_nails1 " ) ;
pr_field_ammo_lava_nails = ED_FindField ( " ammo_lava_nails " ) ;
pr_field_ammo_rockets1 = ED_FindField ( " ammo_rockets1 " ) ;
pr_field_ammo_multi_rockets = ED_FindField ( " ammo_multi_rockets " ) ;
pr_field_ammo_cells1 = ED_FindField ( " ammo_cells1 " ) ;
pr_field_ammo_plasma = ED_FindField ( " ammo_plasma " ) ;
pr_field_idealpitch = ED_FindField ( " idealpitch " ) ;
pr_field_pitch_speed = ED_FindField ( " pitch_speed " ) ;
pr_field_items2 = ED_FindField ( " items2 " ) ;
pr_field_gravity = ED_FindField ( " gravity " ) ;
2014-04-12 12:29:30 +00:00
pr_field_alpha = ED_FindField ( " alpha " ) ;
pr_field_scale = ED_FindField ( " scale " ) ;
pr_field_glowcolor = ED_FindField ( " glow_color " ) ;
pr_field_glowsize = ED_FindField ( " glow_size " ) ;
2014-04-12 12:19:49 +00:00
// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes end
2014-04-12 12:29:30 +00:00
// leilei
2014-04-12 12:19:49 +00:00
// 2000-01-02 EndFrame function by Maddes/FrikaC start
pr_func_endframe = 0 ;
if ( ( f = ED_FindFunction ( " EndFrame " ) ) ! = NULL )
{
pr_func_endframe = ( func_t ) ( f - pr_functions ) ;
}
// 2000-01-02 EndFrame function by Maddes/FrikaC end
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes start
pr_global_cpu_frametime = ED_FindGlobal ( " cpu_frametime " ) ;
if ( pr_global_cpu_frametime )
{
type = pr_global_cpu_frametime - > type ;
type & = ~ DEF_SAVEGLOBAL ;
if ( type ! = ev_float )
{
pr_global_cpu_frametime = NULL ;
}
}
pr_global_org_frametime = ED_FindGlobal ( " org_frametime " ) ;
if ( pr_global_org_frametime )
{
type = pr_global_org_frametime - > type ;
type & = ~ DEF_SAVEGLOBAL ;
if ( type ! = ev_float )
{
pr_global_org_frametime = NULL ;
}
}
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes end
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start
/*
= = = = = = = = = = = = =
PR_BuiltInList_f
For debugging , prints all builtin functions with assigned and default number
= = = = = = = = = = = = =
*/
void PR_BuiltInList_f ( void )
{
int i ;
char * partial ;
int len ;
int count ;
if ( Cmd_Argc ( ) > 1 )
{
partial = Cmd_Argv ( 1 ) ;
len = strlen ( partial ) ;
}
else
{
partial = NULL ;
len = 0 ;
}
count = 0 ;
for ( i = 1 ; i < pr_ebfs_numbuiltins ; i + + )
{
if ( partial & & Q_strncasecmp ( partial , pr_ebfs_builtins [ i ] . funcname , len ) )
{
continue ;
}
count + + ;
Con_Printf ( " %i(%i): %s \n " , pr_ebfs_builtins [ i ] . funcno , pr_ebfs_builtins [ i ] . default_funcno , pr_ebfs_builtins [ i ] . funcname ) ;
}
Con_Printf ( " ------------ \n " ) ;
if ( partial )
{
Con_Printf ( " %i beginning with \" %s \" out of " , count , partial ) ;
}
Con_Printf ( " %i builtin functions \n " , i ) ;
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end
// 2001-09-18 New cvar system by Maddes (Init) start
/*
= = = = = = = = = = = = = = =
PR_Init_Cvars
= = = = = = = = = = = = = = =
*/
void PR_Init_Cvars ( void )
{
nomonsters = Cvar_Get ( " nomonsters " , " 0 " , CVAR_ORIGINAL ) ;
gamecfg = Cvar_Get ( " gamecfg " , " 0 " , CVAR_ORIGINAL ) ;
scratch1 = Cvar_Get ( " scratch1 " , " 0 " , CVAR_ORIGINAL ) ;
scratch2 = Cvar_Get ( " scratch2 " , " 0 " , CVAR_ORIGINAL ) ;
scratch3 = Cvar_Get ( " scratch3 " , " 0 " , CVAR_ORIGINAL ) ;
scratch4 = Cvar_Get ( " scratch4 " , " 0 " , CVAR_ORIGINAL ) ;
savedgamecfg = Cvar_Get ( " savedgamecfg " , " 0 " , CVAR_ARCHIVE | CVAR_ORIGINAL ) ;
saved1 = Cvar_Get ( " saved1 " , " 0 " , CVAR_ARCHIVE | CVAR_ORIGINAL ) ;
saved2 = Cvar_Get ( " saved2 " , " 0 " , CVAR_ARCHIVE | CVAR_ORIGINAL ) ;
saved3 = Cvar_Get ( " saved3 " , " 0 " , CVAR_ARCHIVE | CVAR_ORIGINAL ) ;
saved4 = Cvar_Get ( " saved4 " , " 0 " , CVAR_ARCHIVE | CVAR_ORIGINAL ) ;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start
pr_builtin_find = Cvar_Get ( " pr_builtin_find " , " 0 " , CVAR_ROM ) ;
pr_builtin_remap = Cvar_Get ( " pr_builtin_remap " , " 0 " , CVAR_NONE ) ;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end
pr_checkextension = Cvar_Get ( " pr_checkextension " , " 0 " , CVAR_ROM ) ; // 2001-10-20 Extension System by LordHavoc/Maddes (DP compatibility)
// 2001-09-20 QuakeC string zone by Maddes start
pr_zone_min_strings = Cvar_Get ( " pr_zone_min_strings " , " 64 " , CVAR_NONE ) ;
Cvar_SetRangecheck ( pr_zone_min_strings , Cvar_RangecheckInt , 64 , 8 * 1024 ) ; // up to 8MB
Cvar_SetDescription ( pr_zone_min_strings , " States the size in KB of the zone for PROGS.DAT strings. Note that the PROGS.DAT may set this cvar itself. " ) ;
Cvar_Set ( pr_zone_min_strings , pr_zone_min_strings - > string ) ; // do rangecheck
// 2001-09-20 QuakeC string zone by Maddes end
}
// 2001-09-18 New cvar system by Maddes (Init) end
/*
= = = = = = = = = = = = = = =
PR_Init
= = = = = = = = = = = = = = =
*/
void PR_Init ( void )
{
Cmd_AddCommand ( " edict " , ED_PrintEdict_f ) ;
Cmd_AddCommand ( " edicts " , ED_PrintEdicts ) ;
Cmd_AddCommand ( " edictcount " , ED_Count ) ;
Cmd_AddCommand ( " profile " , PR_Profile_f ) ;
Cmd_AddCommand ( " builtinlist " , PR_BuiltInList_f ) ; // 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes
Cmd_AddCommand ( " extensionlist " , PR_Extension_List_f ) ; // 2001-10-20 Extension System by LordHavoc/Maddes
// 2001-09-18 New cvar system by Maddes (Init) start
/*
nomonsters = Cvar_Get ( " nomonsters " , " 0 " , CVAR_ORIGINAL ) ;
gamecfg = Cvar_Get ( " gamecfg " , " 0 " , CVAR_ORIGINAL ) ;
scratch1 = Cvar_Get ( " scratch1 " , " 0 " , CVAR_ORIGINAL ) ;
scratch2 = Cvar_Get ( " scratch2 " , " 0 " , CVAR_ORIGINAL ) ;
scratch3 = Cvar_Get ( " scratch3 " , " 0 " , CVAR_ORIGINAL ) ;
scratch4 = Cvar_Get ( " scratch4 " , " 0 " , CVAR_ORIGINAL ) ;
savedgamecfg = Cvar_Get ( " savedgamecfg " , " 0 " , CVAR_ARCHIVE | CVAR_ORIGINAL ) ;
saved1 = Cvar_Get ( " saved1 " , " 0 " , CVAR_ARCHIVE | CVAR_ORIGINAL ) ;
saved2 = Cvar_Get ( " saved2 " , " 0 " , CVAR_ARCHIVE | CVAR_ORIGINAL ) ;
saved3 = Cvar_Get ( " saved3 " , " 0 " , CVAR_ARCHIVE | CVAR_ORIGINAL ) ;
saved4 = Cvar_Get ( " saved4 " , " 0 " , CVAR_ARCHIVE | CVAR_ORIGINAL ) ;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start
pr_builtin_find = Cvar_Get ( " pr_builtin_find " , " 0 " , CVAR_ROM ) ;
pr_builtin_remap = Cvar_Get ( " pr_builtin_remap " , " 0 " , CVAR_NONE ) ;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end
// pr_checkextension = Cvar_Get ("pr_checkextension", "0", CVAR_ROM); // 2001-10-20 Extension System by LordHavoc/Maddes (DP compatibility)
*/
// 2001-09-18 New cvar system by Maddes (Init) end
}
edict_t * EDICT_NUM ( int n )
{
if ( n < 0 | | n > = sv . max_edicts )
Sys_Error ( " EDICT_NUM: bad number %i " , n ) ;
return ( edict_t * ) ( ( byte * ) sv . edicts + ( n ) * pr_edict_size ) ;
}
int NUM_FOR_EDICT ( edict_t * e )
{
int b ;
b = ( byte * ) e - ( byte * ) sv . edicts ;
b = b / pr_edict_size ;
if ( b < 0 | | b > = sv . num_edicts )
Sys_Error ( " NUM_FOR_EDICT: bad pointer " ) ;
return b ;
}