From 569375b64fabf1683ebb8e953497a57d150b3c76 Mon Sep 17 00:00:00 2001 From: Zanieon Date: Thu, 31 Aug 2023 12:17:51 -0300 Subject: [PATCH 01/10] Matchmaking Logic and Mixtape Playlists Update --- .../scripts/vscripts/ui/menu_fdplaylist.nut | 527 +++++++++ .../mod/scripts/vscripts/ui/menu_lobby.nut | 211 +++- .../mod/scripts/vscripts/ui/menu_playlist.nut | 513 ++++++++ .../vscripts/ui/menu_playlist_mixtape.nut | 1049 +++++++++++++++++ Northstar.Custom/keyvalues/playlists_v2.txt | 161 ++- 5 files changed, 2450 insertions(+), 11 deletions(-) create mode 100644 Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut create mode 100644 Northstar.Client/mod/scripts/vscripts/ui/menu_playlist.nut create mode 100644 Northstar.Client/mod/scripts/vscripts/ui/menu_playlist_mixtape.nut diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut new file mode 100644 index 000000000..715d55964 --- /dev/null +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut @@ -0,0 +1,527 @@ +global function InitFDPlaylistMenu +global function SetChecklistButtonSelected +global function GetDifficultyData +global function GetFDDifficultyArray + +const int FD_PLAYLIST_EASY = 1 << 0 +const int FD_PLAYLIST_NORMAL = 1 << 1 +const int FD_PLAYLIST_HARD = 1 << 2 +const int FD_PLAYLIST_MASTER = 1 << 3 +const int FD_PLAYLIST_INSANE = 1 << 4 + +global struct FDDifficultyInfo +{ + string abbrev + string name + string playlist + int difficultyIndex + int difficultyBits +} + +struct +{ + var menu + var playButton + var tutorialButton + var hostButton + array checklistIconButtons + array difficulties + bool isOnPromoButton = false + bool isOnPlayButton = false + array titanButtons + + var fdProperties + var fdPropertiesData + var selectedTitanButton + var hintBox + var hintIcon + var descriptionBox + var playHintBox + var playHintIcon + var playDescriptionBox +} file + + +void function InitFDPlaylistMenu() +{ + CreateDifficultyInfo( "fd_easy", "Easy", "#FD_DIFFICULTY_EASY", FD_PLAYLIST_EASY ) + CreateDifficultyInfo( "fd_normal", "Normal", "#FD_DIFFICULTY_NORMAL", FD_PLAYLIST_NORMAL ) + CreateDifficultyInfo( "fd_hard", "Hard", "#FD_DIFFICULTY_HARD", FD_PLAYLIST_HARD ) + CreateDifficultyInfo( "fd_master", "Master", "#FD_DIFFICULTY_MASTER", FD_PLAYLIST_MASTER ) + CreateDifficultyInfo( "fd_insane", "Insane", "#FD_DIFFICULTY_INSANE", FD_PLAYLIST_INSANE ) + + file.menu = GetMenu( "FDMenu" ) + + AddMenuEventHandler( file.menu, eUIEvent.MENU_NAVIGATE_BACK, OnFDMenu_NavigateBack ) + + file.playButton = Hud_GetChild( file.menu, "PlayButton" ) + AddButtonEventHandler( file.playButton, UIE_CLICK, OnPlayButtonClick ) + AddButtonEventHandler( file.playButton, UIE_GET_FOCUS, OnPlayButtonFocus ) + AddButtonEventHandler( file.playButton, UIE_LOSE_FOCUS, OnPlayButtonFocusLost ) + + AddMenuEventHandler( file.menu, eUIEvent.MENU_OPEN, OnOpenFDMenu ) + AddMenuEventHandler( file.menu, eUIEvent.MENU_CLOSE, OnCloseFDMenu ) + + AddMenuFooterOption( file.menu, BUTTON_A, "#A_BUTTON_SELECT" ) + AddMenuFooterOption( file.menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) + + for ( int idx = 0; idx < 4; ++idx ) + { + string buttonName = ("BtnPlaylistIcon" + format( "%02d", idx )) + var button = Hud_GetChild( file.menu, buttonName ) + + AddButtonEventHandler( button, UIE_CLICK, OnChecklistIconButtonClick ) + AddButtonEventHandler( button, UIE_GET_FOCUS, OnChecklistIconButtonFocus ) + AddButtonEventHandler( button, UIE_LOSE_FOCUS, OnChecklistIconButtonFocusLost ) + file.checklistIconButtons.append( button ) + + var rui = Hud_GetRui( button ) + RuiSetBool( rui, "alwaysShowTitle", true ) + + if ( idx==0 ) + SetChecklistButtonSelected( button, true ) + } + + for ( int i=0; i ) + RuiSetFloat( rui, "basicImageAlpha", 0.5 ) + + file.descriptionBox = Hud_GetChild( file.menu, "LabelDetails" ) + + file.playHintIcon = Hud_GetChild( file.menu, "PlayHintIcon" ) + rui = Hud_GetRui( file.playHintIcon ) + RuiSetImage( rui, "basicImage", $"rui/hud/gametype_icons/fd/coop_harvester" ) + + file.playHintBox = Hud_GetChild( file.menu, "PlayHintBackground" ) + rui = Hud_GetRui( file.playHintBox ) + RuiSetImage( rui, "basicImage", $"rui/borders/menu_border_button" ) + RuiSetFloat3( rui, "basicImageColor", <0,0,0> ) + RuiSetFloat( rui, "basicImageAlpha", 0.5 ) + + file.playDescriptionBox = Hud_GetChild( file.menu, "PlayLabelDetails" ) + + file.tutorialButton = Hud_GetChild( file.menu, "TutorialButton" ) + AddButtonEventHandler( file.tutorialButton, UIE_CLICK, OnTutorialButtonClick ) +} + +void function OnOpenFDMenu() +{ + StopMatchmaking() + + UI_SetPresentationType( ePresentationType.FD_FIND_GAME ) + + bool openInviting = IsSendOpenInviteTrue() + + var pbRui = Hud_GetRui( file.playButton ) + RuiSetBool( pbRui, "bigPresentation", false ) + RuiSetImage( pbRui, "itemImage", GetPlaylistImage( "aitdm" ) ) + RuiSetString( pbRui, "title", "#FD_PLAY_BUTTON" ) + + SetupDifficultyButtons() + entity player = GetUIPlayer() + var dataTable = GetDataTable( $"datatable/titan_properties.rpak" ) + int loadoutIconCol = GetDataTableColumnByName( dataTable, "loadoutIcon" ) + int titanCol = GetDataTableColumnByName( dataTable, "titanRef" ) + for ( int i=0; i 0 + SetChecklistButtonSelected( button, selected && !locked ) + + selectedSomething = selectedSomething || (selected && !locked) + } + + if ( !selectedSomething ) + SetChecklistButtonSelected( file.checklistIconButtons[0], true ) + + thread UpdateDifficultyButtonsThread() +} + +void function UpdateDifficultyButtonsThread() +{ + while ( GetTopNonDialogMenu() == GetMenu( "FDMenu" ) ) + { + if ( GetUIPlayer() ) + { + int length = file.checklistIconButtons.len() + for( int idx = 0; idx < length; ++idx ) + { + var panel = file.checklistIconButtons[idx] + var panelRui = Hud_GetRui( panel ) + + bool isMuted = (file.isOnPromoButton) + RuiSetBool( panelRui, "isMuted", isMuted ) + + bool isGlowing = (file.isOnPlayButton) + RuiSetBool( panelRui, "isGlowing", isGlowing ) + } + } + WaitFrame() + } +} + +array function GetFDDifficultyArray() +{ + array difficulties + + foreach ( info in file.difficulties ) + difficulties.append( info.playlist ) + + return difficulties +} + +FDDifficultyInfo function GetDifficultyDataFromPlaylistName( string playlist ) +{ + foreach ( data in file.difficulties ) + { + if ( playlist == data.playlist ) + return data + } + + unreachable +} + +FDDifficultyInfo function GetDifficultyData( int idx ) +{ + return file.difficulties[idx] +} + +void function CreateDifficultyInfo( string playlist, string name, string abbrev, int bits ) +{ + FDDifficultyInfo data + data.name = name + data.playlist = playlist + data.abbrev = abbrev + data.difficultyIndex = file.difficulties.len() + data.difficultyBits = bits + file.difficulties.append( data ) +} + + +void function OnChecklistIconButtonFocus( var button ) +{ + Hud_Show( file.hintIcon ) + Hud_Show( file.hintBox ) + + string desc + + for ( int i=0; i selectedDifficulties = GetSelectedPlaylists() + + if ( selectedDifficulties.len() == 0 ) + { + Hud_SetFocused( file.checklistIconButtons[0] ) + return + } + + if ( Hud_IsLocked( button ) ) + return + + CloseActiveMenu() + Lobby_SetFDMode( true ) + thread StartNSMatchmaking( selectedDifficulties ) +} + +void function OnPlayButtonFocus( var button ) +{ + file.isOnPlayButton = true + + Hud_Show( file.playHintIcon ) + Hud_Show( file.playHintBox ) + + array selectedDifficulties = GetSelectedPlaylists() + + string desc = BuildPlayWarningMessageTop( selectedDifficulties ) + + var rui = Hud_GetRui( file.playDescriptionBox ) + RuiSetString( rui, "messageText", desc ) +} + + +string function BuildPlayWarningMessageTop( array pl ) +{ + int playlistCount = pl.len() + switch ( playlistCount ) + { + case 0: + return Localize( "#MENU_FD_DIFFICULTY_SEARCH_0" ) + case 1: + return Localize( "#MENU_FD_DIFFICULTY_SEARCH_1", pldn(pl,0) ) + case 2: + return Localize( "#MENU_FD_DIFFICULTY_SEARCH_2", pldn(pl,0), pldn(pl,1) ) + case 3: + return Localize( "#MENU_FD_DIFFICULTY_SEARCH_3", pldn(pl,0), pldn(pl,1), pldn(pl,2) ) + case 4: + return Localize( "#MENU_FD_DIFFICULTY_SEARCH_4", pldn(pl,0), pldn(pl,1), pldn(pl,2), pldn(pl,3) ) + } + unreachable +} + +string function pldn( array pl, int index ) +{ + string playlistName = pl[index] + FDDifficultyInfo data = GetDifficultyDataFromPlaylistName( playlistName ) + return Localize( data.abbrev ) +} + +void function OnPlayButtonFocusLost( var button ) +{ + file.isOnPlayButton = false + + Hud_Hide( file.playHintIcon ) + Hud_Hide( file.playHintBox ) + + var rui = Hud_GetRui( file.playDescriptionBox ) + RuiSetString( rui, "messageText", "" ) +} + + +void function OnHostButtonClick( var button ) +{ + AdvanceMenu( GetMenu( "FDHostMatchMenu" ) ) +} + +void function OnHostButtonFocus( var button ) +{ + file.isOnPromoButton = true +} + +void function OnHostButtonFocusLost( var button ) +{ + file.isOnPromoButton = false +} + +array function GetSelectedPlaylists() +{ + array pl = [] + for ( int i=0; i selectedPlaylists ) +{ + MatchmakingSetCountdownTimer( Time() + 4.0, false ) + MatchmakingSetSearchText( "#MATCHMAKING_SEARCHING_FOR_MATCH" ) + MatchmakingSetSearchVisible( true ) + MatchmakingSetCountdownVisible( true ) + ShowMatchmakingStatusIcons() + + var searchMenu = GetMenu( "SearchMenu" ) + AdvanceMenu( searchMenu ) + var statusEl = Hud_GetChild( searchMenu, "MatchmakingStatusBig" ) + + string statusText = Localize( "#MATCHMAKING_PLAYLISTS" ) + RuiSetString( Hud_GetRui( statusEl ), "statusText", statusText ) + for ( int idx = 1; idx <= 5; ++idx ) + RuiSetString( Hud_GetRui( statusEl ), ("bulletPointText" + idx), "" ) + + const int MAX_SHOWN_PLAYLISTS = 9 + int searchingCount = minint( selectedPlaylists.len(), MAX_SHOWN_PLAYLISTS ) + RuiSetInt( Hud_GetRui( statusEl ), "playlistCount", searchingCount ) + for( int idx = 0; idx < searchingCount; ++idx ) + { + asset playlistThumbnail = GetPlaylistThumbnailImage( selectedPlaylists[idx] ) + RuiSetImage( Hud_GetRui( statusEl ), format( "playlistIcon%d", idx ), playlistThumbnail ) + } + Hud_Show( statusEl ) + + wait 3.0 //Fancy delay just because server finder is pratically immediate, whole block above is to show "fake" matchmaking search + MatchmakingSetCountdownVisible( false ) + + NSClearRecievedServerList() + NSRequestServerList() + + while ( NSIsRequestingServerList() ) + WaitFrame() + + array servers = NSGetGameServers() + array PlaylistServers + array filteredServers + + foreach( index, string playlist in selectedPlaylists ) + { + foreach ( ServerInfo server in servers ) + { + if ( server.playlist == playlist ) + PlaylistServers.append( server ) + } + } + + foreach ( ServerInfo server in PlaylistServers ) + { + if ( server.playerCount == 0 || server.playerCount == server.maxPlayerCount || server.requiresPassword ) + continue; + + filteredServers.append( server ) + } + + if( filteredServers.len() ) + thread MatchmakedAuthAndConnectToServer( filteredServers[ RandomInt( filteredServers.len() ) ] ) + else + { + foreach ( ServerInfo server in PlaylistServers ) //If we failed to find servers with players in it, consider joining empty ones + { + if ( server.playerCount == server.maxPlayerCount || server.requiresPassword ) + continue; + + filteredServers.append( server ) + } + + if( filteredServers.len() ) + thread MatchmakedAuthAndConnectToServer( filteredServers[ RandomInt( filteredServers.len() ) ] ) + else + { + MatchmakingSetSearchVisible( false ) + HideMatchmakingStatusIcons() + Hud_Hide( statusEl ) + + if ( uiGlobal.activeMenu == searchMenu ) + CloseActiveMenu() + + DialogData dialogData + dialogData.header = "#ERROR" + dialogData.message = "#MATCHMAKING_NOSERVERS" + dialogData.image = $"ui/menu/common/dialog_error" + + #if PC_PROG + AddDialogButton( dialogData, "#DISMISS" ) + AddDialogFooter( dialogData, "#A_BUTTON_SELECT" ) + #endif // PC_PROG + + AddDialogFooter( dialogData, "#B_BUTTON_DISMISS_RUI" ) + OpenDialog( dialogData ) + return + } + } +} + +void function MatchmakedAuthAndConnectToServer( ServerInfo matchmakedserver, string password = "" ) +{ + var statusEl = Hud_GetChild( GetMenu( "SearchMenu" ), "MatchmakingStatusBig" ) + if ( NSIsAuthenticatingWithServer() ) + return + + NSTryAuthWithServer( matchmakedserver.index, password ) + + while ( NSIsAuthenticatingWithServer() ) + WaitFrame() + + if ( NSWasAuthSuccessful() ) + { + bool modsChanged = false + + foreach ( string modName in NSGetModNames() ) + { + if ( NSIsModRequiredOnClient( modName ) && NSIsModEnabled( modName ) ) + { + bool found = false + foreach ( RequiredModInfo mod in matchmakedserver.requiredMods ) + { + if (mod.name == modName) + { + found = true + break + } + } + if (!found) + { + modsChanged = true + NSSetModEnabled( modName, false ) + } + } + } + + foreach ( RequiredModInfo mod in matchmakedserver.requiredMods ) + { + if ( NSIsModRequiredOnClient( mod.name ) && !NSIsModEnabled( mod.name )) + { + modsChanged = true + NSSetModEnabled( mod.name, true ) + } + } + + EmitUISound( MATCHMAKING_AUDIO_CONNECTING ) + MatchmakingSetSearchText( "#MATCHMAKING_MATCH_CONNECTING" ) + MatchmakingSetCountdownVisible( false ) + HideMatchmakingStatusIcons() + Hud_Hide( statusEl ) + OpenConnectingDialog() + + wait 2.0 + + MatchmakingSetSearchVisible( false ) + + if ( modsChanged ) + ReloadMods() + + NSConnectToAuthedServer() + } + else + { + MatchmakingSetSearchVisible( false ) + HideMatchmakingStatusIcons() + Hud_Hide( statusEl ) + if ( uiGlobal.activeMenu == GetMenu( "SearchMenu" ) ) + CloseActiveMenu() + string reason = NSGetAuthFailReason() + + DialogData dialogData + dialogData.header = "#ERROR" + dialogData.message = reason + dialogData.image = $"ui/menu/common/dialog_error" + + #if PC_PROG + AddDialogButton( dialogData, "#DISMISS" ) + AddDialogFooter( dialogData, "#A_BUTTON_SELECT" ) + #endif // PC_PROG + + AddDialogFooter( dialogData, "#B_BUTTON_DISMISS_RUI" ) + OpenDialog( dialogData ) + } } \ No newline at end of file diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_playlist.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_playlist.nut new file mode 100644 index 000000000..288b53173 --- /dev/null +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_playlist.nut @@ -0,0 +1,513 @@ +untyped + +global function GetVisiblePlaylists + +global function InitPlaylistMenu +global function SendOpenInvite +global function IsSendOpenInviteTrue +global function GetPlaylistImage +global function GetPlaylistThumbnailImage +global function BuyIntoColiseumTicket +global function UpdatePlaylistButton +global function PlaylistButton_Click_Internal +global function PlaylistShouldShowAsLocked +global function CanPlaylistFitMyParty + +struct +{ + bool initialized = false + GridMenuData gridData + array playlistNames + var menu + var unlockReq + + bool sendOpenInvite = false + + bool showColiseumPartyWarning = true + array coliseumRefreshButtons + var coliseumButton +} file + +void function InitPlaylistMenu() +{ + var menu = GetMenu( "PlaylistMenu" ) + + file.unlockReq = Hud_GetChild( menu, "UnlockReq" ) + + AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnPlaylistMenu_Open ) + AddMenuEventHandler( menu, eUIEvent.MENU_CLOSE, OnPlaylistMenu_Close ) + + AddMenuFooterOption( menu, BUTTON_A, "#A_BUTTON_SELECT" ) + AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) +} + +bool function PlaylistButtonInit( var button, int elemNum ) +{ + var rui = Hud_GetRui( button ) + GridMenuData data = Grid_GetGridDataForButton( button ) + + string playlistName = file.playlistNames[ elemNum ] + + string levelName = GetPlaylistVarOrUseValue( playlistName, "name", "#UNKNOWN_PLAYLIST_NAME" ) + string imageName = GetPlaylistVarOrUseValue( playlistName, "image", "default" ) + bool doubleXP = GetPlaylistVarOrUseValue( playlistName, "double_xp_enabled", "0" ) == "1" + var dataTable = GetDataTable( $"datatable/playlist_items.rpak" ) + + int row = GetDataTableRowMatchingStringValue( dataTable, GetDataTableColumnByName( dataTable, "playlist" ), imageName ) + asset levelImage = GetDataTableAsset( dataTable, row, GetDataTableColumnByName( dataTable, "image" ) ) + + RuiSetImage( rui, "itemImage", levelImage ) + RuiSetString( rui, "title", levelName ) + RuiSetBool( rui, "doubleXP", doubleXP ) + + return true +} + +asset function GetPlaylistImage( string playlistName ) +{ + string imageName = GetPlaylistVarOrUseValue( playlistName, "image", "default" ) + var dataTable = GetDataTable( $"datatable/playlist_items.rpak" ) + int row = GetDataTableRowMatchingStringValue( dataTable, GetDataTableColumnByName( dataTable, "playlist" ), imageName ) + asset levelImage = GetDataTableAsset( dataTable, row, GetDataTableColumnByName( dataTable, "image" ) ) + + return levelImage +} + +asset function GetPlaylistThumbnailImage( string playlistName ) +{ + string imageName = GetPlaylistVarOrUseValue( playlistName, "image", playlistName ) + var dataTable = GetDataTable( $"datatable/playlist_items.rpak" ) + int row = GetDataTableRowMatchingStringValue( dataTable, GetDataTableColumnByName( dataTable, "playlist" ), imageName ) + if ( row == -1 ) + row = GetDataTableRowMatchingStringValue( dataTable, GetDataTableColumnByName( dataTable, "playlist" ), "default" ) + asset levelImage = GetDataTableAsset( dataTable, row, GetDataTableColumnByName( dataTable, "thumbnail" ) ) + + return levelImage +} + +void function SendOpenInvite( bool state ) +{ + file.sendOpenInvite = state +} + +bool function IsSendOpenInviteTrue() +{ + return file.sendOpenInvite +} + +void function PlaylistButton_GetFocus( var button, int elemNum ) +{ + string playlistName = file.playlistNames[ elemNum ] + + string unlockReq + if ( IsUnlockValid( playlistName ) ) + unlockReq = GetItemUnlockReqText( playlistName ) + RHud_SetText( file.unlockReq, unlockReq ) + + string levelName = GetPlaylistVarOrUseValue( playlistName, "name", "#UNKNOWN_PLAYLIST_NAME" ) + string desc = GetPlaylistVarOrUseValue( playlistName, "description", "#UNKNOWN_PLAYLIST_NAME" ) + + file.menu = GetMenu( "PlaylistMenu" ) + file.menu.GetChild( "ContentDescriptionTitle" ).SetText( levelName ) + file.menu.GetChild( "ContentDescription" ).SetText( desc ) + file.menu.GetChild( "PlayerCount" ).SetText( "#PLAYLIST_PLAYERCOUNT_COMBINED", GetPlaylistCountDescForRegion( playlistName ), GetPlaylistCountDescForWorld( playlistName ) ) +} + +void function OnPlaylistMenu_Open() +{ + file.showColiseumPartyWarning = true + StopMatchmaking() + + var menu = GetMenu( "PlaylistMenu" ) + + file.playlistNames = GetVisiblePlaylists() + int numRows = file.playlistNames.len() + file.gridData.numElements = numRows + file.gridData.rows = 2 + file.gridData.columns = 4 + file.gridData.paddingVert = 10 + file.gridData.paddingHorz = 10 + file.gridData.pageType = eGridPageType.HORIZONTAL + file.gridData.tileWidth = Grid_GetMaxWidthForSettings( menu, file.gridData ) + + float tileHeight = ( file.gridData.tileWidth * 9.0 ) / 21.0 + + file.gridData.tileHeight = int( tileHeight ) + + file.gridData.initCallback = PlaylistButtonInit + file.gridData.getFocusCallback = PlaylistButton_GetFocus + file.gridData.clickCallback = PlaylistButton_Click +// file.gridData.buttonFadeCallback = FadePlaylistButton + + file.gridData.currentPage = 0 + + if ( file.initialized ) + Grid_InitPage( menu, file.gridData, true ) + else + GridMenuInit( menu, file.gridData ) + + file.initialized = true + + Hud_SetFocused( Grid_GetButtonAtRowColumn( menu, 0, 0 ) ) + + UI_SetPresentationType( ePresentationType.NO_MODELS ) + + Grid_RegisterPageNavInputs( menu ) + + thread UpdatePlaylistButtons() +} + + +void function OnPlaylistMenu_Close() +{ + file.showColiseumPartyWarning = true + var menu = GetMenu( "PlaylistMenu" ) + Grid_DeregisterPageNavInputs( menu ) + +} + +bool function CanPlaylistFitMyParty( string playlistName ) +{ + int partySize = GetPartySize() + int maxPlayers = GetMaxPlayersForPlaylistName( playlistName ) + int maxTeams = GetMaxTeamsForPlaylistName( playlistName ) + int maxPlayersPerTeam = int( max( maxPlayers / maxTeams, 1 ) ) + bool partiesAllowed = GetCurrentPlaylistVarInt( "parties_allowed", 1 ) > 0 + + if ( playlistName == "coliseum" ) + { + if ( partySize == 2 && GetCurrentPlaylistVarInt( "enable_coliseum_party", 0 ) == 1 ) + return true + } + + if ( partySize > maxPlayersPerTeam ) + return false + + if ( file.sendOpenInvite && maxPlayersPerTeam == 1 ) + return false + + if ( !partiesAllowed ) + { + if ( partySize > 1 ) + return false + + if ( file.sendOpenInvite ) + return false + } + + return true +} + +bool function PlaylistShouldShowAsLocked( string playlistName ) +{ + bool isLocked = false + + if ( playlistName == "private_match" ) + { + isLocked = false + } + else if ( !CanPlaylistFitMyParty( playlistName ) ) + { + isLocked = true + } + else if ( IsUnlockValid( playlistName ) && IsItemLocked( GetUIPlayer(), playlistName ) ) + { + isLocked = true + } + + return isLocked +} + +void function UpdatePlaylistButton( var button, string playlistName, bool forceLocked ) +{ + if ( playlistName == "coliseum" ) + { + var rui = Hud_GetRui( button ) + RuiSetInt( rui, "specialObjectCount", Player_GetColiseumTicketCount( GetUIPlayer() ) ) + RuiSetImage( rui, "specialObjectIcon", $"rui/menu/common/ticket_icon" ) + RuiSetFloat( rui, "specialAlpha", 1.0 ) + } + else + { + var rui = Hud_GetRui( button ) + RuiSetInt( rui, "specialObjectCount", 0 ) + RuiSetImage( rui, "specialObjectIcon", $"" ) + RuiSetFloat( rui, "specialAlpha", 0.0 ) + } + + int costOverride = -1 + if ( playlistName == "private_match" ) + { + costOverride = 0 + } + else if ( !CanPlaylistFitMyParty( playlistName ) ) + { + costOverride = 0 + } + + bool isLocked = PlaylistShouldShowAsLocked( playlistName ) + Hud_SetLocked( button, (isLocked || forceLocked) ) + + if ( IsRefValid( playlistName ) ) + RefreshButtonCost( button, playlistName, "", -1, costOverride ) +} + + +void function UpdatePlaylistButtons() +{ + while ( GetTopNonDialogMenu() == GetMenu( "PlaylistMenu" ) ) + { + table< int, var > activePageButtons = Grid_GetActivePageButtons( GetMenu( "PlaylistMenu" ) ) + + if ( GetUIPlayer() ) + { + foreach ( buttonIndex, button in activePageButtons ) + { + string playlistName = file.playlistNames[ buttonIndex ] + UpdatePlaylistButton( button, playlistName, false ) + } + } + WaitFrame() + } +} + +void function CreatePartyAndStartPrivateMatch() +{ + /* Parties are not supported in NS atm + while ( !PartyHasMembers() && !AmIPartyLeader() ) + { + ClientCommand( "createparty" ) + WaitFrameOrUntilLevelLoaded() + } + */ + ClientCommand( "StartPrivateMatchSearch" ) + //OpenConnectingDialog() +} + +void function StartPrivateMatch() +{ + thread CreatePartyAndStartPrivateMatch() +} + +bool function PlaylistButton_Click_Internal( var button, string playlistName, array refreshButtons ) +{ + if ( playlistName == "private_match" ) + { + if ( Hud_IsLocked( button ) ) + return false + + ClientCommand( "StartPrivateMatchSearch" ) + return true + + /* Respawn stuff + if ( !file.sendOpenInvite ) + { + StartPrivateMatch() + return false + } + */ + } + + if ( Hud_IsLocked( button ) ) + { + if ( !CanPlaylistFitMyParty( playlistName ) ) + return false + + if ( ItemDefined( playlistName ) ) + OpenBuyItemDialog( refreshButtons, button, GetItemName( playlistName ), playlistName ) + else + printt( "Not calling OpenBuyItemDialog() for '" + playlistName + "', because it doesn't exist as an Item." ) + return false + } + + //DO CHECK HERE TO SEE IF WE ARE TYING TO ENTER COLISEUM + if ( playlistName == "coliseum" ) + { + // Does player have a ticket? + + int requiredTickets = 1 + if ( GetPartySize() == 2 ) + requiredTickets = 2 + + if ( Player_GetColiseumTicketCount( GetLocalClientPlayer() ) >= requiredTickets ) + { + ColiseumPlaylist_SpendTicketDialogue( button, requiredTickets ) + return false + } + else if ( requiredTickets == 2 ) //&& file.showColiseumPartyWarning ) + { + ColiseumPlaylist_WarnFriendDialogue( refreshButtons, button ) + return false + } + else + { + ColiseumPlaylist_OfferToBuyTickets( refreshButtons, button, 1 ) + return false + } + } + + if ( playlistName == "fd" ) + { + AdvanceMenu( GetMenu( "FDMenu" ) ) + return true + } + + CloseActiveMenu() // playlist selection menu + array selectedPlaylists = [] + selectedPlaylists.append( playlistName ) + thread StartNSMatchmaking( selectedPlaylists ) + + /* Respawn matchmaking + printt( "Setting match_playlist to '" + playlistName + "' from playlist menu" ) + if ( file.sendOpenInvite ) + ClientCommand( "openinvite playlist " + playlistName ) + else + StartMatchmaking( playlistName ) + */ + + return true +} + +void function PlaylistButton_Click( var button, int elemNum ) +{ + string playlistName = file.playlistNames[ elemNum ] + array refreshButtons = GetElementsByClassname( file.menu, "GridButtonClass" ) + PlaylistButton_Click_Internal( button, playlistName, refreshButtons ) +} + +array function GetVisiblePlaylists() +{ + int numPlaylists = GetPlaylistCount() + + array list = [] + + bool rearrangeForAngelCity = false + + for ( int i=0; i refreshButtons, var button ) +{ + DialogData dialogData + dialogData.header = "#COLISEUM_WARN_HEADER_INVITE" + dialogData.message = "#COLISEUM_WARN_MESSAGE_INVITE" + + file.coliseumRefreshButtons = refreshButtons + file.coliseumButton = button + + AddDialogButton( dialogData, "#YES", ColiseumPlaylist_OfferToBuyTicketAfterWarn ) + AddDialogButton( dialogData, "#NO" ) + + AddDialogFooter( dialogData, "#A_BUTTON_SELECT" ) + AddDialogFooter( dialogData, "#B_BUTTON_BACK" ) + + OpenDialog( dialogData ) +} + +void function ColiseumPlaylist_SpendTicketDialogue( var button, int numTickets = 1 ) +{ + DialogData dialogData + if ( numTickets == 1 ) + { + dialogData.header = "#COLISEUM_PAY_HEADER" + dialogData.message = "#COLISEUM_PAY_MESSAGE" + AddDialogButton( dialogData, "#YES", BuyIntoColiseumTicket ) + } + else + { + dialogData.header = "#COLISEUM_PAY_HEADER_INVITE" + dialogData.message = "#COLISEUM_PAY_MESSAGE_INVITE" + AddDialogButton( dialogData, "#YES", BuyIntoColiseumTicketParty ) + } + + AddDialogButton( dialogData, "#NO" ) + + AddDialogFooter( dialogData, "#A_BUTTON_SELECT" ) + AddDialogFooter( dialogData, "#B_BUTTON_BACK" ) + + OpenDialog( dialogData ) +} + +void function ColiseumPlaylist_OfferToBuyTicketAfterWarn() +{ + file.showColiseumPartyWarning = false + + int requiredTickets = 1 + if ( GetPartySize() == 2 ) + requiredTickets = 2 + + int ticketsToBuy = requiredTickets - Player_GetColiseumTicketCount( GetLocalClientPlayer() ) + + if ( ticketsToBuy > 0 ) + ColiseumPlaylist_OfferToBuyTickets( file.coliseumRefreshButtons, file.coliseumButton, ticketsToBuy ) +} + +void function ColiseumPlaylist_OfferToBuyTickets( array refreshButtons, var button, int numTickets ) +{ + OpenBuyTicketDialog( refreshButtons, button, numTickets ) +} + +void function BuyIntoColiseumTicketParty() +{ + string playlistName = "coliseum" + CloseActiveMenu() // playlist selection menu + ClientCommand( "MarkForDoubleColiseumTicket" ) + + array selectedPlaylists = [] + selectedPlaylists.append( playlistName ) + thread StartNSMatchmaking( selectedPlaylists ) +} + +void function BuyIntoColiseumTicket() +{ + string playlistName = "coliseum" + CloseActiveMenu() // playlist selection menu + + array selectedPlaylists = [] + selectedPlaylists.append( playlistName ) + thread StartNSMatchmaking( selectedPlaylists ) +} diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_playlist_mixtape.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_playlist_mixtape.nut new file mode 100644 index 000000000..e567663dd --- /dev/null +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_playlist_mixtape.nut @@ -0,0 +1,1049 @@ +global function GetPlaylistMenuName +global function InitPlaylistMixtapeMenu +global function InitPlaylistMixtapeChecklistMenu +global function MixtapeMatchmakingIsEnabled +global function GetChecklistPlaylistsArray +global function GetMixtapeMatchmakingVersion +global function IsMixtapeVersionNew +global function PrintPlaylistAvailability +global function ConvertStringArrayToCSS + +//script_ui AdvanceMenu( GetMenu( "PlaylistMixtapeMenu" ) ) + +struct +{ + var mixtapeMenu + + array promoButtons + array checklistIconButtons + var playButton + var pveButton + var pickButton + + var menuTitle + var contentDescriptionTitle + var contentDescription + var notifyNewTitle + + bool isOnPlaylistCheckboxButton + bool isOnPromoButton + bool isOnPlayButton + bool isShowingPlayButtonDescription + + string lastFocusedPlaylistDisplayName + string lastFocusedPlaylistNoteText + + ///// + + var checklistMenu + array checklistButtons + int checklistButtonsFirstVisibleIndex + array activeChecksOnOpen + + var focusDescription + int topBGHeight +} file + +struct promoInfo +{ + string playlistName + bool isPromoLocked + bool isDoubleXP +} +struct checkInfo +{ + string playlistName + bool isChecked +} +struct +{ + array promo + array checks +} pplInfo + + +bool function MixtapeMatchmakingIsEnabled() +{ + bool result = (Code_GetCurrentPlaylistVarOrUseValue( "mixtape_matchmaking", "0" ) == "1") + return result +} + +string function GetPlaylistMenuName() +{ + bool mixtapeMatchmakingEnabled = MixtapeMatchmakingIsEnabled() + if ( mixtapeMatchmakingEnabled ) + return MIXTAPE_MENU_NAME + + return "PlaylistMenu" +} + +const int PROMO_SLOT_COUNT = 10 +const int CHECKLIST_SLOT_COUNT = 15 + +void function ParsePlaylistInfos() +{ + pplInfo.promo.clear() + pplInfo.promo.resize( PROMO_SLOT_COUNT ) + pplInfo.checks.clear() + pplInfo.checks.resize( CHECKLIST_SLOT_COUNT) + + array checkDisables = GetCheckDisablesFromConvar() + int plCount = GetPlaylistCount() + for ( int idx = 0; idx < plCount; ++idx ) + { + string playlistName = string( GetPlaylistName( idx ) ) + + bool visible = GetPlaylistVarOrUseValue( playlistName, "visible", "0" ) == "1" + if ( !visible ) + continue + + int promoSlot = int( GetPlaylistVarOrUseValue( playlistName, "mixtape_promo_slot", "-1" ) ) + if ( (promoSlot >= 0) && (promoSlot < PROMO_SLOT_COUNT) ) + { + pplInfo.promo[promoSlot].playlistName = playlistName + pplInfo.promo[promoSlot].isPromoLocked = (GetPlaylistVarOrUseValue( playlistName, "mixtape_promo_islocked", "0" ) == "1") + pplInfo.promo[promoSlot].isDoubleXP = (GetPlaylistVarOrUseValue( playlistName, "double_xp_enabled", "0" ) == "1") + } + + int mixtapeSlot = int( GetPlaylistVarOrUseValue( playlistName, "mixtape_slot", "-1" ) ) + if ( (mixtapeSlot >= 0) && (mixtapeSlot < CHECKLIST_SLOT_COUNT) ) + { + pplInfo.checks[mixtapeSlot].playlistName = playlistName + pplInfo.checks[mixtapeSlot].isChecked = !(checkDisables.contains( playlistName )) + } + } +} + +array function GetChecklistPlaylistsArray() +{ + array results + results.resize( CHECKLIST_SLOT_COUNT ) + + int plCount = GetPlaylistCount() + for ( int idx = 0; idx < plCount; ++idx ) + { + string playlistName = string( GetPlaylistName( idx ) ) + + bool visible = GetPlaylistVarOrUseValue( playlistName, "visible", "0" ) == "1" + if ( !visible ) + continue + + int mixtapeSlot = int( GetPlaylistVarOrUseValue( playlistName, "mixtape_slot", "-1" ) ) + if ( (mixtapeSlot >= 0) && (mixtapeSlot < CHECKLIST_SLOT_COUNT) ) + results[mixtapeSlot] = playlistName + } + + return results +} + +const string MIXTAPE_MENU_NAME = "PlaylistMixtapeMenu" +void function InitPlaylistMixtapeMenu() +{ + file.mixtapeMenu = GetMenu( MIXTAPE_MENU_NAME ) + + file.menuTitle = Hud_GetChild( file.mixtapeMenu, "MenuTitle" ) + + // Promo Buttons + + for ( int idx = 0; idx < PROMO_SLOT_COUNT; ++idx ) + { + string btnName = ("PromoButton" + format( "%02d", idx )) + var button = Hud_GetChild( file.mixtapeMenu, btnName ) + + file.promoButtons.append( button ) + + AddButtonEventHandler( button, UIE_CLICK, OnPromoButtonClick ) + AddButtonEventHandler( button, UIE_GET_FOCUS, OnPromoButtonFocus ) + AddButtonEventHandler( button, UIE_LOSE_FOCUS, OnPromoButtonFocusLost ) + } + + for ( int idx = 0; idx < CHECKLIST_SLOT_COUNT; ++idx ) + { + string buttonName = ("BtnPlaylistIcon" + format( "%02d", idx )) + var button = Hud_GetChild( file.mixtapeMenu, buttonName ) + + AddButtonEventHandler( button, UIE_CLICK, OnChecklistIconButtonClick ) + AddButtonEventHandler( button, UIE_GET_FOCUS, OnChecklistIconButtonFocus ) + AddButtonEventHandler( button, UIE_LOSE_FOCUS, OnChecklistIconButtonFocusLost ) + file.checklistIconButtons.append( button ) + } + + file.playButton = Hud_GetChild( file.mixtapeMenu, "PlayButton" ) + AddButtonEventHandler( file.playButton, UIE_CLICK, OnPlayButtonClick ) + AddButtonEventHandler( file.playButton, UIE_GET_FOCUS, OnPlayButtonFocus ) + AddButtonEventHandler( file.playButton, UIE_LOSE_FOCUS, OnPlayButtonFocusLost ) + + file.pveButton = Hud_GetChild( file.mixtapeMenu, "PromoButton09" ) + + file.pickButton = Hud_GetChild( file.mixtapeMenu, "PickButton" ) + AddButtonEventHandler( file.pickButton, UIE_CLICK, OnPickButtonClick ) + AddButtonEventHandler( file.pickButton, UIE_GET_FOCUS, OnPickButtonFocus ) + + file.contentDescriptionTitle = Hud_GetChild( file.mixtapeMenu, "ContentDescriptionTitle" ) + file.contentDescription = Hud_GetChild( file.mixtapeMenu, "ContentDescription" ) + Hud_SetText( file.contentDescription, "" ) + file.notifyNewTitle = Hud_GetChild( file.mixtapeMenu, "NotifyNewTitle" ) + Hud_SetText( file.notifyNewTitle, "#NEW" ) + Hud_SetVisible( file.notifyNewTitle, false ) + + AddMenuEventHandler( file.mixtapeMenu, eUIEvent.MENU_OPEN, OnOpenPlaylistMixtapeMenu ) + + //AddMenuFooterOption( file.mixtapeMenu, BUTTON_A, "#A_BUTTON_SELECT" ) + AddMenuFooterOption( file.mixtapeMenu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) + AddMenuFooterOption( file.mixtapeMenu, BUTTON_Y, "#Y_BUTTON_TOGGLE_ALL", "#TOGGLE_ALL", ToggleAllCheckboxButtons, null ) + //AddMenuFooterOption( file.mixtapeMenu, BUTTON_X, "#X_BUTTON_DETAILS", "#MOUSE2_DETAILS", null, IsOnADetailsButton ) + + file.focusDescription = Hud_GetChild( file.mixtapeMenu, "FocusDescription" ) + file.topBGHeight = Hud_GetHeight( Hud_GetChild( file.mixtapeMenu, "BackgroundLeft" ) ) +} + +bool function IsOnADetailsButton() +{ + if ( file.isOnPlaylistCheckboxButton ) + return true + if ( file.isOnPromoButton ) + return true + if ( file.isOnPlayButton ) + return true + + return false +} + +///////////////// +void function UpdateChecklistIconButtonsThread() +{ + while ( GetTopNonDialogMenu() == GetMenu( MIXTAPE_MENU_NAME ) ) + { + if ( GetUIPlayer() ) + { + int enableCount = 0 + + string singlePlaylistName + int length = file.checklistIconButtons.len() + for( int idx = 0; idx < length; ++idx ) + { + var panel = file.checklistIconButtons[idx] + var panelRui = Hud_GetRui( panel ) + string playlistName = pplInfo.checks[idx].playlistName + if ( playlistName.len() == 0 ) + continue + + bool isLocked = PlaylistShouldShowAsLocked( playlistName ) + RuiSetBool( panelRui, "isLocked", isLocked ) + + bool isChecked = pplInfo.checks[idx].isChecked + RuiSetBool( panelRui, "isChecked", isChecked ) + + if ( isChecked && !isLocked ) + { + ++enableCount + if ( enableCount == 1 ) + singlePlaylistName = GetPlaylistVarOrUseValue( playlistName, "name", "#UNKNOWN_PLAYLIST_NAME" ) + } + + bool isMuted = (file.isOnPromoButton) + RuiSetBool( panelRui, "isMuted", isMuted ) + + bool isGlowing = (file.isOnPlayButton) + RuiSetBool( panelRui, "isGlowing", isGlowing ) + } + + // + { + var playRui = Hud_GetRui( file.playButton ) + RuiSetInt( playRui, "enabledPlaylistCount", enableCount ) + RuiSetString( playRui, "playlistNoteName", singlePlaylistName ) + } + } + WaitFrame() + } +} + +void function SetupChecklistIconButtons() +{ + int length = file.checklistIconButtons.len() + for( int idx = 0; idx < length; ++idx ) + { + var button = file.checklistIconButtons[idx] + string playlistName = pplInfo.checks[idx].playlistName + + Hud_SetVisible( button, false ) + + var buttonRui = Hud_GetRui( button ) + asset playlistThumbnail = GetPlaylistThumbnailImage( playlistName ) + RuiSetImage( buttonRui, "checkImage", playlistThumbnail ) + + string abbr = GetPlaylistVarOrUseValue( playlistName, "abbreviation", "" ) + RuiSetString( buttonRui, "abbreviation", Localize( abbr ) ) + } + + thread UpdateChecklistIconButtonsThread() +} + +void function RefreshDescriptionTitle( bool asEnabled ) +{ + if ( file.isOnPlaylistCheckboxButton && (file.lastFocusedPlaylistDisplayName.len() > 0) ) + { + string titleText = Localize( file.lastFocusedPlaylistDisplayName ) + Hud_SetText( file.contentDescriptionTitle, titleText ) + + string noteText = Localize( file.lastFocusedPlaylistNoteText ) + Hud_SetText( file.contentDescription, noteText ) + + if ( asEnabled ) + Hud_SetColor( file.contentDescriptionTitle, 255, 184, 0, 255 ) + else + Hud_SetColor( file.contentDescriptionTitle, 128, 128, 128, 255 ) + } + else + { + Hud_SetText( file.contentDescriptionTitle, "#MATCHMAKING_MIXTAPE_CHOOSE_INFO" ) + Hud_SetText( file.contentDescription, "" ) + + Hud_SetColor( file.contentDescriptionTitle, 192, 192, 192, 192 ) + } +} + +void function SetDescriptionTitleForIconButton( int buttonID ) +{ + string playlistName = pplInfo.checks[buttonID].playlistName + file.lastFocusedPlaylistDisplayName = GetPlaylistVarOrUseValue( playlistName, "name", "#UNKNOWN_PLAYLIST_NAME" ) + file.lastFocusedPlaylistNoteText = GetPlaylistVarOrUseValue( playlistName, "promo_note", "" ) + + bool isChecked = pplInfo.checks[buttonID].isChecked + RefreshDescriptionTitle( isChecked ) +} + +void function OnChecklistIconButtonFocus( var button ) +{ + file.isOnPlaylistCheckboxButton = true + file.isOnPromoButton = false + file.isOnPlayButton = false + + int buttonID = int( Hud_GetScriptID( button ) ) + SetDescriptionTitleForIconButton( buttonID ) + + string descText = GetPlaylistDescription( pplInfo.checks[buttonID].playlistName ) + Hud_SetText( file.focusDescription, descText ) + file.isShowingPlayButtonDescription = false + + //SetMixtapeVersionCurrent() +} + +void function OnChecklistIconButtonFocusLost( var button ) +{ +// file.isOnPlaylistCheckboxButton = false + file.lastFocusedPlaylistDisplayName = "" + file.lastFocusedPlaylistNoteText = "" + RefreshDescriptionTitle( false ) +} + +void function OnChecklistIconButtonClick( var button ) +{ + int buttonID = int( Hud_GetScriptID( button ) ) + + bool wasChecked = pplInfo.checks[buttonID].isChecked + pplInfo.checks[buttonID].isChecked = !(wasChecked) + WriteCheckDisablesToConvar() + + BouncePlayNoteText( !wasChecked ) + + SetDescriptionTitleForIconButton( buttonID ) + + SetMixtapeVersionCurrent() +} + +bool function AreAnyPlaylistsCheckedOff() +{ + int count = pplInfo.checks.len() + for ( int idx = 0; idx < count; ++idx ) + { + string playlistName = pplInfo.checks[idx].playlistName + if ( playlistName.len() <= 0 ) + continue + + if ( !pplInfo.checks[idx].isChecked ) + return true + } + + return false +} + +void function ToggleAllCheckboxButtons( var button ) +{ + bool turnAllOn = AreAnyPlaylistsCheckedOff() + + int count = pplInfo.checks.len() + for ( int idx = 0; idx < count; ++idx ) + { + string playlistName = pplInfo.checks[idx].playlistName + if ( playlistName.len() <= 0 ) + continue + + bool wasChecked = pplInfo.checks[idx].isChecked + if ( turnAllOn && wasChecked ) + continue + if ( !turnAllOn && !wasChecked ) + continue + + pplInfo.checks[idx].isChecked = !wasChecked + } + WriteCheckDisablesToConvar() + + RefreshDescriptionTitle( turnAllOn ) + + BouncePlayNoteText( turnAllOn ) + + if ( turnAllOn ) + EmitUISound( "Menu_LoadOut_Weapon_Select" ) + else + EmitUISound( "Menu_LoadOut_PilotCamo_Select" ) + + if ( file.isShowingPlayButtonDescription ) + Hud_SetText( file.focusDescription, GetPlayButtonDescription() ) +} + +void function SetChecklistIconButtonsVisible( bool setBool ) +{ + int length = file.checklistIconButtons.len() + for( int idx = 0; idx < length; ++idx ) + { + var button = file.checklistIconButtons[idx] + string playlistName = pplInfo.checks[idx].playlistName + + if ( playlistName.len() == 0 ) + { + Hud_SetVisible( button, false ) + continue + } + + Hud_SetVisible( button, setBool ) + } +} +///////////////// + +void function UpdatePromoButtonsThread() +{ + while ( GetTopNonDialogMenu() == GetMenu( MIXTAPE_MENU_NAME ) ) + { + if ( GetUIPlayer() ) + { + int length = file.promoButtons.len() + for( int idx = 0; idx < length; ++idx ) + { + var button = file.promoButtons[idx] + var buttonRui = Hud_GetRui( button ) + string playlistName = pplInfo.promo[idx].playlistName + if ( playlistName.len() == 0 ) + continue + + UpdatePlaylistButton( button, playlistName, pplInfo.promo[idx].isPromoLocked ) + RuiSetBool( buttonRui, "doubleXP", pplInfo.promo[idx].isDoubleXP ) + } + + } + WaitFrame() + } +} + +void function SetupPromoButtons() +{ + int numPromoButtons = 0 + int length = file.promoButtons.len() + for( int idx = 0; idx < length; ++idx ) + { + var button = file.promoButtons[idx] + var buttonRui = Hud_GetRui( button ) + string playlistName = pplInfo.promo[idx].playlistName + + if ( playlistName.len() == 0 ) + { + Hud_SetVisible( button, false ) + continue + } + + Hud_SetVisible( button, true ) + numPromoButtons++ + + asset playlistImage = GetPlaylistImage( playlistName ) + RuiSetImage( buttonRui, "itemImage", playlistImage ) + + string displayName = GetPlaylistVarOrUseValue( playlistName, "name", "#UNKNOWN_PLAYLIST_NAME" ) + RuiSetString( buttonRui, "title", displayName ) + + string displayNote = GetPlaylistVarOrUseValue( playlistName, "promo_note", "" ) + RuiSetString( buttonRui, "playlistNoteName", displayNote ) + RuiSetBool( buttonRui, "playlistHasPromotText", displayNote != "" ) + } + + var topBG = Hud_GetChild( file.mixtapeMenu, "BackgroundLeft" ) + var bottomBG = Hud_GetChild( file.mixtapeMenu, "DetailsBackground" ) + + //if ( numPromoButtons <= 4 ) + //{ + // int diff = int( file.topBGHeight * 0.2 ) + // Hud_SetHeight( topBG, file.topBGHeight * 0.8 ) + // Hud_SetY( bottomBG, Hud_GetBaseY( bottomBG ) - diff ) + //} + //else + //{ + Hud_SetHeight( topBG, file.topBGHeight ) + Hud_SetY( bottomBG, Hud_GetBaseY( bottomBG ) ) + //} + + thread UpdatePromoButtonsThread() +} + +int function GetMixtapeMatchmakingVersion() +{ + int result = int( Code_GetCurrentPlaylistVarOrUseValue( "mixtape_version", "-1" ) ) + return result +} + +bool function IsMixtapeVersionNew() +{ + int versionNow = GetMixtapeMatchmakingVersion() + int lastVersionSeen = GetConVarInt( "match_mixtape_version" ) + bool mixtapeVersionIsNew = (versionNow != lastVersionSeen) + return mixtapeVersionIsNew +} + +void function SetMixtapeVersionCurrent() +{ + int versionNow = GetMixtapeMatchmakingVersion() + int lastVersionSeen = GetConVarInt( "match_mixtape_version" ) + if ( versionNow == lastVersionSeen ) + return + + SetConVarInt( "match_mixtape_version", versionNow ) + Hud_SetVisible( file.notifyNewTitle, false ) +} + +string function GetMenuHeader() +{ + bool openInviting = IsSendOpenInviteTrue() + return (openInviting ? "#MENU_HEADER_INVITE_ROOM" : "#MENU_HEADER_FIND_GAME") +} + +void function OnOpenPlaylistMixtapeMenu() +{ + StopMatchmaking() + //// + + ParsePlaylistInfos() + + UI_SetPresentationType( ePresentationType.NO_MODELS ) + + bool openInviting = IsSendOpenInviteTrue() + + Hud_SetText( file.menuTitle, GetMenuHeader() ) + + var pbRui = Hud_GetRui( file.playButton ) + RuiSetBool( pbRui, "bigPresentation", true ) + RuiSetImage( pbRui, "itemImage", $"rui/menu/gametype_select/mixtape_play_image" ) + RuiSetString( pbRui, "title", "#MATCHMAKING_MIXTAPE_PLAY_BUTTON" ) + + const bool DO_SHOW_PICK_BUTTON = false + Hud_SetVisible( file.pickButton, DO_SHOW_PICK_BUTTON ) + if ( DO_SHOW_PICK_BUTTON ) + { + SetButtonRuiText( file.pickButton, "#MATCHMAKING_MIXTAPE_CHOOSE_OPTION" ) + SetNamedRuiBool( file.pickButton, "showThinBorder", true ) + + // SetNamedRuiBool( file.pickButton, "isNew", mixtapeVersionIsNew ) + } + + bool mixtapeVersionIsNew = IsMixtapeVersionNew() + Hud_SetVisible( file.notifyNewTitle, mixtapeVersionIsNew ) + + + SetupPromoButtons() + SetupChecklistIconButtons() + + var pveRui = Hud_GetRui( file.pveButton ) + RuiSetBool( pveRui, "bigPresentation", true ) + RuiSetImage( pveRui, "itemImage", $"rui/menu/gametype_select/pve_play_image" ) + //RuiSetString( pveRui, "title", "#MATCHMAKING_PVE_PLAY_BUTTON" ) + + // player count: + { + string playlistName = "at" + string regionDesc = GetPlaylistCountDescForRegion( playlistName ) + string worldDesc = GetPlaylistCountDescForWorld( playlistName ) +#if DEV + if ( worldDesc == "" ) + worldDesc = "37429" +#endif // #if DEV + Hud_SetText( Hud_GetChild( file.mixtapeMenu, "PlayerCount" ), "#PLAYLIST_PLAYERCOUNT_MIXTAPE_SCREEN", regionDesc, worldDesc ) + } + + SetChecklistIconButtonsVisible( true ) + + RefreshDescriptionTitle( false ) + + thread DelayedSetFocusThread( file.playButton ) +} + +bool function IsDialogUp() +{ + bool result = IsDialog( uiGlobal.activeMenu ) + return result +} + +void function DelayedSetFocusThread( var item ) +{ + WaitEndFrame() + if ( IsDialogUp() ) + return + + Hud_SetFocused( item ) +} + +void function OnPromoButtonClick( var button ) +{ + int buttonID = int( Hud_GetScriptID( button ) ) + + CloseAllDialogs() + + string playlistName = pplInfo.promo[buttonID].playlistName + array refreshButtons // empty + + SetNextAutoMatchmakingPlaylist( "" ) + bool didStartMatchmaking = PlaylistButton_Click_Internal( button, playlistName, refreshButtons ) + if ( didStartMatchmaking ) + SetNextAutoMatchmakingPlaylist( playlistName ) +} + + +void function DoPlaylistInfoDialog( string playlistName ) +{ + if ( IsDialogUp() ) + return + + string titleText = GetPlaylistVarOrUseValue( playlistName, "name", "#UNKNOWN_PLAYLIST_NAME" ) + string descText = GetPlaylistVarOrUseValue( playlistName, "description", "#UNKNOWN_PLAYLIST_NAME" ) + + DialogData dialogData + dialogData.header = titleText + dialogData.message = descText + dialogData.noChoiceWithNavigateBack = true + + AddDialogButton( dialogData, "#OK" ) + + OpenDialog( dialogData ) +} + +string function pldn( array pl, int index ) +{ + string playlistName = pl[index] + string playlistDisplayName = GetPlaylistVarOrUseValue( playlistName, "name", "#UNKNOWN_PLAYLIST_NAME" ) + return Localize( playlistDisplayName ) +} + +string function BuildPlayWarningMessageTop( array pl ) +{ + int playlistCount = pl.len() + switch ( playlistCount ) + { + case 0: + return Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_TOP_00" ) + case 1: + return Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_TOP_01", pldn(pl,0) ) + case 2: + return Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_TOP_02", pldn(pl,0), pldn(pl,1) ) + case 3: + return Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_TOP_03", pldn(pl,0), pldn(pl,1), pldn(pl,2) ) + case 4: + return Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_TOP_04", pldn(pl,0), pldn(pl,1), pldn(pl,2), pldn(pl,3) ) + case 5: + return Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_TOP_05", pldn(pl,0), pldn(pl,1), pldn(pl,2), pldn(pl,3), pldn(pl,4) ) + case 6: + return Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_TOP_06", pldn(pl,0), pldn(pl,1), pldn(pl,2), pldn(pl,3), pldn(pl,4), pldn(pl,5) ) + case 7: + return Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_TOP_07", pldn(pl,0), pldn(pl,1), pldn(pl,2), pldn(pl,3), pldn(pl,4), pldn(pl,5), pldn(pl,6) ) + case 8: + return Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_TOP_08", pldn(pl,0), pldn(pl,1), pldn(pl,2), pldn(pl,3), pldn(pl,4), pldn(pl,5), pldn(pl,6), pldn(pl,7) ) + case 9: + return Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_TOP_09", pldn(pl,0), pldn(pl,1), pldn(pl,2), pldn(pl,3), pldn(pl,4), pldn(pl,5), pldn(pl,6), pldn(pl,7), pldn(pl,8) ) + default: + return Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_TOP_MAX", pldn(pl,0), pldn(pl,1), pldn(pl,2), pldn(pl,3), pldn(pl,4), pldn(pl,5), pldn(pl,6), pldn(pl,7), pldn(pl,8) ) + } + unreachable +} + +void function DoPlayButtonWarningDialog( array activePlaylists, bool andThenPlay ) +{ + if ( IsDialogUp() ) + return + + string messageTop = BuildPlayWarningMessageTop( activePlaylists ) + + DialogData dialogData + dialogData.header = "#MENU_HEADER_PLAY" + dialogData.message = messageTop + Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_BOTTOM" ) + dialogData.noChoiceWithNavigateBack = true + + if ( andThenPlay ) + { + AddDialogButton( dialogData, "#MATCHMAKING_MIXTAPE_WARN_OK", DoPlayButtonAction ) + AddDialogButton( dialogData, "#MATCHMAKING_MIXTAPE_WARN_OKNEVERAGAIN", DoPlayButtonActionWithWarningDisable ) + } + else + { + AddDialogButton( dialogData, "#MATCHMAKING_MIXTAPE_WARN_OK" ) + } + + AddDialogFooter( dialogData, "#B_BUTTON_BACK" ) + + OpenDialog( dialogData ) +} + +void function PlayRightClickSound() +{ + EmitUISound( "Menu.Accept" ) +} + +void function OnPromoButtonFocus( var button ) +{ + file.isOnPlaylistCheckboxButton = false + file.isOnPromoButton = true + file.isOnPlayButton = false + + int buttonID = int( Hud_GetScriptID( button ) ) + string descText = GetPlaylistDescription( pplInfo.promo[buttonID].playlistName ) + Hud_SetText( file.focusDescription, descText ) + file.isShowingPlayButtonDescription = false +} + +void function OnPromoButtonFocusLost( var button ) +{ +} + +void function BouncePlayNoteText( bool bounceUp ) +{ + var playRui = Hud_GetRui( file.playButton ) + RuiSetGameTime( playRui, "playlistNoteBounceTime", Time() ) + RuiSetBool( playRui, "playlistNoteBounceUp", bounceUp ) +} + +void function DoPlayButtonAction_Internal( array activePlaylists ) +{ + if ( activePlaylists.len() <= 0 ) + { + thread DelayedSetFocusThread( file.checklistIconButtons[0] ) + return + } + //string playlistsCS = ConvertStringArrayToCSS( activePlaylists ) + + CloseActiveMenu() + + thread StartNSMatchmaking( activePlaylists ) + + /* Respawn Stuff + printt( "Setting match_playlist to '" + playlistsCS + "' from playlist menu" ) + SetNextAutoMatchmakingPlaylist( playlistsCS ) + if ( IsSendOpenInviteTrue() ) + ClientCommand( "openinvite playlist " + playlistsCS ) + else + StartMatchmakingPlaylists( playlistsCS ) + */ +} + +void function DoPlayButtonAction() +{ + array activePlaylists = GetActiveChecks() + if ( activePlaylists.len() == 0 ) + return + + DoPlayButtonAction_Internal( activePlaylists ) +} + +void function DoPlayButtonActionWithWarningDisable() +{ + array activePlaylists = GetActiveChecks() + if ( activePlaylists.len() == 0 ) + return + + SetConVarBool( "match_mixtape_warnOnPlay", false ) + DoPlayButtonAction_Internal( activePlaylists ) +} + +void function OnPlayButtonClick( var button ) +{ + CloseAllDialogs() + + array activePlaylists = GetActiveChecks() + if ( activePlaylists.len() == 0 ) + { + thread DelayedSetFocusThread( file.checklistIconButtons[0] ) + return + } + + bool warnOnPlay = GetConVarBool( "match_mixtape_warnOnPlay" ) + if ( warnOnPlay ) + { + DoPlayButtonWarningDialog( activePlaylists, true ) + return + } + + DoPlayButtonAction_Internal( activePlaylists ) +} + +void function OnPlayButtonFocus( var button ) +{ + file.isOnPlaylistCheckboxButton = false + file.isOnPromoButton = false + file.isOnPlayButton = true + + Hud_SetText( file.focusDescription, GetPlayButtonDescription() ) + file.isShowingPlayButtonDescription = true +} + +void function OnPlayButtonFocusLost( var button ) +{ + file.isOnPlayButton = false +} + +void function OnPickButtonClick( var button ) +{ + AdvanceMenu( file.checklistMenu ) +} + +void function OnPickButtonFocus( var button ) +{ +} + + + +////////////////////////// +////////////////////////// + +const string CHECKLIST_MENU_NAME = "PlaylistMixtapeChecklistMenu" +void function InitPlaylistMixtapeChecklistMenu() +{ + file.checklistMenu = GetMenu( CHECKLIST_MENU_NAME ) + + for ( int idx = 0; idx < CHECKLIST_SLOT_COUNT; ++idx ) + { + string btnName = ("BtnPlaylistCheck" + format( "%02d", idx )) + var button = Hud_GetChild( file.checklistMenu, btnName ) + + file.checklistButtons.append( button ) + + AddButtonEventHandler( button, UIE_GET_FOCUS, OnChecklistButtonFocus ) + AddButtonEventHandler( button, UIE_CLICK, OnChecklistButtonClick ) + } + + AddMenuEventHandler( file.checklistMenu, eUIEvent.MENU_OPEN, OnOpenPlaylistMixtapeChecklistMenu ) + AddMenuFooterOption( file.checklistMenu, BUTTON_A, "#A_BUTTON_SELECT" ) + AddMenuFooterOption( file.checklistMenu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) +} + +void function UpdateChecklistButtonsThread() +{ + while ( GetTopNonDialogMenu() == GetMenu( CHECKLIST_MENU_NAME ) ) + { + if ( GetUIPlayer() ) + { + int length = file.checklistButtons.len() + for( int idx = 0; idx < length; ++idx ) + { + var button = file.checklistButtons[idx] + var buttonRui = Hud_GetRui( button ) + string playlistName = pplInfo.checks[idx].playlistName + if ( playlistName.len() == 0 ) + continue + + bool isLocked = PlaylistShouldShowAsLocked( playlistName ) + RuiSetBool( buttonRui, "isLocked", isLocked ) + + RuiSetBool( buttonRui, "isChecked", pplInfo.checks[idx].isChecked ) + } + + } + WaitFrame() + } +} + +void function SetupChecklistButtons() +{ + file.checklistButtonsFirstVisibleIndex = -1 + int length = file.checklistButtons.len() + for( int idx = 0; idx < length; ++idx ) + { + var button = file.checklistButtons[idx] + var buttonRui = Hud_GetRui( button ) + string playlistName = pplInfo.checks[idx].playlistName + + if ( playlistName.len() == 0 ) + { + Hud_SetVisible( button, false ) + continue + } + + Hud_SetVisible( button, true ) + if ( file.checklistButtonsFirstVisibleIndex < 0 ) + file.checklistButtonsFirstVisibleIndex = idx + + asset playlistThumbnail = GetPlaylistThumbnailImage( playlistName ) + RuiSetImage( buttonRui, "checkImage", playlistThumbnail ) + + string playlistDisplayName = GetPlaylistVarOrUseValue( playlistName, "name", "#UNKNOWN_PLAYLIST_NAME" ) + SetButtonRuiText( button, playlistDisplayName ) + } + + thread UpdateChecklistButtonsThread() +} + +void function OnOpenPlaylistMixtapeChecklistMenu() +{ + SetupChecklistButtons() + + file.activeChecksOnOpen = GetActiveChecks() + + // Clear "New!": + { + int versionNow = GetMixtapeMatchmakingVersion() + SetConVarInt( "match_mixtape_version", versionNow ) + } + + if ( file.checklistButtonsFirstVisibleIndex >= 0 ) + thread DelayedSetFocusThread( file.checklistButtons[file.checklistButtonsFirstVisibleIndex] ) +} + +void function OnChecklistButtonFocus( var button ) +{ + int buttonID = int( Hud_GetScriptID( button ) ) + + string playlistName = pplInfo.checks[buttonID].playlistName + + asset playlistImage = GetPlaylistImage( playlistName ) + RuiSetImage( Hud_GetRui( Hud_GetChild( file.checklistMenu, "PlaylistImage" ) ), "basicImage", playlistImage ) + + string displayName = GetPlaylistVarOrUseValue( playlistName, "name", "#UNKNOWN_PLAYLIST_NAME" ) + Hud_SetText( Hud_GetChild( file.checklistMenu, "PlaylistDescriptionTitle" ), displayName ) + + string descText = GetPlaylistVarOrUseValue( playlistName, "description", "#UNKNOWN_PLAYLIST_NAME" ) + Hud_SetText( Hud_GetChild( file.checklistMenu, "PlaylistDescription" ), descText ) +} + +void function OnChecklistButtonClick( var button ) +{ + int buttonID = int( Hud_GetScriptID( button ) ) + //bool isLocked = PlaylistShouldShowAsLocked( pplInfo.checks[buttonID].playlistName ) + //if ( isLocked ) + // return + + pplInfo.checks[buttonID].isChecked = !(pplInfo.checks[buttonID].isChecked) + WriteCheckDisablesToConvar() +} + +void function WriteCheckDisablesToConvar() +{ + string result = "" + bool foundADisable = false + int checksCount = pplInfo.checks.len() + for ( int idx = 0; idx < checksCount; ++idx ) + { + string playlistName = pplInfo.checks[idx].playlistName + if ( (playlistName.len() > 0) && !pplInfo.checks[idx].isChecked ) + { + if ( !foundADisable ) + foundADisable = true + else + result += "," + result += playlistName + } + } + + SetConVarString( "match_mixtape_unchecked", result ) + + int convarVersionOld = GetConVarInt( "match_mixtape_unchecked_version" ) + int convarVersionNow = int( Code_GetCurrentPlaylistVarOrUseValue( "mixtape_checkbox_memory_version", "-1" ) ) + if ( convarVersionOld != convarVersionNow ) + SetConVarInt( "match_mixtape_unchecked_version", convarVersionNow ) +} + +array function GetCheckDisablesFromConvar() +{ + int convarVersionUsed = GetConVarInt( "match_mixtape_unchecked_version" ) + int convarVersionNow = int( Code_GetCurrentPlaylistVarOrUseValue( "mixtape_checkbox_memory_version", "-1" ) ) + + string convarVal = (convarVersionUsed == convarVersionNow) ? GetConVarString( "match_mixtape_unchecked" ) : "" + array result = split( convarVal, "," ) + return result +} + +array function GetActiveChecks_Internal( bool excludeIfLocked ) +{ + array result + + int count = pplInfo.checks.len() + for ( int idx = 0; idx < count; ++idx ) + { + string playlistName = pplInfo.checks[idx].playlistName + if ( playlistName.len() <= 0 ) + continue + + if ( !pplInfo.checks[idx].isChecked ) + continue + + if ( excludeIfLocked && PlaylistShouldShowAsLocked( playlistName ) ) + continue + + result.append( playlistName ) + } + + return result +} + +array function GetActiveChecks() +{ + return GetActiveChecks_Internal( true ) +} + +string function ConvertStringArrayToCSS( array strArray ) +{ + string result = "" + bool usedOne = false + int count = strArray.len() + for ( int idx = 0; idx < count; ++idx ) + { + string thisStr = strArray[idx] + if ( (thisStr.len() > 0) ) + { + if ( !usedOne ) + usedOne = true + else + result += "," + result += thisStr + } + } + + return result +} + +string function GetPlayButtonDescription() +{ + string message = BuildPlayWarningMessageTop( GetActiveChecks() ) + string descText = message + Localize( "#MATCHMAKING_MIXTAPE_WARN_BODY_BOTTOM" ) + + return descText +} + +string function GetPlaylistDescription( string playlistName ) +{ + return GetPlaylistVarOrUseValue( playlistName, "description", "#UNKNOWN_PLAYLIST_NAME" ) +} + +void function PrintPlaylistAvailability() +{ + printt( "!!!!!!!!!!!!!!!!!!!!!!! PrintPlaylistAvailability() called with party size", GetPartySize() ) + printt( "!!!!!!!!!!!!!!!!!!!!!!! aitdm:", CanPlaylistFitMyParty( "aitdm" ) ) + printt( "!!!!!!!!!!!!!!!!!!!!!!! at: ", CanPlaylistFitMyParty( "at" ) ) + printt( "!!!!!!!!!!!!!!!!!!!!!!! cp: ", CanPlaylistFitMyParty( "cp" ) ) + printt( "!!!!!!!!!!!!!!!!!!!!!!! lts: ", CanPlaylistFitMyParty( "lts" ) ) + printt( "!!!!!!!!!!!!!!!!!!!!!!! ctf: ", CanPlaylistFitMyParty( "ctf" ) ) + printt( "!!!!!!!!!!!!!!!!!!!!!!! ps: ", CanPlaylistFitMyParty( "ps" ) ) + printt( "!!!!!!!!!!!!!!!!!!!!!!! ffa: ", CanPlaylistFitMyParty( "ffa" ) ) +} diff --git a/Northstar.Custom/keyvalues/playlists_v2.txt b/Northstar.Custom/keyvalues/playlists_v2.txt index 21934b319..55419253c 100644 --- a/Northstar.Custom/keyvalues/playlists_v2.txt +++ b/Northstar.Custom/keyvalues/playlists_v2.txt @@ -46,7 +46,6 @@ playlists max_players 12 max_teams 12 classic_mp 1 - scorelimit 21 // temp until we have a way of dynamically setting non-default scorelimit in code gamemode_score_hint #GAMEMODE_SCORE_HINT_FFA @@ -294,7 +293,8 @@ playlists image varietypack //mixtape_slot 7 mixtape_timeout 120 - visible 0 + mixtape_promo_slot 6 + visible 1 } gamemodes { @@ -376,7 +376,8 @@ playlists hint #PL_inf_hint image ps abbreviation #PL_inf_abbr - visible 0 + mixtape_promo_slot 8 + visible 1 } gamemodes { @@ -530,6 +531,8 @@ playlists scorelimit 5 roundtimelimit 2 roundscorelimit 5 + mixtape_promo_slot 1 + visible 1 gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM } @@ -576,6 +579,9 @@ playlists scorelimit 100 timelimit 15 + mixtape_promo_slot 5 + visible 1 + gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM } gamemodes @@ -728,7 +734,8 @@ playlists image ps //mixtape_slot 7 mixtape_timeout 120 - visible 0 + mixtape_promo_slot 7 + visible 1 } gamemodes { @@ -898,5 +905,151 @@ playlists } } } + rocket_lf + { + inherit defaults + vars + { + name #PL_rocket_arena + lobbytitle #PL_rocket_arena_lobby + description #PL_rocket_arena_desc + abbreviation #PL_rocket_arena_abbr + image lf + visible 0 + scorelimit 50 + roundtimelimit 2.0 + featured_mode_rocket_arena 1 + boosts_enabled 1 + } + gamemodes + { + speedball + { + maps + { + mp_lf_stacks 1 + mp_lf_township 1 + mp_lf_uma 1 + mp_lf_traffic 1 + mp_lf_deck 1 + mp_lf_meadow 1 + } + } + } + } + phase_aitdm + { + inherit defaults + vars + { + name "#PL_all_phase" + lobbytitle #PL_all_phase_lobby + description #PL_all_phase_desc + abbreviation #PL_all_phase_abbr + image aitdm + visible 0 + featured_mode_all_phase 1 + } + gamemodes + { + aitdm + { + } + } + } + spicy_aitdm + { + inherit defaults + vars + { + name "#PL_all_spicy" + lobbytitle #PL_all_spicy_lobby + description #PL_all_spicy_desc + abbreviation #PL_all_spicy_abbr + image aitdm + visible 0 + featured_mode_all_ticks 1 + } + gamemodes + { + aitdm + { + } + } + } + fd_insane + { + inherit fd + vars + { + name #PL_fd_insane + lobbytitle #PL_fd_insane_lobby + description #PL_fd_insane_desc + image fd_insane + visible 0 + promo_note #MP_HOMESTEAD + } + gamemodes + { + fd + {} + } + gamemodesWithAncestor + { + fd_insane + { + maps + { + mp_homestead 1 + } + } + } + } + turbo_lts + { + inherit defaults + vars + { + name #PL_turbo_last_titan_standing + lobbytitle #PL_turbo_last_titan_standing_lobby + description #PL_turbo_last_titan_standing_desc + abbreviation #PL_turbo_last_titan_standing_abbr + image lts + visible 0 + featured_mode_turbo_titans 1 + earn_meter_titan_multiplier 2.0 + } + gamemodes + { + lts + { + } + } + } + private_match + { + inherit defaults + vars + { + name #PL_private_match + lobbytitle #PL_private_match_lobby + description #PL_private_match_desc + image private_match + + max_players 16 + lobby_countdown 5 + ranking_supported 0 + mixtape_promo_slot 0 + double_xp_enabled 0 + visible 1 + + // default custom settings + match_visibility 2 + pilot_health_multiplier 1.0 + earn_meter_pilot_multiplier 1.0 + earn_meter_pilot_overdrive 1 + earn_meter_titan_multiplier 1.0 + } + } } } From 13a5ab0f83f7fa27c36bcde28915a07417f3ee74 Mon Sep 17 00:00:00 2001 From: Zanieon Date: Fri, 1 Sep 2023 08:54:10 -0300 Subject: [PATCH 02/10] Improvements: Show server name + desc on connect --- .../mod/scripts/vscripts/ui/menu_lobby.nut | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut index bbb8e576e..64a2d90f3 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut @@ -1671,6 +1671,7 @@ void function StartNSMatchmaking( array selectedPlaylists ) Hud_Show( statusEl ) wait 3.0 //Fancy delay just because server finder is pratically immediate, whole block above is to show "fake" matchmaking search + MatchmakingSetCountdownTimer( 0.0, true ) MatchmakingSetCountdownVisible( false ) NSClearRecievedServerList() @@ -1787,12 +1788,13 @@ void function MatchmakedAuthAndConnectToServer( ServerInfo matchmakedserver, str EmitUISound( MATCHMAKING_AUDIO_CONNECTING ) MatchmakingSetSearchText( "#MATCHMAKING_MATCH_CONNECTING" ) + MatchmakingSetCountdownTimer( 0.0, true ) MatchmakingSetCountdownVisible( false ) HideMatchmakingStatusIcons() Hud_Hide( statusEl ) - OpenConnectingDialog() + ShowServerConnectingInfo( matchmakedserver.name, matchmakedserver.description + "\n\nServer Mods:\n" + FillInServerModsLabel( matchmakedserver.requiredMods ) ) - wait 2.0 + wait 5.0 MatchmakingSetSearchVisible( false ) @@ -1823,4 +1825,30 @@ void function MatchmakedAuthAndConnectToServer( ServerInfo matchmakedserver, str AddDialogFooter( dialogData, "#B_BUTTON_DISMISS_RUI" ) OpenDialog( dialogData ) } +} + +void function ShowServerConnectingInfo( string servername = "", string servercontext = "" ) +{ + CloseAllDialogs() + + string connectingserver = "Found Server" + ": " + servername + + Hud_Hide( uiGlobal.ConfirmMenuMessage ) + Hud_Hide( uiGlobal.ConfirmMenuErrorCode ) + + DialogData dialogData + dialogData.header = connectingserver + dialogData.message = servercontext + dialogData.showSpinner = true + + OpenDialog( dialogData ) +} + +string function FillInServerModsLabel( array mods ) +{ + string ret + foreach ( RequiredModInfo mod in mods ) + ret += format( " %s v%s\n", mod.name, mod.version ) + + return ret } \ No newline at end of file From 803d5b0318dc28150695b00daf68958bb26e740c Mon Sep 17 00:00:00 2001 From: Zanieon Date: Wed, 11 Oct 2023 20:08:46 -0300 Subject: [PATCH 03/10] Update menu_lobby.nut --- .../mod/scripts/vscripts/ui/menu_lobby.nut | 232 +++++++++++++++++- 1 file changed, 223 insertions(+), 9 deletions(-) diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut index 23dae99d5..b147e621c 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut @@ -41,6 +41,8 @@ global function OnStoreButton_Activate global function OnStoreBundlesButton_Activate global function OnStoreNewReleasesButton_Activate +global function StartNSMatchmaking + const string MATCHMAKING_AUDIO_CONNECTING = "menu_campaignsummary_titanunlocked" struct @@ -288,13 +290,15 @@ void function SetupComboButtonTest( var menu ) int buttonIndex = 0 file.playHeader = AddComboButtonHeader( comboStruct, headerIndex, "#MENU_HEADER_PLAY" ) - // server browser + file.findGameButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#MENU_TITLE_FIND_GAME" ) + file.lobbyButtons.append( file.findGameButton ) + Hud_AddEventHandler( file.findGameButton, UIE_CLICK, BigPlayButton1_Activate ) + file.findGameButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#MENU_TITLE_SERVER_BROWSER" ) file.lobbyButtons.append( file.findGameButton ) Hud_SetLocked( file.findGameButton, true ) Hud_AddEventHandler( file.findGameButton, UIE_CLICK, OpenServerBrowser ) - // private match file.inviteRoomButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#PRIVATE_MATCH" ) Hud_AddEventHandler( file.inviteRoomButton, UIE_CLICK, StartPrivateMatch ) @@ -303,9 +307,8 @@ void function SetupComboButtonTest( var menu ) Hud_SetEnabled( file.inviteFriendsButton, false ) Hud_SetVisible( file.inviteFriendsButton, false ) - - // file.toggleMenuModeButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#MENU_LOBBY_SWITCH_FD" ) - // Hud_AddEventHandler( file.toggleMenuModeButton, UIE_CLICK, ToggleLobbyMode ) + Hud_SetEnabled( file.inviteRoomButton, false ) + Hud_SetVisible( file.inviteRoomButton, false ) headerIndex++ buttonIndex = 0 @@ -464,7 +467,8 @@ void function CreatePartyAndInviteFriends() void function ToggleLobbyMode( var button ) { - Lobby_ToggleFDMode() + //Lobby_ToggleFDMode() + AdvanceMenu( GetMenu( "FDMenu" ) ) } void function Lobby_ToggleFDMode() @@ -1037,7 +1041,6 @@ void function UpdateMatchmakingStatus() int mapIdx = int( GetMyMatchmakingStatusParam( 3 ) ) int modeIdx = int( GetMyMatchmakingStatusParam( 4 ) ) string playlistList = GetMyMatchmakingStatusParam( 5 ) - { string statusText = Localize( "#MATCHMAKING_PLAYLISTS" ) RuiSetString( Hud_GetRui( statusEl ), "statusText", statusText ) @@ -1230,7 +1233,7 @@ void function BigPlayButton1_Activate( var button ) if ( Hud_IsLocked( button ) ) return - SendOpenInvite( false ) + //SendOpenInvite( false ) OpenSelectedPlaylistMenu() } @@ -1266,7 +1269,7 @@ function UpdateLobbyUI() uiGlobal.updatingLobbyUI = true thread UpdateLobbyType() - thread UpdateMatchmakingStatus() + //thread UpdateMatchmakingStatus() Commented this one out because it's responsible for the Native Matchmaking which updates menu constantly, not needed for Northstar thread UpdateChatroomThread() //thread UpdateInviteJoinButton() thread UpdateInviteFriendsToNetworkButton() @@ -1656,4 +1659,215 @@ void function Lobby_SetFDModeBasedOnSearching( string playlistToSearch ) } Lobby_SetFDMode( isFDMode ) +} + + +void function StartNSMatchmaking( array selectedPlaylists ) +{ + MatchmakingSetCountdownTimer( Time() + 4.0, false ) + MatchmakingSetSearchText( "#MATCHMAKING_SEARCHING_FOR_MATCH" ) + MatchmakingSetSearchVisible( true ) + MatchmakingSetCountdownVisible( true ) + ShowMatchmakingStatusIcons() + + var searchMenu = GetMenu( "SearchMenu" ) + AdvanceMenu( searchMenu ) + var statusEl = Hud_GetChild( searchMenu, "MatchmakingStatusBig" ) + + string statusText = Localize( "#MATCHMAKING_PLAYLISTS" ) + RuiSetString( Hud_GetRui( statusEl ), "statusText", statusText ) + for ( int idx = 1; idx <= 5; ++idx ) + RuiSetString( Hud_GetRui( statusEl ), ("bulletPointText" + idx), "" ) + + const int MAX_SHOWN_PLAYLISTS = 9 + int searchingCount = minint( selectedPlaylists.len(), MAX_SHOWN_PLAYLISTS ) + RuiSetInt( Hud_GetRui( statusEl ), "playlistCount", searchingCount ) + for( int idx = 0; idx < searchingCount; ++idx ) + { + asset playlistThumbnail = GetPlaylistThumbnailImage( selectedPlaylists[idx] ) + RuiSetImage( Hud_GetRui( statusEl ), format( "playlistIcon%d", idx ), playlistThumbnail ) + } + Hud_Show( statusEl ) + + wait 3.0 //Fancy delay just because server finder is pratically immediate, whole block above is to show "fake" matchmaking search + MatchmakingSetCountdownTimer( 0.0, true ) + MatchmakingSetCountdownVisible( false ) + + NSClearRecievedServerList() + NSRequestServerList() + + while ( NSIsRequestingServerList() ) + WaitFrame() + + array servers = NSGetGameServers() + array PlaylistServers + array filteredServers + + foreach( index, string playlist in selectedPlaylists ) + { + foreach ( ServerInfo server in servers ) + { + if ( server.playlist == playlist ) + PlaylistServers.append( server ) + } + } + + foreach ( ServerInfo server in PlaylistServers ) + { + if ( server.playerCount == 0 || server.playerCount == server.maxPlayerCount || server.requiresPassword ) + continue; + + filteredServers.append( server ) + } + + if( filteredServers.len() ) + thread MatchmakedAuthAndConnectToServer( filteredServers.getrandom() ) + else + { + foreach ( ServerInfo server in PlaylistServers ) //If we failed to find servers with players in it, consider joining empty ones + { + if ( server.playerCount == server.maxPlayerCount || server.requiresPassword ) + continue; + + filteredServers.append( server ) + } + + if( filteredServers.len() ) + thread MatchmakedAuthAndConnectToServer( filteredServers.getrandom() ) + else + { + MatchmakingSetSearchVisible( false ) + HideMatchmakingStatusIcons() + Hud_Hide( statusEl ) + + if ( uiGlobal.activeMenu == searchMenu ) + CloseActiveMenu() + + DialogData dialogData + dialogData.header = "#ERROR" + dialogData.message = "#MATCHMAKING_NOSERVERS" + dialogData.image = $"ui/menu/common/dialog_error" + + #if PC_PROG + AddDialogButton( dialogData, "#DISMISS" ) + AddDialogFooter( dialogData, "#A_BUTTON_SELECT" ) + #endif // PC_PROG + + AddDialogFooter( dialogData, "#B_BUTTON_DISMISS_RUI" ) + OpenDialog( dialogData ) + return + } + } +} + +void function MatchmakedAuthAndConnectToServer( ServerInfo matchmakedserver, string password = "" ) +{ + var statusEl = Hud_GetChild( GetMenu( "SearchMenu" ), "MatchmakingStatusBig" ) + if ( NSIsAuthenticatingWithServer() ) + return + + NSTryAuthWithServer( matchmakedserver.index, password ) + + while ( NSIsAuthenticatingWithServer() ) + WaitFrame() + + if ( NSWasAuthSuccessful() ) + { + bool modsChanged = false + + foreach ( string modName in NSGetModNames() ) + { + if ( NSIsModRequiredOnClient( modName ) && NSIsModEnabled( modName ) ) + { + bool found = false + foreach ( RequiredModInfo mod in matchmakedserver.requiredMods ) + { + if (mod.name == modName) + { + found = true + break + } + } + if (!found) + { + modsChanged = true + NSSetModEnabled( modName, false ) + } + } + } + + foreach ( RequiredModInfo mod in matchmakedserver.requiredMods ) + { + if ( NSIsModRequiredOnClient( mod.name ) && !NSIsModEnabled( mod.name )) + { + modsChanged = true + NSSetModEnabled( mod.name, true ) + } + } + + EmitUISound( MATCHMAKING_AUDIO_CONNECTING ) + MatchmakingSetSearchText( "#MATCHMAKING_MATCH_CONNECTING" ) + MatchmakingSetCountdownTimer( 0.0, true ) + MatchmakingSetCountdownVisible( false ) + HideMatchmakingStatusIcons() + Hud_Hide( statusEl ) + ShowServerConnectingInfo( matchmakedserver.name, matchmakedserver.description + "\n\nServer Mods:\n" + FillInServerModsLabel( matchmakedserver.requiredMods ) ) + + wait 5.0 + + MatchmakingSetSearchVisible( false ) + + if ( modsChanged ) + ReloadMods() + + NSConnectToAuthedServer() + } + else + { + MatchmakingSetSearchVisible( false ) + HideMatchmakingStatusIcons() + Hud_Hide( statusEl ) + if ( uiGlobal.activeMenu == GetMenu( "SearchMenu" ) ) + CloseActiveMenu() + string reason = NSGetAuthFailReason() + + DialogData dialogData + dialogData.header = "#ERROR" + dialogData.message = reason + dialogData.image = $"ui/menu/common/dialog_error" + + #if PC_PROG + AddDialogButton( dialogData, "#DISMISS" ) + AddDialogFooter( dialogData, "#A_BUTTON_SELECT" ) + #endif // PC_PROG + + AddDialogFooter( dialogData, "#B_BUTTON_DISMISS_RUI" ) + OpenDialog( dialogData ) + } +} + +void function ShowServerConnectingInfo( string servername = "", string servercontext = "" ) +{ + CloseAllDialogs() + + string connectingserver = "Found Server" + ": " + servername + + Hud_Hide( uiGlobal.ConfirmMenuMessage ) + Hud_Hide( uiGlobal.ConfirmMenuErrorCode ) + + DialogData dialogData + dialogData.header = connectingserver + dialogData.message = servercontext + dialogData.showSpinner = true + + OpenDialog( dialogData ) +} + +string function FillInServerModsLabel( array mods ) +{ + string ret + foreach ( RequiredModInfo mod in mods ) + ret += format( " %s v%s\n", mod.name, mod.version ) + + return ret } \ No newline at end of file From 30ead23a82dc9a2db0635f25784a2f15a57987e3 Mon Sep 17 00:00:00 2001 From: Zanieon Date: Fri, 13 Oct 2023 20:14:06 -0300 Subject: [PATCH 04/10] Functionality update --- .../scripts/vscripts/ui/menu_fdplaylist.nut | 36 +++++++++++++++++-- .../mod/scripts/vscripts/ui/menu_lobby.nut | 7 ++-- .../vscripts/ui/menu_playlist_mixtape.nut | 20 +++++++++++ 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut index 715d55964..e65c2b595 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut @@ -64,6 +64,7 @@ void function InitFDPlaylistMenu() AddMenuFooterOption( file.menu, BUTTON_A, "#A_BUTTON_SELECT" ) AddMenuFooterOption( file.menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) + //AddMenuFooterOption( file.menu, BUTTON_Y, "#Y_BUTTON_RESET_AEGIS", "#RESET_AEGIS", ShowTitanResetDialog ) for ( int idx = 0; idx < 4; ++idx ) { @@ -482,8 +483,12 @@ void function TitanButton_OnClick( var button ) OpenBuyItemDialog( file.titanButtons, button, GetItemName( loadout.titanClass ), loadout.titanClass ) return } - + + if ( scriptID != uiGlobal.titanSpawnLoadoutIndex ) + EmitUISound( "Menu_LoadOut_Titan_Select" ) + uiGlobal.titanSpawnLoadoutIndex = scriptID + ClientCommand( "RequestTitanLoadout " + scriptID ) SetEditLoadout( "titan", scriptID ) RunMenuClientFunction( "SetEditingTitanLoadoutIndex", scriptID ) AdvanceMenu( GetMenu( "EditTitanLoadoutMenu" ) ) @@ -502,7 +507,6 @@ void function TitanButton_OnFocused( var button ) RunMenuClientFunction( "UpdateTitanModel", scriptID ) RunMenuClientFunction( "SetEditingTitanLoadoutIndex", scriptID ) UpdateFDPanel( file.fdProperties, scriptID, true ) - uiGlobal.titanSpawnLoadoutIndex = scriptID } void function OnFDMenu_NavigateBack() @@ -524,4 +528,32 @@ bool function IsDifficultyOrTitanButtonSelected() return true return false +} + +void function ShowTitanResetDialog( var button ) +{ + DialogData dialogData + dialogData.header = "#RESET_AEGIS_TITLE" + dialogData.message = "#RESET_AEGIS_DESCRIPTION" + dialogData.image = $"rui/menu/common/fd_titan_upgrades" + + AddDialogButton( dialogData, "#NO" ) + AddDialogButton( dialogData, "#YES", ResetCurrentTitanAegis ) + + OpenDialog( dialogData ) +} + +void function ResetCurrentTitanAegis() +{ + EmitUISound( "ui_rankedsummary_demotion" ) + ClientCommand( "ns_resettitanaegis " + uiGlobal.titanSpawnLoadoutIndex ) + thread TitanAegisResetRefresh_Delayed() //Small time for pdata to refresh so we update the Aegis Ranks bar +} + +void function TitanAegisResetRefresh_Delayed() +{ + wait 0.1 + RunMenuClientFunction( "UpdateTitanModel", uiGlobal.titanSpawnLoadoutIndex ) + RunMenuClientFunction( "SetEditingTitanLoadoutIndex", uiGlobal.titanSpawnLoadoutIndex ) + UpdateFDPanel( file.fdProperties, uiGlobal.titanSpawnLoadoutIndex, true ) } \ No newline at end of file diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut index b147e621c..3d6bf5f5e 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut @@ -296,15 +296,14 @@ void function SetupComboButtonTest( var menu ) file.findGameButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#MENU_TITLE_SERVER_BROWSER" ) file.lobbyButtons.append( file.findGameButton ) - Hud_SetLocked( file.findGameButton, true ) Hud_AddEventHandler( file.findGameButton, UIE_CLICK, OpenServerBrowser ) + + file.inviteFriendsButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#MENU_TITLE_INVITE_FRIENDS" ) + Hud_AddEventHandler( file.inviteFriendsButton, UIE_CLICK, InviteFriendsIfAllowed ) file.inviteRoomButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#PRIVATE_MATCH" ) Hud_AddEventHandler( file.inviteRoomButton, UIE_CLICK, StartPrivateMatch ) - file.inviteFriendsButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#MENU_TITLE_INVITE_FRIENDS" ) - Hud_AddEventHandler( file.inviteFriendsButton, UIE_CLICK, InviteFriendsIfAllowed ) - Hud_SetEnabled( file.inviteFriendsButton, false ) Hud_SetVisible( file.inviteFriendsButton, false ) Hud_SetEnabled( file.inviteRoomButton, false ) diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_playlist_mixtape.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_playlist_mixtape.nut index e567663dd..1210839d9 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_playlist_mixtape.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_playlist_mixtape.nut @@ -577,6 +577,8 @@ void function OnOpenPlaylistMixtapeMenu() Hud_SetText( Hud_GetChild( file.mixtapeMenu, "PlayerCount" ), "#PLAYLIST_PLAYERCOUNT_MIXTAPE_SCREEN", regionDesc, worldDesc ) } + thread ShowPlayercount() //Override Playercount with Northstar version + SetChecklistIconButtonsVisible( true ) RefreshDescriptionTitle( false ) @@ -584,6 +586,24 @@ void function OnOpenPlaylistMixtapeMenu() thread DelayedSetFocusThread( file.playButton ) } +void function ShowPlayercount() +{ + NSClearRecievedServerList() + NSRequestServerList() + + Hud_SetText( Hud_GetChild( file.mixtapeMenu, "PlayerCount" ), "#INGAME_PLAYERS", 0, 0 ) + + while ( NSIsRequestingServerList() ) + WaitFrame() + + array servers = NSGetGameServers() + int totalPlayers = 0 + foreach ( ServerInfo server in servers ) + totalPlayers += server.playerCount + + Hud_SetText( Hud_GetChild( file.mixtapeMenu, "PlayerCount" ), "#INGAME_PLAYERS", totalPlayers, totalPlayers ) +} + bool function IsDialogUp() { bool result = IsDialog( uiGlobal.activeMenu ) From 21bd254d1664cb82a0930b458b2bf0b18cfa48e7 Mon Sep 17 00:00:00 2001 From: Zanieon Date: Tue, 23 Jan 2024 15:13:24 -0300 Subject: [PATCH 05/10] Several improvements --- .../northstar_client_localisation_english.txt | 7 + .../mod/resource/ui/menus/playlist_fd.menu | 518 +++++++++++++ .../resource/ui/menus/playlist_mixtape.menu | 721 ++++++++++++++++++ .../scripts/vscripts/ui/menu_fdplaylist.nut | 20 +- .../mod/scripts/vscripts/ui/menu_lobby.nut | 30 +- .../vscripts/ui/menu_private_match.nut | 32 +- 6 files changed, 1306 insertions(+), 22 deletions(-) create mode 100644 Northstar.Client/mod/resource/ui/menus/playlist_fd.menu create mode 100644 Northstar.Client/mod/resource/ui/menus/playlist_mixtape.menu diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt index e6518febb..ec7459f5e 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt @@ -215,6 +215,13 @@ Press Yes if you agree to this. This choice can be changed in the mods menu at a "SCOREBOARD_FASTBALL_HACKS" "Panels Captured" "GAMEMODE_ctf_comp" "Competitive CTF" + + "PL_privmatch" "Host Server" + "PL_privmatch_lobby" "Server Lobby" + "PL_privmatch_desc" "Host a listen server, in a map and mode of your choice. Up to 16 Players." + + "MENU_FD_DIFFICULTY_SEARCH_5" "Search for all Frontier Defense games" + "MENU_HEADER_SERVER_LOBBY" "Server Lobby" // mode settings "MODE_SETTING_CATEGORY_PROMODE" "Promode" diff --git a/Northstar.Client/mod/resource/ui/menus/playlist_fd.menu b/Northstar.Client/mod/resource/ui/menus/playlist_fd.menu new file mode 100644 index 000000000..f5da226f1 --- /dev/null +++ b/Northstar.Client/mod/resource/ui/menus/playlist_fd.menu @@ -0,0 +1,518 @@ +#base "combo_buttons.res" +resource/ui/menus/playlist_mixtape.menu +{ + menu + { + ControlName Frame + xpos 0 + ypos 0 + zpos 3 + wide f0 + tall f0 + autoResize 0 + pinCorner 0 + visible 1 + enabled 1 + PaintBackgroundType 0 + infocus_bgcolor_override "0 0 0 0" + outoffocus_bgcolor_override "0 0 0 0" + + Vignette + { + ControlName ImagePanel + InheritProperties MenuVignette + } + + MenuTitle + { + ControlName Label + InheritProperties MenuTitle + labelText "#FRONTIER_DEFENSE" + } + + ImgTopBar + { + ControlName ImagePanel + InheritProperties MenuTopBar + } + + CreditsAvailable + { + ControlName RuiPanel + InheritProperties CreditsAvailableProperties + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + BackgroundLeft + { + ControlName ImagePanel + InheritProperties R2_ContentBackground + ypos 220 + wide %100 + tall 580 + visible 1 + drawColor "0 0 0 0" + } + + PlayButton + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties Playlist_Button + xpos -106 + ypos 0 + wide 486 // 474 + tall 243 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + navDown BtnPlaylistIcon00 +// navRight HostButton + + rightClickEvents 1 + zpos 1 + + pin_to_sibling BackgroundLeft + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_LEFT + } + + PlayHintBackground + { + ControlName RuiPanel + xpos 40 + ypos -20 + wide 400 + tall 150 + visible 0 + rui "ui/basic_image.rpak" + drawColor "0 0 0 120" + scaleImage 1 + zpos 0 + + pin_to_sibling PlayButton + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + } + + PlayHintIcon + { + ControlName RuiPanel + xpos -4 + wide 80 + tall 80 + pin_to_sibling PlayHintBackground + pin_corner_to_sibling LEFT + pin_to_sibling_corner LEFT + visible 0 + rui "ui/basic_image.rpak" + scaleImage 1 + zpos 1 + } + + PlayLabelDetails + { + ControlName RuiPanel + xpos 10 + pin_to_sibling PlayHintIcon + pin_corner_to_sibling LEFT + pin_to_sibling_corner RIGHT + wide 290 + tall 140 + rui "ui/dialog_titan_properties.rpak" + wrap 1 + visible 1 + zpos 1 + } + + TitanLoadoutFD + { + ControlName CNestedPanel + xpos -125 + ypos 420 + zpos 10 + wide 800 + tall 480 + visible 1 + controlSettingsFile "resource/ui/menus/panels/titanproperties_fd.res" + + pin_to_sibling BackgroundLeft + pin_corner_to_sibling BOTTOM_RIGHT + pin_to_sibling_corner BOTTOM_RIGHT + } + + ContentDescriptionTitle + { + ControlName Label + InheritProperties R2_ContentDescriptionTitle + font DefaultBold_30 + labelText "#FD_DIFFICULTY" + ypos 0 + xpos 0 + fgcolor_override "255 184 0 255" + allcaps 0 + + pin_to_sibling PlayButton + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + } + + BtnPlaylistIcon00 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navRight BtnPlaylistIcon01 + rightClickEvents 1 + scriptID 0 + + pin_to_sibling ContentDescriptionTitle + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + //ypos -60 + xpos 4 + + navDown TitanButton0 + } + BtnPlaylistIcon01 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon00 + navRight BtnPlaylistIcon02 + rightClickEvents 1 + scriptID 1 + + pin_to_sibling BtnPlaylistIcon00 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 36 + + navDown TitanButton0 + } + BtnPlaylistIcon02 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon01 + navRight BtnPlaylistIcon03 + rightClickEvents 1 + scriptID 2 + + pin_to_sibling BtnPlaylistIcon01 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 36 + + navDown TitanButton0 + } + BtnPlaylistIcon03 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon02 + navRight BtnPlaylistIcon04 + rightClickEvents 1 + scriptID 3 + + pin_to_sibling BtnPlaylistIcon02 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 36 + + navDown TitanButton0 + } + BtnPlaylistIcon04 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon03 + rightClickEvents 1 + scriptID 4 + + pin_to_sibling BtnPlaylistIcon03 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 36 + + navDown TitanButton0 + } + + HintBackground + { + ControlName RuiPanel + xpos 40 + ypos -250 + wide 400 + tall 150 + visible 0 + rui "ui/basic_image.rpak" + drawColor "0 0 0 120" + scaleImage 1 + zpos 0 + + pin_to_sibling BtnPlaylistIcon03 + pin_corner_to_sibling BOTTOM_LEFT + pin_to_sibling_corner BOTTOM_RIGHT + } + + HintIcon + { + ControlName RuiPanel + xpos -4 + wide 80 + tall 80 + pin_to_sibling HintBackground + pin_corner_to_sibling LEFT + pin_to_sibling_corner LEFT + visible 0 + rui "ui/basic_image.rpak" + scaleImage 1 + zpos 1 + } + + LabelDetails + { + ControlName RuiPanel + xpos 10 + pin_to_sibling HintIcon + pin_corner_to_sibling LEFT + pin_to_sibling_corner RIGHT + wide 290 + tall 140 + rui "ui/dialog_titan_properties.rpak" + wrap 1 + visible 1 + zpos 1 + } + + TitanSelectTitle + { + ControlName Label + InheritProperties R2_ContentDescriptionTitle + font DefaultBold_30 + labelText "#MENU_TITAN_SELECT" + ypos 35 + xpos 0 + fgcolor_override "255 184 0 255" + allcaps 0 + + pin_to_sibling BtnPlaylistIcon00 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + } + + TitanButton0 + { + ControlName RuiButton + InheritProperties LoadoutButtonSmall + rui "ui/team_titan_select_button_small.rpak" + ypos 0 + xpos 0 + zpos 10 + tall 72 + wide 72 + scriptID 0 + tabPosition 1 + + pin_to_sibling TitanSelectTitle + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + + navUp BtnPlaylistIcon00 + navDown TutorialButton + } + + TitanButton1 + { + ControlName RuiButton + InheritProperties LoadoutButtonSmall + rui "ui/team_titan_select_button_small.rpak" + ypos 0 + xpos 0 + zpos 10 + tall 72 + wide 72 + scriptID 1 + + pin_to_sibling TitanButton0 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + + navUp BtnPlaylistIcon00 + navDown TutorialButton + } + + TitanButton2 + { + ControlName RuiButton + InheritProperties LoadoutButtonSmall + rui "ui/team_titan_select_button_small.rpak" + ypos 0 + xpos 0 + zpos 10 + tall 72 + wide 72 + scriptID 2 + + pin_to_sibling TitanButton1 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + + navUp BtnPlaylistIcon00 + navDown TutorialButton + } + + TitanButton3 + { + ControlName RuiButton + InheritProperties LoadoutButtonSmall + rui "ui/team_titan_select_button_small.rpak" + ypos 0 + xpos 0 + zpos 10 + tall 72 + wide 72 + scriptID 3 + + pin_to_sibling TitanButton2 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + + navUp BtnPlaylistIcon00 + navDown TutorialButton + } + + TitanButton4 + { + ControlName RuiButton + InheritProperties LoadoutButtonSmall + rui "ui/team_titan_select_button_small.rpak" + ypos 0 + xpos 0 + zpos 10 + tall 72 + wide 72 + scriptID 4 + + pin_to_sibling TitanButton3 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + + navUp BtnPlaylistIcon00 + navDown TutorialButton + } + + TitanButton5 + { + ControlName RuiButton + InheritProperties LoadoutButtonSmall + rui "ui/team_titan_select_button_small.rpak" + ypos 0 + xpos 0 + zpos 10 + tall 72 + wide 72 + scriptID 5 + + pin_to_sibling TitanButton4 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + + navUp BtnPlaylistIcon00 + navDown TutorialButton + } + + TitanButton6 + { + ControlName RuiButton + InheritProperties LoadoutButtonSmall + rui "ui/team_titan_select_button_small.rpak" + ypos 0 + xpos 0 + zpos 10 + tall 72 + wide 72 + scriptID 6 + + pin_to_sibling TitanButton5 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + + navUp BtnPlaylistIcon00 + navDown TutorialButton + } + + TutorialButton + { + ControlName RuiButton + InheritProperties RuiStartMatchButton + wide 504 + visible 1 + tabposition 1 + ypos 56 + + pin_to_sibling TitanButton0 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + + navUp TitanButton0 + } + + + + ModelRotateMouseCapture + { + ControlName CMouseMovementCapturePanel + xpos 896 + zpos 12 + wide 1024 + tall 753 + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // LabelDetails + // { + // ControlName RuiPanel + // xpos 925 + // ypos 160 + // wide 850 + // tall 300 + // rui "ui/knowledgebase_panel_main.rpak" + // wrap 1 + // visible 1 + // zpos 1 + // } +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + ButtonRowAnchor + { + ControlName Label + labelText "" + + xpos 96 + ypos 160 + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + ButtonTooltip + { + ControlName CNestedPanel + InheritProperties ButtonTooltip + } + + FooterButtons + { + ControlName CNestedPanel + InheritProperties FooterButtons + } + } +} diff --git a/Northstar.Client/mod/resource/ui/menus/playlist_mixtape.menu b/Northstar.Client/mod/resource/ui/menus/playlist_mixtape.menu new file mode 100644 index 000000000..e83fffca9 --- /dev/null +++ b/Northstar.Client/mod/resource/ui/menus/playlist_mixtape.menu @@ -0,0 +1,721 @@ +#base "combo_buttons.res" +resource/ui/menus/playlist_mixtape.menu +{ + menu + { + ControlName Frame + xpos 0 + ypos 0 + zpos 3 + wide f0 + tall f0 + autoResize 0 + pinCorner 0 + visible 1 + enabled 1 + PaintBackgroundType 0 + infocus_bgcolor_override "0 0 0 0" + outoffocus_bgcolor_override "0 0 0 0" + + Vignette + { + ControlName ImagePanel + InheritProperties MenuVignette + } + + MenuTitle + { + ControlName Label + InheritProperties MenuTitle + labelText "#KNB_MENU_HEADER" + } + + ImgTopBar + { + ControlName ImagePanel + InheritProperties MenuTopBar + } + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + BackgroundLeft + { + ControlName ImagePanel + InheritProperties R2_ContentBackground + ypos 170 + wide %100 + tall 552 + visible 1 + drawColor "0 0 0 100" + } + + PlayButton + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties Playlist_Button + xpos 56 + //xpos 196 + ypos 197 + wide 648 + tall 324 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + //navDown PickButton + navDown BtnPlaylistIcon00 + navRight PromoButton00 + + rightClickEvents 1 + zpos 1 + } + + PromoButton09 + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties PvE_Button + xpos 30 + ypos 10 + wide 358 + tall 324 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + navDown PromoButton05 + navLeft PromoButton00 + + rightClickEvents 0 + zpos 1 + + scriptID 9 + pin_to_sibling PromoButton00 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + } + + PickButton + { + ControlName RuiButton + InheritProperties RuiKNBSubjectButton +// InheritProperties RuiStartMatchButton + pin_to_sibling PlayButton + pin_corner_to_sibling TOP_RIGHT + pin_to_sibling_corner BOTTOM_RIGHT + xpos -20 + ypos 0 + navUp PlayButton + navRight PromoButton00 + } + + PromoButton00 + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties Playlist_Button + pin_to_sibling PlayButton + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 30 + ypos -10 + wide 358 + tall 153 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + navDown PromoButton01 + navLeft PlayButton + navRight PromoButton09 + + scriptID 0 + rightClickEvents 1 + zpos 1 + } + + PromoButton01 + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties Playlist_Button + pin_to_sibling PromoButton00 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + xpos 0 + ypos 0 + wide 358 + tall 153 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + navUp PromoButton00 + navDown PromoButton04 + navLeft PlayButton + navRight PromoButton09 + + scriptID 1 + rightClickEvents 1 + zpos 1 + } + + PromoButton02 + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties Playlist_Button + pin_to_sibling PromoButton00 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 30 + ypos 0 + wide 358 + tall 153 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + navLeft PromoButton00 + navDown PromoButton03 + navRight PromoButton06 + + scriptID 2 + rightClickEvents 1 + zpos 1 + } + + PromoButton03 + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties Playlist_Button + pin_to_sibling PromoButton02 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + xpos 0 + ypos 0 + wide 358 + tall 153 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + navUp PromoButton02 + navLeft PromoButton01 + navDown PromoButton05 + navRight PromoButton07 + + scriptID 3 + rightClickEvents 1 + zpos 1 + } + + PromoButton04 + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties Playlist_Button + pin_to_sibling PromoButton01 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + xpos 0 + ypos 0 + wide 358 + tall 153 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + navUp PromoButton01 + navLeft PlayButton + navRight PromoButton05 + navDown BtnPlaylistIcon00 + + scriptID 4 + rightClickEvents 1 + zpos 1 + } + + PromoButton05 + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties Playlist_Button + pin_to_sibling PromoButton03 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + xpos 0 + ypos 0 + wide 358 + tall 153 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + navUp PromoButton09 + navLeft PromoButton04 + navRight PromoButton08 + navDown BtnPlaylistIcon00 + + scriptID 5 + rightClickEvents 1 + zpos 1 + } + + PromoButton06 + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties Playlist_Button + pin_to_sibling PromoButton02 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 30 + ypos 0 + wide 358 + tall 153 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + navDown PromoButton07 + navLeft PromoButton02 + + scriptID 6 + rightClickEvents 1 + zpos 1 + } + PromoButton07 + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties Playlist_Button + pin_to_sibling PromoButton06 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + xpos 0 + ypos 0 + wide 358 + tall 153 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + navUp PromoButton06 + navDown PromoButton08 + navLeft PromoButton03 + + scriptID 7 + rightClickEvents 1 + zpos 1 + } + PromoButton08 + { + ControlName RuiButton + Classname GridButtonClass + InheritProperties Playlist_Button + pin_to_sibling PromoButton07 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + xpos 0 + ypos 0 + wide 358 + tall 153 + visible 1 + scaleImage 1 + tabPosition 1 + drawColor "255 255 255 255" + + navUp PromoButton07 + navLeft PromoButton05 + + scriptID 8 + rightClickEvents 1 + zpos 1 + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + FocusDescription + { + ControlName Label + wide 648 + auto_tall_tocontents 1 + visible 1 + labelText "" + font Default_28 + textAlignment north-west + wrap 1 + + pin_to_sibling PlayButton + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + DetailsBackground + { + ControlName ImagePanel + InheritProperties R2_ContentBackground + ypos 732 + wide %100 + tall 220 + visible 1 + //drawColor "0 0 0 220" + } + + ContentDescriptionTitle + { + ControlName Label + InheritProperties R2_ContentDescriptionTitle + font DefaultBold_44 + labelText "" + ypos -540 + xpos 0 + fgcolor_override "255 184 0 255" + allcaps 0 + auto_wide_tocontents 1 + + pin_to_sibling PlayButton + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_LEFT + } + + NotifyNewTitle + { + ControlName Label + InheritProperties R2_ContentDescriptionTitle + font DefaultBold_44 + labelText "" + ypos 5 + xpos 30 + fgcolor_override "0 229 65 255" + + pin_to_sibling BtnPlaylistIcon00 + pin_corner_to_sibling TOP_RIGHT + pin_to_sibling_corner TOP_LEFT + } + + ContentDescription + { + ControlName Label + InheritProperties R2_ContentDescription + labelText "" + font Default_38 + xpos 16 + ypos 0 + zpos 3 // Needed or clicking on the background can hide this + wide %50 + tall 100 + wrap 1 + auto_tall_tocontents 1 + textalign north + textAlignment north + fgcolor_override "255 184 0 255" + + font Default_27 [!$JAPANESE && !$TCHINESE] + font Default_31 [$JAPANESE || $TCHINESE] + + pin_to_sibling ContentDescriptionTitle + pin_corner_to_sibling LEFT + pin_to_sibling_corner RIGHT + } + + BtnPlaylistIcon00 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navRight BtnPlaylistIcon01 + rightClickEvents 1 + scriptID 0 + + pin_to_sibling ContentDescriptionTitle + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + //ypos -60 + xpos 4 + } + BtnPlaylistIcon01 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon00 + navRight BtnPlaylistIcon02 + rightClickEvents 1 + scriptID 1 + + pin_to_sibling BtnPlaylistIcon00 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon02 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon01 + navRight BtnPlaylistIcon03 + rightClickEvents 1 + scriptID 2 + + pin_to_sibling BtnPlaylistIcon01 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon03 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon02 + navRight BtnPlaylistIcon04 + rightClickEvents 1 + scriptID 3 + + pin_to_sibling BtnPlaylistIcon02 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon04 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon03 + navRight BtnPlaylistIcon05 + rightClickEvents 1 + scriptID 4 + + pin_to_sibling BtnPlaylistIcon03 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon05 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon04 + navRight BtnPlaylistIcon06 + rightClickEvents 1 + scriptID 5 + + pin_to_sibling BtnPlaylistIcon04 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon06 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon05 + navRight BtnPlaylistIcon07 + rightClickEvents 1 + scriptID 6 + + pin_to_sibling BtnPlaylistIcon05 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon07 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon06 + navRight BtnPlaylistIcon08 + rightClickEvents 1 + scriptID 7 + + pin_to_sibling BtnPlaylistIcon06 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon08 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon07 + navRight BtnPlaylistIcon09 + rightClickEvents 1 + scriptID 8 + + pin_to_sibling BtnPlaylistIcon07 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon09 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon08 + navRight BtnPlaylistIcon10 + rightClickEvents 1 + scriptID 9 + + pin_to_sibling BtnPlaylistIcon08 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon10 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon09 + navRight BtnPlaylistIcon11 + rightClickEvents 1 + scriptID 10 + + pin_to_sibling BtnPlaylistIcon09 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon11 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon10 + navRight BtnPlaylistIcon12 + rightClickEvents 1 + scriptID 11 + + pin_to_sibling BtnPlaylistIcon10 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon12 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon11 + navRight BtnPlaylistIcon13 + rightClickEvents 1 + scriptID 12 + + pin_to_sibling BtnPlaylistIcon11 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon13 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon12 + navRight BtnPlaylistIcon14 + rightClickEvents 1 + scriptID 13 + + pin_to_sibling BtnPlaylistIcon12 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + BtnPlaylistIcon14 + { + ControlName RuiButton + InheritProperties RuiMixtapeChecklistIconButton + navUp PlayButton + navLeft BtnPlaylistIcon13 + //navRight BtnPlaylistIcon15 + rightClickEvents 1 + scriptID 14 + + pin_to_sibling BtnPlaylistIcon13 + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner TOP_RIGHT + xpos 20 + } + + PlayerCount + { + ControlName Label + labelText "" + auto_wide_tocontents 1 + tall 30 + ypos 40 + xpos -540 + + font Default_27 + allcaps 0 + fgcolor_override "255 255 255 255" + + pin_to_sibling DetailsBackground + pin_corner_to_sibling TOP_RIGHT + pin_to_sibling_corner BOTTOM_RIGHT + textAlignment east + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // LabelDetails + // { + // ControlName RuiPanel + // xpos 925 + // ypos 160 + // wide 850 + // tall 300 + // rui "ui/knowledgebase_panel_main.rpak" + // wrap 1 + // visible 1 + // zpos 1 + // } +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + ButtonRowAnchor + { + ControlName Label + labelText "" + + xpos 96 + ypos 160 + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + ButtonTooltip + { + ControlName CNestedPanel + InheritProperties ButtonTooltip + } + + FooterButtons + { + ControlName CNestedPanel + InheritProperties FooterButtons + } + } +} diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut index e65c2b595..c10233b82 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_fdplaylist.nut @@ -64,9 +64,8 @@ void function InitFDPlaylistMenu() AddMenuFooterOption( file.menu, BUTTON_A, "#A_BUTTON_SELECT" ) AddMenuFooterOption( file.menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) - //AddMenuFooterOption( file.menu, BUTTON_Y, "#Y_BUTTON_RESET_AEGIS", "#RESET_AEGIS", ShowTitanResetDialog ) - for ( int idx = 0; idx < 4; ++idx ) + for ( int idx = 0; idx < 5; ++idx ) { string buttonName = ("BtnPlaylistIcon" + format( "%02d", idx )) var button = Hud_GetChild( file.menu, buttonName ) @@ -122,7 +121,7 @@ void function InitFDPlaylistMenu() file.playDescriptionBox = Hud_GetChild( file.menu, "PlayLabelDetails" ) file.tutorialButton = Hud_GetChild( file.menu, "TutorialButton" ) - AddButtonEventHandler( file.tutorialButton, UIE_CLICK, OnTutorialButtonClick ) + AddButtonEventHandler( file.tutorialButton, UIE_CLICK, ShowTitanResetDialog ) } void function OnOpenFDMenu() @@ -174,16 +173,9 @@ void function OnOpenFDMenu() RefreshCreditsAvailable() Lobby_SetFDMode( true ) - if ( GetPlaylistVarOrUseValue( "defaults", "fd_tutorial_url", "" ) != "" ) - { - var rui = Hud_GetRui( file.tutorialButton ) - RuiSetString( rui, "buttonText", GetPlaylistVarOrUseValue( "defaults", "fd_tutorial_title", "" ) ) - Hud_Show( file.tutorialButton ) - } - else - { - Hud_Hide( file.tutorialButton ) - } + var rui = Hud_GetRui( file.tutorialButton ) + RuiSetString( rui, "buttonText", "#RESET_AEGIS" ) + Hud_Show( file.tutorialButton ) } void function OnCloseFDMenu() @@ -418,6 +410,8 @@ string function BuildPlayWarningMessageTop( array pl ) return Localize( "#MENU_FD_DIFFICULTY_SEARCH_3", pldn(pl,0), pldn(pl,1), pldn(pl,2) ) case 4: return Localize( "#MENU_FD_DIFFICULTY_SEARCH_4", pldn(pl,0), pldn(pl,1), pldn(pl,2), pldn(pl,3) ) + case 5: + return Localize( "#MENU_FD_DIFFICULTY_SEARCH_5" ) } unreachable } diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut index 3d6bf5f5e..42373a90f 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut @@ -1663,6 +1663,7 @@ void function Lobby_SetFDModeBasedOnSearching( string playlistToSearch ) void function StartNSMatchmaking( array selectedPlaylists ) { + EndSignal( uiGlobal.signalDummy, "LevelShutdown" ) MatchmakingSetCountdownTimer( Time() + 4.0, false ) MatchmakingSetSearchText( "#MATCHMAKING_SEARCHING_FOR_MATCH" ) MatchmakingSetSearchVisible( true ) @@ -1761,6 +1762,8 @@ void function StartNSMatchmaking( array selectedPlaylists ) void function MatchmakedAuthAndConnectToServer( ServerInfo matchmakedserver, string password = "" ) { + EndSignal( uiGlobal.signalDummy, "CancelRestartingMatchmaking" ) + EndSignal( uiGlobal.signalDummy, "LevelShutdown" ) var statusEl = Hud_GetChild( GetMenu( "SearchMenu" ), "MatchmakingStatusBig" ) if ( NSIsAuthenticatingWithServer() ) return @@ -1806,8 +1809,8 @@ void function MatchmakedAuthAndConnectToServer( ServerInfo matchmakedserver, str EmitUISound( MATCHMAKING_AUDIO_CONNECTING ) MatchmakingSetSearchText( "#MATCHMAKING_MATCH_CONNECTING" ) - MatchmakingSetCountdownTimer( 0.0, true ) - MatchmakingSetCountdownVisible( false ) + MatchmakingSetCountdownTimer( Time() + 5.0, false ) + MatchmakingSetCountdownVisible( true ) HideMatchmakingStatusIcons() Hud_Hide( statusEl ) ShowServerConnectingInfo( matchmakedserver.name, matchmakedserver.description + "\n\nServer Mods:\n" + FillInServerModsLabel( matchmakedserver.requiredMods ) ) @@ -1858,10 +1861,31 @@ void function ShowServerConnectingInfo( string servername = "", string servercon dialogData.header = connectingserver dialogData.message = servercontext dialogData.showSpinner = true - + + #if PC_PROG + AddDialogButton( dialogData, "#CANCEL", CancelServerConnect ) + AddDialogFooter( dialogData, "#A_BUTTON_SELECT" ) + #endif // PC_PROG + + AddDialogFooter( dialogData, "#B_BUTTON_CANCEL" ) OpenDialog( dialogData ) } +void function CancelServerConnect() +{ + Signal( uiGlobal.signalDummy, "CancelRestartingMatchmaking" ) + var statusEl = Hud_GetChild( GetMenu( "SearchMenu" ), "MatchmakingStatusBig" ) + MatchmakingSetSearchVisible( false ) + MatchmakingSetCountdownTimer( 0.0, true ) + MatchmakingSetCountdownVisible( false ) + HideMatchmakingStatusIcons() + Hud_Hide( statusEl ) + if ( uiGlobal.activeMenu == GetMenu( "SearchMenu" ) ) + CloseActiveMenu() + CloseAllDialogs() + Lobby_SetFDMode( false ) +} + string function FillInServerModsLabel( array mods ) { string ret diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_private_match.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_private_match.nut index e3c1f268e..8a66fa6fb 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_private_match.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_private_match.nut @@ -205,6 +205,7 @@ void function InitPrivateMatchMenu() AddMenuFooterOption( menu, BUTTON_A, "#A_BUTTON_SELECT", "" ) AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) + AddMenuFooterOption( menu, BUTTON_BACK, "#BACK_BUTTON_POSTGAME_REPORT", "#POSTGAME_REPORT", OpenPostGameMenu, IsPostGameMenuValid ) AddMenuFooterOption( menu, BUTTON_Y, "#Y_BUTTON_SWITCH_TEAMS", "#SWITCH_TEAMS", PCSwitchTeamsButton_Activate, CanSwitchTeams ) AddMenuFooterOption( menu, BUTTON_X, "#X_BUTTON_MUTE", "#MOUSE2_MUTE", null, CanMute ) AddMenuFooterOption( menu, BUTTON_SHOULDER_RIGHT, "#RB_TRIGGER_TOGGLE_SPECTATE", "#SPECTATE_TEAM", PCToggleSpectateButton_Activate, CanSwitchTeams ) @@ -347,7 +348,7 @@ bool function MatchResultsExist() bool function CanSwitchTeams() { - return ( GetMenuVarBool( "isPrivateMatch" ) && ( level.ui.privatematch_starting != ePrivateMatchStartState.STARTING ) ) + return ( GetMenuVarBool( "isPrivateMatch" ) && ( level.ui.privatematch_starting != ePrivateMatchStartState.STARTING ) && !Lobby_IsFDMode() ) } bool function CanMute() @@ -435,6 +436,11 @@ void function LobbyMenuUpdate( var menu ) while ( GetTopNonDialogMenu() == menu ) { + if( Lobby_IsFDMode() ) + Hud_Hide( file.enemyPlayersPanel ) + else + Hud_Show( file.enemyPlayersPanel ) + WaitFrame() } } @@ -515,6 +521,21 @@ void function SetModeInfo( string modeName ) Hud_Show( nextModeIcon ) Hud_SetText( file.nextGameModeLabel, GetGameModeDisplayName( modeName ) ) + + switch ( modeName ) //Small hack to show Aegis Ranks of Titans in lobby menu + { + case "fd": + case "fd_easy": + case "fd_normal": + case "fd_hard": + case "fd_master": + case "fd_insane": + case "lffd": + Lobby_SetFDMode( true ) + break + default: + Lobby_SetFDMode( false ) + } } function Privatematch_map_Changed() @@ -573,12 +594,12 @@ function UpdatePrivateMatchButtons() Hud_SetLocked( file.selectModeButton, false ) string modeName = PrivateMatch_GetSelectedMode() - bool settingsLocked = IsFDMode( modeName ) + //bool settingsLocked = IsFDMode( modeName ) - if ( settingsLocked && uiGlobal.activeMenu == GetMenu( "MatchSettingsMenu" ) ) - CloseActiveMenu() + //if ( settingsLocked && uiGlobal.activeMenu == GetMenu( "MatchSettingsMenu" ) ) + // CloseActiveMenu() - Hud_SetLocked( file.matchSettingsButton, settingsLocked ) + Hud_SetLocked( file.matchSettingsButton, false ) } } @@ -815,6 +836,5 @@ function UpdatePlayerInfo() void function OnPrivateMatchMenu_Open() { - Lobby_SetFDMode( false ) OnLobbyMenu_Open() } \ No newline at end of file From 0bc866bc1f4dc2bb1146f988623d67b33674afc0 Mon Sep 17 00:00:00 2001 From: Zanieon Date: Fri, 22 Nov 2024 22:22:41 -0300 Subject: [PATCH 06/10] Update to new mod format --- .../mod/scripts/vscripts/ui/menu_lobby.nut | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut index 42373a90f..922cbd431 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut @@ -1777,20 +1777,24 @@ void function MatchmakedAuthAndConnectToServer( ServerInfo matchmakedserver, str { bool modsChanged = false - foreach ( string modName in NSGetModNames() ) + foreach ( ModInfo mod in NSGetModsInformation() ) { - if ( NSIsModRequiredOnClient( modName ) && NSIsModEnabled( modName ) ) + string modName = mod.name + string modVersion = mod.version + + if ( mod.requiredOnClient && mod.enabled ) { bool found = false foreach ( RequiredModInfo mod in matchmakedserver.requiredMods ) { - if (mod.name == modName) + if ( mod.name == modName && ( IsCoreMod( modName ) || mod.version == modVersion ) ) { found = true break } } - if (!found) + + if ( !found ) { modsChanged = true NSSetModEnabled( modName, false ) @@ -1800,10 +1804,30 @@ void function MatchmakedAuthAndConnectToServer( ServerInfo matchmakedserver, str foreach ( RequiredModInfo mod in matchmakedserver.requiredMods ) { - if ( NSIsModRequiredOnClient( mod.name ) && !NSIsModEnabled( mod.name )) + string modName = mod.name + string modVersion = mod.version + array localModInfos = NSGetModInformation( modName ) + + if ( IsCoreMod(modName) ) + { + if ( !localModInfos[0].enabled ) + { + modsChanged = true + NSSetModEnabled( modName, true ) + } + } + + else { - modsChanged = true - NSSetModEnabled( mod.name, true ) + foreach( localMod in localModInfos ) + { + if ( localMod.version == mod.version ) + { + modsChanged = true + NSSetModEnabled( mod.name, true ) + break + } + } } } From ad59e1af3836350d3cd6eb16d3d91b7f20aaf9ce Mon Sep 17 00:00:00 2001 From: Zanieon Date: Fri, 22 Nov 2024 22:29:42 -0300 Subject: [PATCH 07/10] Globalize and move IsCoreMod function --- Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut | 7 +++++++ .../mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut index 922cbd431..80854bfdd 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut @@ -42,6 +42,7 @@ global function OnStoreBundlesButton_Activate global function OnStoreNewReleasesButton_Activate global function StartNSMatchmaking +global function IsCoreMod const string MATCHMAKING_AUDIO_CONNECTING = "menu_campaignsummary_titanunlocked" @@ -1917,4 +1918,10 @@ string function FillInServerModsLabel( array mods ) ret += format( " %s v%s\n", mod.name, mod.version ) return ret +} + +const array CORE_MODS = ["Northstar.Client", "Northstar.Coop", "Northstar.CustomServers", "Northstar.Custom"] +bool function IsCoreMod( string modName ) +{ + return CORE_MODS.find( modName ) != -1 } \ No newline at end of file diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut index f2effd128..c0f0d2acc 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut @@ -1364,12 +1364,6 @@ void function TriggerConnectToServerCallbacks( ServerInfo ornull targetServer = } } -const array CORE_MODS = ["Northstar.Client", "Northstar.Coop", "Northstar.CustomServers", "Northstar.Custom"] -bool function IsCoreMod( string modName ) -{ - return CORE_MODS.find( modName ) != -1 -} - array function GetModVersions( string modName ) { array versions = [] From bbe5cb4960679108371128e4f49eb76678d713e1 Mon Sep 17 00:00:00 2001 From: Zanieon Date: Wed, 17 Sep 2025 18:22:45 -0300 Subject: [PATCH 08/10] Update menu_lobby.nut --- Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut index 80854bfdd..330b8189d 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut @@ -42,7 +42,6 @@ global function OnStoreBundlesButton_Activate global function OnStoreNewReleasesButton_Activate global function StartNSMatchmaking -global function IsCoreMod const string MATCHMAKING_AUDIO_CONNECTING = "menu_campaignsummary_titanunlocked" @@ -1798,7 +1797,7 @@ void function MatchmakedAuthAndConnectToServer( ServerInfo matchmakedserver, str if ( !found ) { modsChanged = true - NSSetModEnabled( modName, false ) + NSSetModEnabled( modName, modVersion, false ) } } } @@ -1814,7 +1813,7 @@ void function MatchmakedAuthAndConnectToServer( ServerInfo matchmakedserver, str if ( !localModInfos[0].enabled ) { modsChanged = true - NSSetModEnabled( modName, true ) + NSSetModEnabled( modName, modVersion, true ) } } @@ -1825,7 +1824,7 @@ void function MatchmakedAuthAndConnectToServer( ServerInfo matchmakedserver, str if ( localMod.version == mod.version ) { modsChanged = true - NSSetModEnabled( mod.name, true ) + NSSetModEnabled( mod.name, localMod.version, true ) break } } From fec340d77d2fe30e121a4cb80472bdd28d3fdbd5 Mon Sep 17 00:00:00 2001 From: Zanieon Date: Wed, 17 Sep 2025 18:25:39 -0300 Subject: [PATCH 09/10] Update menu_lobby.nut --- Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut | 1 + 1 file changed, 1 insertion(+) diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut index 330b8189d..d5e5bcf1f 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut @@ -42,6 +42,7 @@ global function OnStoreBundlesButton_Activate global function OnStoreNewReleasesButton_Activate global function StartNSMatchmaking +global function IsCoreMod const string MATCHMAKING_AUDIO_CONNECTING = "menu_campaignsummary_titanunlocked" From 670fa9b624f4f82a76026cfb504cfb414a4706e5 Mon Sep 17 00:00:00 2001 From: Zanieon Date: Sun, 14 Dec 2025 04:25:25 -0300 Subject: [PATCH 10/10] Update northstar_custom_english.txt --- Northstar.Custom/mod/resource/northstar_custom_english.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Northstar.Custom/mod/resource/northstar_custom_english.txt b/Northstar.Custom/mod/resource/northstar_custom_english.txt index d348aa207..7cafdc035 100644 --- a/Northstar.Custom/mod/resource/northstar_custom_english.txt +++ b/Northstar.Custom/mod/resource/northstar_custom_english.txt @@ -1,4 +1,4 @@ -"lang" +"lang" { "Language" "english" "Tokens"