global function MenuCallbacks_Init void function MenuCallbacks_Init() { AddClientCommandCallback( "LeaveMatch", ClientCommandCallback_LeaveMatch ) AddClientCommandCallback( "GenUp", ClientCommandCallback_GenUp ) } bool function ClientCommandCallback_LeaveMatch( entity player, array args ) { // note: this is imperfect if we have multiple people of the same uid on a server, but that's only a thing in testing if ( NSIsPlayerIndexLocalPlayer( player.GetPlayerIndex() ) ) { if ( GetConVarBool( "ns_should_return_to_lobby" ) && GetMapName() != "mp_lobby" ) { GameRules_EndMatch() return true } foreach ( entity otherPlayer in GetPlayerArray() ) if ( otherPlayer != player ) thread WritePersistenceAndLeave( otherPlayer ) thread WritePersistenceAndLeaveForLocalPlayerOnly( player ) } else thread WritePersistenceAndLeave( player ) return true } void function WritePersistenceAndLeaveForLocalPlayerOnly( entity player ) { float time = Time() while ( GetPlayerArray().len() != 1 && Time() < time + 5.0 ) WaitFrame() if ( IsValid( player ) ) WritePersistenceAndLeave( player ) } void function WritePersistenceAndLeave( entity player ) { // write player persistence before we leave, since leaving player might load local lobby before server writes persistence, so they won't get newest // not super essential, but a nice qol thing NSEarlyWritePlayerIndexPersistenceForLeave( player.GetPlayerIndex() ) while ( NSIsWritingPlayerPersistence() ) WaitFrame() // this is a custom concommand which can be called on clients, it causes them to leave and doesn't have issues if they're host ClientCommand( player, "ns_start_reauth_and_leave_to_lobby" ) } bool function ClientCommandCallback_GenUp( entity player, array args ) { int gen = player.GetPersistentVarAsInt( "gen" ) if ( player.GetPersistentVarAsInt( "xp" ) == GetMaxPlayerXP() && gen < MAX_GEN ) { player.SetPersistentVar( "xp", 0 ) player.SetPersistentVar( "gen", gen + 1 ) // ensure client updates properly player.GenChanged() player.XPChanged() } return true }