aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorF1F7Y <64418963+F1F7Y@users.noreply.github.com>2024-09-10 23:43:36 +0200
committerGitHub <noreply@github.com>2024-09-10 23:43:36 +0200
commit525f671513eb3f80775399ba34a879b528d9a7a4 (patch)
tree2d36b73fd096708ec974ed1041eeab6cea9834ff
parente2931190f9b37fc4ec171cd348d85eb96ed591a3 (diff)
downloadNorthstarMods-525f671513eb3f80775399ba34a879b528d9a7a4.tar.gz
NorthstarMods-525f671513eb3f80775399ba34a879b528d9a7a4.zip
Rework mode select menu (#624)v1.28.0-rc5v1.28.0
Turns mode list from page based into a scrollable list that is categorised and supports filtering.
-rw-r--r--Northstar.Client/mod.json4
-rw-r--r--Northstar.Client/mod/resource/northstar_client_localisation_english.txt12
-rw-r--r--Northstar.Client/mod/resource/ui/menus/mode_select.menu613
-rw-r--r--Northstar.Client/mod/resource/ui/menus/panels/mode_select_button.res31
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_mode_select.nut582
5 files changed, 1003 insertions, 239 deletions
diff --git a/Northstar.Client/mod.json b/Northstar.Client/mod.json
index 44937a2b..0d0cfc16 100644
--- a/Northstar.Client/mod.json
+++ b/Northstar.Client/mod.json
@@ -46,6 +46,10 @@
"Name": "modlist_reverse",
"DefaultValue": "0",
"Flags": "ARCHIVE_PLAYERPROFILE"
+ },
+ {
+ "Name": "modemenu_mode_filter",
+ "DefaultValue": "-1"
}
],
"Scripts": [
diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt
index 29d7cddf..f7c5ee2d 100644
--- a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt
+++ b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt
@@ -324,6 +324,18 @@ Press Yes if you agree to this. This choice can be changed in the mods menu at a
"JSON_PARSE_ERROR" "Error parsing json response"
"UNSUPPORTED_VERSION" "The version you are using is no longer supported"
+ // Mode menu
+ "MODE_MENU_PVPVE" "PvPvE"
+ "MODE_MENU_PVE" "PvE"
+ "MODE_MENU_PVP" "PvP"
+ "MODE_MENU_FFA" "FFA"
+ "MODE_MENU_TITAN_ONLY" "Titan Only"
+ "MODE_MENU_OTHER" "Other"
+ "MODE_MENU_CUSTOM" "Custom"
+ "MODE_MENU_ALL" "All"
+ "MODE_MENU_UNKNOWN" "Unknown"
+ "MODE_MENU_SWITCH" "Filter"
+
"AUTHENTICATION_FAILED_HEADER" "Authentication Failed"
"AUTHENTICATION_FAILED_BODY" "Failed to authenticate with Atlas!"
"AUTHENTICATION_FAILED_ERROR_CODE" "Error code: ^DB6F2C00%s1^"
diff --git a/Northstar.Client/mod/resource/ui/menus/mode_select.menu b/Northstar.Client/mod/resource/ui/menus/mode_select.menu
index e0f51105..bf07164e 100644
--- a/Northstar.Client/mod/resource/ui/menus/mode_select.menu
+++ b/Northstar.Client/mod/resource/ui/menus/mode_select.menu
@@ -38,33 +38,53 @@ resource/ui/menus/mode_select.menu
controlSettingsFile "resource/ui/menus/panels/matchmaking_status.res"
}
- NextModeImageFrame
- {
- ControlName RuiPanel
- xpos 800
+ MenuTitle
+ {
+ ControlName Label
+ InheritProperties MenuTitle
+ labelText "#SELECT_GAME_MODE"
+ }
+
+ ButtonRowAnchor
+ {
+ ControlName Label
+ labelText ""
+
+ xpos 96
+ ypos 140
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// NEXT MODE PANEL
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ NextModeImageFrame
+ {
+ ControlName RuiPanel
+ xpos 740
ypos 160
wide 860
- tall 418
- labelText ""
- visible 1
- bgcolor_override "0 0 0 0"
- paintbackground 1
- rui "ui/basic_border_box.rpak"
- }
+ tall 520
+ labelText ""
+ visible 1
+ bgcolor_override "0 0 0 0"
+ paintbackground 1
+ rui "ui/control_options_description.rpak"
+ }
NextModeImage
{
ControlName RuiPanel
pin_to_sibling NextModeImageFrame
- pin_corner_to_sibling BOTTOM
- pin_to_sibling_corner BOTTOM
-// xpos -12
- ypos -12
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner TOP_LEFT
+ xpos 0
+ ypos 14
wide 480
tall 240
visible 1
scaleImage 1
- rui "ui/basic_menu_image.rpak"
+ rui "ui/basic_menu_image.rpak"
zpos 2
}
@@ -80,23 +100,24 @@ resource/ui/menus/mode_select.menu
tall 72
visible 1
scaleImage 1
- rui "ui/basic_image_add.rpak"
+ rui "ui/basic_image_add.rpak"
zpos 2
}
NextModeName
{
ControlName Label
- pin_to_sibling NextModeImageFrame
- pin_corner_to_sibling TOP
- pin_to_sibling_corner TOP
- ypos -20
+ pin_to_sibling NextModeImage
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ ypos -10
+ xpos -10
wide 840
auto_tall_tocontents 1
visible 1
labelText "Foo"
- textAlignment center
- centerWrap 1
+ //textAlignment center
+ //centerWrap 1
font Default_43_DropShadow
allcaps 1
fgcolor_override "255 255 255 255"
@@ -106,219 +127,463 @@ resource/ui/menus/mode_select.menu
{
ControlName Label
pin_to_sibling NextModeName
- pin_corner_to_sibling TOP
- pin_to_sibling_corner BOTTOM
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
xpos 0
- ypos 0
+ ypos 10
wide 840
wrap 1
auto_tall_tocontents 1
visible 1
labelText "Bar"
- textAlignment center
- centerWrap 1
+ //textAlignment center
+ //centerWrap 1
font Default_27
allcaps 0
fgcolor_override "255 255 255 255"
}
- MenuTitle
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// FILTERS PANEL
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ FiltersPanel
{
- ControlName Label
- InheritProperties MenuTitle
- labelText "#SELECT_GAME_MODE"
+ ControlName RuiPanel
+ xpos 740
+ ypos 682
+ wide 860
+ tall 156
+ zpos -1
+
+ rui "ui/control_options_description.rpak"
}
- ButtonRowAnchor
+ BtnModeLabel
{
- ControlName Label
- labelText ""
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ labelText "#SEARCHBAR_LABEL"
+ textAlignment west
+ classname FilterPanelChild
- xpos 96
- ypos 160
+ wide 500
+ xpos -18
+ ypos -16
+
+ pin_to_sibling FiltersPanel
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner TOP_LEFT
+ }
+
+ BtnModeSearch
+ {
+ ControlName TextEntry
+ classname FilterPanelChild
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ xpos -400
+ ypos -5
+ wide 390
+ tall 30
+ textHidden 0
+ editable 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 1
+
+ pin_to_sibling BtnModeLabel
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner TOP_RIGHT
+ }
+
+ SwtModeLabel
+ {
+ ControlName RuiButton
+ InheritProperties SwitchButton
+ labelText "#MODE_MENU_FILTER"
+ ConVar "modemenu_mode_filter"
+ classname FilterPanelChild
+ wide 500
+ ypos 2
+
+ pin_to_sibling BtnModeLabel
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode1
+ BtnModeFiltersClear
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
- scriptID 0
- navUp BtnMode15
- navDown BtnMode2
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ labelText "#CLEAR_FILTERS"
+ textAlignment west
+ classname FilterPanelChild
- pin_to_sibling ButtonRowAnchor
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner TOP_LEFT
+ wide 100
+ ypos 2
+
+ pin_to_sibling SwtModeLabel
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode2
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// PANELS LIST
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ Panel1
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName CNestedPanel
+ classname ModeSelectorPanel
scriptID 1
- pin_to_sibling BtnMode1
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode1
- navDown BtnMode3
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling ButtonRowAnchor
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode3
+
+ Panel2
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 2
- pin_to_sibling BtnMode2
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode2
- navDown BtnMode4
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel1
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode4
+
+ Panel3
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 3
- pin_to_sibling BtnMode3
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- //ypos 11
- navUp BtnMode3
- navDown BtnMode5
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel2
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode5
+
+ Panel4
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 4
- pin_to_sibling BtnMode4
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode4
- navDown BtnMode6
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel3
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode6
+
+ Panel5
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 5
- pin_to_sibling BtnMode5
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode5
- navDown BtnMode7
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel4
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode7
+
+ Panel6
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 6
- pin_to_sibling BtnMode6
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode6
- navDown BtnMode8
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel5
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode8
+
+ Panel7
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 7
- pin_to_sibling BtnMode7
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode7
- navDown BtnMode9
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel6
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode9
+
+ Panel8
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 8
- pin_to_sibling BtnMode8
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode8
- navDown BtnMode10
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel7
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode10
+
+ Panel9
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 9
- pin_to_sibling BtnMode9
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode9
- navDown BtnMode11
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel8
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode11
+
+ Panel10
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 10
- pin_to_sibling BtnMode10
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode10
- navDown BtnMode12
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel9
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode12
+
+ Panel11
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 11
- pin_to_sibling BtnMode11
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode11
- navDown BtnMode13
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel10
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode13
+
+ Panel12
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 12
- pin_to_sibling BtnMode12
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode12
- navDown BtnMode14
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel11
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode14
+
+ Panel13
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 13
- pin_to_sibling BtnMode13
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode13
- navDown BtnMode15
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel12
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
- BtnMode15
+
+ Panel14
{
- ControlName RuiButton
- InheritProperties RuiSmallButton
- classname ModeButton
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
scriptID 14
- pin_to_sibling BtnMode14
- pin_corner_to_sibling TOP_LEFT
- pin_to_sibling_corner BOTTOM_LEFT
- navUp BtnMode14
- navDown BtnMode1
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel13
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ Panel15
+ {
+ ControlName "CNestedPanel"
+ classname ModeSelectorPanel
+ scriptID 15
+
+ controlSettingsFile "resource/ui/menus/panels/mode_select_button.res"
+ wide %100
+ tall 45
+
+ pin_to_sibling Panel14
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// SLIDER
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ BtnModeListUpArrow
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ //labelText "A"
+ wide 40
+ tall 40
+ xpos 2
+ ypos 2
+
+ image "vgui/hud/white"
+ drawColor "255 255 255 128"
+
+ pin_to_sibling NextModeImageFrame
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_LEFT
+ }
+
+ BtnModeListUpArrowPanel
+ {
+ ControlName RuiPanel
+ wide 40
+ tall 40
+ xpos 2
+ ypos 2
+
+ rui "ui/control_options_description.rpak"
+
+ visible 1
+ zpos -1
+
+ pin_to_sibling NextModeImageFrame
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_LEFT
+ }
+
+ BtnModeListDownArrow
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ //labelText "V"
+ wide 40
+ tall 40
+ xpos 2
+ ypos -639
+
+ image "vgui/hud/white"
+ drawColor "255 255 255 128"
+
+ pin_to_sibling NextModeImageFrame
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_LEFT
+ }
+
+ BtnModeListDownArrowPanel
+ {
+ ControlName RuiPanel
+ wide 40
+ tall 40
+ xpos 2
+ ypos -639
+
+ rui "ui/control_options_description.rpak"
+
+ visible 1
+ zpos -1
+
+ pin_to_sibling NextModeImageFrame
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_LEFT
+ }
+
+ BtnModeListSlider
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ //labelText "V"
+ wide 40
+ tall 599
+ xpos 2
+ ypos -42
+ zpos 0
+
+ image "vgui/hud/white"
+ drawColor "255 255 255 128"
+
+ pin_to_sibling NextModeImageFrame
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_LEFT
+ }
+
+ BtnModeListSliderPanel
+ {
+ ControlName RuiPanel
+ wide 40
+ tall 599
+ xpos 2
+ ypos -42
+
+ rui "ui/control_options_description.rpak"
+
+ visible 1
+ zpos -1
+
+ pin_to_sibling NextModeImageFrame
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_LEFT
+ }
+
+ // sh_menu_models.gnut has a global function which gets called when
+ // left mouse button gets called while hovering and has mouse
+ // deltaX; deltaY which we can yoink for ourselfes
+ MouseMovementCapture
+ {
+ ControlName CMouseMovementCapturePanel
+ wide 40
+ tall 562
+ xpos 2
+ ypos -42
+ zpos 1
+
+ pin_to_sibling NextModeImageFrame
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_LEFT
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/Northstar.Client/mod/resource/ui/menus/panels/mode_select_button.res b/Northstar.Client/mod/resource/ui/menus/panels/mode_select_button.res
new file mode 100644
index 00000000..b361e4fa
--- /dev/null
+++ b/Northstar.Client/mod/resource/ui/menus/panels/mode_select_button.res
@@ -0,0 +1,31 @@
+resource/ui/menus/panels/mode_select_button.res
+{
+ BtnMode
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ labelText "please show up"
+ wide 600
+ tall 45
+
+ pin_to_sibling ControlBox
+ pin_corner_to_sibling LEFT
+ pin_to_sibling_corner RIGHT
+ }
+
+ Header
+ {
+ ControlName Label
+ InheritProperties RuiSmallButton
+ wide 600
+ labelText "labelText"
+ font Default_41
+ fgcolor_override "255 255 255 255"
+ tall 45
+
+ pin_to_sibling ControlBox
+ pin_corner_to_sibling LEFT
+ pin_to_sibling_corner RIGHT
+ }
+}
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 605af383..6cddee2a 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/menu_mode_select.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_mode_select.nut
@@ -1,81 +1,551 @@
+untyped
global function InitModesMenu
+global function NSSetModeCategory
+
+global enum eModeMenuModeCategory
+{
+ UNKNOWN = 0,
+ PVPVE = 1,
+ PVE = 2,
+ PVP = 3,
+ FFA = 4,
+ TITAN = 5,
+ OTHER = 6,
+ CUSTOM = 7
+
+ SIZE
+}
+
+// List of blocked modes due to them being unfinished
+const array<string> blockedModes =
+[
+ "fd_easy",
+ "fd_normal",
+ "fd_hard",
+ "fd_master",
+ "fd_insane"
+]
+
+struct ListEntry_t {
+ string mode
+ int category
+}
+
+// Slider mouse delta buffer
+struct {
+ int deltaX = 0
+ int deltaY = 0
+} mouseDeltaBuffer
struct {
- int currentModePage
+ int scrollOffset
+ var menu
+
+ string searchString
+ int searchEnum
+
+ // Table of category overrides
+ table<string,int> categoryOverrides
+
+ // List of all modes we know
+ array<ListEntry_t> modes
+
+ // Sorted list of modes we want to show with categories included
+ array<string> sortedModes
} file
const int MODES_PER_PAGE = 15
void function InitModesMenu()
{
- var menu = GetMenu( "ModesMenu" )
+ file.menu = GetMenu( "ModesMenu" )
+
+ AddMouseMovementCaptureHandler( Hud_GetChild( file.menu, "MouseMovementCapture"), UpdateMouseDeltaBuffer )
+
+ AddMenuEventHandler( file.menu, eUIEvent.MENU_CLOSE, OnCloseModesMenu )
+ AddMenuEventHandler( file.menu, eUIEvent.MENU_OPEN, OnOpenModesMenu )
+ AddButtonEventHandler( Hud_GetChild( file.menu, "BtnModeListUpArrow"), UIE_CLICK, OnUpArrowSelected )
+ AddButtonEventHandler( Hud_GetChild( file.menu, "BtnModeListDownArrow"), UIE_CLICK, OnDownArrowSelected )
- AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnOpenModesMenu )
+ AddButtonEventHandler( Hud_GetChild( file.menu, "BtnModeLabel"), UIE_CHANGE, FilterAndUpdateList )
+ AddButtonEventHandler( Hud_GetChild( file.menu, "BtnModeSearch"), UIE_CHANGE, FilterAndUpdateList )
+ AddButtonEventHandler( Hud_GetChild( file.menu, "SwtModeLabel"), UIE_CHANGE, FilterAndUpdateList )
- AddEventHandlerToButtonClass( menu, "ModeButton", UIE_GET_FOCUS, ModeButton_GetFocus )
- AddEventHandlerToButtonClass( menu, "ModeButton", UIE_CLICK, ModeButton_Click )
+ AddButtonEventHandler( Hud_GetChild( file.menu, "BtnModeFiltersClear"), UIE_CLICK, OnBtnFiltersClear_Activate )
+
+ array<var> buttons = GetElementsByClassname( file.menu, "ModeSelectorPanel" )
+ foreach ( var panel in buttons )
+ {
+ AddEventHandlerToButton( panel, "BtnMode", UIE_GET_FOCUS, ModeButton_GetFocus )
+ AddEventHandlerToButton( panel, "BtnMode", UIE_CLICK, ModeButton_Click )
+ }
- AddMenuFooterOption( menu, BUTTON_A, "#A_BUTTON_SELECT" )
- AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
-
- AddMenuFooterOption( menu, BUTTON_SHOULDER_LEFT, "#PRIVATE_MATCH_PAGE_PREV", "#PRIVATE_MATCH_PAGE_PREV", CycleModesBack )
- AddMenuFooterOption( menu, BUTTON_SHOULDER_RIGHT, "#PRIVATE_MATCH_PAGE_NEXT", "#PRIVATE_MATCH_PAGE_NEXT", CycleModesForward )
+ Hud_SetText( Hud_GetChild( file.menu, "SwtModeLabel" ), "#MODE_MENU_SWITCH" )
+ SetButtonRuiText( Hud_GetChild( file.menu, "SwtModeLabel" ), "" )
+ Hud_DialogList_AddListItem( Hud_GetChild( file.menu, "SwtModeLabel" ) , "#MODE_MENU_ALL", "-1" )
+ for( int i = 0; i < eModeMenuModeCategory.SIZE; i++ )
+ {
+ Hud_DialogList_AddListItem( Hud_GetChild( file.menu, "SwtModeLabel" ) , GetCategoryStringFromEnum(i), string(i) )
+ }
+
+ AddMenuFooterOption( file.menu, BUTTON_A, "#A_BUTTON_SELECT" )
+ AddMenuFooterOption( file.menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
+}
+
+void function NSSetModeCategory( string mode, int category )
+{
+ if( mode in file.categoryOverrides )
+ {
+ file.categoryOverrides[mode] = category
+ printt( "Overwriting category for mode:", mode )
+ return
+ }
+
+ file.categoryOverrides[mode] <- category
+}
+
+void function OnBtnFiltersClear_Activate( var b )
+{
+ file.searchString = ""
+ file.searchEnum = -1
+
+ SetConVarInt( "modemenu_mode_filter", -1 )
+ Hud_SetText( Hud_GetChild( file.menu, "BtnModeSearch"), "" )
+
+ file.scrollOffset = 0
+
+ BuildSortedModesArray()
+ UpdateListSliderHeight(float(file.sortedModes.len()))
+ UpdateListSliderPosition(file.sortedModes.len())
+ UpdateVisibleModes()
+}
+
+void function FilterAndUpdateList( var n )
+{
+ file.searchString = Hud_GetUTF8Text( Hud_GetChild( file.menu, "BtnModeSearch" ) )
+ file.searchEnum = GetConVarInt( "modemenu_mode_filter" )
+
+ file.scrollOffset = 0
+
+ BuildSortedModesArray()
+ UpdateListSliderHeight(float(file.sortedModes.len()))
+ UpdateListSliderPosition(file.sortedModes.len())
+ UpdateVisibleModes()
}
void function OnOpenModesMenu()
{
+ RegisterButtonPressedCallback( MOUSE_WHEEL_UP , OnScrollUp )
+ RegisterButtonPressedCallback( MOUSE_WHEEL_DOWN , OnScrollDown )
+
+ // Reset filters
+ file.searchString = ""
+ file.searchEnum = -1
+
+ // We rebuild the modes array on open menu to make sure
+ // all modes get listed
+ BuildModesArray()
+ BuildSortedModesArray()
+
+ UpdateListSliderHeight(float(file.sortedModes.len()))
+ UpdateListSliderPosition(file.sortedModes.len())
UpdateVisibleModes()
-
- if ( level.ui.privatematch_mode == 0 ) // set to the first mode if there's no mode focused
- Hud_SetFocused( GetElementsByClassname( GetMenu( "ModesMenu" ), "ModeButton" )[ 0 ] )
+
+ // Set to the first mode if there's no mode focused
+ if ( level.ui.privatematch_mode == 0 )
+ {
+ array<var> panels = GetElementsByClassname( file.menu, "ModeSelectorPanel" )
+ foreach( var panel in panels )
+ {
+ if( Hud_IsEnabled( Hud_GetChild( panel, "BtnMode") ) )
+ {
+ Hud_SetFocused( Hud_GetChild( panel, "BtnMode") )
+ break
+ }
+ }
+ }
+}
+
+void function OnCloseModesMenu()
+{
+ try
+ {
+ DeregisterButtonPressedCallback( MOUSE_WHEEL_UP , OnScrollUp )
+ DeregisterButtonPressedCallback( MOUSE_WHEEL_DOWN , OnScrollDown )
+ }
+ catch ( ex ) {}
}
+string function GetCategoryStringFromEnum( int category )
+{
+ switch( category )
+ {
+ case eModeMenuModeCategory.PVPVE: return "#MODE_MENU_PVPVE"
+ case eModeMenuModeCategory.PVE: return "#MODE_MENU_PVE"
+ case eModeMenuModeCategory.PVP: return "#MODE_MENU_PVP"
+ case eModeMenuModeCategory.FFA: return "#MODE_MENU_FFA"
+ case eModeMenuModeCategory.TITAN: return "#MODE_MENU_TITAN_ONLY"
+ case eModeMenuModeCategory.OTHER: return "#MODE_MENU_OTHER"
+ case eModeMenuModeCategory.CUSTOM: return "#MODE_MENU_CUSTOM"
+ }
+
+ return "#MODE_MENU_UNKNOWN"
+}
+
+void function BuildModesArray()
+{
+ file.modes.clear()
+
+ foreach( string mode in GetPrivateMatchModes() )
+ {
+ ListEntry_t entry
+ entry.mode = mode
+ entry.category = eModeMenuModeCategory.UNKNOWN
+
+ switch( mode )
+ {
+ case "aitdm":
+ case "at":
+ entry.category = eModeMenuModeCategory.PVPVE
+ break
+ case "fd_easy":
+ case "fd_normal":
+ case "fd_hard":
+ case "fd_master":
+ case "fd_insane":
+ entry.category = eModeMenuModeCategory.PVE
+ break
+ case "tdm":
+ case "ctf":
+ case "mfd":
+ case "ps":
+ case "cp":
+ case "speedball":
+ case "rocket_lf":
+ case "holopilot_lf":
+ entry.category = eModeMenuModeCategory.PVP
+ break
+ case "ffa":
+ case "fra":
+ entry.category = eModeMenuModeCategory.FFA
+ break
+ case "lts":
+ case "ttdm":
+ case "attdm":
+ case "turbo_ttdm":
+ case "alts":
+ case "turbo_lts":
+ entry.category = eModeMenuModeCategory.TITAN
+ break
+ case "coliseum":
+ case "sp_coop":
+ entry.category = eModeMenuModeCategory.OTHER
+ break
+ case "chamber":
+ case "hidden":
+ case "sns":
+ case "fw":
+ case "gg":
+ case "tt":
+ case "inf":
+ case "kr":
+ case "fastball":
+ case "hs":
+ case "ctf_comp":
+ case "tffa":
+ entry.category = eModeMenuModeCategory.CUSTOM
+ break
+ }
+
+ file.modes.append(entry)
+ }
+}
+
+int function SortModesAlphabetize( string a, string b )
+{
+ a = Localize( GetGameModeDisplayName( a ) )
+ b = Localize( GetGameModeDisplayName( b ) )
+
+ if ( a > b )
+ return 1
+
+ if ( a < b )
+ return -1
+
+ return 0
+}
+
+void function BuildSortedModesArray()
+{
+ file.sortedModes.clear()
+
+ // Build sorted list of categories
+ array<string> categories
+ for( int i = 0; i < eModeMenuModeCategory.SIZE; i++ )
+ {
+ if( file.searchEnum != -1 && file.searchEnum != i )
+ continue
+
+ categories.append( GetCategoryStringFromEnum( i ) )
+ }
+
+ categories.sort( SortStringAlphabetize )
+
+ // Build final list of mixed modes and categories
+ foreach( string category in categories )
+ {
+ // Build sorted list of modes in category
+ array<string> modes
+ foreach( ListEntry_t entry in file.modes )
+ {
+ int iCategory = entry.category
+ if( entry.mode in file.categoryOverrides )
+ iCategory = file.categoryOverrides[entry.mode]
+
+ if( GetCategoryStringFromEnum( iCategory ) != category )
+ continue
+
+ string mode = entry.mode
+
+ if( file.searchString != "" && Localize(GetGameModeDisplayName(mode)).tolower().find(file.searchString.tolower()) == null )
+ continue
+
+ if( !modes.contains(mode) )
+ modes.append( mode )
+ }
+
+ modes.sort( SortModesAlphabetize )
+
+ if( modes.len() == 0 )
+ continue
+
+ // Add to final list we then display
+ file.sortedModes.append( category )
+ foreach( string mode in modes )
+ file.sortedModes.append( mode )
+ }
+}
+
+////////////////////////////
+// Slider
+////////////////////////////
+void function UpdateMouseDeltaBuffer( int x, int y )
+{
+ mouseDeltaBuffer.deltaX += x
+ mouseDeltaBuffer.deltaY += y
+
+ SliderBarUpdate()
+}
+
+void function FlushMouseDeltaBuffer()
+{
+ mouseDeltaBuffer.deltaX = 0
+ mouseDeltaBuffer.deltaY = 0
+}
+
+
+void function SliderBarUpdate()
+{
+ if( file.sortedModes.len() < MODES_PER_PAGE )
+ return
+
+ var sliderButton = Hud_GetChild( file.menu , "BtnModeListSlider" )
+ var sliderPanel = Hud_GetChild( file.menu , "BtnModeListSliderPanel" )
+ var movementCapture = Hud_GetChild( file.menu , "MouseMovementCapture" )
+
+ Hud_SetFocused( sliderButton )
+
+ int[2] screenSize = GetScreenSize()
+ float minYPos = -40.0 * ( screenSize[1] / 1080.0 )
+ float maxHeight = 596.0 * ( screenSize[1] / 1080.0 )
+ float maxYPos = minYPos - ( maxHeight - Hud_GetHeight( sliderPanel ) )
+ float useableSpace = maxHeight - Hud_GetHeight( sliderPanel )
+
+ float jump = minYPos - ( useableSpace / ( float( file.sortedModes.len() ) ) )
+
+ // got local from official respaw scripts, without untyped throws an error
+ local pos = Hud_GetPos( sliderButton )[1]
+ local newPos = pos - mouseDeltaBuffer.deltaY
+ FlushMouseDeltaBuffer()
+
+ if ( newPos < maxYPos ) newPos = maxYPos
+ if ( newPos > minYPos ) newPos = minYPos
+
+ Hud_SetPos( sliderButton , 2, newPos )
+ Hud_SetPos( sliderPanel , 2, newPos )
+ Hud_SetPos( movementCapture , 2, newPos )
+
+ file.scrollOffset = -int( ( ( newPos - minYPos ) / useableSpace ) * ( file.sortedModes.len() - MODES_PER_PAGE ) )
+ UpdateVisibleModes()
+}
+
+void function UpdateListSliderHeight( float modes )
+{
+ var sliderButton = Hud_GetChild( file.menu , "BtnModeListSlider" )
+ var sliderPanel = Hud_GetChild( file.menu , "BtnModeListSliderPanel" )
+ var movementCapture = Hud_GetChild( file.menu , "MouseMovementCapture" )
+
+ int[2] screenSize = GetScreenSize()
+ float maxHeight = 596.0 * ( screenSize[1] / 1080.0 )
+ float minHeight = 80.0 * ( screenSize[1] / 1080.0 )
+
+ float height = maxHeight * ( MODES_PER_PAGE / modes )
+
+ if ( height > maxHeight ) height = maxHeight
+ if ( height < minHeight ) height = minHeight
+
+ Hud_SetHeight( sliderButton, height )
+ Hud_SetHeight( sliderPanel, height )
+ Hud_SetHeight( movementCapture, height )
+}
+
+
+void function UpdateListSliderPosition( int modes )
+{
+ if( modes < MODES_PER_PAGE )
+ return
+
+ var sliderButton = Hud_GetChild( file.menu, "BtnModeListSlider" )
+ var sliderPanel = Hud_GetChild( file.menu, "BtnModeListSliderPanel" )
+ var movementCapture = Hud_GetChild( file.menu, "MouseMovementCapture" )
+
+ float minYPos = -40.0 * ( GetScreenSize()[1] / 1080.0 )
+ float useableSpace = (596.0 * ( GetScreenSize()[1] / 1080.0 ) - Hud_GetHeight( sliderPanel ) )
+
+ float jump = minYPos - ( useableSpace / ( float( modes ) - MODES_PER_PAGE ) * file.scrollOffset )
+
+ if ( jump > minYPos ) jump = minYPos
+
+ Hud_SetPos( sliderButton, 2, jump )
+ Hud_SetPos( sliderPanel, 2, jump )
+ Hud_SetPos( movementCapture, 2, jump )
+}
+
+void function OnScrollDown( var button )
+{
+ if (file.sortedModes.len() <= MODES_PER_PAGE) return
+ file.scrollOffset += 5
+ if (file.scrollOffset + MODES_PER_PAGE > file.sortedModes.len()) {
+ file.scrollOffset = file.sortedModes.len() - MODES_PER_PAGE
+ }
+ UpdateVisibleModes()
+ UpdateListSliderPosition( file.sortedModes.len() )
+}
+
+void function OnScrollUp( var button )
+{
+ file.scrollOffset -= 5
+ if ( file.scrollOffset < 0 ) {
+ file.scrollOffset = 0
+ }
+ UpdateVisibleModes()
+ UpdateListSliderPosition( file.sortedModes.len() )
+}
+
+void function OnDownArrowSelected( var button )
+{
+ if ( file.sortedModes.len() <= MODES_PER_PAGE ) return
+ file.scrollOffset += 1
+ if ( file.scrollOffset + MODES_PER_PAGE > file.sortedModes.len() )
+ {
+ file.scrollOffset = file.sortedModes.len() - MODES_PER_PAGE
+ }
+
+ UpdateVisibleModes()
+ UpdateListSliderPosition( file.sortedModes.len() )
+}
+
+
+void function OnUpArrowSelected( var button )
+{
+ file.scrollOffset -= 1
+ if ( file.scrollOffset < 0 )
+ {
+ file.scrollOffset = 0
+ }
+
+ UpdateVisibleModes()
+ UpdateListSliderPosition( file.sortedModes.len() )
+}
+
+bool function IsStringCategory( string str )
+{
+ return GetGameModeDisplayName( str ) == ""
+}
+
+/////////////////////////////
+// LIST
+/////////////////////////////
+
void function UpdateVisibleModes()
-{
+{
// ensures that we only ever show enough buttons for the number of modes we have
- array<var> buttons = GetElementsByClassname( GetMenu( "ModesMenu" ), "ModeButton" )
- foreach ( var button in buttons )
+ array<var> buttons = GetElementsByClassname( GetMenu( "ModesMenu" ), "ModeSelectorPanel" )
+ foreach ( var panel in buttons )
{
- Hud_SetEnabled( button, false )
- Hud_SetVisible( button, false )
+ Hud_SetEnabled( panel, false )
+ Hud_SetVisible( panel, false )
+ Hud_SetText( Hud_GetChild( panel, "Header" ), "" )
+ Hud_SetText( Hud_GetChild( panel, "BtnMode" ), "" )
+ SetButtonRuiText( Hud_GetChild( panel, "BtnMode" ), "" )
}
-
- array<string> modesArray = GetPrivateMatchModes()
+
for ( int i = 0; i < MODES_PER_PAGE; i++ )
{
- if ( i + ( file.currentModePage * MODES_PER_PAGE ) >= modesArray.len() )
+ if ( i + file.scrollOffset >= file.sortedModes.len() )
break
-
- int modeIndex = i + ( file.currentModePage * MODES_PER_PAGE )
- SetButtonRuiText( buttons[ i ], GetGameModeDisplayName( modesArray[ modeIndex ] ) )
-
- Hud_SetEnabled( buttons[ i ], true )
- Hud_SetVisible( buttons[ i ], true )
-
- // This check is refactored in the new mode menu so we can just ignore this atrocity
- if ( !ModeSettings_RequiresAI( modesArray[ modeIndex ] ) || modesArray[ modeIndex ] == "aitdm" || modesArray[ modeIndex ] == "at" )
- Hud_SetLocked( buttons[ i ], false )
+
+ // Setup locals
+ var panel = buttons[i]
+ var button = Hud_GetChild( panel, "BtnMode" )
+ var header = Hud_GetChild( panel, "Header" )
+
+ int modeIndex = i + file.scrollOffset
+ string mode = file.sortedModes[ modeIndex ]
+
+ bool bIsCategory = IsStringCategory( mode )
+ mode = bIsCategory ? mode : GetGameModeDisplayName( mode )
+
+ // Show the panel
+ Hud_SetEnabled( panel, true )
+ Hud_SetVisible( panel, true )
+ Hud_SetLocked( button, false )
+
+ if( bIsCategory )
+ {
+ Hud_SetText( header, mode )
+ Hud_SetEnabled( button, false )
+ }
else
- Hud_SetLocked( buttons[ i ], true )
+ {
+ Hud_SetEnabled( button, true )
+ SetButtonRuiText( button, mode )
+
+ if( blockedModes.contains( file.sortedModes[ modeIndex ] ) )
+ Hud_SetLocked( button, true )
+
+ if ( !PrivateMatch_IsValidMapModeCombo( PrivateMatch_GetSelectedMap(), mode ) )
+ {
+ Hud_SetLocked( button, true )
+ SetButtonRuiText( button, mode )
+ }
+ }
}
}
void function ModeButton_GetFocus( var button )
{
- int modeId = int( Hud_GetScriptID( button ) ) + ( file.currentModePage * MODES_PER_PAGE )
-
- var menu = GetMenu( "ModesMenu" )
- var nextModeImage = Hud_GetChild( menu, "NextModeImage" )
- var nextModeIcon = Hud_GetChild( menu, "ModeIconImage" )
- var nextModeName = Hud_GetChild( menu, "NextModeName" )
- var nextModeDesc = Hud_GetChild( menu, "NextModeDesc" )
+ int modeId = int( Hud_GetScriptID( Hud_GetParent( button ) ) ) + file.scrollOffset - 1
- array<string> modesArray = GetPrivateMatchModes()
+ var nextModeImage = Hud_GetChild( file.menu, "NextModeImage" )
+ var nextModeIcon = Hud_GetChild( file.menu, "ModeIconImage" )
+ var nextModeName = Hud_GetChild( file.menu, "NextModeName" )
+ var nextModeDesc = Hud_GetChild( file.menu, "NextModeDesc" )
- if ( modeId > modesArray.len() )
+ if ( modeId > file.sortedModes.len() )
return
- string modeName = modesArray[modeId]
+ string modeName = file.sortedModes[modeId]
asset playlistImage = GetPlaylistImage( modeName )
RuiSetImage( Hud_GetRui( nextModeImage ), "basicImage", playlistImage )
@@ -99,35 +569,17 @@ void function ModeButton_Click( var button )
if ( Hud_IsLocked( button ) )
return
- int modeID = int( Hud_GetScriptID( button ) ) + ( file.currentModePage * MODES_PER_PAGE )
+ int modeID = int( Hud_GetScriptID( Hud_GetParent( button ) ) ) + file.scrollOffset - 1
- array<string> modesArray = GetPrivateMatchModes()
- string modeName = modesArray[ modeID ]
+ string modeName = file.sortedModes[ modeID ]
// on modded servers set us to the first map for that mode automatically
// need this for coliseum mainly which is literally impossible to select without this
- if ( !PrivateMatch_IsValidMapModeCombo( PrivateMatch_GetSelectedMap(), modesArray[ modeID ] ) )
+ if ( !PrivateMatch_IsValidMapModeCombo( PrivateMatch_GetSelectedMap(), modeName ) )
+ {
ClientCommand( "SetCustomMap " + GetPrivateMatchMapsForMode( modeName )[ 0 ] )
-
+ }
// set it
ClientCommand( "PrivateMatchSetMode " + modeName )
CloseActiveMenu()
}
-
-void function CycleModesBack( var button )
-{
- if ( file.currentModePage == 0 )
- return
-
- file.currentModePage--
- UpdateVisibleModes()
-}
-
-void function CycleModesForward( var button )
-{
- if ( ( file.currentModePage + 1 ) * MODES_PER_PAGE >= GetPrivateMatchModes().len() )
- return
-
- file.currentModePage++
- UpdateVisibleModes()
-} \ No newline at end of file