aboutsummaryrefslogtreecommitdiff
path: root/Northstar.Client/mod/scripts
diff options
context:
space:
mode:
authorRoyalBlue1 <malte.hoermeyer@web.de>2022-07-15 00:41:36 +0200
committerRoyalBlue1 <malte.hoermeyer@web.de>2022-07-15 00:41:36 +0200
commit1d9b24faf5280db4b57eea42904f24ff4fdd16ba (patch)
tree558c8c8aa6b3d044f5fd9e17284177f96ba354f3 /Northstar.Client/mod/scripts
parent88d765b41f4ff94c59fa535d53e708274fa22d26 (diff)
parent85eb27362bd295a9e1560982a3369a688e13ded0 (diff)
downloadNorthstarMods-1d9b24faf5280db4b57eea42904f24ff4fdd16ba.tar.gz
NorthstarMods-1d9b24faf5280db4b57eea42904f24ff4fdd16ba.zip
Merge remote-tracking branch 'upsteam/main' into gamemode_fd
Diffstat (limited to 'Northstar.Client/mod/scripts')
-rw-r--r--Northstar.Client/mod/scripts/vscripts/chat.gnut18
-rw-r--r--Northstar.Client/mod/scripts/vscripts/client/cl_chat.gnut22
-rw-r--r--Northstar.Client/mod/scripts/vscripts/presence/cl_presence.nut60
-rw-r--r--Northstar.Client/mod/scripts/vscripts/presence/ui_presence.nut38
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut2
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_main.nut18
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut31
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_mode_select.nut2
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut2
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut451
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_setversionlabel.nut10
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_stats_maps.nut322
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_stats_utility.nut560
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut32
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/ui_vscript.gnut352
15 files changed, 1706 insertions, 214 deletions
diff --git a/Northstar.Client/mod/scripts/vscripts/chat.gnut b/Northstar.Client/mod/scripts/vscripts/chat.gnut
deleted file mode 100644
index ce26434c..00000000
--- a/Northstar.Client/mod/scripts/vscripts/chat.gnut
+++ /dev/null
@@ -1,18 +0,0 @@
-untyped
-globalize_all_functions
-
-void function Chat_NetworkWriteLine(string text) {
- NSChatWriteLine(0, text)
-}
-
-void function Chat_GameWriteLine(string text) {
- NSChatWriteLine(1, text)
-}
-
-void function Chat_NetworkWrite(string text) {
- NSChatWrite(0, text)
-}
-
-void function Chat_GameWrite(string text) {
- NSChatWrite(1, text)
-}
diff --git a/Northstar.Client/mod/scripts/vscripts/client/cl_chat.gnut b/Northstar.Client/mod/scripts/vscripts/client/cl_chat.gnut
new file mode 100644
index 00000000..3a43f312
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/client/cl_chat.gnut
@@ -0,0 +1,22 @@
+untyped
+globalize_all_functions
+
+void function Chat_NetworkWriteLine( string text )
+{
+ NSChatWriteLine( 0, text)
+}
+
+void function Chat_GameWriteLine( string text )
+{
+ NSChatWriteLine( 1, text)
+}
+
+void function Chat_NetworkWrite( string text )
+{
+ NSChatWrite( 0, text)
+}
+
+void function Chat_GameWrite( string text )
+{
+ NSChatWrite( 1, text )
+}
diff --git a/Northstar.Client/mod/scripts/vscripts/presence/cl_presence.nut b/Northstar.Client/mod/scripts/vscripts/presence/cl_presence.nut
new file mode 100644
index 00000000..755396e3
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/presence/cl_presence.nut
@@ -0,0 +1,60 @@
+untyped
+globalize_all_functions
+
+struct {
+ int highestScore = 0
+ int secondHighestScore = 0
+} file
+
+void function OnPrematchStart()
+{
+ if ( GetServerVar( "roundBased" ) )
+ NSUpdateTimeInfo( level.nv.roundEndTime - Time() )
+ else
+ NSUpdateTimeInfo( level.nv.gameEndTime - Time() )
+}
+
+void function NSUpdateGameStateClientStart()
+{
+ #if MP
+ AddCallback_GameStateEnter( eGameState.Prematch, OnPrematchStart )
+ #endif
+
+ thread NSUpdateGameStateLoopClient()
+ OnPrematchStart()
+}
+
+void function NSUpdateGameStateLoopClient()
+{
+ while ( true )
+ {
+ if ( IsSingleplayer() )
+ {
+ NSUpdateGameStateClient( GetPlayerArray().len(), GetCurrentPlaylistVarInt( "max_players", 65535 ), 1, 1, 1, GetServerVar( "roundBased" ), 1 )
+ wait 1.0
+ }
+ else
+ {
+ foreach ( player in GetPlayerArray() )
+ {
+ if ( GameRules_GetTeamScore( player.GetTeam() ) >= file.highestScore )
+ {
+ file.highestScore = GameRules_GetTeamScore( player.GetTeam() )
+ }
+ else if ( GameRules_GetTeamScore( player.GetTeam() ) > file.secondHighestScore )
+ {
+ file.secondHighestScore = GameRules_GetTeamScore( player.GetTeam() )
+ }
+ }
+
+ int ourScore = 0
+ if ( IsValid( GetLocalClientPlayer() ) )
+ ourScore = GameRules_GetTeamScore( GetLocalClientPlayer().GetTeam() )
+
+ int limit = IsRoundBased() ? GetCurrentPlaylistVarInt( "roundscorelimit", 0 ) : GetCurrentPlaylistVarInt( "scorelimit", 0 )
+ NSUpdateGameStateClient( GetPlayerArray().len(), GetCurrentPlaylistVarInt( "max_players", 65535 ), ourScore, file.secondHighestScore, file.highestScore, GetServerVar( "roundBased" ), limit )
+ OnPrematchStart()
+ wait 1.0
+ }
+ }
+}
diff --git a/Northstar.Client/mod/scripts/vscripts/presence/ui_presence.nut b/Northstar.Client/mod/scripts/vscripts/presence/ui_presence.nut
new file mode 100644
index 00000000..1e381989
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/presence/ui_presence.nut
@@ -0,0 +1,38 @@
+untyped
+globalize_all_functions
+
+void function NSUpdateGameStateUIStart()
+{
+ thread NSUpdateGameStateLoopUI()
+}
+
+void function NSUpdateGameStateLoopUI()
+{
+ while ( true )
+ {
+ wait 1.0
+
+ if ( uiGlobal.loadedLevel == "" )
+ {
+ if ( uiGlobal.isLoading )
+ NSSetLoading( true )
+ else
+ {
+ NSSetLoading( false )
+ NSUpdateGameStateUI( "", "", "", "", true, false )
+ }
+
+ continue
+ }
+
+ NSSetLoading( false )
+ if( GetConVarString( "mp_gamemode" ) == "solo" )
+ {
+ NSUpdateGameStateUI( GetActiveLevel(), Localize( GetMapDisplayName( GetActiveLevel() + "_CAMPAIGN_NAME" ) ), "Campaign", "Campaign", IsFullyConnected(), false )
+ }
+ else
+ {
+ NSUpdateGameStateUI( GetActiveLevel(), Localize( GetMapDisplayName( GetActiveLevel() ) ), GetConVarString( "mp_gamemode" ), Localize( GetPlaylistDisplayName( GetConVarString( "mp_gamemode" ) ) ), IsFullyConnected(), false )
+ }
+ }
+}
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut
index 3c868aab..938e0d3f 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut
@@ -372,6 +372,8 @@ void function StartPrivateMatch( var button )
return
ClientCommand( "StartPrivateMatchSearch" )
+ NSSetLoading(true)
+ NSUpdateListenServer()
}
void function DoRoomInviteIfAllowed( var button )
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_main.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_main.nut
index 87cba57e..d75bbb5d 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/menu_main.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_main.nut
@@ -57,7 +57,7 @@ void function InitMainMenu()
#if DEV
if ( DevStartPoints() )
- AddMenuFooterOption( menu, BUTTON_Y, "#Y_BUTTON_DEV_MENU", "#DEV_MENU", OpenSinglePlayerDevMenu )
+ AddMenuFooterOption( menu, BUTTON_SHOULDER_LEFT, "#Y_BUTTON_DEV_MENU", "#DEV_MENU", OpenSinglePlayerDevMenu )
#endif // DEV
}
@@ -72,7 +72,7 @@ void function OnMainMenu_Open()
{
Signal( uiGlobal.signalDummy, "EndOnMainMenu_Open" )
EndSignal( uiGlobal.signalDummy, "EndOnMainMenu_Open" )
-
+
SetConVarString( "communities_hostname", "" ) // disable communities due to crash exploits that are still possible through it
UpdatePromoData() // On script restarts this gives us the last data until the new request is complete
@@ -93,7 +93,7 @@ void function OnMainMenu_Open()
ClientCommand( "map " + Dev_CommandLineParmValue( "+map" ) )
Dev_CommandLineRemoveParm( "+map" )
}
-
+
// do agree to ns remote auth dialog
if ( !GetConVarBool( "ns_has_agreed_to_send_token" ) )
NorthstarMasterServerAuthDialog()
@@ -136,7 +136,7 @@ void function NorthstarMasterServerAuthDialog()
{
// todo: this should be in localisation
DialogData dialogData
- dialogData.header = "#DIALOG_TITLE_INSTALLED_NORTHSTAR"
+ dialogData.header = "#DIALOG_TITLE_INSTALLED_NORTHSTAR"
dialogData.image = $"rui/menu/fd_menu/upgrade_northstar_chassis"
dialogData.message = "#AUTHENTICATION_AGREEMENT_DIALOG_TEXT"
AddDialogButton( dialogData, "#YES", NorthstarMasterServerAuthDialogAgree )
@@ -148,11 +148,11 @@ void function NorthstarMasterServerAuthDialogAgree()
{
int oldValue = GetConVarInt( "ns_has_agreed_to_send_token" )
SetConVarInt( "ns_has_agreed_to_send_token", NS_AGREED_TO_SEND_TOKEN )
-
+
if ( oldValue != 0 && oldValue != NS_AGREED_TO_SEND_TOKEN )
{
DialogData dialogData
- dialogData.header = "#DIALOG_TITLE_INSTALLED_NORTHSTAR"
+ dialogData.header = "#DIALOG_TITLE_INSTALLED_NORTHSTAR"
dialogData.image = $"rui/menu/fd_menu/upgrade_northstar_chassis"
dialogData.message = "#AUTHENTICATION_AGREEMENT_RESTART"
AddDialogButton( dialogData, "#OK" )
@@ -164,11 +164,11 @@ void function NorthstarMasterServerAuthDialogDisagree()
{
int oldValue = GetConVarInt( "ns_has_agreed_to_send_token" )
SetConVarInt( "ns_has_agreed_to_send_token", NS_DISAGREED_TO_SEND_TOKEN )
-
+
if ( oldValue != 0 && oldValue != NS_DISAGREED_TO_SEND_TOKEN )
{
DialogData dialogData
- dialogData.header = "#DIALOG_TITLE_INSTALLED_NORTHSTAR"
+ dialogData.header = "#DIALOG_TITLE_INSTALLED_NORTHSTAR"
dialogData.image = $"rui/menu/fd_menu/upgrade_northstar_chassis"
dialogData.message = "#AUTHENTICATION_AGREEMENT_RESTART"
AddDialogButton( dialogData, "#OK" )
@@ -670,4 +670,4 @@ void function UpdateTrialLabel()
void function OpenSinglePlayerDevMenu( var button )
{
AdvanceMenu( GetMenu( "SinglePlayerDevMenu" ) )
-}
+} \ No newline at end of file
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut
index 44a54e62..930e472b 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut
@@ -77,9 +77,6 @@ void function InitMapsMenu()
AddButtonEventHandler( button, UIE_CLICK, MapButton_Activate )
AddButtonEventHandler( button, UIE_GET_FOCUS, MapButton_Focus )
}
-
-
- FilterMapsArray()
}
@@ -133,8 +130,12 @@ void function OnHitDummyBottom( var button )
file.scrollOffset += 1
+ int compensate = 0
+ if ( file.mapsArrayFiltered.len() % 3 != 0 )
+ compensate = 1
+
if ((file.scrollOffset + BUTTONS_PER_PAGE) * 3 > file.mapsArrayFiltered.len())
- file.scrollOffset = (file.mapsArrayFiltered.len() - BUTTONS_PER_PAGE * 3) / 3 + 1
+ file.scrollOffset = (file.mapsArrayFiltered.len() - BUTTONS_PER_PAGE * 3) / 3 + compensate
UpdateMapsGrid()
UpdateListSliderPosition()
@@ -260,7 +261,6 @@ void function FilterMapsArray()
string searchTerm = Hud_GetUTF8Text( Hud_GetChild( file.menu, "BtnMapsSearch" ) )
bool useSearch = searchTerm != ""
-
bool hideLocked = bool( GetConVarInt( "filter_map_hide_locked" ) )
foreach ( string map in GetPrivateMatchMaps() )
@@ -309,7 +309,7 @@ void function LockMapButton( var element )
bool function IsLocked( string map )
{
- bool sp = map.find( "sp_" ) == 0
+ bool sp = map.find( "sp_" ) == 0 && PrivateMatch_GetSelectedMode() != "sp_coop"
if ( sp )
return true
@@ -321,6 +321,10 @@ bool function IsLocked( string map )
}
}
+ if ( !PrivateMatch_IsValidMapModeCombo( map, PrivateMatch_GetSelectedMode() ) )
+ return true
+
+
return false
}
@@ -375,7 +379,11 @@ void function SliderBarUpdate()
Hud_SetPos( sliderPanel , 2, newPos )
Hud_SetPos( movementCapture , 2, newPos )
- file.scrollOffset = -int( ( (newPos - minYPos) / useableSpace ) * ( file.mapsArrayFiltered.len() / 3 + 1 - BUTTONS_PER_PAGE) )
+ int compensate = 0
+ if ( file.mapsArrayFiltered.len() % 3 != 0 )
+ compensate = 1
+
+ file.scrollOffset = -int( ( (newPos - minYPos) / useableSpace ) * ( file.mapsArrayFiltered.len() / 3 + compensate - BUTTONS_PER_PAGE) )
UpdateMapsGrid()
}
@@ -410,7 +418,11 @@ void function UpdateListSliderPosition()
var sliderPanel = Hud_GetChild( file.menu , "BtnMapGridSliderPanel" )
var movementCapture = Hud_GetChild( file.menu , "MouseMovementCapture" )
- float maps = float ( file.mapsArrayFiltered.len() / 3 + 1 )
+ int compensate = 0
+ if ( file.mapsArrayFiltered.len() % 3 != 0 )
+ compensate = 1
+
+ float maps = float ( file.mapsArrayFiltered.len() / 3 + compensate )
float minYPos = -42.0 * (GetScreenSize()[1] / 1080.0)
float useableSpace = (582.0 * (GetScreenSize()[1] / 1080.0) - Hud_GetHeight( sliderPanel ))
@@ -429,7 +441,10 @@ void function UpdateListSliderPosition()
void function OnDownArrowSelected( var button )
{
if ( file.mapsArrayFiltered.len() <= BUTTONS_PER_PAGE || file.mapsArrayFiltered.len() <= 12 ) return
+ if ( file.scrollOffset + 5 > file.mapsArrayFiltered.len() / 3 && file.mapsArrayFiltered.len() % 3 == 0 ) return
+
file.scrollOffset += 1
+
if ((file.scrollOffset + BUTTONS_PER_PAGE) * 3 > file.mapsArrayFiltered.len()) {
file.scrollOffset = (file.mapsArrayFiltered.len() - BUTTONS_PER_PAGE * 3) / 3 + 1
}
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_mode_select.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_mode_select.nut
index 608db46e..4a2cf64a 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/menu_mode_select.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_mode_select.nut
@@ -52,7 +52,7 @@ void function UpdateVisibleModes()
Hud_SetEnabled( buttons[ i ], true )
Hud_SetVisible( buttons[ i ], true )
- if ( !ModeSettings_RequiresAI( modesArray[ modeIndex ] ) )
+ if ( !ModeSettings_RequiresAI( modesArray[ modeIndex ] ) || modesArray[ modeIndex ] == "aitdm" )
Hud_SetLocked( buttons[ i ], false )
else if( IsFDMode( modesArray[ i ] ) )
Hud_SetLocked( buttons[ i ], false )
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut
index 56db0ccc..b5a2e9b6 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut
@@ -47,6 +47,8 @@ void function OnConnectWithPasswordMenuOpened()
Hud_SetText( file.connectButton, "#MENU_CONNECT_MENU_CONNECT" )
Hud_SetText( file.enterPasswordBox, "" )
Hud_SetText( file.enterPasswordDummy, "" )
+ Hud_SetFocused( file.enterPasswordBox )
+
}
void function ConnectWithPassword( var button )
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 b294f57c..eb068374 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut
@@ -7,15 +7,16 @@ global function ThreadedAuthAndConnectToServer
// Stop peeking
-const int BUTTONS_PER_PAGE = 15
-const float DOUBLE_CLICK_TIME_MS = 0.4 // unsure what the ideal value is
-
+const int BUTTONS_PER_PAGE = 15 // Number of servers we show
+const float DOUBLE_CLICK_TIME_MS = 0.4 // Max time between clicks for double click registering
+// Stores mouse delta used for scroll bar
struct {
int deltaX = 0
int deltaY = 0
} mouseDeltaBuffer
+// Filters
struct {
bool hideFull = false
bool hideEmpty = false
@@ -32,6 +33,7 @@ struct {
enum sortingBy
{
NONE,
+ DEFAULT,
NAME,
PLAYERS,
MAP,
@@ -39,6 +41,7 @@ enum sortingBy
LATENCY
}
+// Column sort direction, only one of these can be aplied at once
struct {
// true = alphabeticaly false = reverse
bool serverName = true
@@ -46,8 +49,8 @@ struct {
bool serverMap = true
bool serverGamemode = true
bool serverLatency = true
- // 0 = none; 1 = name; 2 = players; 3 = map; 5 = gamemode; 6 = latency
- int sortingBy = 0
+ // 0 = none; 1 = default; 2 = name; 3 = players; 4 = map; 5 = gamemode; 6 = latency
+ int sortingBy = 1
} filterDirection
struct serverStruct {
@@ -62,6 +65,7 @@ struct serverStruct {
}
struct {
+ // UI state vars
var menu
int lastSelectedServer = 999
int focusedServerIndex = 0
@@ -72,9 +76,11 @@ struct {
int serverButtonFocusedID = 0
bool shouldFocus = true
bool cancelConnection = false
-
+
+ // filtered array of servers
array<serverStruct> serversArrayFiltered
-
+
+ // UI references
array<var> serverButtons
array<var> serversName
array<var> playerCountLabels
@@ -86,9 +92,10 @@ struct {
-bool function floatCompareInRange(float arg1, float arg2, float tolerance)
+bool function FloatsEqual( float arg1, float arg2, float epsilon )
{
- if ( arg1 > arg2 - tolerance && arg1 < arg2 + tolerance) return true
+ if ( fabs( arg1 - arg2 ) < epsilon ) return true
+
return false
}
@@ -159,7 +166,7 @@ void function InitServerBrowserMenu()
AddMenuFooterOption( file.menu, BUTTON_Y, PrependControllerPrompts( BUTTON_Y, "#REFRESH_SERVERS" ), "#REFRESH_SERVERS", RefreshServers )
// Setup server buttons
- var width = 1120.0 * (GetScreenSize()[1] / 1080.0)
+ var width = 1120.0 * ( GetScreenSize()[1] / 1080.0 )
foreach ( var button in GetElementsByClassname( file.menu, "ServerButton" ) )
{
AddButtonEventHandler( button, UIE_CLICK, OnServerButtonClicked )
@@ -206,20 +213,20 @@ void function InitServerBrowserMenu()
// Hidden cause no need, if server descriptions become too long use this
- Hud_SetEnabled( Hud_GetChild( file.menu, "BtnServerDescription"), false)
- Hud_SetEnabled( Hud_GetChild( file.menu, "BtnServerMods"), false)
- Hud_SetText( Hud_GetChild( file.menu, "BtnServerDescription"), "")
- Hud_SetText( Hud_GetChild( file.menu, "BtnServerMods"), "")
+ Hud_SetEnabled( Hud_GetChild( file.menu, "BtnServerDescription"), false )
+ Hud_SetEnabled( Hud_GetChild( file.menu, "BtnServerMods"), false )
+ Hud_SetText( Hud_GetChild( file.menu, "BtnServerDescription"), "" )
+ Hud_SetText( Hud_GetChild( file.menu, "BtnServerMods"), "" )
// Unfinished features
Hud_SetLocked( Hud_GetChild( file.menu, "BtnServerLatencyTab" ), true )
// Rui is a pain
- RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnHideFull")), "buttonText", "")
- RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnHideEmpty")), "buttonText", "")
- RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnHideProtected")), "buttonText", "")
- RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnSelectMap")), "buttonText", "")
- RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnSelectGamemode")), "buttonText", "")
+ RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnHideFull") ), "buttonText", "" )
+ RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnHideEmpty") ), "buttonText", "" )
+ RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnHideProtected") ), "buttonText", "" )
+ RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnSelectMap") ), "buttonText", "" )
+ RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnSelectGamemode") ), "buttonText", "" )
ToggleConnectingHUD(false)
@@ -231,7 +238,7 @@ void function InitServerBrowserMenu()
////////////////////////////
// Slider
////////////////////////////
-void function UpdateMouseDeltaBuffer(int x, int y)
+void function UpdateMouseDeltaBuffer( int x, int y )
{
mouseDeltaBuffer.deltaX += x
mouseDeltaBuffer.deltaY += y
@@ -248,7 +255,7 @@ void function FlushMouseDeltaBuffer()
void function SliderBarUpdate()
{
- if ( file.serversArrayFiltered.len() <= 15 )
+ if ( file.serversArrayFiltered.len() <= BUTTONS_PER_PAGE )
{
FlushMouseDeltaBuffer()
return
@@ -258,17 +265,17 @@ void function SliderBarUpdate()
var sliderPanel = Hud_GetChild( file.menu , "BtnServerListSliderPanel" )
var movementCapture = Hud_GetChild( file.menu , "MouseMovementCapture" )
- Hud_SetFocused(sliderButton)
+ Hud_SetFocused( sliderButton )
- float minYPos = -40.0 * (GetScreenSize()[1] / 1080.0)
- float maxHeight = 562.0 * (GetScreenSize()[1] / 1080.0)
- float maxYPos = minYPos - (maxHeight - Hud_GetHeight( sliderPanel ))
- float useableSpace = (maxHeight - Hud_GetHeight( sliderPanel ))
+ float minYPos = -40.0 * ( GetScreenSize()[1] / 1080.0 )
+ float maxHeight = 562.0 * ( GetScreenSize()[1] / 1080.0 )
+ float maxYPos = minYPos - ( maxHeight - Hud_GetHeight( sliderPanel ) )
+ float useableSpace = ( maxHeight - Hud_GetHeight( sliderPanel ) )
- float jump = minYPos - (useableSpace / ( float( file.serversArrayFiltered.len())))
+ float jump = minYPos - ( useableSpace / ( float( file.serversArrayFiltered.len() ) ) )
// got local from official respaw scripts, without untyped throws an error
- local pos = Hud_GetPos(sliderButton)[1]
+ local pos = Hud_GetPos( sliderButton )[1]
local newPos = pos - mouseDeltaBuffer.deltaY
FlushMouseDeltaBuffer()
@@ -279,7 +286,7 @@ void function SliderBarUpdate()
Hud_SetPos( sliderPanel , 2, newPos )
Hud_SetPos( movementCapture , 2, newPos )
- file.scrollOffset = -int( ( (newPos - minYPos) / useableSpace ) * (file.serversArrayFiltered.len() - 15) )
+ file.scrollOffset = -int( ( ( newPos - minYPos ) / useableSpace ) * ( file.serversArrayFiltered.len() - BUTTONS_PER_PAGE ) )
UpdateShownPage()
}
@@ -289,10 +296,10 @@ void function UpdateListSliderHeight( float servers )
var sliderPanel = Hud_GetChild( file.menu , "BtnServerListSliderPanel" )
var movementCapture = Hud_GetChild( file.menu , "MouseMovementCapture" )
- float maxHeight = 562.0 * (GetScreenSize()[1] / 1080.0)
- float minHeight = 80.0 * (GetScreenSize()[1] / 1080.0)
+ float maxHeight = 562.0 * ( GetScreenSize()[1] / 1080.0 )
+ float minHeight = 80.0 * ( GetScreenSize()[1] / 1080.0 )
- float height = maxHeight * (15.0 / servers )
+ float height = maxHeight * ( BUTTONS_PER_PAGE / servers )
if ( height > maxHeight ) height = maxHeight
if ( height < minHeight ) height = minHeight
@@ -309,12 +316,10 @@ void function UpdateListSliderPosition( int servers )
var sliderPanel = Hud_GetChild( file.menu , "BtnServerListSliderPanel" )
var movementCapture = Hud_GetChild( file.menu , "MouseMovementCapture" )
- float minYPos = -40.0 * (GetScreenSize()[1] / 1080.0)
- float useableSpace = (562.0 * (GetScreenSize()[1] / 1080.0) - Hud_GetHeight( sliderPanel ))
+ float minYPos = -40.0 * ( GetScreenSize()[1] / 1080.0 )
+ float useableSpace = (562.0 * ( GetScreenSize()[1] / 1080.0 ) - Hud_GetHeight( sliderPanel ) )
- float jump = minYPos - (useableSpace / ( float( servers ) - 15.0 ) * file.scrollOffset)
-
- //jump = jump * (GetScreenSize()[1] / 1080.0)
+ float jump = minYPos - ( useableSpace / ( float( servers ) - BUTTONS_PER_PAGE ) * file.scrollOffset )
if ( jump > minYPos ) jump = minYPos
@@ -325,7 +330,7 @@ void function UpdateListSliderPosition( int servers )
void function OnScrollDown( var button )
{
- if (file.serversArrayFiltered.len() <= 15) return
+ if (file.serversArrayFiltered.len() <= BUTTONS_PER_PAGE) return
file.scrollOffset += 5
if (file.scrollOffset + BUTTONS_PER_PAGE > file.serversArrayFiltered.len()) {
file.scrollOffset = file.serversArrayFiltered.len() - BUTTONS_PER_PAGE
@@ -337,7 +342,7 @@ void function OnScrollDown( var button )
void function OnScrollUp( var button )
{
file.scrollOffset -= 5
- if (file.scrollOffset < 0) {
+ if ( file.scrollOffset < 0 ) {
file.scrollOffset = 0
}
UpdateShownPage()
@@ -349,7 +354,7 @@ void function OnScrollUp( var button )
////////////////////////////
void function ToggleConnectingHUD( bool vis )
{
- foreach (e in GetElementsByClassname(file.menu, "connectingHUD")) {
+ foreach (e in GetElementsByClassname( file.menu, "connectingHUD" ) ) {
Hud_SetEnabled( e, vis )
Hud_SetVisible( e, vis )
}
@@ -369,7 +374,7 @@ void function ConnectingButton_Activate( var button )
// This doesn't werk on some obscure resolutions, mostly really small 4:3
void function UpdateServerInfoBasedOnRes()
{
- if (floatCompareInRange(float(GetScreenSize()[0]) / float(GetScreenSize()[1]) , 1.6, 0.07)) // 16/10
+ if ( FloatsEqual( float(GetScreenSize()[0] ) / float( GetScreenSize()[1] ) , 1.6, 0.07 ) ) // 16/10
{
Hud_SetWidth( Hud_GetChild(file.menu, "ServerName"), 392)
Hud_SetWidth( Hud_GetChild(file.menu, "NextMapImage"), 400)
@@ -378,7 +383,7 @@ void function UpdateServerInfoBasedOnRes()
Hud_SetWidth( Hud_GetChild(file.menu, "LabelDescription"), 360)
Hud_SetWidth( Hud_GetChild(file.menu, "ServerDetailsPanel"), 400)
}
- if(floatCompareInRange(float(GetScreenSize()[0]) / float(GetScreenSize()[1]) , 1.3, 0.055)) // 4/3
+ if( FloatsEqual( float( GetScreenSize()[0] ) / float( GetScreenSize()[1] ) , 1.3, 0.055 ) ) // 4/3
{
Hud_SetWidth( Hud_GetChild(file.menu, "ServerName"), 292)
Hud_SetWidth( Hud_GetChild(file.menu, "NextMapImage"), 300)
@@ -396,17 +401,19 @@ void function OnCloseServerBrowserMenu()
{
try
{
- DeregisterButtonPressedCallback(MOUSE_WHEEL_UP , OnScrollUp)
- DeregisterButtonPressedCallback(MOUSE_WHEEL_DOWN , OnScrollDown)
- DeregisterButtonPressedCallback(KEY_TAB , OnKeyTabPressed)
+ DeregisterButtonPressedCallback( MOUSE_WHEEL_UP , OnScrollUp )
+ DeregisterButtonPressedCallback( MOUSE_WHEEL_DOWN , OnScrollDown )
+ DeregisterButtonPressedCallback( KEY_TAB , OnKeyTabPressed )
+ DeregisterButtonPressedCallback( KEY_ENTER, OnEnterPressed )
+ DeregisterButtonPressedCallback( KEY_R, OnKeyRPressed )
}
catch ( ex ) {}
}
void function OnServerBrowserMenuOpened()
{
- Hud_SetText( Hud_GetChild( file.menu, "InGamePlayerLabel" ), Localize("#INGAME_PLAYERS", "0") )
- Hud_SetText( Hud_GetChild( file.menu, "TotalServerLabel" ), Localize("#TOTAL_SERVERS", "0") )
+ Hud_SetText( Hud_GetChild( file.menu, "InGamePlayerLabel" ), Localize( "#INGAME_PLAYERS", "0" ) )
+ Hud_SetText( Hud_GetChild( file.menu, "TotalServerLabel" ), Localize( "#TOTAL_SERVERS", "0" ) )
UpdatePrivateMatchModesAndMaps()
Hud_SetText( Hud_GetChild( file.menu, "Title" ), "#MENU_TITLE_SERVER_BROWSER" )
UI_SetPresentationType( ePresentationType.KNOWLEDGEBASE_MAIN )
@@ -419,23 +426,28 @@ void function OnServerBrowserMenuOpened()
NSRequestServerList()
}
+ filterDirection.sortingBy = sortingBy.DEFAULT
+
thread WaitForServerListRequest()
- RegisterButtonPressedCallback(MOUSE_WHEEL_UP , OnScrollUp)
- RegisterButtonPressedCallback(MOUSE_WHEEL_DOWN , OnScrollDown)
- RegisterButtonPressedCallback(KEY_TAB , OnKeyTabPressed)
+ RegisterButtonPressedCallback( MOUSE_WHEEL_UP , OnScrollUp )
+ RegisterButtonPressedCallback( MOUSE_WHEEL_DOWN , OnScrollDown )
+ RegisterButtonPressedCallback( KEY_TAB , OnKeyTabPressed )
+ RegisterButtonPressedCallback( KEY_ENTER, OnEnterPressed )
+ RegisterButtonPressedCallback( KEY_R, OnKeyRPressed )
}
////////////////////////////
// Arrow navigation fuckery
////////////////////////////
-bool function IsFilterPanelElementFocused() {
+bool function IsFilterPanelElementFocused()
+{
// get name of focused element
- var focusedElement = GetFocus();
- var name = Hud_GetHudName(focusedElement);
+ var focusedElement = GetFocus()
- foreach (element in GetElementsByClassname( file.menu, "FilterPanelChild")) {
+ foreach ( element in GetElementsByClassname( file.menu, "FilterPanelChild" ) )
+ {
if ( element == focusedElement ) return true
}
@@ -443,66 +455,78 @@ bool function IsFilterPanelElementFocused() {
return false;
}
-void function OnKeyTabPressed(var button) {
+void function OnKeyTabPressed( var button )
+{
try
{
// toggle focus between server list and filter panel
- if (IsFilterPanelElementFocused()) {
- // print("Switching focus from filter panel to server list")
- Hud_SetFocused(Hud_GetChild(file.menu, "BtnServer1"))
+ if ( IsFilterPanelElementFocused() )
+ {
+ Hud_SetFocused( Hud_GetChild( file.menu, "BtnServer1" ) )
}
- else {
- // print("Switching focus from server list to filter panel")
- Hud_SetFocused(Hud_GetChild(file.menu, "BtnServerSearch"))
+ else
+ {
+ Hud_SetFocused( Hud_GetChild( file.menu, "BtnServerSearch" ) )
HideServerInfo()
}
}
catch ( ex ) {}
}
-void function OnHitDummyTop(var button) {
+void function OnHitDummyTop( var button )
+{
file.scrollOffset -= 1
- if (file.scrollOffset < 0) {
+ if ( file.scrollOffset < 0 )
+ {
// was at top already
file.scrollOffset = 0
Hud_SetFocused(Hud_GetChild(file.menu, "BtnServerNameTab"))
- } else {
+ }
+ else
+ {
// only update if list position changed
UpdateShownPage()
UpdateListSliderPosition( file.serversArrayFiltered.len() )
- DisplayFocusedServerInfo(file.serverButtonFocusedID)
- Hud_SetFocused(Hud_GetChild(file.menu, "BtnServer1"))
+ DisplayFocusedServerInfo( file.serverButtonFocusedID )
+ Hud_SetFocused( Hud_GetChild( file.menu, "BtnServer1" ) )
}
}
-void function OnHitDummyBottom(var button) {
+void function OnHitDummyBottom( var button )
+{
file.scrollOffset += 1
- if (file.scrollOffset + BUTTONS_PER_PAGE > file.serversArrayFiltered.len())
+ if ( file.scrollOffset + BUTTONS_PER_PAGE > file.serversArrayFiltered.len() )
{
// was at bottom already
file.scrollOffset = file.serversArrayFiltered.len() - BUTTONS_PER_PAGE
- Hud_SetFocused(Hud_GetChild(file.menu, "BtnServerSearch"))
- } else {
+ Hud_SetFocused( Hud_GetChild( file.menu, "BtnServerSearch" ) )
+ HideServerInfo()
+ }
+ else
+ {
// only update if list position changed
UpdateShownPage()
UpdateListSliderPosition( file.serversArrayFiltered.len() )
- DisplayFocusedServerInfo(file.serverButtonFocusedID)
- Hud_SetFocused(Hud_GetChild(file.menu, "BtnServer15"))
+ DisplayFocusedServerInfo( file.serverButtonFocusedID )
+ Hud_SetFocused( Hud_GetChild( file.menu, "BtnServer15" ) )
}
}
-void function OnHitDummyAfterFilterClear(var button) {
- Hud_SetFocused(Hud_GetChild(file.menu, "BtnServerNameTab"))
+void function OnHitDummyAfterFilterClear( var button )
+{
+ Hud_SetFocused( Hud_GetChild( file.menu, "BtnServerNameTab" ) )
}
void function OnDownArrowSelected( var button )
{
- if (file.serversArrayFiltered.len() <= 15) return
+ if ( file.serversArrayFiltered.len() <= BUTTONS_PER_PAGE ) return
file.scrollOffset += 1
- if (file.scrollOffset + BUTTONS_PER_PAGE > file.serversArrayFiltered.len()) {
+ if ( file.scrollOffset + BUTTONS_PER_PAGE > file.serversArrayFiltered.len() )
+ {
file.scrollOffset = file.serversArrayFiltered.len() - BUTTONS_PER_PAGE
}
+
UpdateShownPage()
UpdateListSliderPosition( file.serversArrayFiltered.len() )
}
@@ -511,44 +535,89 @@ void function OnDownArrowSelected( var button )
void function OnUpArrowSelected( var button )
{
file.scrollOffset -= 1
- if (file.scrollOffset < 0) {
+ if ( file.scrollOffset < 0 )
+ {
file.scrollOffset = 0
}
+
UpdateShownPage()
UpdateListSliderPosition( file.serversArrayFiltered.len() )
}
+////////////////////////
+// Key Callbacks
+////////////////////////
+void function OnEnterPressed( arg )
+{
+ // only trigger if a server is focused
+ if ( IsServerButtonFocused() )
+ {
+ OnServerSelected(0)
+ }
+}
+
+void function OnKeyRPressed( arg )
+{
+ if ( !IsSearchBarFocused() )
+ {
+ RefreshServers(0);
+ }
+}
+
+bool function IsServerButtonFocused()
+{
+ var focusedElement = GetFocus()
+ if ( focusedElement == null )
+ return false
+
+ var name = Hud_GetHudName( focusedElement )
+
+ foreach ( element in GetElementsByClassname( file.menu, "ServerButton" ) )
+ {
+ if ( element == focusedElement )
+ return true
+ }
+
+ return false
+}
+
+bool function IsSearchBarFocused()
+{
+ return Hud_GetChild( file.menu, "BtnServerSearch" ) == GetFocus()
+}
+
////////////////////////////
// Unused
////////////////////////////
void function ShowServerDescription( var button )
{
- Hud_SetVisible( Hud_GetChild( file.menu, "LabelDescription"), true)
- Hud_SetVisible( Hud_GetChild( file.menu, "LabelMods"), false)
+ Hud_SetVisible( Hud_GetChild( file.menu, "LabelDescription" ), true )
+ Hud_SetVisible( Hud_GetChild( file.menu, "LabelMods" ), false )
}
void function ShowServerMods( var button )
{
- Hud_SetVisible( Hud_GetChild( file.menu, "LabelDescription"), false)
- Hud_SetVisible( Hud_GetChild( file.menu, "LabelMods"), true)
+ Hud_SetVisible( Hud_GetChild( file.menu, "LabelDescription" ), false )
+ Hud_SetVisible( Hud_GetChild( file.menu, "LabelMods" ), true )
}
////////////////////////////
// Server list; filter,update,...
////////////////////////////
-void function HideServerInfo() {
- Hud_SetVisible(Hud_GetChild(file.menu, "BtnServerDescription"), false)
- Hud_SetVisible(Hud_GetChild(file.menu, "BtnServerMods"), false)
- Hud_SetVisible(Hud_GetChild(file.menu, "BtnServerJoin"), false)
- Hud_SetVisible(Hud_GetChild(file.menu, "LabelDescription"), false)
- Hud_SetVisible(Hud_GetChild(file.menu, "LabelMods"), false)
- Hud_SetVisible(Hud_GetChild(file.menu, "NextMapImage"), false)
- Hud_SetVisible(Hud_GetChild(file.menu, "NextMapBack"), false)
- Hud_SetVisible(Hud_GetChild(file.menu, "NextMapName"), false)
- Hud_SetVisible(Hud_GetChild(file.menu, "ServerName"), false)
- Hud_SetVisible(Hud_GetChild(file.menu, "NextModeIcon"), false)
- Hud_SetVisible(Hud_GetChild(file.menu, "NextGameModeName"), false)
+void function HideServerInfo()
+{
+ Hud_SetVisible( Hud_GetChild( file.menu, "BtnServerDescription" ), false )
+ Hud_SetVisible( Hud_GetChild( file.menu, "BtnServerMods" ), false )
+ Hud_SetVisible( Hud_GetChild( file.menu, "BtnServerJoin" ), false )
+ Hud_SetVisible( Hud_GetChild( file.menu, "LabelDescription" ), false )
+ Hud_SetVisible( Hud_GetChild( file.menu, "LabelMods" ), false )
+ Hud_SetVisible( Hud_GetChild( file.menu, "NextMapImage" ), false )
+ Hud_SetVisible( Hud_GetChild( file.menu, "NextMapBack" ), false )
+ Hud_SetVisible( Hud_GetChild( file.menu, "NextMapName" ), false )
+ Hud_SetVisible( Hud_GetChild( file.menu, "ServerName" ), false )
+ Hud_SetVisible( Hud_GetChild( file.menu, "NextModeIcon" ), false )
+ Hud_SetVisible( Hud_GetChild( file.menu, "NextGameModeName" ), false )
}
void function OnBtnFiltersClear_Activate( var button )
@@ -577,6 +646,7 @@ void function FilterAndUpdateList( var n )
file.scrollOffset = 0
UpdateListSliderPosition( file.serversArrayFiltered.len() )
+ HideServerInfo()
FilterServerList()
@@ -585,6 +655,10 @@ void function FilterAndUpdateList( var n )
case sortingBy.NONE:
UpdateShownPage()
break
+ case sortingBy.DEFAULT:
+ filterDirection.serverName = !filterDirection.serverName
+ SortServerListByDefault_Activate(0)
+ break
case sortingBy.NAME:
filterDirection.serverName = !filterDirection.serverName
SortServerListByName_Activate(0)
@@ -633,8 +707,7 @@ void function RefreshServers( var button )
void function WaitForServerListRequest()
{
-
- for ( int i = 0; i < 15; i++)
+ for ( int i = 0; i < BUTTONS_PER_PAGE; i++)
{
Hud_SetVisible( file.serversProtected[ i ], false )
Hud_SetVisible( file.serverButtons[ i ], false )
@@ -645,12 +718,9 @@ void function WaitForServerListRequest()
Hud_SetText( file.serversLatency[ i ], "" )
}
-
HideServerInfo()
-
Hud_SetVisible( file.serversName[ 0 ], true )
-
Hud_SetText( file.serversName[ 0 ], "#NS_SERVERBROWSER_WAITINGFORSERVERS" )
// wait for request to complete
@@ -665,7 +735,7 @@ void function WaitForServerListRequest()
else
{
FilterAndUpdateList(0)
- Hud_SetFocused(Hud_GetChild(file.menu, "BtnServer1"))
+ Hud_SetFocused( Hud_GetChild(file.menu, "BtnServer1" ) )
}
}
@@ -690,61 +760,60 @@ void function FilterServerList()
totalPlayers += tempServer.serverPlayers
- // Branchless programming ;)
- if (!(filterArguments.hideEmpty && tempServer.serverPlayers == 0) && !(filterArguments.hideFull && tempServer.serverPlayers == tempServer.serverPlayersMax) && !(filterArguments.hideProtected && tempServer.serverProtected))
- {
- if ( filterArguments.useSearch )
- {
- string sName = tempServer.serverName.tolower() + " " + Localize(GetMapDisplayName(tempServer.serverMap)).tolower() + " " + tempServer.serverMap.tolower() + " " + tempServer.serverGamemode.tolower() + " " + Localize(tempServer.serverGamemode).tolower()
-
- string sTerm = filterArguments.searchTerm.tolower()
-
- if ( sName.find(sTerm) != null)
- {
- if (filterArguments.filterMap != "SWITCH_ANY" && filterArguments.filterMap == tempServer.serverMap)
- {
- CheckGamemode( tempServer )
- }
- else if (filterArguments.filterMap == "SWITCH_ANY")
- {
- CheckGamemode( tempServer )
- }
- }
- }
- else
+ // Filters
+ if ( filterArguments.hideEmpty && tempServer.serverPlayers == 0 )
+ continue;
+
+ if ( filterArguments.hideFull && tempServer.serverPlayers == tempServer.serverPlayersMax )
+ continue;
+
+ if ( filterArguments.hideProtected && tempServer.serverProtected )
+ continue;
+
+ if ( filterArguments.filterMap != "SWITCH_ANY" && filterArguments.filterMap != tempServer.serverMap )
+ continue;
+
+ if ( filterArguments.filterGamemode != "SWITCH_ANY" && filterArguments.filterGamemode != tempServer.serverGamemode )
+ continue;
+
+ // Search
+ if ( filterArguments.useSearch )
+ {
+ array<string> sName
+ sName.append( tempServer.serverName.tolower() )
+ sName.append( Localize( GetMapDisplayName( tempServer.serverMap ) ).tolower() )
+ sName.append( tempServer.serverMap.tolower() )
+ sName.append( tempServer.serverGamemode.tolower() )
+ sName.append( Localize( tempServer.serverGamemode ).tolower() )
+ sName.append( NSGetServerDescription( i ).tolower() )
+
+ string sTerm = filterArguments.searchTerm.tolower()
+
+ bool found = false
+ for( int j = 0; j < sName.len(); j++ )
{
- if (filterArguments.filterMap != "SWITCH_ANY" && filterArguments.filterMap == tempServer.serverMap)
- {
- CheckGamemode( tempServer )
- }
- else if (filterArguments.filterMap == "SWITCH_ANY")
- {
- CheckGamemode( tempServer )
- }
+ if ( sName[j].find( sTerm ) != null )
+ found = true
}
+
+ if ( !found )
+ continue;
}
- Hud_SetText( Hud_GetChild( file.menu, "InGamePlayerLabel" ), Localize("#INGAME_PLAYERS", string(totalPlayers)) )
- Hud_SetText( Hud_GetChild( file.menu, "TotalServerLabel" ), Localize("#TOTAL_SERVERS", string( NSGetServerCount()) ) )
- }
-}
-
-void function CheckGamemode( serverStruct t )
-{
- if (filterArguments.filterGamemode != "SWITCH_ANY" && filterArguments.filterGamemode == t.serverGamemode)
- {
- file.serversArrayFiltered.append( t )
- }
- else if (filterArguments.filterGamemode == "SWITCH_ANY")
- {
- file.serversArrayFiltered.append( t )
+
+ // Server fits our requirements, add it to the list
+ file.serversArrayFiltered.append( tempServer )
}
+
+ // Update player and server count
+ Hud_SetText( Hud_GetChild( file.menu, "InGamePlayerLabel" ), Localize("#INGAME_PLAYERS", string( totalPlayers ) ) )
+ Hud_SetText( Hud_GetChild( file.menu, "TotalServerLabel" ), Localize("#TOTAL_SERVERS", string( NSGetServerCount() ) ) )
}
void function UpdateShownPage()
{
- for ( int i = 0; i < 15; i++)
+ for ( int i = 0; i < BUTTONS_PER_PAGE; i++ )
{
Hud_SetVisible( file.serversProtected[ i ], false )
Hud_SetVisible( file.serverButtons[ i ], false )
@@ -755,7 +824,7 @@ void function UpdateShownPage()
Hud_SetText( file.serversLatency[ i ], "" )
}
- int j = file.serversArrayFiltered.len() > 15 ? 15 : file.serversArrayFiltered.len()
+ int j = file.serversArrayFiltered.len() > BUTTONS_PER_PAGE ? BUTTONS_PER_PAGE : file.serversArrayFiltered.len()
for ( int i = 0; i < j; i++ )
{
@@ -785,26 +854,26 @@ void function UpdateShownPage()
void function OnServerButtonFocused( var button )
{
- if (file.scrollOffset < 0)
+ if ( file.scrollOffset < 0 )
file.scrollOffset = 0
- int scriptID = int (Hud_GetScriptID(button))
+ int scriptID = int ( Hud_GetScriptID( button ) )
file.serverButtonFocusedID = scriptID
if ( file.serversArrayFiltered.len() > 0 )
file.focusedServerIndex = file.serversArrayFiltered[ file.scrollOffset + scriptID ].serverIndex
- DisplayFocusedServerInfo(scriptID);
+ DisplayFocusedServerInfo( scriptID )
}
void function OnServerButtonClicked(var button)
{
- int scriptID = int (Hud_GetScriptID(button))
+ int scriptID = int ( Hud_GetScriptID( button ) )
- DisplayFocusedServerInfo(scriptID)
- CheckDoubleClick(scriptID, true)
+ DisplayFocusedServerInfo( scriptID )
+ CheckDoubleClick( scriptID, true )
}
-void function CheckDoubleClick(int scriptID, bool wasClickNav)
+void function CheckDoubleClick( int scriptID, bool wasClickNav )
{
if ( NSGetServerCount() == 0 ) return
@@ -812,34 +881,31 @@ void function CheckDoubleClick(int scriptID, bool wasClickNav)
int serverIndex = file.scrollOffset + scriptID
bool sameServer = false
- if (file.lastSelectedServer == serverIndex) sameServer = true
+ if ( file.lastSelectedServer == serverIndex ) sameServer = true
file.serverSelectedTimeLast = file.serverSelectedTime
file.serverSelectedTime = Time()
- printt(file.serverSelectedTime - file.serverSelectedTimeLast, file.lastSelectedServer, serverIndex)
-
file.lastSelectedServer = serverIndex
-
- if (wasClickNav && (file.serverSelectedTime - file.serverSelectedTimeLast < DOUBLE_CLICK_TIME_MS) && sameServer)
+ if ( wasClickNav && ( file.serverSelectedTime - file.serverSelectedTimeLast < DOUBLE_CLICK_TIME_MS ) && sameServer )
{
OnServerSelected(0)
}
}
-void function DisplayFocusedServerInfo( int scriptID)
+void function DisplayFocusedServerInfo( int scriptID )
{
- if (scriptID == 999 || scriptID == -1 || scriptID == 16) return
+ if ( scriptID == 999 || scriptID == -1 || scriptID == 16 ) return
- if ( NSIsRequestingServerList() || NSGetServerCount() == 0 || file.serverListRequestFailed || file.serversArrayFiltered.len() == 0)
+ if ( NSIsRequestingServerList() || NSGetServerCount() == 0 || file.serverListRequestFailed || file.serversArrayFiltered.len() == 0 )
return
var menu = GetMenu( "ServerBrowserMenu" )
int serverIndex = file.scrollOffset + scriptID
- if (serverIndex < 0) serverIndex = 0
+ if ( serverIndex < 0 ) serverIndex = 0
Hud_SetVisible( Hud_GetChild( menu, "BtnServerDescription" ), true )
@@ -848,7 +914,7 @@ void function DisplayFocusedServerInfo( int scriptID)
// text panels
Hud_SetVisible( Hud_GetChild( menu, "LabelDescription" ), true )
Hud_SetVisible( Hud_GetChild( menu, "LabelMods" ), false )
- Hud_SetText( Hud_GetChild( menu, "LabelDescription" ), NSGetServerDescription( file.serversArrayFiltered[ serverIndex ].serverIndex ) + "\n\nRequired Mods:\n" + FillInServerModsLabel( file.serversArrayFiltered[ serverIndex ].serverIndex ))
+ Hud_SetText( Hud_GetChild( menu, "LabelDescription" ), NSGetServerDescription( file.serversArrayFiltered[ serverIndex ].serverIndex ) + "\n\nRequired Mods:\n" + FillInServerModsLabel( file.serversArrayFiltered[ serverIndex ].serverIndex ) )
// map name/image/server name
string map = file.serversArrayFiltered[ serverIndex ].serverMap
@@ -970,24 +1036,39 @@ void function ThreadedAuthAndConnectToServer( string password = "" )
return
print( "trying to authenticate with server " + NSGetServerName( file.lastSelectedServer ) + " with password " + password )
+
NSTryAuthWithServer( file.lastSelectedServer, password )
ToggleConnectingHUD( true )
- while ( NSIsAuthenticatingWithServer() && !file.cancelConnection)
+ while ( NSIsAuthenticatingWithServer() && !file.cancelConnection )
{
WaitFrame()
}
ToggleConnectingHUD( false )
- if (file.cancelConnection)
+ if ( file.cancelConnection )
{
file.cancelConnection = false
+ // re-focus server list
+ Hud_SetFocused( Hud_GetChild( file.menu, "BtnServer" + ( file.serverButtonFocusedID + 1 ) ) )
return
}
file.cancelConnection = false
+ NSSetLoading( true )
+ NSUpdateServerInfo(
+ NSGetServerID( file.lastSelectedServer ),
+ NSGetServerName( file.lastSelectedServer ),
+ password,
+ NSGetServerPlayerCount( file.lastSelectedServer ),
+ NSGetServerMaxPlayerCount( file.lastSelectedServer ),
+ NSGetServerMap( file.lastSelectedServer ),
+ Localize( GetMapDisplayName( NSGetServerMap( file.lastSelectedServer ) ) ),
+ NSGetServerPlaylist( file.lastSelectedServer ),
+ Localize( GetPlaylistDisplayName( NSGetServerPlaylist( file.lastSelectedServer ) ) )
+ )
if ( NSWasAuthSuccessful() )
{
@@ -1010,6 +1091,7 @@ void function ThreadedAuthAndConnectToServer( string password = "" )
// only actually reload if we need to since the uiscript reset on reload lags hard
if ( modsChanged )
ReloadMods()
+
NSConnectToAuthedServer()
}
else
@@ -1033,7 +1115,7 @@ void function ThreadedAuthAndConnectToServer( string password = "" )
//////////////////////////////////////
// Shadow realm
//////////////////////////////////////
-int function ServerSortLogic ( serverStruct a, serverStruct b)
+int function ServerSortLogic ( serverStruct a, serverStruct b )
{
var aTemp
var bTemp
@@ -1041,7 +1123,24 @@ int function ServerSortLogic ( serverStruct a, serverStruct b)
bool direction
// We can hard code this cause adding entire columns isn't as easy
- switch ( filterDirection.sortingBy ) {
+ switch ( filterDirection.sortingBy )
+ {
+ case sortingBy.DEFAULT:
+ aTemp = a.serverPlayers
+ bTemp = b.serverPlayers
+
+ // `1000` is assumed to always be higher than `serverPlayersMax`
+ if (aTemp + 1 < a.serverPlayersMax)
+ aTemp = aTemp+2000
+ if (bTemp + 1 < b.serverPlayersMax)
+ bTemp = bTemp+2000
+ if (aTemp + 1 == a.serverPlayersMax)
+ aTemp = aTemp+1000
+ if (bTemp + 1 == b.serverPlayersMax)
+ bTemp = bTemp+1000
+
+ direction = filterDirection.serverName
+ break;
case sortingBy.NAME:
aTemp = a.serverName.tolower()
bTemp = b.serverName.tolower()
@@ -1053,13 +1152,13 @@ int function ServerSortLogic ( serverStruct a, serverStruct b)
direction = filterDirection.serverPlayers
break;
case sortingBy.MAP:
- aTemp = Localize(a.serverMap).tolower()
- bTemp = Localize(b.serverMap).tolower()
+ aTemp = Localize( a.serverMap ).tolower()
+ bTemp = Localize( b.serverMap ).tolower()
direction = filterDirection.serverMap
break;
case sortingBy.GAMEMODE:
- aTemp = Localize(a.serverGamemode).tolower()
- bTemp = Localize(b.serverGamemode).tolower()
+ aTemp = Localize( a.serverGamemode ).tolower()
+ bTemp = Localize( b.serverGamemode ).tolower()
direction = filterDirection.serverGamemode
break;
case sortingBy.LATENCY:
@@ -1082,6 +1181,18 @@ int function ServerSortLogic ( serverStruct a, serverStruct b)
return 0
}
+void function SortServerListByDefault_Activate ( var button )
+{
+ filterDirection.sortingBy = sortingBy.DEFAULT
+
+ file.serversArrayFiltered.sort( ServerSortLogic )
+
+ filterDirection.serverName = !filterDirection.serverName
+
+ UpdateShownPage()
+}
+
+
void function SortServerListByName_Activate ( var button )
{
filterDirection.sortingBy = sortingBy.NAME
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_setversionlabel.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_setversionlabel.nut
new file mode 100644
index 00000000..6dbafde9
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_setversionlabel.nut
@@ -0,0 +1,10 @@
+untyped
+global function NS_SetVersionLabel
+
+void function NS_SetVersionLabel()
+{
+ var mainMenu = GetMenu( "MainMenu" ) //Gets main menu element
+ var versionLabel = GetElementsByClassname( mainMenu, "nsVersionClass" )[0] //Gets the label from the mainMenu element.
+ Hud_SetText( versionLabel, "v" + NSGetModVersionByModName("Northstar.Client")) //Sets the label text (Getting Northstar version from Northstar.Client)
+}
+
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_stats_maps.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_stats_maps.nut
new file mode 100644
index 00000000..eb844af4
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_stats_maps.nut
@@ -0,0 +1,322 @@
+global function InitViewStatsMapsMenu
+global function setit
+struct
+{
+ var menu
+ GridMenuData gridData
+ bool isGridInitialized = false
+ array<string> allMaps
+} file
+
+// Why this file is included in Northstar:
+// As it turns out, the Respawn developers in all their infinite wisdom decided to add a check to floats for NaN and Inf
+// which does not exist in base Squirrel
+// The code looks a bit like this:
+// if ( strcpy_s(fos + 4, 0x16ui64, "1#QNAN") )
+// invoke_watson(0i64, 0i64, 0i64, 0, 0i64);
+// goto LABEL_27;
+// As if turns out, there is NO way to check if a float is one of these values in script
+// This alone, however, wouldn't be that bad, as it would simply result in a 1#QNAN being output to the screen.
+// Unfortunately, Respawns universe sized brains did not stop there.
+// One day, a dev at Respawn had to write a function to convert an amount of hours into a timestring.
+// Now, you and i dear reader would, being mortals, opt for the O(1) time solution of using the floor() and modulo functions
+// You may think this would work perfectly, but you would be wrong. This is not the respawn Way!
+// Instead, they opted to write the following piece of O(n) time algorithm:
+// while ( minutes >= 60 )
+// {
+// minutes -= 60
+// hours++
+// }
+// Now you may ask: "Is this horribly inefficient and bug-prone?", but you must understand: This is the Respawn Way
+// Passing in a NaN does not simply output a NaN to the screen, for that would be too simple.
+// Nay, instead, it hangs the UI thread for all eternity, as it tries to subtract 60 from a NaN
+// In fact, i think we should thank that developer for all the fun times we have had tracking and fixing this bug
+// However, we mortals cannot possibly wield the greatness of Respawn's code, and we must settle for a lowly O(1) algorithm instead
+// P.S: The other part of this fix is menu_stats_utility.nut
+
+void function InitViewStatsMapsMenu()
+{
+ var menu = GetMenu( "ViewStats_Maps_Menu" )
+ file.menu = menu
+
+ Hud_SetText( Hud_GetChild( file.menu, "MenuTitle" ), "#STATS_MAPS" )
+
+ file.gridData.rows = 5
+ file.gridData.columns = 1
+ //file.gridData.numElements // Set in OnViewStatsWeapons_Open after itemdata exists
+ file.gridData.pageType = eGridPageType.VERTICAL
+ file.gridData.tileWidth = 224
+ file.gridData.tileHeight = 112
+ file.gridData.paddingVert = 6
+ file.gridData.paddingHorz = 6
+
+ Grid_AutoAspectSettings( menu, file.gridData )
+
+ file.gridData.initCallback = MapButton_Init
+ file.gridData.getFocusCallback = MapButton_GetFocus
+ file.gridData.clickCallback = MapButton_Activate
+
+ AddMenuEventHandler( file.menu, eUIEvent.MENU_OPEN, OnViewStatsWeapons_Open )
+
+ AddMenuFooterOption( file.menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
+}
+
+void function OnViewStatsWeapons_Open()
+{
+ UI_SetPresentationType( ePresentationType.NO_MODELS )
+
+ file.allMaps = GetPrivateMatchMaps()
+
+ file.gridData.numElements = file.allMaps.len()
+
+ if ( !file.isGridInitialized )
+ {
+ GridMenuInit( file.menu, file.gridData )
+ file.isGridInitialized = true
+ }
+
+ file.gridData.currentPage = 0
+
+ Grid_InitPage( file.menu, file.gridData )
+ Hud_SetFocused( Grid_GetButtonForElementNumber( file.menu, 0 ) )
+ UpdateStatsForMap( file.allMaps[ 0 ] )
+}
+
+bool function MapButton_Init( var button, int elemNum )
+{
+ string mapName = file.allMaps[ elemNum ]
+
+ asset mapImage = GetMapImageForMapName( mapName )
+
+ var rui = Hud_GetRui( button )
+ RuiSetImage( rui, "buttonImage", mapImage )
+
+ Hud_SetEnabled( button, true )
+ Hud_SetVisible( button, true )
+
+ return true
+}
+
+void function MapButton_GetFocus( var button, int elemNum )
+{
+ if ( IsControllerModeActive() )
+ UpdateStatsForMap( file.allMaps[ elemNum ] )
+}
+
+void function MapButton_Activate( var button, int elemNum )
+{
+ if ( !IsControllerModeActive() )
+ UpdateStatsForMap( file.allMaps[ elemNum ] )
+}
+
+int function GetGameStatForMapInt( string gameStat, string mapName )
+{
+ array<string> privateMatchModes = GetPrivateMatchModes()
+
+ int totalStat = 0
+ int enumCount = PersistenceGetEnumCount( "gameModes" )
+ for ( int modeId = 0; modeId < enumCount; modeId++ )
+ {
+ string modeName = PersistenceGetEnumItemNameForIndex( "gameModes", modeId )
+
+ totalStat += GetGameStatForMapAndModeInt( gameStat, mapName, modeName )
+ }
+
+ return totalStat
+}
+
+int function GetGameStatForMapAndModeInt( string gameStat, string mapName, string modeName, string difficulty = "1" )
+{
+ string statString = GetStatVar( "game_stats", gameStat, "" )
+ string persistentVar = Stats_GetFixedSaveVar( statString, mapName, modeName, difficulty )
+
+ return GetUIPlayer().GetPersistentVarAsInt( persistentVar )
+}
+
+float function GetGameStatForMapFloat( string gameStat, string mapName )
+{
+ array<string> privateMatchModes = GetPrivateMatchModes()
+
+ float totalStat = 0
+ int enumCount = PersistenceGetEnumCount( "gameModes" )
+ for ( int modeId = 0; modeId < enumCount; modeId++ )
+ {
+ string modeName = PersistenceGetEnumItemNameForIndex( "gameModes", modeId )
+
+ if ( (GetGameStatForMapAndModeFloat( gameStat, mapName, modeName ).tostring() ) != "1.#QNAN" )
+ totalStat += GetGameStatForMapAndModeFloat( gameStat, mapName, modeName )
+ else
+ print("Hey buddy, I just saved you from a game freeze. You're welcome :)")
+ }
+
+ return totalStat
+}
+
+float function GetGameStatForMapAndModeFloat( string gameStat, string mapName, string modeName )
+{
+ string statString = GetStatVar( "game_stats", gameStat, "" )
+ string persistentVar = Stats_GetFixedSaveVar( statString, mapName, modeName, "1" )
+
+ return expect float( GetUIPlayer().GetPersistentVar( persistentVar ) )
+}
+
+
+void function UpdateStatsForMap( string mapName )
+{
+ entity player = GetUIPlayer()
+ if ( player == null )
+ return
+
+ Hud_SetText( Hud_GetChild( file.menu, "WeaponName" ), GetMapDisplayName( mapName ) )
+
+ // Image
+ var imageElem = Hud_GetRui( Hud_GetChild( file.menu, "WeaponImageLarge" ) )
+ RuiSetImage( imageElem, "basicImage", GetMapImageForMapName( mapName ) )
+ var hoursplayed = GetGameStatForMapFloat( "hoursPlayed", mapName )
+ string timePlayed = HoursToTimeString( GetGameStatForMapFloat( "hoursPlayed", mapName ) )
+ string gamesPlayed = string( GetGameStatForMapInt( "game_completed", mapName ) )
+
+ SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat0" ), Localize( "#STATS_HEADER_TIME_PLAYED" ), timePlayed )
+ SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat1" ), Localize( "#STATS_GAMES_PLAYED" ), gamesPlayed )
+ //SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat2" ), Localize( "#STATS_GAMES_PLAYED" ), gamesPlayed )
+ //SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat3" ), Localize( "#STATS_GAMES_PLAYED" ), gamesPlayed )
+
+ string winPercent = GetPercent( float( GetGameStatForMapInt( "game_won", mapName ) ), float( GetGameStatForMapInt( "game_completed", mapName ) ), 0 )
+
+ SetStatsLabelValue( file.menu, "KillsLabel0", "#STATS_GAMES_WIN_PERCENT" )
+ SetStatsLabelValue( file.menu, "KillsValue0", ("" + winPercent + "%") )
+
+ SetStatsLabelValue( file.menu, "KillsLabel1", "#STATS_GAMES_WON" )
+ SetStatsLabelValue( file.menu, "KillsValue1", GetGameStatForMapInt( "game_won", mapName ) )
+
+ SetStatsLabelValue( file.menu, "KillsLabel2", "#STATS_GAMES_MVP" )
+ SetStatsLabelValue( file.menu, "KillsValue2", GetGameStatForMapInt( "mvp", mapName ) )
+
+ SetStatsLabelValue( file.menu, "KillsLabel3", "#STATS_GAMES_TOP3" )
+ SetStatsLabelValue( file.menu, "KillsValue3", GetGameStatForMapInt( "top3OnTeam", mapName ) )
+
+ SetStatsLabelValue( file.menu, "KillsLabel4", "--" )
+ SetStatsLabelValue( file.menu, "KillsValue4", "--" )
+
+ //var anchorElem = Hud_GetChild( file.menu, "WeaponStatsBackground" )
+ //printt( Hud_GetX( anchorElem ) )
+ //printt( Hud_GetX( anchorElem ) )
+ //printt( Hud_GetX( anchorElem ) )
+ //printt( Hud_GetX( anchorElem ) )
+ //Hud_SetX( anchorElem, 0 )
+ //
+ array<string> gameModesArray = GetPersistenceEnumAsArray( "gameModes" )
+
+ array<PieChartEntry> modes
+ foreach ( modeName in gameModesArray )
+ {
+ float modePlayedTime = GetGameStatForMapAndModeFloat( "hoursPlayed", mapName, modeName )
+ if ( modePlayedTime > 0 )
+ AddPieChartEntry( modes, GameMode_GetName( modeName ), modePlayedTime, GetGameModeDisplayColor( modeName ) )
+ }
+
+ const MAX_MODE_ROWS = 8
+
+ if ( modes.len() > 0 )
+ {
+ modes.sort( ComparePieChartEntryValues )
+
+ if ( modes.len() > MAX_MODE_ROWS )
+ {
+ float otherValue
+ for ( int i = MAX_MODE_ROWS-1; i < modes.len() ; i++ )
+ otherValue += modes[i].numValue
+
+ modes.resize( MAX_MODE_ROWS-1 )
+ AddPieChartEntry( modes, "#GAMEMODE_OTHER", otherValue, [127, 127, 127, 255] )
+ }
+ }
+
+ PieChartData modesPlayedData
+ modesPlayedData.entries = modes
+ modesPlayedData.labelColor = [ 255, 255, 255, 255 ]
+ SetPieChartData( file.menu, "ModesPieChart", "#GAME_MODES_PLAYED", modesPlayedData )
+
+ array<string> fdMaps = GetPlaylistMaps( "fd" )
+
+ if ( fdMaps.contains( mapName ) )
+ {
+ array<var> pveElems = GetElementsByClassname( file.menu, "PvEGroup" )
+ foreach ( elem in pveElems )
+ {
+ Hud_Show( elem )
+ }
+
+ vector perfectColor = TEAM_COLOR_FRIENDLY / 219.0
+
+ var iconLegendRui = Hud_GetRui( Hud_GetChild( file.menu, "PvEIconLegend" ) )
+ RuiSetImage( iconLegendRui, "basicImage", $"rui/menu/gametype_select/playlist_fd_normal" )
+ RuiSetFloat3( iconLegendRui, "basicImageColor", perfectColor )
+
+ var icon0Rui = Hud_GetRui( Hud_GetChild( file.menu, "PvEIcon0" ) )
+ RuiSetImage( icon0Rui, "basicImage", $"rui/menu/gametype_select/playlist_fd_easy" )
+ int easyWins = GetGameStatForMapAndModeInt( "games_completed_fd", mapName, "fd", "0" )
+ SetStatsLabelValue( file.menu, "PvELabel0", "#FD_DIFFICULTY_EASY" )
+ SetStatsLabelValue( file.menu, "PvEValueA0", easyWins )
+ if ( GetGameStatForMapAndModeInt( "perfectMatches", mapName, "fd", "0" ) )
+ RuiSetFloat3( icon0Rui, "basicImageColor", perfectColor )
+ else
+ RuiSetFloat3( icon0Rui, "basicImageColor", easyWins > 0 ? <1, 1, 1> : <0.15, 0.15, 0.15> )
+
+ var icon1Rui = Hud_GetRui( Hud_GetChild( file.menu, "PvEIcon1" ) )
+ RuiSetImage( icon1Rui, "basicImage", $"rui/menu/gametype_select/playlist_fd_normal" )
+ int normalWins = GetGameStatForMapAndModeInt( "games_completed_fd", mapName, "fd", "1" )
+ SetStatsLabelValue( file.menu, "PvELabel1", "#FD_DIFFICULTY_NORMAL" )
+ SetStatsLabelValue( file.menu, "PvEValueA1", normalWins )
+ if ( GetGameStatForMapAndModeInt( "perfectMatches", mapName, "fd", "1" ) )
+ RuiSetFloat3( icon1Rui, "basicImageColor", perfectColor )
+ else
+ RuiSetFloat3( icon1Rui, "basicImageColor", normalWins > 0 ? <1, 1, 1> : <0.15, 0.15, 0.15> )
+
+ var icon2Rui = Hud_GetRui( Hud_GetChild( file.menu, "PvEIcon2" ) )
+ RuiSetImage( icon2Rui, "basicImage", $"rui/menu/gametype_select/playlist_fd_hard" )
+ int hardWins = GetGameStatForMapAndModeInt( "games_completed_fd", mapName, "fd", "2" )
+ SetStatsLabelValue( file.menu, "PvELabel2", "#FD_DIFFICULTY_HARD" )
+ SetStatsLabelValue( file.menu, "PvEValueA2", hardWins )
+ if ( GetGameStatForMapAndModeInt( "perfectMatches", mapName, "fd", "2" ) )
+ RuiSetFloat3( icon2Rui, "basicImageColor", perfectColor )
+ else
+ RuiSetFloat3( icon2Rui, "basicImageColor", hardWins > 0 ? <1, 1, 1> : <0.15, 0.15, 0.15> )
+
+ var icon3Rui = Hud_GetRui( Hud_GetChild( file.menu, "PvEIcon3" ) )
+ RuiSetImage( icon3Rui, "basicImage", $"rui/menu/gametype_select/playlist_fd_master" )
+ int masterWins = GetGameStatForMapAndModeInt( "games_completed_fd", mapName, "fd", "3" )
+ SetStatsLabelValue( file.menu, "PvELabel3", "#FD_DIFFICULTY_MASTER" )
+ SetStatsLabelValue( file.menu, "PvEValueA3", masterWins )
+ if ( GetGameStatForMapAndModeInt( "perfectMatches", mapName, "fd", "3" ) )
+ RuiSetFloat3( icon3Rui, "basicImageColor", perfectColor )
+ else
+ RuiSetFloat3( icon3Rui, "basicImageColor", masterWins > 0 ? <1, 1, 1> : <0.15, 0.15, 0.15> )
+
+ var icon4Rui = Hud_GetRui( Hud_GetChild( file.menu, "PvEIcon4" ) )
+ RuiSetImage( icon4Rui, "basicImage", $"rui/menu/gametype_select/playlist_fd_insane" )
+ int insaneWins = GetGameStatForMapAndModeInt( "games_completed_fd", mapName, "fd", "4" )
+ SetStatsLabelValue( file.menu, "PvELabel4", "#FD_DIFFICULTY_INSANE" )
+ SetStatsLabelValue( file.menu, "PvEValueA4", insaneWins )
+ if ( GetGameStatForMapAndModeInt( "perfectMatches", mapName, "fd", "4" ) )
+ RuiSetFloat3( icon4Rui, "basicImageColor", perfectColor )
+ else
+ RuiSetFloat3( icon4Rui, "basicImageColor", insaneWins > 0 ? <1, 1, 1> : <0.15, 0.15, 0.15> )
+ }
+ else
+ {
+ array<var> pveElems = GetElementsByClassname( file.menu, "PvEGroup" )
+ foreach ( elem in pveElems )
+ {
+ Hud_Hide( elem )
+ }
+ }
+}
+
+
+var function setit( vector color )
+{
+ var iconLegendRui = Hud_GetRui( Hud_GetChild( file.menu, "PvEIconLegend" ) )
+ RuiSetImage( iconLegendRui, "basicImage", $"rui/menu/gametype_select/playlist_fd_normal" )
+ RuiSetFloat3( iconLegendRui, "basicImageColor", color )
+} \ No newline at end of file
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_stats_utility.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_stats_utility.nut
new file mode 100644
index 00000000..e1d0a8f9
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_stats_utility.nut
@@ -0,0 +1,560 @@
+untyped
+
+
+global function SetPieChartData
+global function SetStatsBarValues
+global function SetStatsValueInfo
+global function SetStatsLabelValue
+global function GetPercent
+//global function GetChallengeCompleteData
+global function GetItemUnlockCountData
+global function GetOverviewWeaponData
+global function StatToTimeString
+global function HoursToTimeString
+global function StatToDistanceString
+global function ComparePieChartEntryValues
+global function SetStatBoxDisplay
+global function SetMedalStatBoxDisplay
+
+void function SetPieChartData( var menu, string panelName, string titleString, PieChartData data )
+{
+ Assert( data.entries.len() <= 8 )
+
+ // Get nested panel
+ var piePanel = GetElem( menu, panelName )
+
+ // Create background
+ var background = Hud_GetChild( piePanel, "BarBG" )
+ Hud_SetBarProgress( background, 1.0 )
+ Hud_SetColor( background, [190, 190, 190, 255] )
+
+ // Calculate total of all values combined
+ foreach ( entry in data.entries )
+ data.sum += entry.numValue
+
+ // Calculate bar fraction for each value
+ foreach ( entry in data.entries )
+ {
+ if ( data.sum > 0 )
+ entry.fracValue = entry.numValue / data.sum
+ else
+ entry.fracValue = 0.0
+ }
+
+ // Set slice sizes and text data
+ var titleLabel = Hud_GetChild( piePanel, "Title" )
+ Hud_SetText( titleLabel, titleString )
+ Hud_SetColor( titleLabel, data.labelColor )
+
+ var noDataLabel = Hud_GetChild( piePanel, "NoData" )
+
+ for ( int index = 0; index < 8; index++ )
+ {
+ var barColorGuide = Hud_GetChild( piePanel, "BarColorGuide" + index )
+ // Hud_SetColor( barColorGuide, entry.color )
+ Hud_Hide( barColorGuide )
+
+ var barColorGuideFrame = Hud_GetChild( piePanel, "BarColorGuideFrame" + index )
+ Hud_Hide( barColorGuideFrame )
+
+ var barName = Hud_GetChild( piePanel, "BarName" + index )
+ Hud_SetColor( barName, data.labelColor )
+ Hud_SetText( barName, "" )
+
+ var bar = Hud_GetChild( piePanel, "Bar" + index )
+ //Hud_SetBarProgress( bar, combinedFrac )
+ //Hud_SetColor( bar, entry.color )
+ Hud_Hide( bar )
+ }
+
+ if ( data.entries.len() > 0 )
+ {
+ Hud_Hide( noDataLabel )
+
+ float combinedFrac = 0.0
+ int largestTextWidth = 0
+
+ foreach ( index, entry in data.entries )
+ {
+ var barColorGuide = Hud_GetChild( piePanel, "BarColorGuide" + index )
+ Hud_SetColor( barColorGuide, entry.color )
+ Hud_Show( barColorGuide )
+
+ var barColorGuideFrame = Hud_GetChild( piePanel, "BarColorGuideFrame" + index )
+ Hud_Show( barColorGuideFrame )
+
+ string percent = GetPercent( entry.fracValue, 1.0, 0, true )
+ var barName = Hud_GetChild( piePanel, "BarName" + index )
+ Hud_SetColor( barName, data.labelColor )
+
+ if ( data.timeBased )
+ Hud_SetText( barName, PieChartHoursToTimeString( entry.numValue, entry.displayName, percent ) )
+ else
+ Hud_SetText( barName, "#STATS_TEXT_AND_PERCENTAGE", entry.displayName, percent )
+
+ int currentTextWidth = Hud_GetTextWidth( barName )
+ if ( currentTextWidth > largestTextWidth )
+ largestTextWidth = currentTextWidth
+
+ Hud_Show( barName )
+
+ combinedFrac += entry.fracValue
+ var bar = Hud_GetChild( piePanel, "Bar" + index )
+ Hud_SetBarProgress( bar, combinedFrac )
+ Hud_SetColor( bar, entry.color )
+ Hud_Show( bar )
+ }
+
+ // Position the list
+ int xOffset = int( ( largestTextWidth / -2 ) + ContentScaledX( 18 ) )
+ Hud_SetX( Hud_GetChild( piePanel, "BarName0" ), xOffset )
+ }
+ else
+ {
+ Hud_Show( noDataLabel )
+ for ( int index = 0; index < 8; index++ )
+ {
+ var barColorGuide = Hud_GetChild( piePanel, "BarColorGuide" + index )
+// Hud_SetColor( barColorGuide, entry.color )
+ Hud_Hide( barColorGuide )
+
+ var barColorGuideFrame = Hud_GetChild( piePanel, "BarColorGuideFrame" + index )
+ Hud_Hide( barColorGuideFrame )
+
+ var barName = Hud_GetChild( piePanel, "BarName" + index )
+ Hud_SetColor( barName, data.labelColor )
+ Hud_SetText( barName, "" )
+
+ var bar = Hud_GetChild( piePanel, "Bar" + index )
+ //Hud_SetBarProgress( bar, combinedFrac )
+ //Hud_SetColor( bar, entry.color )
+ Hud_Hide( bar )
+ }
+ }
+}
+
+function SetStatsBarValues( menu, panelName, titleString, startValue, endValue, currentValue )
+{
+ Assert( endValue > startValue )
+ Assert( currentValue >= startValue && currentValue <= endValue )
+
+ // Get nested panel
+ var panel = GetElem( menu, panelName )
+
+ // Update titel
+ var title = Hud_GetChild( panel, "Title" )
+ Hud_SetText( title, titleString )
+
+ // Update progress text
+ var progressText = Hud_GetChild( panel, "ProgressText" )
+ Hud_SetText( progressText, "#STATS_PROGRESS_BAR_VALUE", currentValue, endValue )
+
+ // Update bar progress
+ float frac = GraphCapped( currentValue, startValue, endValue, 0.0, 1.0 )
+
+ var barFill = Hud_GetChild( panel, "BarFill" )
+ Hud_SetScaleX( barFill, frac )
+
+ var barFillShadow = Hud_GetChild( panel, "BarFillShadow" )
+ Hud_SetScaleX( barFillShadow, frac )
+}
+
+void function SetStatsValueInfo( var menu, valueID, labelText, textString )
+{
+ var elem = GetElem( menu, "Column0Label" + valueID )
+ Assert( elem != null )
+ Hud_SetText( elem, labelText )
+
+ elem = GetElem( menu, "Column0Value" + valueID )
+ Assert( elem != null )
+ SetStatsLabelValueOnLabel( elem, textString )
+}
+
+void function SetStatsLabelValue( var menu, labelName, textString )
+{
+ var elem = GetElem( menu, labelName )
+ Assert( elem != null)
+ SetStatsLabelValueOnLabel( elem, textString )
+}
+
+void function SetStatsLabelValueOnLabel( elem, textString )
+{
+ if ( type( textString ) == "array" )
+ {
+ if ( textString.len() == 6 )
+ Hud_SetText( elem, string( textString[0] ), textString[1], textString[2], textString[3], textString[4], textString[5] )
+ if ( textString.len() == 5 )
+ Hud_SetText( elem, string( textString[0] ), textString[1], textString[2], textString[3], textString[4] )
+ if ( textString.len() == 4 )
+ Hud_SetText( elem, string( textString[0] ), textString[1], textString[2], textString[3] )
+ if ( textString.len() == 3 )
+ Hud_SetText( elem, string( textString[0] ), textString[1], textString[2] )
+ if ( textString.len() == 2 )
+ Hud_SetText( elem, string( textString[0] ), textString[1] )
+ if ( textString.len() == 1 )
+ Hud_SetText( elem, string( textString[0] ) )
+ }
+ else
+ {
+ Hud_SetText( elem, string( textString ) )
+ }
+}
+
+string function GetPercent( float val, float total, float defaultPercent, bool doClamp = true )
+{
+ float percent = defaultPercent
+ if ( total > 0 )
+ {
+ percent = val / total
+ percent *= 100
+ }
+
+ if ( doClamp )
+ percent = clamp( percent, 0, 100 )
+
+ string formattedPercent
+ if ( int( percent * 10 ) % 10 == 0 )
+ formattedPercent = format( "%.0f", percent )
+ else
+ formattedPercent = format( "%.1f", percent )
+
+ return formattedPercent
+}
+
+//function GetChallengeCompleteData()
+//{
+// local Table = {}
+// Table.total <- 0
+// Table.complete <- 0
+//
+// UI_GetAllChallengesProgress()
+// var allChallenges = GetLocalChallengeTable()
+//
+// foreach( challengeRef, val in allChallenges )
+// {
+// if ( IsDailyChallenge( challengeRef ) )
+// continue
+// local tierCount = GetChallengeTierCount( challengeRef )
+// Table.total += tierCount
+// for ( int i = 0; i < tierCount; i++ )
+// {
+// if ( IsChallengeTierComplete( challengeRef, i ) )
+// Table.complete++
+// }
+// }
+//
+// return Table
+//}
+
+function GetItemUnlockCountData()
+{
+ entity player = GetUIPlayer()
+ if ( player == null )
+ return {}
+
+ local Table = {}
+ Table[ "weapons" ] <- {}
+ Table[ "weapons" ].total <- 0
+ Table[ "weapons" ].unlocked <- 0
+ Table[ "attachments" ] <- {}
+ Table[ "attachments" ].total <- 0
+ Table[ "attachments" ].unlocked <- 0
+ Table[ "mods" ] <- {}
+ Table[ "mods" ].total <- 0
+ Table[ "mods" ].unlocked <- 0
+ Table[ "abilities" ] <- {}
+ Table[ "abilities" ].total <- 0
+ Table[ "abilities" ].unlocked <- 0
+ Table[ "gear" ] <- {}
+ Table[ "gear" ].total <- 0
+ Table[ "gear" ].unlocked <- 0
+/*
+ local tableMapping = {}
+
+ tableMapping[ eItemTypes.PILOT_PRIMARY ] <- "weapons"
+ tableMapping[ eItemTypes.PILOT_SECONDARY ] <- "weapons"
+ tableMapping[ eItemTypes.PILOT_ORDNANCE ] <- "weapons"
+ tableMapping[ eItemTypes.TITAN_PRIMARY ] <- "weapons"
+ tableMapping[ eItemTypes.TITAN_ORDNANCE ] <- "weapons"
+ tableMapping[ eItemTypes.PILOT_PRIMARY_ATTACHMENT ] <- "attachments"
+ tableMapping[ eItemTypes.PILOT_PRIMARY_MOD ] <- "mods"
+ tableMapping[ eItemTypes.PILOT_SECONDARY_MOD ] <- "mods"
+ tableMapping[ eItemTypes.TITAN_PRIMARY_MOD ] <- "mods"
+ tableMapping[ eItemTypes.PILOT_SPECIAL_MOD ] <- "mods"
+ tableMapping[ eItemTypes.TITAN_SPECIAL_MOD ] <- "mods"
+ tableMapping[ eItemTypes.PILOT_SPECIAL ] <- "abilities"
+ tableMapping[ eItemTypes.TITAN_SPECIAL ] <- "abilities"
+
+ local itemRefs = GetAllItemRefs()
+ foreach ( data in itemRefs )
+ {
+ if ( !( data.Type in tableMapping ) )
+ continue
+ Table[ tableMapping[ data.Type ] ].total++
+
+ if ( !IsItemLocked( player, expect string( data.childRef ), expect string( data.ref ) ) )
+ Table[ tableMapping[ data.Type ] ].unlocked++
+ }
+*/
+ return Table
+}
+
+table<string, table> function GetOverviewWeaponData()
+{
+ table<string, table> Table = {}
+ Table[ "most_kills" ] <- {}
+ Table[ "most_kills" ].ref <- ""
+ Table[ "most_kills" ].printName <- ""
+ Table[ "most_kills" ].val <- 0
+ Table[ "most_used" ] <- {}
+ Table[ "most_used" ].ref <- ""
+ Table[ "most_used" ].printName <- ""
+ Table[ "most_used" ].val <- 0
+ Table[ "highest_kpm" ] <- {}
+ Table[ "highest_kpm" ].ref <- ""
+ Table[ "highest_kpm" ].printName <- ""
+ Table[ "highest_kpm" ].val <- 0
+
+ entity player = GetUIPlayer()
+ if ( player == null )
+ return Table
+
+ array<ItemDisplayData> allWeapons = []
+
+ allWeapons.extend( GetVisibleItemsOfType( eItemTypes.PILOT_PRIMARY ) )
+ allWeapons.extend( GetVisibleItemsOfType( eItemTypes.PILOT_SECONDARY ) )
+ //allWeapons.extend( GetVisibleItemsOfType( eItemTypes.PILOT_ORDNANCE ) ) // art looks bad
+ allWeapons.extend( GetVisibleItemsOfType( eItemTypes.TITAN_PRIMARY ) )
+ allWeapons.extend( GetVisibleItemsOfType( eItemTypes.TITAN_ORDNANCE ) )
+ allWeapons.extend( GetVisibleItemsOfType( eItemTypes.TITAN_ANTIRODEO ) )
+ allWeapons.extend( GetVisibleItemsOfType( eItemTypes.TITAN_SPECIAL ) )
+ //allWeapons.extend( GetVisibleItemsOfType( eItemTypes.BURN_METER_REWARD ) ) // script errors
+
+ foreach ( weapon in allWeapons )
+ {
+ string weaponName = weapon.ref
+ string weaponDisplayName = expect string( GetWeaponInfoFileKeyField_Global( weaponName, "printname" ) )
+
+ if ( !PersistenceEnumValueIsValid( "loadoutWeaponsAndAbilities", weaponName ) )
+ continue
+
+ int val = GetPlayerStatInt( player, "weapon_kill_stats", "total", weaponName )
+ if ( val > Table[ "most_kills" ].val )
+ {
+ Table[ "most_kills" ].ref = weaponName
+ Table[ "most_kills" ].printName = weaponDisplayName
+ Table[ "most_kills" ].val = val
+ }
+
+ float fVal = GetPlayerStatFloat( player, "weapon_stats", "hoursUsed", weaponName )
+ if ( fVal > Table[ "most_used" ].val )
+ {
+ Table[ "most_used" ].ref = weaponName
+ Table[ "most_used" ].printName = weaponDisplayName
+ Table[ "most_used" ].val = fVal
+ }
+
+ local killsPerMinute = 0
+ local hoursEquipped = GetPlayerStatFloat( player, "weapon_stats", "hoursEquipped", weaponName )
+ local killCount = GetPlayerStatInt( player, "weapon_kill_stats", "total", weaponName )
+ if ( hoursEquipped > 0 )
+ killsPerMinute = format( "%.2f", ( killCount / ( hoursEquipped * 60.0 ) ).tofloat() )
+ if ( killsPerMinute.tofloat() > Table[ "highest_kpm" ].val.tofloat() )
+ {
+ Table[ "highest_kpm" ].ref = weaponName
+ Table[ "highest_kpm" ].printName = weaponDisplayName
+ Table[ "highest_kpm" ].val = killsPerMinute
+ }
+ }
+
+ return Table
+}
+
+string function StatToTimeString( string category, string alias, string weapon = "" )
+{
+ entity player = GetUIPlayer()
+ if ( player == null )
+ return "0"
+
+ string statString = GetStatVar( category, alias, weapon )
+ float savedHours = expect float( player.GetPersistentVar( statString ) )
+
+ return HoursToTimeString( savedHours )
+}
+
+string function HoursToTimeString( float savedHours )
+{
+ string timeString
+ local minutes = floor( savedHours * 60.0 )
+
+ if ( minutes < 0 )
+ minutes = 0
+
+ int days = 0
+ int hours = 0
+
+ // For archiving code, i would like to keep this code here
+ // It is a testament to Respawn's hubris and determination to writing the absolutely worst fucking code ever
+ // These motherfuckers managed to run an O(1) operation in O(n) time. Genuinely impressive.
+ // while ( minutes >= 1440 )
+ // {
+ // minutes -= 1440
+ // days++
+ // }
+ //
+ // while ( minutes >= 60 )
+ // {
+ // minutes -= 60
+ // hours++
+ // }
+
+ days = int(floor(minutes / 1440))
+ minutes = minutes % 1440
+
+ hours = int(floor(minutes / 60))
+ minutes = minutes % 60
+
+ if ( days > 0 && hours > 0 && minutes > 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_D_H_M", days, hours, minutes )
+ }
+ else if ( days > 0 && hours == 0 && minutes == 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_D", days )
+ }
+ else if ( days == 0 && hours > 0 && minutes == 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_H", hours )
+ }
+ else if ( days == 0 && hours == 0 && minutes >= 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_M", minutes )
+ }
+ else if ( days > 0 && hours > 0 && minutes == 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_D_H", days, hours )
+ }
+ else if ( days == 0 && hours > 0 && minutes > 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_H_M", hours, minutes )
+ }
+ else if ( days > 0 && hours == 0 && minutes > 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_D_M", days, minutes )
+ }
+ else
+ {
+ Assert( 0, "Unhandled time string creation case" )
+ }
+
+ return timeString
+}
+
+string function PieChartHoursToTimeString( float savedHours, string pieChartHeader, string pieChartPercent )
+{
+ string timeString
+ local minutes = floor( savedHours * 60.0 )
+
+ if ( minutes < 0 )
+ minutes = 0
+
+ int days = 0
+ int hours = 0
+
+ while ( minutes >= 1440 )
+ {
+ minutes -= 1440
+ days++
+ }
+
+ while ( minutes >= 60 )
+ {
+ minutes -= 60
+ hours++
+ }
+
+ if ( days > 0 && hours > 0 && minutes > 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_D_H_M_PIECHART", days, hours, minutes, Localize( pieChartHeader ), pieChartPercent )
+ }
+ else if ( days > 0 && hours == 0 && minutes == 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_D_PIECHART", days, Localize( pieChartHeader ), pieChartPercent )
+ }
+ else if ( days == 0 && hours > 0 && minutes == 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_H_PIECHART", hours, Localize( pieChartHeader ), pieChartPercent )
+ }
+ else if ( days == 0 && hours == 0 && minutes >= 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_M_PIECHART", minutes, Localize( pieChartHeader ), pieChartPercent )
+ }
+ else if ( days > 0 && hours > 0 && minutes == 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_D_H_PIECHART", days, hours, Localize( pieChartHeader ), pieChartPercent )
+ }
+ else if ( days == 0 && hours > 0 && minutes > 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_H_M_PIECHART", hours, minutes, Localize( pieChartHeader ), pieChartPercent )
+ }
+ else if ( days > 0 && hours == 0 && minutes > 0 )
+ {
+ timeString = Localize( "#STATS_TIME_STRING_D_M_PIECHART", days, minutes, Localize( pieChartHeader ), pieChartPercent )
+ }
+ else
+ {
+ Assert( 0, "Unhandled time string creation case" )
+ }
+
+ return timeString
+}
+
+string function StatToDistanceString( string category, string alias, string weapon = "" )
+{
+ entity player = GetUIPlayer()
+ if ( player == null )
+ return ""
+
+ string statString = GetStatVar( category, alias, weapon )
+ float kilometers = expect float( player.GetPersistentVar( statString ) )
+
+ string formattedNum
+ if ( kilometers % 1 == 0 )
+ formattedNum = format( "%.0f", kilometers )
+ else
+ formattedNum = format( "%.2f", kilometers )
+
+ string distString = Localize( "#STATS_KILOMETERS_ABBREVIATION", formattedNum )
+
+ return distString
+}
+
+int function ComparePieChartEntryValues( PieChartEntry a, PieChartEntry b )
+{
+ float aVal = a.numValue
+ float bVal = b.numValue
+
+ if ( aVal < bVal )
+ return 1
+ else if ( aVal > bVal )
+ return -1
+
+ return 0
+}
+
+void function SetStatBoxDisplay( var vguiElem, string text, string value )
+{
+ var rui = Hud_GetRui( vguiElem )
+
+ RuiSetString( rui, "statText", text )
+ RuiSetString( rui, "statValue", value )
+}
+
+void function SetMedalStatBoxDisplay( var vguiElem, string text, asset image, int value )
+{
+ var rui = Hud_GetRui( vguiElem )
+
+ RuiSetString( rui, "statText", text )
+ RuiSetString( rui, "statValue", string( value ) )
+ RuiSetImage( rui, "statImage", image )
+} \ No newline at end of file
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut b/Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut
index 65a8ca9b..95b7bdae 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut
@@ -6,6 +6,8 @@ global function UpdatePromoData
global function UICodeCallback_GetOnPartyServer
global function UICodeCallback_MainMenuPromosUpdated
+global bool isOnMainMenu = false
+
// defining this here because it's the only place it's used rn, custom const for a hook in launcher
global const WEBBROWSER_FLAG_FORCEEXTERNAL = 1 << 1 // 2
@@ -526,6 +528,7 @@ void function OnPlayFDButton_Activate( var button ) // repurposed for launching
if ( !Hud_IsLocked( button ) )
{
SetConVarBool( "ns_is_modded_server", true )
+ SetConVarString( "communities_hostname", "" ) // disable communities due to crash exploits that are still possible through it
NSTryAuthWithLocalServer()
thread TryAuthWithLocalServer()
}
@@ -552,19 +555,32 @@ void function TryAuthWithLocalServer()
}
WaitFrame()
}
-
+
if ( NSWasAuthSuccessful() )
{
NSCompleteAuthWithLocalServer()
+ if ( GetConVarString( "mp_gamemode" ) == "solo" )
+ SetConVarString( "mp_gamemode", "tdm" )
+
+ CloseAllDialogs()
+
+ ClientCommand( "setplaylist tdm" )
+ ClientCommand( "map mp_lobby" )
}
-
- if ( GetConVarString( "mp_gamemode" ) == "solo" )
- SetConVarString( "mp_gamemode", "tdm" )
+ else
+ {
+ CloseAllDialogs()
+
+ var reason = NSGetAuthFailReason()
- CloseAllDialogs()
+ DialogData dialogData
+ dialogData.image = $"ui/menu/common/dialog_error"
+ dialogData.header = "#ERROR"
+ dialogData.message = Localize("#NS_SERVERBROWSER_CONNECTIONFAILED") + "\nERROR: " + reason + "\n" + Localize("#" + reason)
- ClientCommand( "setplaylist tdm" )
- ClientCommand( "map mp_lobby" )
+ AddDialogButton( dialogData, "#OK", null )
+ OpenDialog( dialogData )
+ }
}
void function CancelNSLocalAuth()
@@ -923,7 +939,7 @@ void function SpotlightButton_Activate( var button )
else
{
// discord links don't work in origin overlay
- if ( link.find( "https://discord.gg" ) == 0 || link == "https://northstar.tf/discord" )
+ if ( link.find( "https://discord.gg" ) == 0 || link == "https://northstar.tf/discord" || link == "https://northstar.tf/wiki" )
LaunchExternalWebBrowser( link, WEBBROWSER_FLAG_FORCEEXTERNAL )
else
LaunchExternalWebBrowser( link, WEBBROWSER_FLAG_MUTEGAME )
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/ui_vscript.gnut b/Northstar.Client/mod/scripts/vscripts/ui/ui_vscript.gnut
new file mode 100644
index 00000000..63535bec
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/ui/ui_vscript.gnut
@@ -0,0 +1,352 @@
+
+// Events for handlers
+// UIE_CLICK
+// UIE_GET_FOCUS
+// UIE_LOSE_FOCUS
+
+global function UICodeCallback_UIInit
+global function UICodeCallback_ControllerModeChanged
+global function UICodeCallback_OnVideoOver
+global function AddUICallback_OnLevelInit
+
+global struct TabDef
+{
+ var panel
+ string title
+}
+
+global struct InputDef
+{
+ int input
+ string gamepadLabel
+ var vguiElem
+ string mouseLabel
+ bool functionref() conditionCheckFunc
+ bool lastConditionCheckResult
+ void functionref( var ) activateFunc
+ void functionref( InputDef ) updateFunc
+}
+
+global struct DialogButtonData
+{
+ string label
+ void functionref() activateFunc
+ string focusMessage
+ bool startFocused
+}
+
+global struct DialogFooterData
+{
+ string label
+ void functionref() activateFunc
+}
+
+global struct DialogMessageRuiData
+{
+ string message = ""
+ vector style1Color = <1.0, 1.0, 1.0>
+ vector style2Color = <0.5, 0.5, 0.5>
+ vector style3Color = <0.5, 0.5, 0.5>
+
+ float style1FontScale = 1.0
+ float style2FontScale = 1.0
+ float style3FontScale = 1.0
+}
+
+global struct DialogData
+{
+ var menu
+ string header
+ string message
+ DialogMessageRuiData &ruiMessage
+ array messageColor = [161, 161, 161, 255]
+ asset image
+ asset rightImage = $""
+ bool forceChoice = false
+ bool noChoice = false
+ bool noChoiceWithNavigateBack = false
+ bool showSpinner = false
+ bool showPCBackButton = false
+ float inputDisableTime = 0
+ table<int,bool> coloredButton
+ bool darkenBackground = false
+ bool useFullMessageHeight = false
+
+ array<DialogButtonData> buttonData
+ array<DialogFooterData> footerData
+}
+
+global struct MenuDef
+{
+ void functionref() initFunc
+ void functionref() openFunc
+ void functionref() closeFunc
+ void functionref() showFunc // TODO: Needs hooking up
+ void functionref() hideFunc // TODO: Needs hooking up
+ void functionref() thinkFunc
+ void functionref() navBackFunc
+ void functionref() tabChangedFunc
+ void functionref() inputModeChangedFunc
+ void functionref() entitlementsChangedFunc
+
+ array<InputDef> footerData
+ table<int, void functionref( var )> registeredInput
+
+ bool hasTabs = false
+ array<TabDef> tabsData
+ int tabIndex = 0
+
+ bool isDialog = false
+ DialogData& dialogData
+ bool isDynamicHeight = false
+
+ bool isPVEMenu = false
+
+ var lastFocus // Only used for restoring submenu focus so far
+}
+
+global struct PanelDef
+{
+ void functionref() initFunc
+ void functionref() showFunc
+ void functionref() hideFunc
+
+ string tabTitle = "Default"
+
+ array<InputDef> footerData
+ table<int, void functionref( var )> registeredInput
+
+ var defaultFocus
+}
+
+global struct PieChartEntry
+{
+ string displayName
+ float numValue
+ array<int> color = [127, 127, 127, 255]
+ float fracValue = 0.0
+}
+
+global struct PieChartData
+{
+ array<PieChartEntry> entries
+ array<int> labelColor = [46, 49, 51, 255]
+ bool timeBased = false
+ float sum = 0.0
+}
+
+global struct UIGlobals
+{
+ table menus = {}
+ array allMenus = []
+ array<var> menuStack
+ string loadingLevel = ""
+ string loadedLevel = ""
+ string previousLevel = ""
+ string previousPlaylist = ""
+ var activeMenu = null
+ bool lastMenuNavDirection = MENU_NAV_FORWARD
+ bool lobbyFromLoadingScreen = false
+ bool eventHandlersAdded = false
+ bool loadoutsInitialized = false
+ bool itemsInitialized = false
+ bool matchmaking = false
+ var dialogCloseCallback = null
+ table signalDummy = {}
+ float dialogInputEnableTime = 0.0
+ bool lobbyMenusLeftOpen = false
+ bool playingMusic = false
+ var mainMenuFocus = null
+ int announcementVersionSeen = -1
+ var lastCategoryFocus = null
+
+ int pilotSpawnLoadoutIndex = -1
+ int titanSpawnLoadoutIndex = -1
+
+ bool updatePilotSpawnLoadout = false
+ bool updateTitanSpawnLoadout = false
+
+ string editingLoadoutType = "pilot"
+ string editingLoadoutProperty = ""
+ int editingLoadoutIndex = -1
+ string editingItemRef = ""
+ int editingItemType = -1
+ var editingSubitemRef = null
+ int editingSubitemType = -1
+ var editingParentItemRef = null
+ int editingWeaponCategory = -1
+
+ int entitlementId = -1
+ string testStoreWeaponRef // TODO: Remove when done testing
+
+ bool EOGAutoAdvance = true
+ bool EOGOpenInLobby = false
+ string EOGChallengeFilter = ""
+ var eogCoopFocusedButton = null
+ var eogCoopSelectedButton = null
+ var eogScoreboardFocusedButton = null
+ bool eogNavigationButtonsRegistered = false
+
+ table<string, var> ui_ChallengeProgress = {}
+
+ int decalScrollState = 0
+
+ bool isLobby
+
+ var ConfirmMenuMessage
+ var ConfirmMenuErrorCode
+ array<DialogButtonData> dialogButtonData
+
+ bool updatingLobbyUI = false
+
+ array buttonConfigs
+ array stickConfigs
+
+ var playlistList
+
+ table< string, array > eog_challengesToShow
+ table< string, array > eog_unlocks
+
+ bool videoSettingsChanged = false
+
+ bool playingVideo = false
+ bool playingCredits = false
+
+ bool mapSupportsMenuModels = false
+ bool mapSupportsMenuModelsUpdated = false
+ bool interpolateCameraMoves = true
+ int activePresentationType = ePresentationType.INACTIVE
+ bool rotateCharacterInputRegistered = false
+
+ table<var,MenuDef> menuData
+
+ table<string, int> intVars
+ table<string, bool> boolVars
+ table<string, var> varVars
+ table<string, array<void functionref()> > varChangeFuncs
+
+ array<void functionref()> onLevelInitCallbacks
+
+ bool tabButtonsRegistered = false
+
+ table panels = {}
+ array<var> allPanels
+ table<var,PanelDef> panelData
+
+ bool sp_showAlternateMissionLog = false
+
+ int launching = eLaunching.FALSE
+ bool triedNucleusRegistration = false
+ int consoleSettingMenu = eConsoleSettingsMenu.FALSE
+
+ bool updateCachedNewItems = true
+
+ var menuToOpenFromPromoButton = null
+
+ bool isLoading = false
+
+}
+
+global UIGlobals uiGlobal
+
+global const MAINMENU_MUSIC_DELAY = 4.0
+
+
+void function UICodeCallback_UIInit()
+{
+ ScriptCompilerTest()
+
+ ShUtilityAll_Init()
+ LevelVarInit()
+
+ VPKNotifyFile( "media/intro_captions.txt" )
+
+ UtilityUI_Init()
+
+ Settings_Init() // UI script doesn't need everything in this, reorganize
+ GameModes_Init()
+ UIVars_Init()
+
+ PassivesShared_Init()
+ ChallengesShared_Init()
+ ChallengesContent_Init()
+ XP_Init()
+
+ MenuLobby_Init()
+ MenuPrivateMatch_Init()
+
+ MenuGamepadLayout_Init()
+ MenuChallenges_Init()
+ MenuEOG_Init()
+ MenuUtility_Init()
+ MenuAdvocateLetter_Init()
+ MenuCredits_Init()
+ MenuMapSelect_Init()
+
+ RegisterSignal( "LevelShutdown" )
+ RegisterSignal( "CleanupInGameMenus" )
+ RegisterSignal( "OnCloseLobbyMenu" )
+ RegisterSignal( "OnCancelConnect" )
+ RegisterSignal( "PlayVideoEnded" )
+ RegisterSignal( "ActiveMenuChanged" )
+ RegisterSignal( "LevelFinishedLoading")
+ RegisterSignal( "OpenErrorDialog" )
+ RegisterSignal( "BoughtItem" )
+
+ thread UpdateClientMenuOpenState()
+
+ InitGamepadConfigs()
+ Store_Init()
+ InitMenus()
+
+ if ( !IsSingleplayer() )
+ thread UpdateCachedLoadouts() // Needs to wait for persistent data to ready
+}
+
+void function UICodeCallback_ControllerModeChanged( bool controllerModeEnabled )
+{
+ //printt( "CONTROLLER! " + controllerModeEnabled + ", " + IsControllerModeActive() )
+
+ if ( uiGlobal.activeMenu == null )
+ return
+
+ if ( uiGlobal.menuData[ uiGlobal.activeMenu ].inputModeChangedFunc != null )
+ thread uiGlobal.menuData[ uiGlobal.activeMenu ].inputModeChangedFunc()
+
+ UpdateFooterOptions()
+
+ if ( IsDialog( uiGlobal.activeMenu ) )
+ UpdateDialogFooterVisibility( uiGlobal.activeMenu, controllerModeEnabled )
+}
+
+void function UICodeCallback_OnVideoOver()
+{
+ SetIntroViewed( true )
+
+ Signal( uiGlobal.signalDummy, "PlayVideoEnded" )
+}
+
+void function UpdateClientMenuOpenState()
+{
+ for ( ;; )
+ {
+ WaitSignal( uiGlobal.signalDummy, "ActiveMenuChanged" )
+
+ if ( IsMultiplayer() && !IsLobby() )
+ {
+ int newState = 0
+ if ( IsDialogOnlyActiveMenu() )
+ newState = 2
+ else if ( uiGlobal.activeMenu != null)
+ newState = 1
+
+ RunMenuClientFunction( "SetMenuOpenState", newState )
+ }
+ }
+}
+
+void function AddUICallback_OnLevelInit( void functionref() callbackFunc )
+{
+ Assert( !( uiGlobal.onLevelInitCallbacks.contains( callbackFunc ) ), "Already added " + string( callbackFunc ) + " with AddUICallback_OnLevelInit" )
+ uiGlobal.onLevelInitCallbacks.append( callbackFunc )
+}