From d2a7bcbfed51494caa11da1e1376b21feb6976d6 Mon Sep 17 00:00:00 2001 From: EladNLG Date: Wed, 24 May 2023 20:11:04 +0300 Subject: Add Mod Settings (#518) * Add Mod Settings * Make rounding optional * Add recursive search * too much shit Add custom buttons, expand menu further, sanitize display names, cleanup, add more descriptive errors and throw them early, rework slightly func params * Remove Test Stuff * Clean-Up * Revert mod version change * Replace GetIndex with PureModulo better, more understandable version of the function. * Fix Slider bug * Fix Localization * Add eject quotes (#527) * Upload cl_titan_cockpit.nut * Add eject string in script * Moved to client * index issue + removed else so always returns * Apply suggestions from code review Co-authored-by: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> * Rest of the suggestions because github makes me want to cry * Commit suggestions from review GitHub really hates batching suggestions Co-authored-by: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> * Update localization * Update Northstar.Client/mod/scripts/vscripts/ui/menu_mod_settings.nut From ASpoonPlaysGames Co-authored-by: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> * Update Northstar.Client/mod.json From ASpoonPlaysames Co-authored-by: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> * Update Northstar.Client/mod/scripts/vscripts/ui/menu_mod_settings.nut From ASpoonPlaysGames Co-authored-by: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> * Delete cl_titan_cockpit.nut * Apply suggestions from Spoon's code review Co-authored-by: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> * Formatting for ModSettings + Remove Base Northstar Settings (#1) * fix formatting * add newline * formatting part 1 * formatting part 2 * formatting again Co-authored-by: EladNLG * reset vmt (#2) * reset vmt * formatting * more formatting * Fixes, color modification * Fix Image behind button & make image clickable using a hack because imagepanels don't get click events and i hate them * Formatting Fixes The First * Apply suggestions from Spoon's review Co-authored-by: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> * Formatting Fixes The Second * Fix reset popup appearing when not clicking on button * Fix only being able to type 1 char at a time * Fix more bugs - never being able to get out of modsettings dialogs - setting duplication glitch * Fix alignment * add no results/mods (need localization) * he forgor :( make addmodsettingsbutton global Co-authored-by: uniboi <64006268+uniboi@users.noreply.github.com> * Clean up (thanks @uniboi) Co-authored-by: uniboi <64006268+uniboi@users.noreply.github.com> * forgot to add this too Co-authored-by: uniboi <64006268+uniboi@users.noreply.github.com> * Mod settings submenus (#4) * allow for submenu closing * hide reset vgui on buttons * My code got GECKO'd gecko suggestions Co-authored-by: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: uniboi <64006268+uniboi@users.noreply.github.com> * uniboi fixing his own mistakes moment + more prints removed (thanks @uniboi) Co-authored-by: uniboi <64006268+uniboi@users.noreply.github.com> * aaaaaaaa Co-authored-by: uniboi <64006268+uniboi@users.noreply.github.com> * rename ms_slider * add a newline * add temporary aliases * fix aliases and localization * update button width for categories * fix resets accessing out of bounds index * allow unicode search * use correct index variable * update function names --------- Co-authored-by: JMM889901 <41163714+JMM889901@users.noreply.github.com> Co-authored-by: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> Co-authored-by: uniboi <64006268+uniboi@users.noreply.github.com> Co-authored-by: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> Co-authored-by: uniboi Co-authored-by: uniboi --- Northstar.Client/mod.json | 11 + Northstar.Client/mod/materials/vgui/reset.vmt | 12 + Northstar.Client/mod/materials/vgui/reset.vtf | Bin 0 -> 5712 bytes .../northstar_client_localisation_english.txt | 21 + .../northstar_client_localisation_french.txt | 18 + .../northstar_client_localisation_italian.txt | 18 + .../mod/resource/ui/menus/mod_settings.menu | 511 +++++++++ .../mod/resource/ui/menus/panels/mod_setting.res | 183 ++++ .../mod/scripts/vscripts/ui/menu_ingame.nut | 15 +- .../mod/scripts/vscripts/ui/menu_lobby.nut | 9 +- .../mod/scripts/vscripts/ui/menu_mod_settings.nut | 1105 ++++++++++++++++++++ .../mod/scripts/vscripts/ui/ns_slider.nut | 52 + .../mod/scripts/vscripts/ui/panel_mainmenu.nut | 4 + 13 files changed, 1952 insertions(+), 7 deletions(-) create mode 100644 Northstar.Client/mod/materials/vgui/reset.vmt create mode 100644 Northstar.Client/mod/materials/vgui/reset.vtf create mode 100644 Northstar.Client/mod/resource/ui/menus/mod_settings.menu create mode 100644 Northstar.Client/mod/resource/ui/menus/panels/mod_setting.res create mode 100644 Northstar.Client/mod/scripts/vscripts/ui/menu_mod_settings.nut create mode 100644 Northstar.Client/mod/scripts/vscripts/ui/ns_slider.nut diff --git a/Northstar.Client/mod.json b/Northstar.Client/mod.json index 54834676..e9536d66 100644 --- a/Northstar.Client/mod.json +++ b/Northstar.Client/mod.json @@ -115,6 +115,17 @@ "RunOn": "UI" }, { + "Path": "ui/ns_slider.nut", + "RunOn": "UI" + }, + { + "Path": "ui/menu_mod_settings.nut", + "RunOn": "UI", + "UICallback":{ + "Before": "AddModSettingsMenu" + } + }, + { "Path": "ui/ui_mouse_capture.nut", "RunOn": "UI" } diff --git a/Northstar.Client/mod/materials/vgui/reset.vmt b/Northstar.Client/mod/materials/vgui/reset.vmt new file mode 100644 index 00000000..84034586 --- /dev/null +++ b/Northstar.Client/mod/materials/vgui/reset.vmt @@ -0,0 +1,12 @@ +"Basic" +{ + "$basetexture" "vgui/reset" + "$translucent" 1 + "$vertexcolor" 1 + "$vertexalpha" 1 + "$no_fullbright" 1 + "$ignorez" 1 + "$nolod" 1 + + "$SHADERSRGBREAD360" 1 +} diff --git a/Northstar.Client/mod/materials/vgui/reset.vtf b/Northstar.Client/mod/materials/vgui/reset.vtf new file mode 100644 index 00000000..5ffb86a9 Binary files /dev/null and b/Northstar.Client/mod/materials/vgui/reset.vtf differ diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt index c25708a6..5dabd539 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt @@ -321,5 +321,26 @@ Press Yes if you agree to this. This choice can be changed in the mods menu at a "INVALID_MASTERSERVER_TOKEN" "Invalid or expired masterserver token" "JSON_PARSE_ERROR" "Error parsing json response" "UNSUPPORTED_VERSION" "The version you are using is no longer supported" + + // Mod Settings + "MOD_SETTINGS" "Mod Settings" + "NORTHSTAR_BASE_SETTINGS" "Northstar Base Settings" + "ONLY_HOST_MATCH_SETTINGS" "Only Host can change Private Match settings" + "ONLY_HOST_CAN_START_MATCH" "Only Host can Start the Match" + "MATCH_COUNTDOWN_LENGTH" "Private Match Countdown Duration" + "LOG_UNKNOWN_CLIENTCOMMANDS" "Log Unknown Client Commands" + "DISALLOWED_TACTICALS" "Prohibited Tacticals" + "TACTICAL_REPLACEMENT" "Replacement Tactical" + "DISALLOWED_WEAPONS" "Prohibited Weapons" + "REPLACEMENT_WEAPON" "Replacement Weapon" + "SHOULD_RETURN_TO_LOBBY" "Return To Lobby After Match End" + "ARE_YOU_SURE" "Are you sure?" + "WILL_RESET_ALL_SETTINGS" "This will reset ALL settings that belong to this category.\n\nThis is not revertable." + "WILL_RESET_SETTING" "This will reset the %s1 setting to it's default value.\n\nThis is not revertable." + "MOD_SETTINGS_SERVER" "Server" + "MOD_SETTINGS_RESET" "Reset" + "MOD_SETTINGS_RESET_ALL" "Reset All" + "NO_RESULTS" "No results." + "NO_MODS" "No settings available! Install more mods at ^5588FF00northstar.thunderstore.io^0." } } diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_french.txt b/Northstar.Client/mod/resource/northstar_client_localisation_french.txt index 2a199186..d90cea05 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_french.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_french.txt @@ -319,5 +319,23 @@ Choisissez Oui si vous êtes d'accord. Ce choix peut être modifié à tout inst "INVALID_MASTERSERVER_TOKEN" "Jeton du server maître invalide ou expiré" "JSON_PARSE_ERROR" "Une erreur est survenue durant l'analyse JSON" "UNSUPPORTED_VERSION" "La version que vous utilisez n'est plus supportée" + + "MOD_SETTINGS" "Paramètres de mod" + "NORTHSTAR_BASE_SETTINGS" "Paramètres de base de Northstar" + "ONLY_HOST_MATCH_SETTINGS" "Seul l'hôte peut changer les paramètres de match privé" + "ONLY_HOST_CAN_START_MATCH" "Seul l'hôte peut lancer le match" + "MATCH_COUNTDOWN_LENGTH" "Durée du compte à rebours de match privé" + "LOG_UNKNOWN_CLIENTCOMMANDS" "Enregistrer les commandes client inconnues" + "DISALLOWED_TACTICALS" "Capacités interdites" + "TACTICAL_REPLACEMENT" "Capacités de remplacement" + "DISALLOWED_WEAPONS" "Armes interdites" + "REPLACEMENT_WEAPON" "Armes de remplacement" + "SHOULD_RETURN_TO_LOBBY" "Retour au lobby après la fin du match" + "ARE_YOU_SURE" "Êtes-vous certain ?" + "WILL_RESET_ALL_SETTINGS" "Ceci réinitialisera tous les paramètres de cette catégorie.\n\nCette action est irréversible." + "WILL_RESET_SETTING" "Ceci réinitialisera le paramètre %s1 à sa valeur par défaut.\n\nCette action est irréversible." + "MOD_SETTINGS_SERVER" "Serveur" + "MOD_SETTINGS_RESET" "Réinitialiser" + "MOD_SETTINGS_RESET_ALL" "Tout réinitialiser" } } diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_italian.txt b/Northstar.Client/mod/resource/northstar_client_localisation_italian.txt index 72bf7030..13835b8b 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_italian.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_italian.txt @@ -319,5 +319,23 @@ Premi Sì se sei d'accordo. Questa scelta può essere modificata in qualsiasi mo "INVALID_MASTERSERVER_TOKEN" "Token Masterserver invalido o scaduto" "JSON_PARSE_ERROR" "Errore nell'analisi di risposta json" "UNSUPPORTED_VERSION" "La versione che stai usando non è più supportata" + + "MOD_SETTINGS" "Impostazioni Mod" + "NORTHSTAR_BASE_SETTINGS" "Impostazioni base Northstar" + "ONLY_HOST_MATCH_SETTINGS" "Solo l'Host può modificare le impostazioni della Partita Privata" + "ONLY_HOST_CAN_START_MATCH" "Solo l'Host può Iniziare la Partita" + "MATCH_COUNTDOWN_LENGTH" "Durata Countdown della Partita Privata" + "LOG_UNKNOWN_CLIENTCOMMANDS" "Registra Comandi Client Sconosciuti" + "DISALLOWED_TACTICALS" "Abilità Proibite" + "TACTICAL_REPLACEMENT" "Sostituzione Abilità" + "DISALLOWED_WEAPONS" "Armi Proibite" + "REPLACEMENT_WEAPON" "Sostituzione Armi" + "SHOULD_RETURN_TO_LOBBY" "Ritorna alla Lobby dopo Fine Partita" + "ARE_YOU_SURE" "Sei sicuro?" + "WILL_RESET_ALL_SETTINGS" "Questo ripristinerà TUTTE le impostazioni che appartengono a questa categoria.\n\nNON può essere annullato." + "WILL_RESET_SETTING" "Questo ripristinerà l'impostazione %s1 al suo valore predefinito.\n\nNON può essere annullato" // obviously, don't translate %s1. + "MOD_SETTINGS_SERVER" "Server" + "MOD_SETTINGS_RESET" "Ripristina" + "MOD_SETTINGS_RESET_ALL" "Ripristina Tutto" } } diff --git a/Northstar.Client/mod/resource/ui/menus/mod_settings.menu b/Northstar.Client/mod/resource/ui/menus/mod_settings.menu new file mode 100644 index 00000000..2fed2bd1 --- /dev/null +++ b/Northstar.Client/mod/resource/ui/menus/mod_settings.menu @@ -0,0 +1,511 @@ +"resource/ui/menus/mods_browse.menu" +{ + "menu" + { + "ControlName" "Frame" + "xpos" "0" + "ypos" "0" + "zpos" "3" + "wide" "f0" + "tall" "f0" + "autoResize" "1" + "visible" "1" + "enabled" "1" + "pinCorner" "0" + "PaintBackgroundType" "0" + "infocus_bgcolor_override" "0 0 0 0" + "outoffocus_bgcolor_override" "0 0 0 0" + "Vignette" + { + "ControlName" "ImagePanel" + "InheritProperties" "MenuVignette" + } + "Title" + { + "ControlName" "Label" + "InheritProperties" "MenuTitle" + "labelText" "#MOD_SETTINGS" + } + "ImgTopBar" + { + "ControlName" "ImagePanel" + "InheritProperties" "MenuTopBar" + } + "DarkenBackground" + { + "ControlName" "Label" + "classname" "ConnectingHUD" + "xpos" "0" + "ypos" "0" + "zpos" "99" + "wide" "%100" + "tall" "%100" + "labelText" "" + "bgcolor_override" "0 0 0 0" + "visible" "0" + "paintbackground" "1" + } + "ButtonRowAnchor" + { + "ControlName" "Label" + "labelText" "" + "pin_to_sibling" "DarkenBackground" + "pin_to_sibling_corner" "TOP_LEFT" + "pin_corner_to_sibling" "BOTTOM_LEFT" + "xpos" "-150" + "ypos" "-200" + } + "FilterButtonsRowAnchor" + { + "ControlName" "Label" + "pin_to_sibling" "LabelDetails" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "pin_corner_to_sibling" "TOP_LEFT" + "labelText" "" + "ypos" "12" + } + "NoResultLabel" + { + "ControlName" "Label" + "xpos" "0" + ypos "0" + wide "1200" + tall "675" + //auto_tall_tocontents 1 + visible "1" + enabled "1" + //auto_wide_tocontents 1 + labelText "No results." + textAlignment "center" + //auto_wide_tocontents "1" + //auto_tall_tocontents "1" + //fgcolor_override "255 255 255 255" + //bgcolor_override "0 0 0 200" + font Default_41 + + pin_to_sibling ButtonRowAnchor + pin_to_sibling_corner TOP_LEFT + pin_corner_to_sibling TOP_LEFT + } + // pain // + "BtnMod1" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "pin_to_sibling" "ButtonRowAnchor" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "TOP_LEFT" + "navUp" "BtnMod15" + "navDown" "BtnMod2" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "scriptID" "0" + } + "BtnMod2" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "pin_to_sibling" "BtnMod1" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod1" + "navDown" "BtnMod3" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "scriptID" "1" + } + "BtnMod3" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "2" + "pin_to_sibling" "BtnMod2" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod2" + "navDown" "BtnMod4" + } + "BtnMod4" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "3" + "pin_to_sibling" "BtnMod3" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod3" + "navDown" "BtnMod5" + } + "BtnMod5" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "4" + "pin_to_sibling" "BtnMod4" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod4" + "navDown" "BtnMod6" + } + "BtnMod6" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "5" + "pin_to_sibling" "BtnMod5" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod5" + "navDown" "BtnMod7" + } + "BtnMod7" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "6" + "pin_to_sibling" "BtnMod6" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod6" + "navDown" "BtnMod8" + } + "BtnMod8" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "7" + "pin_to_sibling" "BtnMod7" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod7" + "navDown" "BtnMod9" + } + "BtnMod9" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "8" + "pin_to_sibling" "BtnMod8" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod8" + "navDown" "BtnMod10" + } + "BtnMod10" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "9" + "pin_to_sibling" "BtnMod9" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod9" + "navDown" "BtnMod11" + } + "BtnMod11" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "10" + "pin_to_sibling" "BtnMod10" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod10" + "navDown" "BtnMod12" + } + "BtnMod12" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "11" + "pin_to_sibling" "BtnMod11" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod11" + "navDown" "BtnMod13" + } + "BtnMod13" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "12" + "pin_to_sibling" "BtnMod12" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod12" + "navDown" "BtnMod14" + } + "BtnMod14" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "13" + "pin_to_sibling" "BtnMod13" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod13" + "navDown" "BtnMod15" + } + "BtnMod15" + { + "ControlName" "CNestedPanel" + "classname" "ModButton" + "tall" "45" + "wide" "1200" + "controlSettingsFile" "resource/UI/menus/panels/mod_setting.res" + "classname" "ModButton" + "scriptID" "14" + "pin_to_sibling" "BtnMod14" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + "navUp" "BtnMod14" + "navDown" "BtnMod1" + } + // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + "FilterPanel" + { + "ControlName" "RuiPanel" + "wide" "1220" + "tall" "112" + //"xpos" "-8" + "classname" "FilterPanelChild" + "rui" "ui/knowledgebase_panel.rpak" + "visible" "1" + "zpos" "-1" + "pin_to_sibling" "FilterButtonsRowAnchor" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "TOP_LEFT" + } + "LabelDetails" + { + "ControlName" "RuiPanel" + "tall" "695" + "wide" "1220" + "xpos" "10" + "ypos" "10" + "pin_to_sibling" "ButtonRowAnchor" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "TOP_LEFT" + "rui" "ui/knowledgebase_panel.rpak" + "wrap" "1" + "visible" "1" + "zpos" "-1" + } + "BtnSearchLabel" + { + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + "labelText" "#SEARCHBAR_LABEL" + "textAlignment" "west" + "classname" "FilterPanelChild" + "wide" "500" + "xpos" "-23" + "ypos" "-16" + "wrap" "1" + "visible" "1" + "zpos" "0" + "pin_to_sibling" "FilterButtonsRowAnchor" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "TOP_LEFT" + } + "BtnModsSearch" + { + "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" "1" + "unicode" "1" + "pin_to_sibling" "BtnSearchLabel" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "TOP_RIGHT" + } + "BtnFiltersClear" + { + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + "labelText" "#CLEAR_FILTERS" + "classname" "FilterPanelChild" + "wide" "100" + "xpos" "0" + "ypos" "0" + "zpos" "90" + "scriptID" "999" + "pin_to_sibling" "BtnSearchLabel" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "TOP_RIGHT" + } + // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + "BtnModListUpArrow" + { + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + // labelText "A"F + "wide" "40" + "tall" "40" + "xpos" "2" + "ypos" "0" + "image" "vgui/hud/white" + "drawColor" "255 255 255 128" + "pin_to_sibling" "LabelDetails" + "pin_corner_to_sibling" "TOP_RIGHT" + "pin_to_sibling_corner" "TOP_LEFT" + } + "BtnModListUpArrowPanel" + { + "ControlName" "RuiPanel" + "wide" "40" + "tall" "40" + "xpos" "2" + "ypos" "0" + "rui" "ui/knowledgebase_panel.rpak" + "visible" "1" + "zpos" "-1" + "pin_to_sibling" "LabelDetails" + "pin_corner_to_sibling" "TOP_RIGHT" + "pin_to_sibling_corner" "TOP_LEFT" + } + "BtnModListDownArrow" + { + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + // labelText "V" + "wide" "40" + "tall" "40" + "xpos" "2" + "ypos" "-655" + "image" "vgui/hud/white" + "drawColor" "255 255 255 128" + "pin_to_sibling" "LabelDetails" + "pin_corner_to_sibling" "TOP_RIGHT" + "pin_to_sibling_corner" "TOP_LEFT" + } + "BtnModListDownArrowPanel" + { + "ControlName" "RuiPanel" + "wide" "40" + "tall" "40" + "xpos" "2" + "ypos" "-655" + "rui" "ui/knowledgebase_panel.rpak" + "visible" "1" + "zpos" "-1" + "pin_to_sibling" "LabelDetails" + "pin_corner_to_sibling" "TOP_RIGHT" + "pin_to_sibling_corner" "TOP_LEFT" + } + "BtnModListSlider" + { + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + // labelText "V" + "wide" "40" + "tall" "420" + "xpos" "2" + "ypos" "-40" + "zpos" "0" + "image" "vgui/hud/white" + "drawColor" "255 255 255 128" + "pin_to_sibling" "LabelDetails" + "pin_corner_to_sibling" "TOP_RIGHT" + "pin_to_sibling_corner" "TOP_LEFT" + } + "BtnModListSliderPanel" + { + "ControlName" "RuiPanel" + "wide" "40" + "tall" "420" + "xpos" "2" + "ypos" "-40" + "rui" "ui/knowledgebase_panel.rpak" + "visible" "1" + "zpos" "-1" + "pin_to_sibling" "LabelDetails" + "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" "604" + "xpos" "2" + "ypos" "-40" + "zpos" "1" + "pin_to_sibling" "LabelDetails" + "pin_corner_to_sibling" "TOP_RIGHT" + "pin_to_sibling_corner" "TOP_LEFT" + } + "ButtonTooltip" + { + "ControlName" "CNestedPanel" + "InheritProperties" "ButtonTooltip" + } + // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + "FooterButtons" + { + "ControlName" "CNestedPanel" + "InheritProperties" "FooterButtons" + } + } +} diff --git a/Northstar.Client/mod/resource/ui/menus/panels/mod_setting.res b/Northstar.Client/mod/resource/ui/menus/panels/mod_setting.res new file mode 100644 index 00000000..92dce922 --- /dev/null +++ b/Northstar.Client/mod/resource/ui/menus/panels/mod_setting.res @@ -0,0 +1,183 @@ +"resource/ui/menus/panels/mod_setting.res" +{ + "FULL" + { + "ControlName" "Label" + "classname" "ConnectingHUD" + "xpos" "0" + "ypos" "0" + "zpos" "99" + "wide" "1200" + "tall" "45" + "labelText" "" + "bgcolor_override" "0 0 0 0" + "visible" "0" + "paintbackground" "1" + } + "BtnMod" + { + "ControlName" "Label" + "InheritProperties" "RuiSmallButton" + "labelText" "Mod" + //"auto_wide_tocontents" "1" + "navRight" "EnumSelectButton" + "navLeft" "TextEntrySetting" + "wide" "390" + "tall" "45" + } + // we're getting to the top of this :) + "TopLine" + { + "ControlName" "ImagePanel" + "InheritProperties" "MenuTopBar" + "ypos" "0" + "wide" "%100" + "pin_to_sibling" "BtnMod" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "TOP_LEFT" + } + "ModTitle" + { + "ControlName" "Label" + "InheritProperties" "RuiSmallButton" + "labelText" "Mod" + "font" "DefaultBold_43" + //"auto_wide_tocontents" "1" + "zpos" "-999" + "textAlignment" "center" + "navRight" "EnumSelectButton" + "navLeft" "TextEntrySetting" + "wide" "1200" + "tall" "45" + + } + "Slider" + { + "ControlName" "SliderControl" + //"InheritProperties" "RuiSmallButton" + minValue 0.0 + maxValue 2.0 + stepSize 0.05 + "pin_to_sibling" "BtnMod" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "TOP_RIGHT" + "navRight" "ResetModToDefault" + "navLeft" "TextEntrySetting" + //isValueClampedToStepSize 1 + BtnDropButton + { + ControlName RuiButton + //InheritProperties WideButton + style SliderButton + "wide" "320" + "tall" "45" + "labelText" "" + "auto_wide_tocontents" "0" + } + "wide" "320" + "tall" "45" + } + "EnumSelectButton" + { + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + "style" "DialogListButton" + "labelText" "" + "zpos" "4" + "wide" "225" + "tall" "45" + //"xpos" "10" + "scriptID" "0" + "pin_to_sibling" "FULL" + "pin_corner_to_sibling" "RIGHT" + "pin_to_sibling_corner" "RIGHT" + "navLeft" "ResetModToDefault" + "navRight" "TextEntrySetting" + } + "ResetModToDefault" + { + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + "labelText" "" + "zpos" "0" + "xpos" "10" + "wide" "45" + "tall" "45" + "scriptID" "0" + "pin_to_sibling" "EnumSelectButton" + "pin_corner_to_sibling" "RIGHT" + "pin_to_sibling_corner" "LEFT" + "navLeft" "Slider" + "navRight" "TextEntrySetting" + } + "ResetModImage" + { + "ControlName" "ImagePanel" + "image" "vgui/reset" + "scaleImage" "1" + "drawColor" "180 180 180 255" // vanilla label color + "visible" "0" + "wide" "30" + "tall" "30" + "enabled" "0" + + "pin_to_sibling" "ResetModToDefault" + "pin_corner_to_sibling" "CENTER" + "pin_to_sibling_corner" "CENTER" + } + "OpenCustomMenu" + { + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + "labelText" "Open" + //"auto_wide_tocontents" "1" + "zpos" "4" + "wide" "1200" + "textAlignment" "center" + //"font" "Default_41" + //"xpos" "10" + "tall" "40" + "scriptID" "0" + "visible" "0" + "pin_to_sibling" "FULL" + "pin_corner_to_sibling" "RIGHT" + "pin_to_sibling_corner" "RIGHT" + "navLeft" "TextEntrySetting" + "navRight" "TextEntrySetting" + } + "TextEntrySetting" + { + "ControlName" "TextEntry" + "classname" "MatchSettingTextEntry" + //"xpos" "-35" + //"ypos" "-5" + "zpos" "100" // This works around input weirdness when the control is constructed by code instead of VGUI blackbox. + "wide" "160" + "tall" "30" + "scriptID" "0" + "textHidden" "0" + "editable" "1" + // NumericInputOnly 1 + "font" "Default_21" + "allowRightClickMenu" "0" + "allowSpecialCharacters" "1" + "unicode" "0" + "pin_to_sibling" "EnumSelectButton" + "pin_corner_to_sibling" "CENTER" + "pin_to_sibling_corner" "CENTER" + "navLeft" "EnumSelectButton" + "navRight" "EnumSelectButton" + } + // we're getting to the bottom of this :) + "BottomLine" + { + "ControlName" "ImagePanel" + "InheritProperties" "MenuTopBar" + "ypos" "5" + "wide" "%100" + //"tall" "0" + "pin_to_sibling" "FULL" + "pin_corner_to_sibling" "BOTTOM_LEFT" + "pin_to_sibling_corner" "BOTTOM_LEFT" + } +} diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ingame.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ingame.nut index 03bd8959..35c9e9ba 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_ingame.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ingame.nut @@ -112,8 +112,13 @@ void function InitInGameMPMenu() Hud_AddEventHandler( soundButton, UIE_CLICK, AdvanceMenuEventHandler( GetMenu( "VideoMenu" ) ) ) #endif - file.faqButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#KNB_MENU_HEADER" ) - Hud_AddEventHandler( file.faqButton, UIE_CLICK, AdvanceMenuEventHandler( GetMenu( "KnowledgeBaseMenu" ) ) ) + // MOD SETTINGS + var modSettingsButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "Mod Settings" ) + Hud_AddEventHandler( modSettingsButton, UIE_CLICK, AdvanceMenuEventHandler( GetMenu( "ModSettings" ) ) ) + + // Nobody reads the FAQ so we replace it with ModSettings because of the limited combobutton space available + //file.faqButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#KNB_MENU_HEADER" ) + //Hud_AddEventHandler( file.faqButton, UIE_CLICK, AdvanceMenuEventHandler( GetMenu( "KnowledgeBaseMenu" ) ) ) //var dataCenterButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#DATA_CENTER" ) //Hud_AddEventHandler( dataCenterButton, UIE_CLICK, OpenDataCenterDialog ) @@ -133,7 +138,7 @@ void function OnInGameMPMenu_Open() bool faqIsNew = !GetConVarBool( "menu_faq_viewed" ) || HaveNewPatchNotes() || HaveNewCommunityNotes() RuiSetBool( Hud_GetRui( file.settingsHeader ), "isNew", faqIsNew ) - ComboButton_SetNew( file.faqButton, faqIsNew ) + //ComboButton_SetNew( file.faqButton, faqIsNew ) UpdateLoadoutButtons() RefreshCreditsAvailable() @@ -255,6 +260,10 @@ void function InitInGameSPMenu() var videoButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#VIDEO" ) Hud_AddEventHandler( videoButton, UIE_CLICK, AdvanceMenuEventHandler( GetMenu( "VideoMenu" ) ) ) #endif + + // MOD SETTINGS + var modSettingsButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "Mod Settings" ) + Hud_AddEventHandler( modSettingsButton, UIE_CLICK, AdvanceMenuEventHandler( GetMenu( "ModSettings" ) ) ) array orderedButtons diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut index 3c868aab..2bef0e20 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut @@ -352,8 +352,9 @@ void function SetupComboButtonTest( var menu ) var soundButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#VIDEO" ) Hud_AddEventHandler( soundButton, UIE_CLICK, AdvanceMenuEventHandler( GetMenu( "VideoMenu" ) ) ) #endif - file.faqButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#KNB_MENU_HEADER" ) - Hud_AddEventHandler( file.faqButton, UIE_CLICK, AdvanceMenuEventHandler( GetMenu( "KnowledgeBaseMenu" ) ) ) + // MOD SETTINGS + var modSettingsButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#MOD_SETTINGS" ) + Hud_AddEventHandler( modSettingsButton, UIE_CLICK, AdvanceMenuEventHandler( GetMenu( "ModSettings" ) ) ) comboStruct.navUpButtonDisabled = true comboStruct.navDownButton = file.genUpButton @@ -635,9 +636,9 @@ void function OnLobbyMenu_Open() ComboButton_SetNew( file.factionButton, anyNewFactions ) } - bool faqIsNew = !GetConVarBool( "menu_faq_viewed" ) || HaveNewPatchNotes() || HaveNewCommunityNotes() + /*bool faqIsNew = !GetConVarBool( "menu_faq_viewed" ) || HaveNewPatchNotes() || HaveNewCommunityNotes() RuiSetBool( Hud_GetRui( file.settingsHeader ), "isNew", faqIsNew ) - ComboButton_SetNew( file.faqButton, faqIsNew ) + ComboButton_SetNew( file.faqButton, faqIsNew )*/ TryUnlockSRSCallsign() diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_mod_settings.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_mod_settings.nut new file mode 100644 index 00000000..a45082c7 --- /dev/null +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_mod_settings.nut @@ -0,0 +1,1105 @@ +untyped +global function AddModSettingsMenu +global function ModSettings_AddSetting +global function ModSettings_AddEnumSetting +global function ModSettings_AddSliderSetting +global function ModSettings_AddButton +global function ModSettings_AddModTitle +global function ModSettings_AddModCategory +global function PureModulo + +// Legacy functions for backwards compatability. These will be removed eventually +global function AddConVarSetting +global function AddConVarSettingEnum +global function AddConVarSettingSlider +global function AddModSettingsButton +global function AddModTitle +global function AddModCategory + +const int BUTTONS_PER_PAGE = 15 +const string SETTING_ITEM_TEXT = " " // this is long enough to be the same size as the textentry field + +enum eEmptySpaceType +{ + None, + TopBar, + BottomBar +} + +struct ConVarData { + string displayName + bool isEnumSetting = false + string conVar + string type + + string modName + string catName + bool isCategoryName = false + bool isModName = false + + bool isEmptySpace = false + int spaceType = 0 + + // SLIDER BULLSHIT + bool sliderEnabled = false + float min = 0.0 + float max = 1.0 + float stepSize = 0.05 + bool forceClamp = false + + bool isCustomButton = false + void functionref() onPress + + array values + var customMenu + bool hasCustomMenu = false +} + +struct { + var menu + int scrollOffset = 0 + bool updatingList = false + bool isOpen + + array conVarList + // if people use searches - i hate them but it'll do : ) + array filteredList + string filterText = "" + table enumRealValues + table setFuncs + array modPanels + array resetModButtons + array sliders + string currentMod = "" + string currentCat = "" +} file + +struct { + int deltaX = 0 + int deltaY = 0 +} mouseDeltaBuffer + +void function AddModSettingsMenu() +{ + AddMenu( "ModSettings", $"resource/ui/menus/mod_settings.menu", InitModMenu ) +} + +void function InitModMenu() +{ + file.menu = GetMenu( "ModSettings" ) + // DumpStack(2) + AddMenuFooterOption( file.menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) + + ///////////////////////////// + // BASE NORTHSTAR SETTINGS // + ///////////////////////////// + + /* + ModSettings_AddModTitle( "^FF000000EXAMPLE" ) + ModSettings_AddModCategory( "I wasted way too much time on this..." ) + ModSettings_AddButton( "This is a custom button you can click on!", void function() : () + { + print( "HELLOOOOOO" ) + } ) + ModSettings_AddEnumSetting( "filter_mods", "Very Huge Enum Example", split( "Never gonna give you up Never gonna let you down Never gonna run around and desert you Never gonna make you cry Never gonna say goodbye Never gonna tell a lie and hurt you", " " ) ) + */ + // Nuke weird rui on filter switch :D + // RuiSetString( Hud_GetRui( Hud_GetChild( file.menu, "SwtBtnShowFilter" ) ), "buttonText", "" ) + + file.modPanels = GetElementsByClassname( file.menu, "ModButton" ) + + AddMenuEventHandler( file.menu, eUIEvent.MENU_OPEN, OnModMenuOpened ) + AddMenuEventHandler( file.menu, eUIEvent.MENU_CLOSE, OnModMenuClosed ) + + int len = file.modPanels.len() + for ( int i = 0; i < len; i++ ) + { + + // AddButtonEventHandler( button, UIE_CHANGE, OnSettingButtonPressed ) + // get panel + var panel = file.modPanels[i] + + // reset to default nav + var child = Hud_GetChild( panel, "BtnMod" ) + + + child.SetNavUp( Hud_GetChild( file.modPanels[ int( PureModulo( i - 1, len ) ) ], "BtnMod" ) ) + child.SetNavDown( Hud_GetChild( file.modPanels[ int( PureModulo( i + 1, len ) ) ], "BtnMod" ) ) + + // Enum button nav + child = Hud_GetChild( panel, "EnumSelectButton" ) + Hud_DialogList_AddListItem( child, SETTING_ITEM_TEXT, "main" ) + Hud_DialogList_AddListItem( child, SETTING_ITEM_TEXT, "next" ) + Hud_DialogList_AddListItem( child, SETTING_ITEM_TEXT, "prev" ) + + child.SetNavUp( Hud_GetChild( file.modPanels[ int( PureModulo( i - 1, len ) ) ], "EnumSelectButton" ) ) + child.SetNavDown( Hud_GetChild( file.modPanels[ int( PureModulo( i + 1, len ) ) ], "EnumSelectButton" ) ) + Hud_AddEventHandler( child, UIE_CLICK, UpdateEnumSetting ) + + // reset button nav + + child = Hud_GetChild( panel, "ResetModToDefault" ) + Hud_AddEventHandler( child, UIE_GET_FOCUS, void function( var child ) : (panel) + { + Hud_SetColor( Hud_GetChild( panel, "ResetModImage" ), 0, 0, 0, 255 ) + }) + Hud_AddEventHandler( child, UIE_LOSE_FOCUS, void function( var child ) : (panel) + { + Hud_SetColor( Hud_GetChild( panel, "ResetModImage" ), 180, 180, 180, 180 ) + }) + + child.SetNavUp( Hud_GetChild( file.modPanels[ int( PureModulo( i - 1, len ) ) ], "ResetModToDefault" ) ) + child.SetNavDown( Hud_GetChild( file.modPanels[ int( PureModulo( i + 1, len ) ) ], "ResetModToDefault" ) ) + + Hud_AddEventHandler( child, UIE_CLICK, ResetConVar ) + file.resetModButtons.append(child) + + // text field nav + child = Hud_GetChild( panel, "TextEntrySetting" ) + + Hud_AddEventHandler( child, UIE_LOSE_FOCUS, SendTextPanelChanges ) + + child.SetNavUp( Hud_GetChild( file.modPanels[ int( PureModulo( i - 1, len ) ) ], "TextEntrySetting" ) ) + child.SetNavDown( Hud_GetChild( file.modPanels[ int( PureModulo( i + 1, len ) ) ], "TextEntrySetting" ) ) + + child = Hud_GetChild( panel, "Slider" ) + + child.SetNavUp( Hud_GetChild( file.modPanels[ int( PureModulo( i - 1, len ) ) ], "Slider" ) ) + child.SetNavDown( Hud_GetChild( file.modPanels[ int( PureModulo( i + 1, len ) ) ], "Slider" ) ) + + file.sliders.append( MS_Slider_Setup( child ) ) + + Hud_AddEventHandler( child, UIE_CHANGE, OnSliderChange ) + + child = Hud_GetChild( panel, "OpenCustomMenu" ) + + Hud_AddEventHandler( child, UIE_CLICK, CustomButtonPressed ) + } + + // Hud_AddEventHandler( Hud_GetChild( file.menu, "BtnModsSearch" ), UIE_LOSE_FOCUS, OnFilterTextPanelChanged ) + Hud_AddEventHandler( Hud_GetChild( file.menu, "BtnFiltersClear" ), UIE_CLICK, OnClearButtonPressed ) + // mouse delta + AddMouseMovementCaptureHandler( file.menu, UpdateMouseDeltaBuffer ) + + Hud_AddEventHandler( Hud_GetChild( file.menu, "BtnModsSearch" ), UIE_CHANGE, void function ( var inputField ) : () + { + file.filterText = Hud_GetUTF8Text( inputField ) + OnFiltersChange() + } ) +} + +// "PureModulo" +// Used instead of modulo in some places. +// Why? beacuse PureModulo loops back onto positive numbers instead of going into the negatives. +// DO NOT TOUCH. +// a / b != floor( float( a ) / b ) +// int( float( a ) / b ) != floor( float( a ) / b ) +// Examples: +// -1 % 5 = -1 +// PureModulo( -1, 5 ) = 4 +float function PureModulo( int a, int b ) +{ + return b * ( ( float( a ) / b ) - floor( float( a ) / b ) ) +} + +void function ResetConVar( var button ) +{ + ConVarData conVar = file.filteredList[ int ( Hud_GetScriptID( Hud_GetParent( button ) ) ) + file.scrollOffset ] + + if ( conVar.isCategoryName ) + ShowAreYouSureDialog( "#ARE_YOU_SURE", ResetAllConVarsForModEventHandler( conVar.catName ), "#WILL_RESET_ALL_SETTINGS" ) + else + ShowAreYouSureDialog( "#ARE_YOU_SURE", ResetConVarEventHandler( int ( Hud_GetScriptID( Hud_GetParent( button ) ) ) + file.scrollOffset ), Localize( "#WILL_RESET_SETTING", Localize( conVar.displayName ) ) ) +} + +void function ShowAreYouSureDialog( string header, void functionref() func, string details ) +{ + DialogData dialogData + dialogData.header = header + dialogData.message = details + + AddDialogButton( dialogData, "#NO" ) + AddDialogButton( dialogData, "#YES", func ) + + AddDialogFooter( dialogData, "#A_BUTTON_SELECT" ) + AddDialogFooter( dialogData, "#B_BUTTON_BACK" ) + + OpenDialog( dialogData ) +} + +void functionref() function ResetAllConVarsForModEventHandler( string catName ) +{ + return void function() : ( catName ) + { + for ( int i = 0; i < file.conVarList.len(); i++ ) + { + ConVarData c = file.conVarList[ i ] + if ( c.catName != catName || c.isCategoryName || c.isEmptySpace || c.isCustomButton ) + continue + SetConVarToDefault( c.conVar ) + + int index = file.filteredList.find( c ) + if ( file.filteredList.find( c ) < 0 ) + continue + + if ( min( BUTTONS_PER_PAGE - 1, max( 0, index - file.scrollOffset ) ) == index - file.scrollOffset ) + { + Hud_SetText( Hud_GetChild( file.modPanels[ index - file.scrollOffset ], "TextEntrySetting" ), c.isEnumSetting ? c.values[ GetConVarInt( c.conVar ) ] : GetConVarString( c.conVar ) ) + if( c.sliderEnabled ) + MS_Slider_SetValue( file.sliders[ index - file.scrollOffset ], GetConVarFloat( c.conVar ) ) + } + } + } +} + +void functionref() function ResetConVarEventHandler( int modIndex ) +{ + return void function() : ( modIndex ) + { + ConVarData c = file.filteredList[ modIndex ] + SetConVarToDefault( c.conVar ) + if ( min( BUTTONS_PER_PAGE - 1, max( 0, modIndex - file.scrollOffset ) ) == modIndex - file.scrollOffset ) + { + Hud_SetText( Hud_GetChild( file.modPanels[ modIndex - file.scrollOffset ], "TextEntrySetting" ), c.isEnumSetting ? c.values[ GetConVarInt( c.conVar ) ] : GetConVarString( c.conVar ) ) + if( c.sliderEnabled ) + MS_Slider_SetValue( file.sliders[ modIndex - file.scrollOffset ], GetConVarFloat( c.conVar ) ) + } + } +} + +//////////// +// 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.filteredList.len() <= 15 ) + { + FlushMouseDeltaBuffer() + return + } + + var sliderButton = Hud_GetChild( file.menu, "BtnModListSlider" ) + var sliderPanel = Hud_GetChild( file.menu, "BtnModListSliderPanel" ) + var movementCapture = Hud_GetChild( file.menu, "MouseMovementCapture" ) + + Hud_SetFocused( sliderButton ) + + float minYPos = -40.0 * ( GetScreenSize()[1] / 1080.0 ) // why the hardcoded positions?!?!?!?!?! + float maxHeight = 615.0 * ( GetScreenSize()[1] / 1080.0 ) + float maxYPos = minYPos - ( maxHeight - Hud_GetHeight( sliderPanel ) ) + float useableSpace = ( maxHeight - Hud_GetHeight( sliderPanel ) ) + + float jump = minYPos - ( useableSpace / ( float( file.filteredList.len() ) ) ) + + int pos = expect int( expect array( Hud_GetPos( sliderButton ) )[1] ) + float newPos = float( 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.filteredList.len() - BUTTONS_PER_PAGE ) ) + UpdateList() +} + +void function UpdateListSliderHeight() +{ + var sliderButton = Hud_GetChild( file.menu, "BtnModListSlider" ) + var sliderPanel = Hud_GetChild( file.menu, "BtnModListSliderPanel" ) + var movementCapture = Hud_GetChild( file.menu, "MouseMovementCapture" ) + + float mods = float ( file.filteredList.len() ) + + float maxHeight = 615.0 * ( GetScreenSize()[1] / 1080.0 ) // why the hardcoded 320/80??? + float minHeight = 80.0 * ( GetScreenSize()[1] / 1080.0 ) + + float height = maxHeight * ( float( BUTTONS_PER_PAGE ) / mods ) + + if ( height > maxHeight ) height = maxHeight + if ( height < minHeight ) height = minHeight + + Hud_SetHeight( sliderButton, height ) + Hud_SetHeight( sliderPanel, height ) + Hud_SetHeight( movementCapture, height ) +} + +void function UpdateList() +{ + Hud_SetFocused( Hud_GetChild( file.menu, "BtnModsSearch" ) ) + file.updatingList = true + + array filteredList = [] + + array filters = split( file.filterText, "," ) + array list = file.conVarList + if ( filters.len() <= 0 ) + filters.append( "" ) + foreach( string f in filters ) + { + string filter = strip( f ) + string lastCatNameInFilter = "" + string lastModNameInFilter = "" + int curCatIndex = 0 + int curModTitleIndex = -1 + for ( int i = 0; i < list.len(); i++ ) + { + ConVarData prev = list[ maxint( 0, i - 1 ) ] + ConVarData c = list[i] + ConVarData next = list[ minint( list.len() - 1, i + 1 ) ] + if ( c.isEmptySpace ) + continue + + string displayName = c.displayName + if ( c.isModName ) + { + displayName = c.modName + curModTitleIndex = i + } + if ( c.isCategoryName ) + { + displayName = c.catName + curCatIndex = i + } + if ( filter == "" || SanitizeDisplayName( Localize( displayName ) ).tolower().find( filter.tolower() ) != null ) + { + if ( c.isModName ) + { + lastModNameInFilter = c.modName + array modVars = GetAllVarsInMod( list, c.modName ) + if ( filteredList.len() <= 0 && modVars[0].spaceType == eEmptySpaceType.None ) + filteredList.extend( modVars.slice( 1, modVars.len() ) ) + else filteredList.extend( modVars ) + + i += modVars.len() - 1 + } + else if ( c.isCategoryName ) + { + if ( lastModNameInFilter != c.modName ) + { + array modVars = GetModConVarDatas( list, curModTitleIndex ) + if ( filteredList.len() <= 0 && modVars[0].spaceType == eEmptySpaceType.None ) + filteredList.extend( modVars.slice( 1, modVars.len() ) ) + else filteredList.extend( modVars ) + + lastModNameInFilter = c.modName + } + filteredList.extend( GetAllVarsInCategory( list, c.catName ) ) + i += GetAllVarsInCategory( list, c.catName ).len() - 1 + lastCatNameInFilter = c.catName + } + else + { + if ( lastModNameInFilter != c.modName ) + { + array modVars = GetModConVarDatas( list, curModTitleIndex ) + if ( filteredList.len() <= 0 && modVars[0].spaceType == eEmptySpaceType.None ) + filteredList.extend( modVars.slice( 1, modVars.len() ) ) + else filteredList.extend( modVars ) + + lastModNameInFilter = c.modName + } + if ( lastCatNameInFilter != c.catName ) + { + filteredList.extend( GetCatConVarDatas( curCatIndex ) ) + lastCatNameInFilter = c.catName + } + filteredList.append( c ) + } + } + } + list = filteredList + filteredList = [] + } + filteredList = list + + + file.filteredList = filteredList + + int j = int( min( file.filteredList.len() + file.scrollOffset, BUTTONS_PER_PAGE ) ) + + for ( int i = 0; i < BUTTONS_PER_PAGE; i++ ) + { + Hud_SetEnabled( file.modPanels[i], i < j ) + Hud_SetVisible( file.modPanels[i], i < j ) + + if ( i < j ) + SetModMenuNameText( file.modPanels[i] ) + } + file.updatingList = false + + if ( file.conVarList.len() <= 0 ) + { + Hud_SetVisible( Hud_GetChild( file.menu, "NoResultLabel" ), true ) + Hud_SetText( Hud_GetChild( file.menu, "NoResultLabel" ), "#NO_MODS" ) + } + else if ( file.filteredList.len() <= 0 ) + { + Hud_SetVisible( Hud_GetChild( file.menu, "NoResultLabel" ), true ) + Hud_SetText( Hud_GetChild( file.menu, "NoResultLabel" ), "#NO_RESULTS" ) + } + else + { + Hud_Hide( Hud_GetChild( file.menu, "NoResultLabel" ) ) + } +} + +array function GetModConVarDatas( array arr, int index ) +{ + if ( index <= 1 ) + return [ arr[ index - 1 ], arr[ index ], arr[ index + 1 ] ] + return [ arr[ index - 2 ], arr[ index - 1 ], arr[ index ], arr[ index + 1 ] ] +} + +array function GetCatConVarDatas( int index ) +{ + if ( file.conVarList[ index - 1 ].spaceType != eEmptySpaceType.None ) + return [ file.conVarList[ index ] ] + return [ file.conVarList[ index - 1 ], file.conVarList[ index ] ] +} + +array function GetAllVarsInCategory( array arr, string catName ) +{ + array vars = [] + for ( int i = 0; i < arr.len(); i++ ) + { + ConVarData c = arr[i] + if ( c.catName == catName ) + { + vars.append( arr[i] ) + } + } + return vars +} + +array function GetAllVarsInMod( array arr, string modName ) +{ + array vars = [] + for ( int i = 0; i < arr.len(); i++ ) + { + ConVarData c = arr[i] + if ( c.modName == modName ) + { + vars.append( arr[i] ) + } + } + return vars +} + +void function SetModMenuNameText( var button ) +{ + int index = int ( Hud_GetScriptID( button ) ) + file.scrollOffset + ConVarData conVar = file.filteredList[ int ( Hud_GetScriptID( button ) ) + file.scrollOffset ] + + var panel = file.modPanels[ int ( Hud_GetScriptID( button ) ) ] + + var label = Hud_GetChild( panel, "BtnMod" ) + var textField = Hud_GetChild( panel, "TextEntrySetting" ) + var enumButton = Hud_GetChild( panel, "EnumSelectButton" ) + var resetButton = Hud_GetChild( panel, "ResetModToDefault" ) + var resetVGUI = Hud_GetChild( panel, "ResetModImage" ) + var bottomLine = Hud_GetChild( panel, "BottomLine" ) + var topLine = Hud_GetChild( panel, "TopLine" ) + var modTitle = Hud_GetChild( panel, "ModTitle" ) + var customMenuButton = Hud_GetChild( panel, "OpenCustomMenu") + var slider = Hud_GetChild( panel, "Slider" ) + Hud_SetVisible( slider, false ) + Hud_SetEnabled( slider, true ) + + + if ( conVar.isEmptySpace ) + { + string s = "" + Hud_SetPos( label, 0, 0 ) + Hud_SetVisible( label, false ) + Hud_SetVisible( textField, false ) + Hud_SetVisible( enumButton, false ) + Hud_SetVisible( resetButton, false ) + Hud_SetVisible( resetVGUI, false ) + Hud_SetVisible( modTitle, false ) + Hud_SetVisible( customMenuButton, false ) + Hud_SetVisible( bottomLine, false ) + Hud_SetVisible( topLine, false ) + switch ( conVar.spaceType ) + { + case eEmptySpaceType.TopBar: + Hud_SetVisible( topLine, true ) + return + + case eEmptySpaceType.BottomBar: + Hud_SetVisible( bottomLine, true ) + return + + case eEmptySpaceType.None: + return + } + } + + Hud_SetVisible( textField, !conVar.isCategoryName ) + Hud_SetVisible( bottomLine, conVar.isCategoryName || conVar.spaceType == eEmptySpaceType.BottomBar ) + Hud_SetVisible( topLine, false ) + Hud_SetVisible( enumButton, !conVar.isCategoryName && conVar.isEnumSetting ) + Hud_SetVisible( modTitle, conVar.isModName ) + Hud_SetVisible( customMenuButton, false ) + float scaleX = GetScreenSize()[1] / 1080.0 + float scaleY = GetScreenSize()[1] / 1080.0 + if ( conVar.sliderEnabled ) + { + Hud_SetSize( slider, int( 320 * scaleX ), int( 45 * scaleY ) ) + MS_Slider s = file.sliders[ int ( Hud_GetScriptID( button ) ) ] + MS_Slider_SetMin( s, conVar.min ) + MS_Slider_SetMax( s, conVar.max ) + MS_Slider_SetStepSize( s, conVar.stepSize ) + MS_Slider_SetValue( s, GetConVarFloat( conVar.conVar ) ) + } + else Hud_SetSize( slider, 0, int( 45 * scaleY ) ) + if ( conVar.isCustomButton ) + { + Hud_SetVisible( label, false ) + Hud_SetVisible( textField, false ) + Hud_SetVisible( enumButton, false ) + Hud_SetVisible( resetButton, false ) + Hud_SetVisible( modTitle, false ) + Hud_SetVisible( resetVGUI, false ) + Hud_SetVisible( customMenuButton, true ) + Hud_SetText( customMenuButton, conVar.displayName ) + } + else if ( conVar.isModName ) + { + Hud_SetText( modTitle, conVar.modName ) + Hud_SetPos( label, 0, 0 ) + Hud_SetVisible( label, false ) + Hud_SetVisible( textField, false ) + Hud_SetVisible( enumButton, false ) + Hud_SetVisible( resetButton, false ) + Hud_SetVisible( resetVGUI, false ) + Hud_SetVisible( bottomLine, false ) + Hud_SetVisible( topLine, false ) + } + else if ( conVar.isCategoryName ) + { + Hud_SetText( label, conVar.catName ) + Hud_SetPos( label, 0, 0 ) + Hud_SetSize( label, int( scaleX * ( 1180 - 420 - 85 ) ), int( scaleY * 40 ) ) + Hud_SetVisible( label, true ) + Hud_SetVisible( textField, false ) + Hud_SetVisible( enumButton, false ) + Hud_SetVisible( resetButton, true ) + Hud_SetVisible( resetVGUI, true ) + + Hud_SetSize( resetButton, int( scaleX * 90 ), int( scaleY * 40 ) ) + } + else { + Hud_SetVisible( slider, conVar.sliderEnabled ) + + Hud_SetText( label, conVar.displayName ) + if (conVar.type == "float") + Hud_SetText( textField, string( GetConVarFloat(conVar.conVar) ) ) + else Hud_SetText( textField, conVar.isEnumSetting ? conVar.values[ GetConVarInt( conVar.conVar ) ] : GetConVarString( conVar.conVar ) ) + Hud_SetPos( label, int(scaleX * 25), 0 ) + Hud_SetText( resetButton, "" ) + if (conVar.sliderEnabled) + Hud_SetSize( label, int(scaleX * (375 + 85)), int(scaleY * 40) ) + else Hud_SetSize( label, int(scaleX * (375 + 405)), int(scaleY * 40) ) + if ( conVar.type == "float" ) + Hud_SetText( textField, string( GetConVarFloat( conVar.conVar ) ) ) + else Hud_SetText( textField, conVar.isEnumSetting ? conVar.values[ GetConVarInt( conVar.conVar ) ] : GetConVarString( conVar.conVar ) ) + Hud_SetPos( label, int( scaleX * 25 ), 0 ) + Hud_SetText( resetButton, "" ) + Hud_SetSize( resetButton, int( scaleX * 90 ), int( scaleY * 40 ) ) + if ( conVar.sliderEnabled ) + Hud_SetSize( label, int( scaleX * ( 375 + 85 ) ), int( scaleY * 40 ) ) + else Hud_SetSize( label, int( scaleX * ( 375 + 405 ) ), int( scaleY * 40 ) ) + Hud_SetVisible( label, true ) + Hud_SetVisible( textField, true ) + Hud_SetVisible( resetButton, true ) + Hud_SetVisible( resetVGUI, true ) + } +} + +void function CustomButtonPressed( var button ) +{ + var panel = Hud_GetParent( button ) + ConVarData c = file.filteredList[ int( Hud_GetScriptID( panel ) ) + file.scrollOffset ] + c.onPress() +} + +void function OnScrollDown( var button ) +{ + if ( file.filteredList.len() <= BUTTONS_PER_PAGE ) return + file.scrollOffset += 5 + if ( file.scrollOffset + BUTTONS_PER_PAGE > file.filteredList.len() ) + { + file.scrollOffset = file.filteredList.len() - BUTTONS_PER_PAGE + } + UpdateList() + UpdateListSliderPosition() +} + +void function OnScrollUp( var button ) +{ + file.scrollOffset -= 5 + if ( file.scrollOffset < 0 ) + { + file.scrollOffset = 0 + } + UpdateList() + UpdateListSliderPosition() +} + +void function UpdateListSliderPosition() +{ + var sliderButton = Hud_GetChild( file.menu , "BtnModListSlider" ) + var sliderPanel = Hud_GetChild( file.menu , "BtnModListSliderPanel" ) + var movementCapture = Hud_GetChild( file.menu , "MouseMovementCapture" ) + + float mods = float ( file.filteredList.len() ) + + float minYPos = -40.0 * ( GetScreenSize()[1] / 1080.0 ) + float useableSpace = ( 615.0 * ( GetScreenSize()[1] / 1080.0 ) - Hud_GetHeight( sliderPanel ) ) + + float jump = minYPos - ( useableSpace / ( mods - float( BUTTONS_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 OnModMenuOpened() +{ + if( !file.isOpen ) + { + file.scrollOffset = 0 + file.filterText = "" + + RegisterButtonPressedCallback( MOUSE_WHEEL_UP , OnScrollUp ) + RegisterButtonPressedCallback( MOUSE_WHEEL_DOWN , OnScrollDown ) + RegisterButtonPressedCallback( MOUSE_LEFT , OnClick ) + + OnFiltersChange() + file.isOpen = true + } +} + +void function OnClick( var button ) +{ + if (file.resetModButtons.contains(GetFocus())) + thread CheckFocus(GetFocus()) + if (GetFocus() == Hud_GetChild(file.menu, "NoResultLabel")) + thread CheckFocus(GetFocus()) +} + +void function CheckFocus( var button ) +{ + wait 0.05 + if (file.resetModButtons.contains(GetFocus())) + { + thread ResetConVar(GetFocus()) + } + if (GetFocus() == Hud_GetChild(file.menu, "NoResultLabel")) + LaunchExternalWebBrowser( "https://northstar.thunderstore.io/", WEBBROWSER_FLAG_FORCEEXTERNAL ) +} + +void function OnFiltersChange() +{ + file.scrollOffset = 0 + + UpdateList() + + UpdateListSliderHeight() +} + +void function OnModMenuClosed() +{ + DeregisterButtonPressedCallback( MOUSE_WHEEL_UP , OnScrollUp ) + DeregisterButtonPressedCallback( MOUSE_WHEEL_DOWN , OnScrollDown ) + DeregisterButtonPressedCallback( MOUSE_LEFT , OnClick ) + + file.scrollOffset = 0 + UpdateListSliderPosition() + file.isOpen = false +} + +void function ModSettings_AddModTitle( string modName, int stackPos = 2 ) +{ + file.currentMod = modName + if ( file.conVarList.len() > 0 ) + { + ConVarData catData + + catData.isEmptySpace = true + catData.modName = file.currentMod + + file.conVarList.append( catData ) + } + ConVarData topBar + topBar.isEmptySpace = true + topBar.modName = modName + topBar.spaceType = eEmptySpaceType.TopBar + + + ConVarData modData + + modData.modName = modName + modData.displayName = modName + modData.isModName = true + + + ConVarData botBar + botBar.isEmptySpace = true + botBar.modName = modName + botBar.spaceType = eEmptySpaceType.BottomBar + file.conVarList.extend( [ topBar, modData, botBar ] ) + file.setFuncs[ expect string( getstackinfos( stackPos )[ "func" ] ) ] <- false +} + +void function AddModTitle( string modName, int stackPos = 2 ) +{ + ModSettings_AddModTitle( modName, stackPos + 1 ) +} + +void function ModSettings_AddModCategory( string catName, int stackPos = 2 ) +{ + if ( !( getstackinfos( stackPos )[ "func" ] in file.setFuncs ) ) + throw getstackinfos( stackPos )[ "src" ] + " #" + getstackinfos( stackPos )[ "line" ] + "\nCannot add a category before a mod title!" + + ConVarData space + space.isEmptySpace = true + space.modName = file.currentMod + space.catName = catName + file.conVarList.append( space ) + + ConVarData catData + + catData.catName = catName + catData.displayName = catName + catData.modName = file.currentMod + catData.isCategoryName = true + + file.conVarList.append( catData ) + + file.currentCat = catName + file.setFuncs[ expect string( getstackinfos( stackPos )[ "func" ] ) ] = true +} + +void function AddModCategory( string catName, int stackPos = 2 ) +{ + ModSettings_AddModCategory( catName, stackPos + 1 ) +} + +void function ModSettings_AddButton( string buttonLabel, void functionref() onPress, int stackPos = 2 ) +{ + if ( !( getstackinfos( stackPos )[ "func" ] in file.setFuncs ) || !file.setFuncs[ expect string( getstackinfos( stackPos )[ "func" ] ) ] ) + throw getstackinfos( stackPos )[ "src" ] + " #" + getstackinfos( stackPos )[ "line" ] + "\nCannot add a button before a category and mod title!" + + ConVarData data + + data.isCustomButton = true + data.displayName = buttonLabel + data.modName = file.currentMod + data.catName = file.currentCat + data.onPress = onPress + + file.conVarList.append( data ) +} + +void function AddModSettingsButton( string buttonLabel, void functionref() onPress, int stackPos = 2 ) +{ + ModSettings_AddButton( buttonLabel, onPress, stackPos + 1 ) +} + +void function ModSettings_AddSetting( string conVar, string displayName, string type = "", int stackPos = 2 ) +{ + if ( !( getstackinfos( stackPos )[ "func" ] in file.setFuncs ) || !file.setFuncs[ expect string( getstackinfos( stackPos )[ "func" ] ) ] ) + throw getstackinfos( stackPos )[ "src" ] + " #" + getstackinfos( stackPos )[ "line" ] + "\nCannot add a setting before a category and mod title!" + ConVarData data + + data.catName = file.currentCat + data.conVar = conVar + data.modName = file.currentMod + data.displayName = displayName + data.type = type + + file.conVarList.append( data ) +} + +void function AddConVarSetting( string conVar, string displayName, string type = "", int stackPos = 2 ) +{ + ModSettings_AddSetting( conVar, displayName, type, stackPos + 1 ) +} + +void function ModSettings_AddSliderSetting( string conVar, string displayName, float min = 0.0, float max = 1.0, float stepSize = 0.1, bool forceClamp = false, int stackPos = 2 ) +{ + if ( !( getstackinfos( stackPos )[ "func" ] in file.setFuncs ) || !file.setFuncs[ expect string( getstackinfos( stackPos )[ "func" ] ) ] ) + throw getstackinfos( stackPos )[ "src" ] + " #" + getstackinfos( stackPos )[ "line" ] + "\nCannot add a setting before a category and mod title!" + ConVarData data + + data.catName = file.currentCat + data.conVar = conVar + data.modName = file.currentMod + data.displayName = displayName + data.type = "float" + data.sliderEnabled = true + data.forceClamp = false + data.min = min + data.max = max + data.stepSize = stepSize + + file.conVarList.append( data ) +} + +void function AddConVarSettingSlider( string conVar, string displayName, float min = 0.0, float max = 1.0, float stepSize = 0.1, bool forceClamp = false, int stackPos = 2 ) +{ + ModSettings_AddSliderSetting( conVar, displayName, min, max, stepSize, forceClamp, stackPos + 1 ) +} + +void function ModSettings_AddEnumSetting( string conVar, string displayName, array values, int stackPos = 2 ) +{ + if ( !( getstackinfos( stackPos )[ "func" ] in file.setFuncs ) || !file.setFuncs[ expect string( getstackinfos( stackPos )[ "func" ] ) ] ) + throw getstackinfos( stackPos )[ "src" ] + " #" + getstackinfos( stackPos )[ "line" ] + "\nCannot add a setting before a category and mod title!" + ConVarData data + + data.catName = file.currentCat + data.modName = file.currentMod + data.conVar = conVar + data.displayName = displayName + data.values = values + data.isEnumSetting = true + data.min = 0 + data.max = values.len() - 1.0 + data.sliderEnabled = values.len() > 2 + data.forceClamp = true + data.stepSize = 1 + + file.conVarList.append( data ) +} + +void function AddConVarSettingEnum( string conVar, string displayName, array values, int stackPos = 2 ) +{ + ModSettings_AddEnumSetting( conVar, displayName, values, stackPos + 1 ) +} + +void function OnSliderChange( var button ) +{ + if ( file.updatingList ) + return + var panel = Hud_GetParent( button ) + ConVarData c = file.filteredList[ int( Hud_GetScriptID( panel ) ) + file.scrollOffset ] + var textPanel = Hud_GetChild( panel, "TextEntrySetting" ) + + if ( c.isEnumSetting ) + { + int val = int( RoundToNearestInt( Hud_SliderControl_GetCurrentValue( button ) ) ) + SetConVarInt( c.conVar, val ) + Hud_SetText( textPanel, ( c.values[ GetConVarInt( c.conVar ) ] ) ) + MS_Slider_SetValue( file.sliders[ int( Hud_GetScriptID( Hud_GetParent( textPanel ) ) ) ], float( val ) ) + + return + } + float val = Hud_SliderControl_GetCurrentValue( button ) + if ( c.forceClamp ) + { + int mod = int( RoundToNearestInt( val % c.stepSize / c.stepSize ) ) + val = ( int( val / c.stepSize ) + mod ) * c.stepSize + } + SetConVarFloat( c.conVar, val ) + MS_Slider_SetValue( file.sliders[ int( Hud_GetScriptID( Hud_GetParent( textPanel ) ) ) ], val ) + + Hud_SetText( textPanel, string( GetConVarFloat( c.conVar ) ) ) +} + +void function SendTextPanelChanges( var textPanel ) +{ + ConVarData c = file.filteredList[ int( Hud_GetScriptID( Hud_GetParent( textPanel ) ) ) + file.scrollOffset ] + if ( c.conVar == "" ) return + // enums don't need to do this + if ( !c.isEnumSetting ) + { + string newSetting = Hud_GetUTF8Text( textPanel ) + + switch ( c.type ) + { + case "int": + try + { + SetConVarInt( c.conVar, newSetting.tointeger() ) + } + catch ( ex ) + { + ThrowInvalidValue( "This setting is an integer, and only accepts whole numbers." ) + Hud_SetText( textPanel, GetConVarString( c.conVar ) ) + } + case "bool": + if ( newSetting != "0" && newSetting != "1" ) + { + ThrowInvalidValue( "This setting is a boolean, and only accepts values of 0 or 1." ) + + // set back to previous value : ) + Hud_SetText( textPanel, string( GetConVarBool( c.conVar ) ) ) + + break + } + SetConVarBool( c.conVar, newSetting == "1" ) + break + case "float": + try + { + SetConVarFloat( c.conVar, newSetting.tofloat() ) + } + catch ( ex ) + { + printt( ex ) + ThrowInvalidValue( "This setting is a float, and only accepts a number - we could not parse this!\n\n( Use \".\" for the floating point, not \",\". )" ) + } + if ( c.sliderEnabled ) + { + var panel = Hud_GetParent( textPanel ) + MS_Slider s = file.sliders[ int ( Hud_GetScriptID( panel ) ) ] + + MS_Slider_SetValue( s, GetConVarFloat( c.conVar ) ) + } + break + case "float2": + try + { + array split = split( newSetting, " " ) + if ( split.len() != 2 ) + { + ThrowInvalidValue( "This setting is a float2, and only accepts a pair of numbers - you put in " + split.len() + "!" ) + Hud_SetText( textPanel, GetConVarString( c.conVar ) ) + break + } + vector settingTest = < split[0].tofloat(), split[1].tofloat(), 0 > + + SetConVarString( c.conVar, newSetting ) + } + catch ( ex ) + { + ThrowInvalidValue( "This setting is a float2, and only accepts a pair of numbers - you put something we could not parse!\n\n( Use \".\" for the floating point, not \",\". )" ) + Hud_SetText( textPanel, GetConVarString( c.conVar ) ) + } + break + // idk sometimes it's called Float3 most of the time it's called vector, I am not complaining. + case "vector": + case "float3": + try + { + array split = split( newSetting, " " ) + if ( split.len() != 3 ) + { + ThrowInvalidValue( "This setting is a float3, and only accepts a trio of numbers - you put in " + split.len() + "!" ) + Hud_SetText( textPanel, GetConVarString( c.conVar ) ) + break + } + vector settingTest = < split[0].tofloat(), split[1].tofloat(), 0 > + + SetConVarString( c.conVar, newSetting ) + } + catch ( ex ) + { + ThrowInvalidValue( "This setting is a float3, and only accepts a trio of numbers - you put something we could not parse!\n\n( Use \".\" for the floating point, not \",\". )" ) + Hud_SetText( textPanel, GetConVarString( c.conVar ) ) + } + break + default: + SetConVarString( c.conVar, newSetting ) + break; + } + } + else Hud_SetText( textPanel, Localize( c.values[ GetConVarInt( c.conVar ) ] ) ) +} + +void function ThrowInvalidValue( string desc ) +{ + DialogData dialogData + dialogData.header = "Invalid Value" + dialogData.image = $"ui/menu/common/dialog_error" + dialogData.message = desc + AddDialogButton( dialogData, "#OK" ) + OpenDialog( dialogData ) +} + +void function UpdateEnumSetting( var button ) +{ + int scriptId = int( Hud_GetScriptID( Hud_GetParent( button ) ) ) + ConVarData c = file.filteredList[ scriptId + file.scrollOffset ] + + var panel = file.modPanels[ scriptId ] + + var textPanel = Hud_GetChild( panel, "TextEntrySetting" ) + + string selectionVal = Hud_GetDialogListSelectionValue( button ) + + if ( selectionVal == "main" ) + return + + int enumVal = GetConVarInt( c.conVar ) + if ( selectionVal == "next" ) // enum val += 1 + enumVal = ( enumVal + 1 ) % c.values.len() + else // enum val -= 1 + { + enumVal-- + if ( enumVal == -1 ) + enumVal = c.values.len() - 1 + } + + SetConVarInt( c.conVar, enumVal ) + Hud_SetText( textPanel, c.values[ enumVal ] ) + + Hud_SetDialogListSelectionValue( button, "main" ) +} + +void function OnClearButtonPressed( var button ) +{ + file.filterText = "" + Hud_SetText( Hud_GetChild( file.menu, "BtnModsSearch" ), "" ) + + OnFiltersChange() +} + +string function SanitizeDisplayName( string displayName ) +{ + array parts = split( displayName, "^" ) + string result = "" + if ( parts.len() == 1 ) + return parts[0] + foreach ( string p in parts ) + { + if ( p == "" ) + { + result += "^" + continue + } + int i = 0 + for ( i = 0; i < 8 && i < p.len(); i++ ) + { + var c = p[i] + if ( ( c < 'a' || c > 'f' ) && ( c < 'A' || c > 'F' ) && ( c < '0' || c > '9' ) ) + break + } + if ( i == 0 ) + result += p + else result += p.slice( i, p.len() ) + } + return result +} diff --git a/Northstar.Client/mod/scripts/vscripts/ui/ns_slider.nut b/Northstar.Client/mod/scripts/vscripts/ui/ns_slider.nut new file mode 100644 index 00000000..33a79cdc --- /dev/null +++ b/Northstar.Client/mod/scripts/vscripts/ui/ns_slider.nut @@ -0,0 +1,52 @@ +// ModSettings_Slider +// since we are missing some utility functions (e.g. GetMax, GetMin, SetValue), this is basically a collection of workarounds. +global struct MS_Slider +{ + var slider + float min = 0.0 + float max = 1.0 + float stepSize = 0.05 +} + +globalize_all_functions + +MS_Slider function MS_Slider_Setup( var slider, float min = 0.0, float max = 1.0, float startVal = 0.0, float stepSize = 0.05 ) +{ + MS_Slider result + result.slider = slider + result.min = min + result.max = max + result.stepSize = stepSize + Hud_SliderControl_SetMin( slider, startVal ) + Hud_SliderControl_SetMax( slider, startVal ) + Hud_SliderControl_SetStepSize( slider, stepSize ) + Hud_SliderControl_SetMin( slider, min ) + Hud_SliderControl_SetMax( slider, max ) + return result +} + +void function MS_Slider_SetValue( MS_Slider slider, float val ) +{ + Hud_SliderControl_SetMin( slider.slider, val ) + Hud_SliderControl_SetMax( slider.slider, val ) + Hud_SliderControl_SetMin( slider.slider, slider.min ) + Hud_SliderControl_SetMax( slider.slider, slider.max ) +} + +void function MS_Slider_SetMin( MS_Slider slider, float min ) +{ + slider.min = min + Hud_SliderControl_SetMin( slider.slider, min ) +} + +void function MS_Slider_SetMax( MS_Slider slider, float max ) +{ + slider.max = max + Hud_SliderControl_SetMax( slider.slider, max ) +} + +void function MS_Slider_SetStepSize( MS_Slider slider, float stepSize ) +{ + slider.stepSize = stepSize + Hud_SliderControl_SetStepSize( slider.slider, stepSize ) +} diff --git a/Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut b/Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut index 53d85387..eef19b5e 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut @@ -101,6 +101,10 @@ void function InitMainMenuPanel() var videoButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#VIDEO" ) Hud_AddEventHandler( videoButton, UIE_CLICK, AdvanceMenuEventHandler( GetMenu( "VideoMenu" ) ) ) #endif + + // MOD SETTINGS + var modSettingsButton = AddComboButton( comboStruct, headerIndex, buttonIndex++, "#MOD_SETTINGS" ) + Hud_AddEventHandler( modSettingsButton, UIE_CLICK, AdvanceMenuEventHandler( GetMenu( "ModSettings" ) ) ) var spotlightLargeButton = Hud_GetChild( file.spotlightPanel, "SpotlightLarge" ) spotlightLargeButton.SetNavLeft( file.spButtons[0] ) -- cgit v1.2.3