/* ================= G_ShutdownGame ================= */ void G_ShutdownGame( int restart ) { G_Printf ("==== ShutdownGame ====\n"); if ( level.logFile ) { G_LogPrintf("ShutdownGame:\n" ); G_LogPrintf("------------------------------------------------------------\n" ); trap_FS_FCloseFile( level.logFile ); } // write all the client session data so we can get it back G_WriteSessionData(); if ( trap_Cvar_VariableIntegerValue( "bot_enable" ) ) { BotAIShutdown( restart ); } }
/* ============== SpawnEntities Creates a server's entity / program execution context by parsing textual entity definitions out of an ent file. ============== */ void Level::SpawnEntities( const char *themapname, const char *entities, int levelTime ) { int inhibit,count=0; const char *value; SpawnArgs args; char *spawnpos; // Init the level variables Init(); spawnpos = const_cast<char*>(strchr( themapname, '$' )); if ( spawnpos ) { mapname = str( themapname, 0, spawnpos - themapname ); spawnpoint = spawnpos + 1; } else { mapname = themapname; spawnpoint = ""; } // set up time so functions still have valid times setTime( levelTime, 1000 / 20 ); if ( !LoadingServer ) { // Get rid of anything left over from the last level //CleanUp( false ); // Set up for a new map thePathManager.Init( mapname ); } setSkill( skill->integer ); // reset out count of the number of game traces sv_numtraces = 0; // parse world entities = args.Parse( entities ); spawn_entnum = ENTITYNUM_WORLD; args.Spawn(); if ( !world ) Com_Error( ERR_FATAL, "No world\n" ); if ( g_gametype->integer == GT_MULTIPLAYER || g_gametype->integer == GT_BOT_SINGLE_PLAYER ) { multiplayerManager.initMultiplayerGame(); } // parse ents inhibit = 0; for( entities = args.Parse( entities ); entities != NULL; entities = args.Parse( entities ) ) { // remove things (except the world) from different skill levels or deathmatch spawnflags = 0; value = args.getArg( "spawnflags" ); if ( value ) { spawnflags = atoi( value ); if ( inhibitEntity( spawnflags ) ) { inhibit++; continue; } } args.Spawn(); count++; gi.ProcessLoadingScreen( "$$SpawningEntities$$" ); } gi.DPrintf( "%i entities spawned\n", count ); gi.DPrintf( "%i entities inhibited\n", inhibit ); // Process the spawn events L_ProcessPendingEvents(); if ( multiplayerManager.inMultiplayer() ) { multiplayerManager.initItems(); } // Setup bots if ( gi.Cvar_VariableIntegerValue( "bot_enable" ) && multiplayerManager.inMultiplayer() ) { BotAIShutdown( 0 ); BotAISetup( 0 ); BotAILoadMap( 0 ); G_InitBots( 0 ); } if ( !LoadingServer || game.autosaved ) { Start(); } postLoad(); //------------------------------------------------------------------------------- // // Deletion Note: // Since hNodeController is an Entity, it is deleted // when all the other entities are deleted in the clean up function // specifically the line // // // if ( active_edicts.next->entity ) // { // delete active_edicts.next->entity; // } // // // Since it is already being deleted like this // We do not need to explcitily delete the controller... In fact // you will error out if you try to. //-------------------------------------------------------------------------------- hNodeController = new HelperNodeController; if ( hNodeController ) hNodeController->SetTargetName( "HelperNodeController" ); // // if this is a single player game, spawn the single player in now // this allows us to read persistant data into the player before the client // is completely ready // if ( game.maxclients == 1 ) { spawn_entnum = 0; new Player; } }