qboolean SV_NewGame( const char *mapName, qboolean loadGame ) { if( !loadGame ) { if( !SV_MapIsValid( mapName, GI->sp_entity, NULL )) { return false; } SV_ClearSaveDir (); SV_Shutdown( true ); } else { S_StopAllSounds (); SV_DeactivateServer (); } sv.loadgame = loadGame; sv.background = false; sv.changelevel = false; if( !SV_SpawnServer( mapName, NULL )) return false; SV_LevelInit( mapName, NULL, NULL, loadGame ); sv.loadgame = loadGame; SV_ActivateServer(); if( sv.state != ss_active ) return false; return true; }
void SV_ChangeLevel2_f( void ) { char *spawn_entity, *mapname; int flags, c = Cmd_Argc(); if( c < 2 ) { Msg( "Usage: changelevel2 <map> [landmark]\n" ); return; } mapname = Cmd_Argv( 1 ); // determine spawn entity classname if( sv_maxclients->integer == 1 ) spawn_entity = GI->sp_entity; else spawn_entity = GI->mp_entity; flags = SV_MapIsValid( mapname, spawn_entity, Cmd_Argv( 2 )); if( flags & MAP_INVALID_VERSION ) { Msg( "SV_ChangeLevel: Map %s is invalid or not supported.\n", mapname ); return; } if(!( flags & MAP_IS_EXIST )) { Msg( "SV_ChangeLevel: Map %s doesn't exist.\n", mapname ); return; } if( c >= 3 && !Q_stricmp( sv.name, Cmd_Argv( 1 ))) { MsgDev( D_INFO, "SV_ChangeLevel: Can't changelevel with same map. Ignored.\n" ); return; } // bad changelevel position invoke enables in one-way transtion if( sv.net_framenum < 30 ) { if( sv_validate_changelevel->integer ) { MsgDev( D_INFO, "SV_ChangeLevel: An infinite changelevel detected.\n" ); MsgDev( D_INFO, "Changelevel will be disabled until the next save\\restore.\n" ); return; // lock with svs.spawncount here } } /*if( sv.state != ss_active ) { MsgDev( D_INFO, "Only the server may changelevel\n" ); return; }*/ SCR_BeginLoadingPlaque( false ); SV_ChangeLevel( true, Cmd_Argv( 1 ), Cmd_Argv( 2 )); }
/* ================== SV_Map_f Goes directly to a given map without any savegame archiving. For development work ================== */ void SV_Map_f( void ) { char *spawn_entity; string mapname; int flags; if( Cmd_Argc() != 2 ) { Msg( "Usage: map <mapname>\n" ); return; } // hold mapname to other place Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname )); // determine spawn entity classname if( sv_maxclients->integer == 1 ) spawn_entity = GI->sp_entity; else spawn_entity = GI->mp_entity; flags = SV_MapIsValid( mapname, spawn_entity, NULL ); if( flags & MAP_INVALID_VERSION ) { Msg( "SV_NewMap: map %s is invalid or not supported\n", mapname ); return; } if(!( flags & MAP_IS_EXIST )) { Msg( "SV_NewMap: map %s doesn't exist\n", mapname ); return; } if(!( flags & MAP_HAS_SPAWNPOINT )) { Msg( "SV_NewMap: map %s doesn't have a valid spawnpoint\n", mapname ); return; } // init network stuff NET_Config(( sv_maxclients->integer > 1 )); // changing singleplayer to multiplayer or back. refresh the player count if(( sv_maxclients->modified ) || ( deathmatch->modified ) || ( coop->modified ) || ( teamplay->modified )) Host_ShutdownServer(); SCR_BeginLoadingPlaque( false ); sv.changelevel = false; sv.background = false; sv.loadgame = false; // set right state SV_ClearSaveDir (); // delete all temporary *.hl files SV_DeactivateServer(); SV_SpawnServer( mapname, NULL ); SV_LevelInit( mapname, NULL, NULL, false ); SV_ActivateServer (); }
/* ================== SV_Map_f Goes directly to a given map without any savegame archiving. For development work ================== */ void SV_Map_f( void ) { char *spawn_entity; string mapname; int flags; if( Cmd_Argc() != 2 ) { Msg( "Usage: map <mapname>\n" ); return; } // hold mapname to other place Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname )); // determine spawn entity classname if( sv_maxclients->integer == 1 ) spawn_entity = GI->sp_entity; else spawn_entity = GI->mp_entity; flags = SV_MapIsValid( mapname, spawn_entity, NULL ); if( flags & MAP_INVALID_VERSION ) { Msg( "SV_NewMap: map %s is invalid or not supported\n", mapname ); return; } if(!( flags & MAP_IS_EXIST )) { Msg( "SV_NewMap: map %s doesn't exist\n", mapname ); return; } if(!( flags & MAP_HAS_SPAWNPOINT )) { Msg( "SV_NewMap: map %s doesn't have a valid spawnpoint\n", mapname ); return; } #ifndef _DEDICATED SCR_BeginLoadingPlaque( false ); #endif sv.background = false; sv.loadgame = false; // set right state SV_ClearSaveDir (); // delete all temporary *.hl files SV_DeactivateServer(); SV_SpawnServer( mapname, NULL ); SV_LevelInit( mapname, NULL, NULL, false ); SV_ActivateServer (); }
/* ================== SV_MapBackground_f Set background map (enable physics in menu) ================== */ void SV_MapBackground_f( void ) { string mapname; int flags; if( Cmd_Argc() != 2 ) { Msg( "Usage: map_background <mapname>\n" ); return; } if( sv.state == ss_active && !sv.background ) { Msg( "SV_NewMap: can't set background map while game is active\n" ); return; } // hold mapname to other place Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname )); flags = SV_MapIsValid( mapname, GI->sp_entity, NULL ); if(!( flags & MAP_IS_EXIST )) { Msg( "SV_NewMap: map %s doesn't exist\n", mapname ); return; } // background maps allow without spawnpoints (just throw warning) if(!( flags & MAP_HAS_SPAWNPOINT )) MsgDev( D_WARN, "SV_NewMap: map %s doesn't have a valid spawnpoint\n", mapname ); Q_strncpy( host.finalmsg, "", MAX_STRING ); SV_Shutdown( true ); NET_Config ( false ); // close network sockets sv.background = true; sv.loadgame = false; // set right state // reset all multiplayer cvars Cvar_FullSet( "coop", "0", CVAR_LATCH ); Cvar_FullSet( "teamplay", "0", CVAR_LATCH ); Cvar_FullSet( "deathmatch", "0", CVAR_LATCH ); Cvar_FullSet( "maxplayers", "1", CVAR_LATCH ); #ifndef _DEDICATED SCR_BeginLoadingPlaque( true ); #endif SV_SpawnServer( mapname, NULL ); SV_LevelInit( mapname, NULL, NULL, false ); SV_ActivateServer (); }
/* ================== SV_ChangeLevel_f Saves the state of the map just being exited and goes to a new map. ================== */ void SV_ChangeLevel_f( void ) { char *spawn_entity, *mapname; int flags, c = Cmd_Argc(); if( c < 2 ) { Msg( "Usage: changelevel <map> [landmark]\n" ); return; } if( host_xashds_hacks->value ) { Cbuf_InsertText(va("rcon changelevel %s %s\n",Cmd_Argv( 1 ), Cmd_Argv( 2 ))); return; } mapname = Cmd_Argv( 1 ); // determine spawn entity classname if( sv_maxclients->integer == 1 ) spawn_entity = GI->sp_entity; else spawn_entity = GI->mp_entity; flags = SV_MapIsValid( mapname, spawn_entity, Cmd_Argv( 2 )); if( flags & MAP_INVALID_VERSION ) { Msg( "SV_ChangeLevel: Map %s is invalid or not supported\n", mapname ); return; } if(!( flags & MAP_IS_EXIST )) { Msg( "SV_ChangeLevel: Map %s doesn't exist\n", mapname ); return; } if( c >= 3 && !( flags & MAP_HAS_LANDMARK )) { if( sv_validate_changelevel->integer ) { // NOTE: we find valid map but specified landmark it's doesn't exist // run simple changelevel like in q1, throw warning MsgDev( D_INFO, "SV_ChangeLevel: map %s exists but doesn't contain\n", mapname ); MsgDev( D_INFO, "landmark with name %s. Run classic Quake changelevel.\n", Cmd_Argv( 2 )); c = 2; // reduce args } } if( c >= 3 && !Q_stricmp( sv.name, Cmd_Argv( 1 ))) { MsgDev( D_INFO, "SV_ChangeLevel: Can't changelevel with same map. Ignored.\n" ); return; } if( c == 2 && !( flags & MAP_HAS_SPAWNPOINT )) { if( sv_validate_changelevel->integer ) { MsgDev( D_INFO, "SV_ChangeLevel: Map %s doesn't have a valid spawnpoint. Ignored.\n", mapname ); return; } } // bad changelevel position invoke enables in one-way transtion if( sv.net_framenum < 30 ) { if( sv_validate_changelevel->integer && host.type != HOST_DEDICATED ) { MsgDev( D_INFO, "SV_ChangeLevel: An infinite changelevel detected.\n" ); MsgDev( D_INFO, "Changelevel will be disabled until the next save\\restore.\n" ); return; // lock with svs.spawncount here } } if( sv.state != ss_active ) { MsgDev( D_INFO, "Only the server may changelevel\n" ); return; } SCR_BeginLoadingPlaque( false ); if( sv.background ) { // just load map Cbuf_AddText( va( "map %s\n", mapname )); return; } if( c == 2 ) SV_ChangeLevel( false, Cmd_Argv( 1 ), NULL ); else SV_ChangeLevel( true, Cmd_Argv( 1 ), Cmd_Argv( 2 )); }