📄 g_spawn.cpp
字号:
num = arc.ReadInteger();
spawnArgList.Resize( num );
for( i = 1; i <= num; i++ )
{
arc.ReadObject( spawnArgList.AddressOfObjectAt( i ) );
}
}
/****************************************************************************
SpawnArgsForEntity Class Definition
****************************************************************************/
CLASS_DECLARATION( Class, SpawnArgsForEntity, NULL );
ResponseDef SpawnArgsForEntity::Responses[] =
{
{ NULL, NULL }
};
void SpawnArgsForEntity::Reset
(
void
)
{
groupList.FreeObjectList();
entnumList.FreeObjectList();
}
void SpawnArgsForEntity::AddEnt
(
Entity *ent
)
{
int num;
SpawnArgGroup group;
if ( ent && ent->isSubclassOf( Sentient ) )
{
G_InitSpawnArguments();
entnumList.AddObject( ent->entnum );
groupList.AddObject( group );
num = groupList.NumObjects();
groupList.Resize( num );
entnumList.Resize( num );
( ( Sentient * )ent )->WritePersistantData( groupList.ObjectAt( num ) );
}
}
qboolean SpawnArgsForEntity::RestoreEnt
(
Entity *ent
)
{
int num;
SpawnArgGroup *group;
num = entnumList.IndexOfObject( ent->entnum );
if ( num && ent->isSubclassOf( Sentient ) )
{
group = groupList.AddressOfObjectAt( num );
( ( Sentient * )ent )->RestorePersistantData( *group );
G_InitSpawnArguments();
return true;
}
return false;
}
void SpawnArgsForEntity::RestoreEnts
(
void
)
{
int num;
int i;
int entnum;
edict_t *ent;
SpawnArgGroup *group;
num = groupList.NumObjects();
for( i = 1; i <= num; i++ )
{
entnum = entnumList.ObjectAt( i );
ent = &g_edicts[ entnum ];
group = groupList.AddressOfObjectAt( i );
group->RestoreArgs( 1 );
game.force_entnum = true;
game.spawn_entnum = ent->s.number;
G_CallSpawn();
game.force_entnum = false;
if ( ent->entity && ent->entity->isSubclassOf( Sentient ) )
{
( ( Sentient * )ent->entity )->RestorePersistantData( *group );
}
}
Reset();
}
void SpawnArgsForEntity::Archive
(
Archiver &arc
)
{
int i;
int num;
Class::Archive( arc );
num = groupList.NumObjects();
arc.WriteInteger( num );
for( i = 1; i <= num; i++ )
{
arc.WriteInteger( entnumList.ObjectAt( i ) );
arc.WriteObject( groupList.AddressOfObjectAt( i ) );
}
}
void SpawnArgsForEntity::Unarchive
(
Archiver &arc
)
{
int i;
int num;
Reset();
Class::Unarchive( arc );
num = arc.ReadInteger();
entnumList.Resize( num );
groupList.Resize( num );
for( i = 1; i <= num; i++ )
{
arc.ReadInteger( entnumList.AddressOfObjectAt( i ) );
arc.ReadObject( groupList.AddressOfObjectAt( i ) );
}
}
/****************************************************************************
spawn arg management
****************************************************************************/
void G_SetFloatArg
(
const char *key,
double value
)
{
char text[ 20 ];
sprintf( text, "%f", value );
G_SetSpawnArg( key, text );
}
void G_SetIntArg
(
const char *key,
int value
)
{
char text[ 20 ];
sprintf( text, "%d", value );
G_SetSpawnArg( key, text );
}
void G_DefaultArg
(
const char *key,
const char *defaultvalue
)
{
if ( !G_GetSpawnArg( key ) )
{
G_SetSpawnArg( key, defaultvalue );
}
}
void G_DefaultFloatArg
(
const char *key,
double defaultvalue
)
{
if ( !G_GetSpawnArg( key ) )
{
G_SetFloatArg( key, defaultvalue );
}
}
void G_DefaultIntArg
(
const char *key,
int defaultvalue
)
{
if ( !G_GetSpawnArg( key ) )
{
G_SetIntArg( key, defaultvalue );
}
}
Vector G_GetVectorArg
(
const char *key,
Vector defaultvalue
)
{
const char *text;
text = G_GetSpawnArg( key );
if ( text )
{
return Vector(text);
}
return defaultvalue;
}
float G_GetFloatArg
(
const char *key,
double defaultvalue
)
{
const char *text;
text = G_GetSpawnArg( key );
if ( text )
{
return (float)atof( text );
}
return (float)defaultvalue;
}
int G_GetIntArg
(
const char *key,
int defaultvalue
)
{
const char *text;
text = G_GetSpawnArg( key );
if ( text )
{
return atoi( text );
}
return defaultvalue;
}
str G_GetStringArg
(
const char *key,
const char *defaultvalue
)
{
const char *text;
str ret;
text = G_GetSpawnArg( key );
if ( !text )
{
text = defaultvalue;
}
if ( text )
{
return text;
}
return "";
}
void G_InitSpawnArguments
(
void
)
{
int i;
numSpawnArgs = 0;
for( i = 0; i < NUM_SPAWN_ARGS; i++ )
{
memset( spawnArgs[ i ].key, 0, sizeof( spawnArgs[ i ].key ) );
memset( spawnArgs[ i ].value, 0, sizeof( spawnArgs[ i ].value ) );
}
}
qboolean G_SetSpawnArg
(
const char *keyname,
const char *value
)
{
int i;
for( i = 0; i < numSpawnArgs; i++ )
{
if ( !strcmp( keyname, spawnArgs[ i ].key ) )
{
break;
}
}
if ( i >= NUM_SPAWN_ARGS )
{
return false;
}
if ( i == numSpawnArgs )
{
strncpy( spawnArgs[ i ].key, keyname, sizeof( spawnArgs[ 0 ].key ) - 1 );
numSpawnArgs++;
}
strncpy( spawnArgs[ i ].value, value, sizeof( spawnArgs[ 0 ].value ) - 1 );
return true;
}
const char *G_GetSpawnArg
(
const char *key,
const char *defaultvalue
)
{
int i;
for( i = 0; i < numSpawnArgs; i++ )
{
if ( !strcmp( key, spawnArgs[ i ].key ) )
{
return spawnArgs[ i ].value;
}
}
return defaultvalue;
}
int G_GetNumSpawnArgs
(
void
)
{
return numSpawnArgs;
}
/*
===============
G_GetClassFromArgs
Finds the spawn function for the entity and returns ClassDef *
===============
*/
ClassDef *G_GetClassFromArgs
(
void
)
{
const char *classname;
ClassDef *cls = NULL;
classname = G_GetSpawnArg( "classname" );
//
// check normal spawn functions
// see if the class name is stored within the model
//
if ( classname )
{
cls = getClassForID( classname );
if ( !cls )
{
cls = getClass( classname );
}
}
if ( !cls )
{
const char *model;
//
// get Object in case we cannot find an alternative
//
cls = &Object::ClassInfo;
model = G_GetSpawnArg( "model" );
if ( model )
{
sinmdl_cmd_t *cmds;
int modelindex;
int i;
//
// get handle to def file
//
if ( ( strlen( model ) >= 3 ) && ( !strcmpi( &model[ strlen(model) - 3 ], "def" ) ) )
{
if ( !strchr( model, '\\' ) && !strchr( model, '/' ) )
{
char str[128];
strcpy( str, "models/" );
strcat( str, model );
modelindex = gi.modelindex( str );
}
else
modelindex = gi.modelindex( model );
if ( gi.IsModel( modelindex ) )
{
cmds = gi.InitCommands( modelindex );
if (cmds)
{
for (i=0;i<cmds->num_cmds;i++)
{
if ( !strcmpi( cmds->cmds[i].args[0], "classname" ) )
{
cls = getClass( cmds->cmds[i].args[1] );
break;
}
}
if ( i == cmds->num_cmds )
gi.dprintf( "Classname %s used, but 'classname' was not found in Initialization commands, using Object.\n", classname );
}
else
gi.dprintf( "Classname %s used, but SINMDL had no Initialization commands, using Object.\n", classname );
}
else
gi.dprintf( "Classname %s used, but SINMDL was not valid, using Object.\n", classname );
}
else
gi.dprintf( "Classname %s used, but model was not a SINMDL, using Object.\n", classname );
}
else
{
gi.dprintf( "Classname %s' used, but no model was set, using Object.\n", classname );
}
}
return cls;
}
/*
===============
G_CallSpawn
Finds the spawn function for the entity and calls it.
Returns pointer to Entity
===============
*/
Entity *G_CallSpawn
(
void
)
{
str classname;
ClassDef *cls;
Entity *obj;
classname = G_GetStringArg( "classname" );
cls = G_GetClassFromArgs();
if ( !cls )
{
gi.dprintf( "%s doesn't have a spawn function\n", classname.c_str() );
G_InitSpawnArguments();
return NULL;
}
obj = ( Entity * )cls->newInstance();
G_InitSpawnArguments();
if ( !obj )
{
gi.dprintf( "%s failed on newInstance\n", classname.c_str() );
return NULL;
}
return obj;
}
/*
====================
G_ParseEdict
Parses an edict out of the given string, returning the new position
ed should be a properly initialized empty edict.
====================
*/
const char *G_ParseEdict
(
const char *data
)
{
qboolean init;
char keyname[ 256 ];
const char *com_token;
init = false;
G_InitSpawnArguments();
// go through all the dictionary pairs
while (1)
{
// parse key
com_token = COM_Parse( &data );
if ( com_token[ 0 ] == '}' )
{
break;
}
if ( !data )
{
gi.error( "G_ParseEntity: EOF without closing brace" );
}
strncpy( keyname, com_token, sizeof( keyname ) - 1 );
// parse value
com_token = COM_Parse( &data );
if ( !data )
{
gi.error( "G_ParseEntity: EOF without closing brace" );
}
if ( com_token[ 0 ] == '}' )
{
gi.error( "G_ParseEntity: closing brace without data" );
}
init = true;
// keynames with a leading underscore are used for utility comments,
// and are immediately discarded by quake
if ( keyname[ 0 ] == '_' )
{
continue;
}
G_SetSpawnArg( keyname, com_token );
}
return data;
}
/*
================
G_FindTeams
Chain together all entities with a matching team field.
All but the first will have the FL_TEAMSLAVE flag set.
All but the last will have the teamchain field set to the next one
================
*/
void G_FindTeams (void)
{
edict_t *e;
edict_t *e2;
edict_t *next;
edict_t *next2;
Entity *chain;
Entity *ent;
Entity *ent2;
int c;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -