/* ================= CL_PrepVideo Call before entering a new level, or after changing dlls ================= */ void CL_PrepVideo( void ) { string mdlname, mapname; int i, mdlcount, step; int map_checksum; // dummy if( !cl.model_precache[1][0] ) return; // no map loaded Cvar_SetFloat( "scr_loading", 0.0f ); // reset progress bar MsgDev( D_NOTE, "CL_PrepVideo: %s\n", clgame.mapname ); // let the render dll load the map Q_strncpy( mapname, cl.model_precache[1], MAX_STRING ); Mod_LoadWorld( mapname, (uint *)&map_checksum, false ); cl.worldmodel = Mod_Handle( 1 ); // get world pointer Cvar_SetFloat( "scr_loading", 25.0f ); SCR_UpdateScreen(); // make sure what map is valid if( !cls.demoplayback && map_checksum != cl.checksum ) Host_Error( "Local map version differs from server: %i != '%i'\n", map_checksum, cl.checksum ); for( i = 0, mdlcount = 0; i < MAX_MODELS && cl.model_precache[i+1][0]; i++ ) mdlcount++; // total num models step = mdlcount/10; for( i = 0; i < MAX_MODELS && cl.model_precache[i+1][0]; i++ ) { Q_strncpy( mdlname, cl.model_precache[i+1], MAX_STRING ); Mod_RegisterModel( mdlname, i+1 ); Cvar_SetFloat( "scr_loading", scr_loading->value + 75.0f / mdlcount ); if( step && !( i % step ) && ( cl_allow_levelshots->integer || cl.background ) ) SCR_UpdateScreen(); } // update right muzzleflash indexes CL_RegisterMuzzleFlashes (); // invalidate all decal indexes Q_memset( cl.decal_index, 0, sizeof( cl.decal_index )); CL_ClearWorld (); R_NewMap(); // tell the render about new map V_SetupOverviewState(); // set overview bounds // must be called after lightmap loading! clgame.dllFuncs.pfnVidInit(); // release unused SpriteTextures for( i = 1; i < MAX_IMAGES; i++ ) { if( !clgame.sprites[i].name[0] ) continue; // free slot if( clgame.sprites[i].needload != clgame.load_sequence ) Mod_UnloadSpriteModel( &clgame.sprites[i] ); } Mod_FreeUnused (); Q_memset( cl.playermodels, 0, sizeof( cl.playermodels ) ); Cvar_SetFloat( "scr_loading", 100.0f ); // all done if( host.decalList ) { // need to reapply all decals after restarting for( i = 0; i < host.numdecals; i++ ) { decallist_t *entry = &host.decalList[i]; cl_entity_t *pEdict = CL_GetEntityByIndex( entry->entityIndex ); int decalIndex = CL_DecalIndex( CL_DecalIndexFromName( entry->name )); int modelIndex = 0; if( pEdict ) modelIndex = pEdict->curstate.modelindex; CL_DecalShoot( decalIndex, entry->entityIndex, modelIndex, entry->position, entry->flags ); } Z_Free( host.decalList ); } host.decalList = NULL; host.numdecals = 0; if( host.soundList ) { // need to reapply all ambient sounds after restarting for( i = 0; i < host.numsounds; i++ ) { soundlist_t *entry = &host.soundList[i]; if( entry->looping && entry->entnum != -1 ) { MsgDev( D_NOTE, "Restarting sound %s...\n", entry->name ); S_AmbientSound( entry->origin, entry->entnum, S_RegisterSound( entry->name ), entry->volume, entry->attenuation, entry->pitch, 0 ); } } } host.soundList = NULL; host.numsounds = 0; if( host.developer <= 2 ) Con_ClearNotify(); // clear any lines of console text SCR_UpdateScreen (); cl.video_prepped = true; cl.force_refdef = true; }
/* ================ SV_SpawnServer Change the server to a new map, taking all connected clients along with it. ================ */ qboolean SV_SpawnServer( const char *mapname, const char *startspot ) { int i, current_skill; qboolean loadgame, paused; qboolean background, changelevel; // save state loadgame = sv.loadgame; background = sv.background; changelevel = sv.changelevel; paused = sv.paused; if( sv.state == ss_dead ) SV_InitGame(); // the game is just starting else if( !sv_maxclients->modified ) Cmd_ExecuteString( "latch\n", src_command ); else MsgDev( D_ERROR, "SV_SpawnServer: while 'maxplayers' was modified.\n" ); sv_maxclients->modified = false; deathmatch->modified = false; teamplay->modified = false; coop->modified = false; if( !svs.initialized ) return false; svgame.globals->changelevel = false; // will be restored later if needed svs.timestart = Sys_DoubleTime(); svs.spawncount++; // any partially connected client will be restarted if( startspot ) { MsgDev( D_INFO, "Spawn Server: %s [%s]\n", mapname, startspot ); } else { MsgDev( D_INFO, "Spawn Server: %s\n", mapname ); } sv.state = ss_dead; Host_SetServerState( sv.state ); Q_memset( &sv, 0, sizeof( sv )); // wipe the entire per-level structure // restore state sv.paused = paused; sv.loadgame = loadgame; sv.background = background; sv.changelevel = changelevel; sv.time = 1.0f; // server spawn time it's always 1.0 second svgame.globals->time = sv.time; // initialize buffers BF_Init( &sv.datagram, "Datagram", sv.datagram_buf, sizeof( sv.datagram_buf )); BF_Init( &sv.reliable_datagram, "Datagram R", sv.reliable_datagram_buf, sizeof( sv.reliable_datagram_buf )); BF_Init( &sv.multicast, "Multicast", sv.multicast_buf, sizeof( sv.multicast_buf )); BF_Init( &sv.signon, "Signon", sv.signon_buf, sizeof( sv.signon_buf )); BF_Init( &sv.spectator_datagram, "Spectator Datagram", sv.spectator_buf, sizeof( sv.spectator_buf )); // leave slots at start for clients only for( i = 0; i < sv_maxclients->integer; i++ ) { // needs to reconnect if( svs.clients[i].state > cs_connected ) svs.clients[i].state = cs_connected; } // make cvars consistant if( Cvar_VariableInteger( "coop" )) Cvar_SetFloat( "deathmatch", 0 ); current_skill = (int)(Cvar_VariableValue( "skill" ) + 0.5f); current_skill = bound( 0, current_skill, 3 ); Cvar_SetFloat( "skill", (float)current_skill ); if( sv.background ) { // tell the game parts about background state Cvar_FullSet( "sv_background", "1", CVAR_READ_ONLY ); Cvar_FullSet( "cl_background", "1", CVAR_READ_ONLY ); } else { Cvar_FullSet( "sv_background", "0", CVAR_READ_ONLY ); Cvar_FullSet( "cl_background", "0", CVAR_READ_ONLY ); } // make sure what server name doesn't contain path and extension FS_FileBase( mapname, sv.name ); if( startspot ) Q_strncpy( sv.startspot, startspot, sizeof( sv.startspot )); else sv.startspot[0] = '\0'; Q_snprintf( sv.model_precache[1], sizeof( sv.model_precache[0] ), "maps/%s.bsp", sv.name ); Mod_LoadWorld( sv.model_precache[1], &sv.checksum, false ); sv.worldmodel = Mod_Handle( 1 ); // get world pointer for( i = 1; i < sv.worldmodel->numsubmodels; i++ ) { Q_sprintf( sv.model_precache[i+1], "*%i", i ); Mod_RegisterModel( sv.model_precache[i+1], i+1 ); } // precache and static commands can be issued during map initialization sv.state = ss_loading; Host_SetServerState( sv.state ); // clear physics interaction links SV_ClearWorld(); // tell dlls about new level started svgame.dllFuncs.pfnParmsNewLevel(); return true; }