⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g_spawn.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 3 页
字号:

   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 + -