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

📄 g_main.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	for( i = 0; i < game.maxclients; i++ )
   	{
		ent = &g_edicts[ 1 + i ];
		if ( !ent->inuse || !ent->entity )
         {
			continue;
         }

      PersistantData.AddEnt( ent->entity );
	   }
   }

/*
=================
WriteLevel

=================
*/
void WriteLevel
   (
   const char *filename,
   qboolean autosave
   )

   {
	int		i;
   int      num;
	edict_t	*edict;
   Archiver arc;

   if ( autosave )
      {
	   for( i = 0; i < game.maxclients; i++ )
   	   {
		   edict = &g_edicts[ 1 + i ];
		   if ( !edict->inuse && !edict->entity )
            {
			   continue;
            }

         delete edict->entity;
	      }
      }

   arc.Create( filename );

   // write out the version number
   arc.WriteInteger( GAME_API_VERSION );
   arc.WriteInteger( SAVEGAME_VERSION );

   // Write out the pending events.  These are written first in case 
   // later objects need to post events when reading the archive.
   G_ArchiveEvents( arc );

	// write out level_locals_t
   arc.WriteObject( &level );

   // write out consoles
   arc.WriteObject( &consoleManager );

   // write out script librarian
   arc.WriteObject( &ScriptLib );

   // write out gravity paths
   arc.WriteObject( &gravPathManager );

   // write out paths
   arc.WriteObject( &PathManager );

   // write out script controller
   arc.WriteObject( &Director );

   // write out surface manager
   arc.WriteObject( &surfaceManager );

   // write out Viewmodel manager (for debugging only)
   arc.WriteObject( &Viewmodel );

	// count the entities
   num = 0;
	for( i = 0; i < globals.num_edicts; i++ )
	   {
		edict = &g_edicts[ i ];
		if ( edict->inuse && edict->entity && !( edict->entity->flags & FL_DONTSAVE ) )
         {
			num++;
         }
      }

	// write out all the entities
   arc.WriteInteger( globals.num_edicts );
   arc.WriteInteger( num );
	for( i = 0; i < globals.num_edicts; i++ )
	   {
		edict = &g_edicts[ i ];
		if ( !edict->inuse || !edict->entity || ( edict->entity->flags & FL_DONTSAVE ) )
         {
			continue;
         }

      arc.WriteObject( edict->entity );
	   }

   arc.Close();
   }

void G_WriteLevel
   (
   const char *filename,
   qboolean autosave
   )

	{
	// If we get an error, call the server's error function
	if ( setjmp( G_AbortGame ) )
		{
		G_ExitWithError();
		}

   WriteLevel( filename, autosave );
   }

/*
=================
ReadLevel

SpawnEntities will already have been called on the
level the same way it was when the level was saved.

That is necessary to get the baselines set up identically.

The server will have cleared all of the world links before
calling ReadLevel.

No clients are connected yet.
=================
*/
void ReadLevel
   (
   const char *filename
   )

   {
	int		i;
   int      num;
   Archiver arc;
   int      version;
   int      savegame_version;

   LoadingSavegame = true;

   // Get rid of anything left over from the last level
   G_LevelShutdown();
   G_ResetEdicts();

	arc.Read( filename );

   // read the version number
   arc.ReadInteger( &version );
   if ( version < GAME_API_VERSION )
      {
      gi.error( "Savegame from an older version (%d) of Sin.\n", version );
      }
   else if ( version > GAME_API_VERSION )
      {
      gi.error( "Savegame from version %d of Sin.\n", version );
      }

   arc.ReadInteger( &savegame_version );
   if ( savegame_version < SAVEGAME_VERSION )
      {
      gi.error( "Savegame from an older version (%d) of Sin.\n", version );
      }
   else if ( savegame_version > SAVEGAME_VERSION )
      {
      gi.error( "Savegame from version %d of Sin.\n", version );
      }

   // Read in the pending events.  These are read in first in case 
   // later objects need to post events.
   G_UnarchiveEvents( arc );

	// read level_locals_t
   arc.ReadObject( &level );

   // read consoles
   arc.ReadObject( &consoleManager );

   // read script librarian
   arc.ReadObject( &ScriptLib );

   // read gravity paths
   arc.ReadObject( &gravPathManager );

   // read paths
   arc.ReadObject( &PathManager );

   // read script controller
   arc.ReadObject( &Director );

   // read surface manager
   arc.ReadObject( &surfaceManager );

   // read Viewmodel manager (for debugging only)
   arc.ReadObject( &Viewmodel );

	// read all the entities
   arc.ReadInteger( &globals.num_edicts );
   arc.ReadInteger( &num );
	for( i = 0; i < num; i++ )
	   {
      arc.ReadObject();
	   }

   arc.Close();

   // call the precache scripts
   G_Precache();

   LoadingSavegame = false;
   }

void G_ReadLevel
   (
   const char *filename
   )

	{
	// If we get an error, call the server's error function
	if ( setjmp( G_AbortGame ) )
		{
		G_ExitWithError();
		}

   ReadLevel( filename );
   }

/*
=================
GetGameAPI

Returns a pointer to the structure with all entry points
and global variables
=================
*/
game_export_t *GetGameAPI
   (
   game_import_t *import
   )

	{
	gi = *import;

	globals.apiversion				= GAME_API_VERSION;
	globals.Init						= G_InitGame;
	globals.Shutdown					= G_ShutdownGame;
	globals.SpawnEntities			= G_SpawnEntities;
   globals.CreateSurfaces        = CreateSurfaces;

	globals.WriteGame					= G_WriteGame;
	globals.ReadGame					= G_ReadGame;
	globals.WriteLevel				= G_WriteLevel;
	globals.ReadLevel					= G_ReadLevel;

	globals.ClientThink				= G_ClientThink;
	globals.ClientConnect			= G_ClientConnect;
	globals.ClientUserinfoChanged = G_ClientUserinfoChanged;
	globals.ClientDisconnect		= G_ClientDisconnect;
	globals.ClientBegin				= G_ClientBegin;
	globals.ClientCommand			= G_ClientCommand;

	globals.RunFrame					= G_RunFrame;
	globals.ServerCommand         = G_ServerCommand;

	globals.edict_size		= sizeof(edict_t);
   globals.console_size		= sizeof(netconsole_t);
   globals.conbuffer_size	= sizeof(netconbuffer_t);
   globals.surface_size		= sizeof(netsurface_t);

	return &globals;
	}

#ifndef GAME_HARD_LINKED
// this is only here so the functions in q_shared.c and q_shwin.c can link
void Sys_Error
   (
   const char *error,
   ...
   )

	{
	va_list		argptr;
	char		text[1024];

	va_start (argptr, error);
	vsprintf (text, error, argptr);
	va_end (argptr);

	gi.error (ERR_FATAL, "%s", text);
	}

void Com_Printf
   (
   const char *msg,
   ...
   )

	{
	va_list		argptr;
	char		text[1024];

	va_start (argptr, msg);
	vsprintf (text, msg, argptr);
	va_end (argptr);

	gi.dprintf ("%s", text);
	}

#endif

//======================================================================


/*
=================
G_ClientEndServerFrames
=================
*/
void G_ClientEndServerFrames 
	(
	void
	)

	{
	int		i;
	edict_t	*ent;

	// calc the player views now that all pushing
	// and damage has been added
	for( i = 0; i < maxclients->value; i++ )
		{
		ent = g_edicts + 1 + i;
		if ( !ent->inuse || !ent->client || !ent->entity )
			{
			continue;
			}

		ent->entity->ProcessEvent( EV_ClientEndFrame );
		}
	}

/*
=================
G_EndDMLevel

The timelimit or fraglimit has been exceeded
=================
*/
void G_EndDMLevel 
	(
	void
	)

   {
	int                  num;
	TriggerChangeLevel   *ent;
   char                 *s, *t, *f;
	static const char    *seps = " ,\n\r";

	// stay on same level flag
	if ( DM_FLAG( DF_SAME_LEVEL ) )
		{
		G_BeginIntermission( level.mapname.c_str() );
	   return;
      }
	
 	// see if it's in the map list
	if ( *sv_maplist->string )
      {
		s = strdup(sv_maplist->string);
		f = NULL;
		t = strtok( s, seps );
		while ( t != NULL )
         {
			if ( !stricmp( t, level.mapname.c_str() ) )
            {
				// it's in the list, go to the next one
				t = strtok( NULL, seps );
				if ( t == NULL ) 
               { // end of list, go to first one
					if ( f == NULL ) // there isn't a first one, same level
						G_BeginIntermission( level.mapname.c_str() );
					else
						G_BeginIntermission( f );
				   }
            else
               {
					G_BeginIntermission( t );
               }
				free(s);
				return;
			}
			if (!f)
            {
            f = t;
            }
			t = strtok(NULL, seps);
		}
		free(s);
	}

   if ( !level.nextmap.length() )
		{
		// search for a changelevel
		num = G_FindClass( 0, "target_changelevel" );
		if ( !num )
			{
			// the map designer didn't include a changelevel,
			// so go back to the same level
			G_BeginIntermission( level.mapname.c_str() );
			}
		else
			{
			ent = ( TriggerChangeLevel * )G_GetEntity( num );
			G_BeginIntermission( ent->Map() );
			}
		}	
   }

/*
=================
G_CheckDMRules
=================
*/
void G_CheckDMRules 
	(
	void
	)

	{
	int			i;
	gclient_t	*cl;

	if ( level.intermissiontime )
		{
		return;
		}

	if ( !deathmatch->value )
		{
		return;
		}

	if ( timelimit->value )
		{
		if ( level.time >= timelimit->value * 60 )
			{
			gi.bprintf( PRINT_HIGH, "Timelimit hit.\n" );
			G_EndDMLevel();
			return;
			}
		}

	if ( fraglimit->value )
		{
		for( i = 0; i < maxclients->value; i++ )
			{
			cl = game.clients + i;
			if ( !g_edicts[ i + 1 ].inuse )
				{
				continue;
				}

			if ( cl->resp.score >= fraglimit->value )
				{
				gi.bprintf( PRINT_HIGH, "Fraglimit hit.\n" );
				G_EndDMLevel();
				return;
				}
			}
		}
	}

void G_MoveClientToIntermission
   (
   Entity *ent
   )

   {
   // Display the scores for the client
	if ( deathmatch->value || coop->value )
	   {
		ent->client->showinfo = true;
		G_DeathmatchScoreboardMessage( ent, NULL );
		gi.unicast( ent->edict, true );
	   }
   }

void G_BeginIntermission
	(
	const char *map
	)
	
	{
   edict_t	   *client;
   Entity      *ent;
   Entity      *path;
   int         i,num;
   Event       *event, event2;

	assert( map );
   if ( !map )
      {
      gi.dprintf( "G_BeginIntermission : Null map name\n" );
      return;
      }

   if ( level.missionfailed )
      {
      // don't allow map changes when a mission has failed
      return;
      }

	if ( level.intermissiontime )
		{
		// already activated
		return;
		}

	level.intermissiontime = level.time;

   if ( level.clearsavegames && ( map[ 0 ] != '*' ) )
      {
      level.nextmap = str( "*" ) + map;
      }
   else
      {
      level.nextmap = map;
      }

   level.clearsavegames = false;

   level.exitintermission = !( deathmatch->value || coop->value );
	
   // find an intermission spot
   num = G_FindClass( 0, "info_player_intermission" );

   // Only do the camera stuff if the node exists.
   if ( num )
      {
      ent = G_GetEntity( num );
	   SetCamera( ent );
      event = new Event( EV_Camera_Orbit );

      // Find the end node
      num = G_FindTarget( 0, "endnode1" );      
      if ( num )
         {
         path = G_GetEntity( num );
         event->AddEntity( path );
         ent->ProcessEvent( event );
         event = new Event( EV_Camera_JumpCut );
         ent->ProcessEvent( event );
         }
      }

   // Display scores for all the clients
	for( i = 0; i < maxclients->value; i++ )
      {
      client = g_edicts + 1 + i;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -