From 901629d93173d31afdd84dea4cb95c7648628b87 Mon Sep 17 00:00:00 2001 From: C J Silverio Date: Thu, 11 Jan 2024 16:16:06 -0800 Subject: [PATCH] feat(layouts): override layout anchor points with user settings (#108) Players can now choose to override a layout's chosen anchor point with their own preferred HUD location. This won't work well for every layout, but players can decide that for themselves. Added the new option to the settings struct and MCM config. It's an enum that allows players to choose from the current list of anchor names. Added new translation strings to support the config. `apply_settings()` now refreshes the layout to pick up any location changes. Added a test to ensure that the setting is respected by the anchor_point() function if set. This bottleneck ensures that flattened layouts get the overridden location automatically. To support the test, added a way to specific a refresh-from file for the settings lazy static. The new convenience functions to Layout that match on its variants are also there to support tests. --- extern/CommonLibSSE-NG | 2 +- .../Translations/SoulsyHUD_czech.txt | Bin 25456 -> 26808 bytes .../Translations/SoulsyHUD_english.txt | Bin 25456 -> 26840 bytes .../Translations/SoulsyHUD_french.txt | Bin 25456 -> 26808 bytes .../Translations/SoulsyHUD_german.txt | Bin 25456 -> 26808 bytes .../Translations/SoulsyHUD_italian.txt | Bin 25456 -> 26808 bytes .../Translations/SoulsyHUD_japanese.txt | Bin 25456 -> 26808 bytes .../Translations/SoulsyHUD_polish.txt | Bin 25456 -> 26808 bytes .../Translations/SoulsyHUD_russian.txt | Bin 25456 -> 26808 bytes .../Translations/SoulsyHUD_spanish.txt | Bin 25456 -> 26808 bytes .../core/mcm/config/SoulsyHUD/config.json | 1256 +++++++++-------- .../core/mcm/config/SoulsyHUD/settings.ini | 1 + src/controller/control.rs | 3 + src/controller/settings.rs | 43 +- src/layouts/mod.rs | 43 +- src/layouts/shared.rs | 22 + tests/fixtures/all-types.ini | 1 + tests/fixtures/test-settings.ini | 34 + 18 files changed, 784 insertions(+), 621 deletions(-) create mode 100644 tests/fixtures/test-settings.ini diff --git a/extern/CommonLibSSE-NG b/extern/CommonLibSSE-NG index 3838fe49..718cddbe 160000 --- a/extern/CommonLibSSE-NG +++ b/extern/CommonLibSSE-NG @@ -1 +1 @@ -Subproject commit 3838fe49a93bda641e3c313149cb9c8b069f3f37 +Subproject commit 718cddbee7e7e79cf1c683cfce6078cbf2249504 diff --git a/installer/core/Interface/Translations/SoulsyHUD_czech.txt b/installer/core/Interface/Translations/SoulsyHUD_czech.txt index b6a8c8edf424b291a28356d80665f290520c27bc..34d8c49a261cde9158ae305ede2df4eb1cf726cc 100644 GIT binary patch delta 1005 zcmah|K}y3=5PcC`MCd|X6qQ0;xzJX+D2O6bD+p3tNWrDVn8sk6grr(siD$?Oyn#zk zAa1>hNAOKT{E0~kA^Cr1{(Cd?{^aLV`}o%011tVo-Z<*RgM~Zz2r=Z>!Zl8~&iMG4 z(r07Ly$UoI43}`>FhiLmOe4b5u3{N5hew>v+H~Zs_;qRXtPYXyqJV~h z8`Yt39oBJ;cs?lBKo(Ib5d3i!K2t7NHyJXoL8bq?6OPpqN31p1bh#UoDmbxr-Wrt7 z@V1n`#Z1ay%GIsnNqfxd(~;V_o9-<}say)DZns^j?}+_BB~vkEhtJgVftKWxDKxov zx%1+!y`8J7%sNgv7bfP!m_$tytYV51zc9|Ip$oD9b2s+aw3#Q*>R diff --git a/installer/core/Interface/Translations/SoulsyHUD_english.txt b/installer/core/Interface/Translations/SoulsyHUD_english.txt index b6a8c8edf424b291a28356d80665f290520c27bc..1bf933bfd450434c060811b53eedecb72f267a4c 100644 GIT binary patch delta 1051 zcmah|%}T>S5dJE7h|sgB2=Sr^wWSA96p>m%4@FSwxx|>(Vw!{`T0M!+kSFjBdzL}k$@Aul*XYDPplaKl3P8%L<+`>nQF8?i7Vs#Tci|3J8CNFamc#EnO^W{F!e9>Ag_J-Px$zSC0Fw9OC3+y{XM!kFR@F zHShl0gKN#rzRvd<@vh4G39D~m!hBnlxT=ryu8x#kx;ti%joA0{s&b##_m(z9D-)4U zh)KJEcbkX-mxCMXMx2T9{^GNoVl_c7wGC=yvc$)%2qr{ivH7&UqwSEppYihU;DIaT oJWfT3Ey^NVn=-8}j;qPh%f`lJ=#~PfEhqm8sVur_ppFIn0MXIWbpQYW delta 9 Qcmca{k@3SZ#tj9@02>7ahNAOKT{E0~kA^Cr1{(Cd?{^aLV`}o%011tVo-Z<*RgM~Zz2r=Z>!Zl8~&iMG4 z(r07Ly$UoI43}`>FhiLmOe4b5u3{N5hew>v+H~Zs_;qRXtPYXyqJV~h z8`Yt39oBJ;cs?lBKo(Ib5d3i!K2t7NHyJXoL8bq?6OPpqN31p1bh#UoDmbxr-Wrt7 z@V1n`#Z1ay%GIsnNqfxd(~;V_o9-<}say)DZns^j?}+_BB~vkEhtJgVftKWxDKxov zx%1+!y`8J7%sNgv7bfP!m_$tytYV51zc9|Ip$oD9b2s+aw3#Q*>R diff --git a/installer/core/Interface/Translations/SoulsyHUD_german.txt b/installer/core/Interface/Translations/SoulsyHUD_german.txt index b6a8c8edf424b291a28356d80665f290520c27bc..34d8c49a261cde9158ae305ede2df4eb1cf726cc 100644 GIT binary patch delta 1005 zcmah|K}y3=5PcC`MCd|X6qQ0;xzJX+D2O6bD+p3tNWrDVn8sk6grr(siD$?Oyn#zk zAa1>hNAOKT{E0~kA^Cr1{(Cd?{^aLV`}o%011tVo-Z<*RgM~Zz2r=Z>!Zl8~&iMG4 z(r07Ly$UoI43}`>FhiLmOe4b5u3{N5hew>v+H~Zs_;qRXtPYXyqJV~h z8`Yt39oBJ;cs?lBKo(Ib5d3i!K2t7NHyJXoL8bq?6OPpqN31p1bh#UoDmbxr-Wrt7 z@V1n`#Z1ay%GIsnNqfxd(~;V_o9-<}say)DZns^j?}+_BB~vkEhtJgVftKWxDKxov zx%1+!y`8J7%sNgv7bfP!m_$tytYV51zc9|Ip$oD9b2s+aw3#Q*>R diff --git a/installer/core/Interface/Translations/SoulsyHUD_italian.txt b/installer/core/Interface/Translations/SoulsyHUD_italian.txt index b6a8c8edf424b291a28356d80665f290520c27bc..34d8c49a261cde9158ae305ede2df4eb1cf726cc 100644 GIT binary patch delta 1005 zcmah|K}y3=5PcC`MCd|X6qQ0;xzJX+D2O6bD+p3tNWrDVn8sk6grr(siD$?Oyn#zk zAa1>hNAOKT{E0~kA^Cr1{(Cd?{^aLV`}o%011tVo-Z<*RgM~Zz2r=Z>!Zl8~&iMG4 z(r07Ly$UoI43}`>FhiLmOe4b5u3{N5hew>v+H~Zs_;qRXtPYXyqJV~h z8`Yt39oBJ;cs?lBKo(Ib5d3i!K2t7NHyJXoL8bq?6OPpqN31p1bh#UoDmbxr-Wrt7 z@V1n`#Z1ay%GIsnNqfxd(~;V_o9-<}say)DZns^j?}+_BB~vkEhtJgVftKWxDKxov zx%1+!y`8J7%sNgv7bfP!m_$tytYV51zc9|Ip$oD9b2s+aw3#Q*>R diff --git a/installer/core/Interface/Translations/SoulsyHUD_japanese.txt b/installer/core/Interface/Translations/SoulsyHUD_japanese.txt index b6a8c8edf424b291a28356d80665f290520c27bc..34d8c49a261cde9158ae305ede2df4eb1cf726cc 100644 GIT binary patch delta 1005 zcmah|K}y3=5PcC`MCd|X6qQ0;xzJX+D2O6bD+p3tNWrDVn8sk6grr(siD$?Oyn#zk zAa1>hNAOKT{E0~kA^Cr1{(Cd?{^aLV`}o%011tVo-Z<*RgM~Zz2r=Z>!Zl8~&iMG4 z(r07Ly$UoI43}`>FhiLmOe4b5u3{N5hew>v+H~Zs_;qRXtPYXyqJV~h z8`Yt39oBJ;cs?lBKo(Ib5d3i!K2t7NHyJXoL8bq?6OPpqN31p1bh#UoDmbxr-Wrt7 z@V1n`#Z1ay%GIsnNqfxd(~;V_o9-<}say)DZns^j?}+_BB~vkEhtJgVftKWxDKxov zx%1+!y`8J7%sNgv7bfP!m_$tytYV51zc9|Ip$oD9b2s+aw3#Q*>R diff --git a/installer/core/Interface/Translations/SoulsyHUD_polish.txt b/installer/core/Interface/Translations/SoulsyHUD_polish.txt index b6a8c8edf424b291a28356d80665f290520c27bc..34d8c49a261cde9158ae305ede2df4eb1cf726cc 100644 GIT binary patch delta 1005 zcmah|K}y3=5PcC`MCd|X6qQ0;xzJX+D2O6bD+p3tNWrDVn8sk6grr(siD$?Oyn#zk zAa1>hNAOKT{E0~kA^Cr1{(Cd?{^aLV`}o%011tVo-Z<*RgM~Zz2r=Z>!Zl8~&iMG4 z(r07Ly$UoI43}`>FhiLmOe4b5u3{N5hew>v+H~Zs_;qRXtPYXyqJV~h z8`Yt39oBJ;cs?lBKo(Ib5d3i!K2t7NHyJXoL8bq?6OPpqN31p1bh#UoDmbxr-Wrt7 z@V1n`#Z1ay%GIsnNqfxd(~;V_o9-<}say)DZns^j?}+_BB~vkEhtJgVftKWxDKxov zx%1+!y`8J7%sNgv7bfP!m_$tytYV51zc9|Ip$oD9b2s+aw3#Q*>R diff --git a/installer/core/Interface/Translations/SoulsyHUD_russian.txt b/installer/core/Interface/Translations/SoulsyHUD_russian.txt index b6a8c8edf424b291a28356d80665f290520c27bc..34d8c49a261cde9158ae305ede2df4eb1cf726cc 100644 GIT binary patch delta 1005 zcmah|K}y3=5PcC`MCd|X6qQ0;xzJX+D2O6bD+p3tNWrDVn8sk6grr(siD$?Oyn#zk zAa1>hNAOKT{E0~kA^Cr1{(Cd?{^aLV`}o%011tVo-Z<*RgM~Zz2r=Z>!Zl8~&iMG4 z(r07Ly$UoI43}`>FhiLmOe4b5u3{N5hew>v+H~Zs_;qRXtPYXyqJV~h z8`Yt39oBJ;cs?lBKo(Ib5d3i!K2t7NHyJXoL8bq?6OPpqN31p1bh#UoDmbxr-Wrt7 z@V1n`#Z1ay%GIsnNqfxd(~;V_o9-<}say)DZns^j?}+_BB~vkEhtJgVftKWxDKxov zx%1+!y`8J7%sNgv7bfP!m_$tytYV51zc9|Ip$oD9b2s+aw3#Q*>R diff --git a/installer/core/Interface/Translations/SoulsyHUD_spanish.txt b/installer/core/Interface/Translations/SoulsyHUD_spanish.txt index b6a8c8edf424b291a28356d80665f290520c27bc..34d8c49a261cde9158ae305ede2df4eb1cf726cc 100644 GIT binary patch delta 1005 zcmah|K}y3=5PcC`MCd|X6qQ0;xzJX+D2O6bD+p3tNWrDVn8sk6grr(siD$?Oyn#zk zAa1>hNAOKT{E0~kA^Cr1{(Cd?{^aLV`}o%011tVo-Z<*RgM~Zz2r=Z>!Zl8~&iMG4 z(r07Ly$UoI43}`>FhiLmOe4b5u3{N5hew>v+H~Zs_;qRXtPYXyqJV~h z8`Yt39oBJ;cs?lBKo(Ib5d3i!K2t7NHyJXoL8bq?6OPpqN31p1bh#UoDmbxr-Wrt7 z@V1n`#Z1ay%GIsnNqfxd(~;V_o9-<}say)DZns^j?}+_BB~vkEhtJgVftKWxDKxov zx%1+!y`8J7%sNgv7bfP!m_$tytYV51zc9|Ip$oD9b2s+aw3#Q*>R diff --git a/installer/core/mcm/config/SoulsyHUD/config.json b/installer/core/mcm/config/SoulsyHUD/config.json index 9c7f00f3..2791446c 100644 --- a/installer/core/mcm/config/SoulsyHUD/config.json +++ b/installer/core/mcm/config/SoulsyHUD/config.json @@ -1,620 +1,642 @@ { - "modName": "SoulsyHUD", - "displayName": "SoulsyHUD", - "minMcmVersion": 11, - "cursorFillMode": "topToBottom", - "pages": [ - { - "pageDisplayName": "$SoulsyHUD_Settings_Page", - "cursorFillMode": "topToBottom", - "content": [ - { - "text": "$SoulsyHUD_Controls_KeysHeader", - "type": "header" - }, - { - "id": "uPowerCycleKey:Controls", - "text": "$SoulsyHUD_Controls_PowerCycleKey_Text", - "help": "$SoulsyHUD_Controls_PowerCycleKey_Help", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "uLeftCycleKey:Controls", - "text": "$SoulsyHUD_Controls_LeftCycleKey_Text", - "help": "$SoulsyHUD_Controls_LeftCycleKey_Help", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "uRightCycleKey:Controls", - "text": "$SoulsyHUD_Controls_RightCycleKey_Text", - "help": "$SoulsyHUD_Controls_RightCycleKey_Help", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "text": "$SoulsyHUD_Controls_ModifiersHeader", - "type": "header" - }, - { - "id": "uHowToCycle:Controls", - "text": "$SoulsyHUD_Controls_Advance_Text", - "help": "$SoulsyHUD_Controls_Advance_Help", - "type": "enum", - "valueOptions": { - "options": [ - "$SoulsyHUD_Cycle_Enum_Hotkey", - "$SoulsyHUD_Cycle_Enum_LongPress", - "$SoulsyHUD_Cycle_Enum_Mod" - ], - "sourceType": "ModSettingInt", - "defaultValue": 0 - } - }, - { - "type": "hiddenToggle", - "text": "hidden toggle for cycle modifier hotkey", - "groupControl": 1, - "valueOptions": { - "sourceType": "PropertyValueBool", - "propertyName": "pCycleNeedsModifier" - } - }, - { - "id": "iCycleModifierKey:Controls", - "text": "$SoulsyHUD_Controls_CycleModifierKey_Text", - "help": "$SoulsyHUD_Controls_CycleModifierKey_Help", - "groupCondition": 1, - "groupBehavior": "skip", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "uHowToggleInMenus:Controls", - "text": "$SoulsyHUD_Controls_Menus_Text", - "help": "$SoulsyHUD_Controls_Menus_Help", - "type": "enum", - "valueOptions": { - "options": [ - "$SoulsyHUD_Menu_Enum_Hotkey", - "$SoulsyHUD_Menu_Enum_LongPress", - "$SoulsyHUD_Menu_Enum_Mod" - ], - "sourceType": "ModSettingInt", - "defaultValue": 0 - } - }, - { - "type": "hiddenToggle", - "text": "menu modifier hotkey", - "groupControl": 2, - "valueOptions": { - "sourceType": "PropertyValueBool", - "propertyName": "pMenuNeedsModifier" - } - }, - { - "id": "iMenuModifierKey:Controls", - "text": "$SoulsyHUD_Controls_MenuModifierKey_Text", - "help": "$SoulsyHUD_Controls_MenuModifierKey_Help", - "ignoreConflicts": true, - "groupCondition": 2, - "groupBehavior": "skip", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "bLinkToFavorites:Options", - "text": "$SoulsyHUD_Options_Favoriting_Text", - "help": "$SoulsyHUD_Options_Favoriting_Help", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingBool" - } - }, - { - "id": "uHowToUnequip:Controls", - "text": "$SoulsyHUD_Controls_Unarmed_Text", - "help": "$SoulsyHUD_Controls_Unarmed_Help", - "type": "enum", - "valueOptions": { - "options": [ - "$SoulsyHUD_Unarmed_Enum_None", - "$SoulsyHUD_Unarmed_Enum_LongPress", - "$SoulsyHUD_Unarmed_Enum_Mod", - "$SoulsyHUD_Unarmed_Enum_Add", - "$SoulsyHUD_Unarmed_Enum_Hotkey" - ], - "sourceType": "ModSettingInt", - "defaultValue": 0 - } - }, - { - "type": "hiddenToggle", - "text": "hidden toggle for unequip modifier hotkey", - "groupControl": 3, - "valueOptions": { - "sourceType": "PropertyValueBool", - "propertyName": "pEnableUnequipModifier" - } - }, - { - "id": "iUnequipModifierKey:Controls", - "text": "$SoulsyHUD_Controls_UnequipModifierKey_Text", - "help": "$SoulsyHUD_Controls_UnequipModifierKey_Help", - "groupCondition": 3, - "groupBehavior": "skip", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "type": "hiddenToggle", - "text": "hidden toggle for unequip dedicated hotkey", - "groupControl": 4, - "valueOptions": { - "sourceType": "PropertyValueBool", - "propertyName": "pEnableUnequipHotkey" - } - }, - { - "id": "iUnequipHotkey:Controls", - "text": "$SoulsyHUD_Controls_UnequipHotkey_Text", - "help": "$SoulsyHUD_Controls_UnequipHotkey_Help", - "groupCondition": 4, - "groupBehavior": "skip", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "type": "hiddenToggle", - "text": "hidden toggle for long-press-to-match setting", - "groupControl": 5, - "valueOptions": { - "sourceType": "PropertyValueBool", - "propertyName": "pEnableLongPressMatchOption" - } - }, - { - "id": "bLongPressMatches:Controls", - "text": "$SoulsyHUD_LongPressToMatch_Text", - "help": "$SoulsyHUD_LongPressToMatch_Help", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingBool" - }, - "groupCondition": 5, - "groupBehavior": "skip" - }, - { - "text": "$SoulsyHUD_Controls_Consumables_Header", - "type": "header", - "position": 1 - }, - { - "id": "bGroupPotions:Options", - "text": "$SoulsyHUD_Controls_GroupPotions_Text", - "help": "$SoulsyHUD_Controls_GroupPotions_Help", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "uUtilityCycleKey:Controls", - "text": "$SoulsyHUD_Controls_UtilityCycleKey_Text", - "help": "$SoulsyHUD_Controls_UtilityCycleKey_Help", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "uHowToActivate:Controls", - "text": "$SoulsyHUD_Activate_When_Text", - "help": "$SoulsyHUD_Activate_When_Help", - "type": "enum", - "valueOptions": { - "options": [ - "$SoulsyHUD_Activate_Enum_Hotkey", - "$SoulsyHUD_Activate_Enum_LongPress", - "$SoulsyHUD_Activate_Enum_Mod" - ], - "sourceType": "ModSettingInt", - "defaultValue": 0 - } - }, - { - "type": "hiddenToggle", - "text": "hidden toggle for utility activate modifier", - "groupControl": 6, - "valueOptions": { - "sourceType": "PropertyValueBool", - "propertyName": "pEnableActivateModifier" - } - }, - { - "id": "iUtilityActivateModifier:Controls", - "text": "$SoulsyHUD_Controls_ActivateModifier_Text", - "help": "$SoulsyHUD_Controls_ActivateModifier_Help", - "groupCondition": 6, - "groupBehavior": "skip", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "type": "hiddenToggle", - "text": "hidden toggle for utility hotkey", - "groupControl": 7, - "valueOptions": { - "sourceType": "PropertyValueBool", - "propertyName": "pEnableActivateHotkey" - } - }, - { - "id": "uUtilityActivateKey:Controls", - "text": "$SoulsyHUD_Controls_ActivateKey_Text", - "help": "$SoulsyHUD_Controls_ActivateKey_Help", - "groupCondition": 7, - "groupBehavior": "skip", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "bCycleAmmo:Options", - "text": "$SoulsyHUD_Options_CycleAmmo_Text", - "help": "$SoulsyHUD_Options_CycleAmmo_Help", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "text": "$SoulsyHUD_Gameplay_FeelHeader", - "type": "header" - }, - { - "id": "uEquipDelay:Options", - "text": "$SoulsyHUD_Options_EquipDelay_Text", - "help": "$SoulsyHUD_Options_EquipDelay_Help", - "type": "slider", - "valueOptions": { - "min": 0, - "max": 2500, - "step": 50, - "sourceType": "ModSettingInt" - } - }, - { - "id": "uLongPressMillis:Options", - "text": "$SoulsyHUD_Options_LongPress_Text", - "help": "$SoulsyHUD_Options_LongPress_Help", - "type": "slider", - "valueOptions": { - "min": 750, - "max": 2500, - "step": 50, - "sourceType": "ModSettingInt" - } - }, - { - "id": "bCyclingSlowsTime:Options", - "text": "$SoulsyHUD_Options_SlowTime_Text", - "help": "$SoulsyHUD_Options_SlowTime_Help", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "uSlowTimeFactor:Options", - "text": "$SoulsyHUD_Options_HowSlow_Text", - "help": "$SoulsyHUD_Options_HowSlow_Help", - "type": "slider", - "valueOptions": { - "min": 10, - "max": 90, - "step": 1, - "sourceType": "ModSettingInt" - } - } - ] - }, - { - "pageDisplayName": "$SoulsyHUD_Display_Page", - "cursorFillMode": "topToBottom", - "content": [ - { - "text": "$SoulsyHUD_Display_Header", - "type": "header" - }, - { - "id": "bAutoFade:Options", - "text": "$SoulsyHUD_Options_Fade_Text", - "help": "$SoulsyHUD_Options_Fade_Help", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "uFadeTime:Options", - "text": "$SoulsyHUD_Options_FadeTime_Text", - "help": "$SoulsyHUD_Options_FadeTime_Help", - "type": "slider", - "valueOptions": { - "min": 0, - "max": 5000, - "step": 100, - "sourceType": "ModSettingInt" - } - }, - { - "id": "fMaxAlpha:Options", - "text": "$SoulsyHUD_Options_MaxAlpha_Text", - "help": "$SoulsyHUD_Options_MaxAlpha_Help", - "type": "slider", - "valueOptions": { - "min": 0.2, - "max": 1.0, - "step": 0.01, - "sourceType": "ModSettingFloat", - "formatString": "{2}" - } - }, - { - "id": "uShowHideKey:Controls", - "text": "$SoulsyHUD_Controls_ShowHideKey_Text", - "help": "$SoulsyHUD_Controls_ShowHideKey_Help", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "bColorizeIcons:Options", - "text": "$SoulsyHUD_Options_Colorize_Text", - "help": "$SoulsyHUD_Options_Colorize_Help", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "uControllerKind:Options", - "text": "$SoulsyHUD_Options_Controller_Text", - "type": "enum", - "help": "$SoulsyHUD_Options_Controller_Help", - "valueOptions": { - "options": ["$SoulsyHUD_Controls_PS", "$SoulsyHUD_Controls_Xbox"], - "sourceType": "ModSettingInt", - "defaultValue": 0 - } - }, - { - "id": "uRefreshKey:Controls", - "text": "$SoulsyHUD_Controls_RefreshKey_Text", - "help": "$SoulsyHUD_Controls_RefreshKey_Help", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "sSKSEIdentifier:Options", - "text": "$SoulsyHUD_ModIdString_Text", - "help": "$SoulsyHUD_ModIdString_Help", - "type": "input", - "valueOptions": { - "sourceType": "ModSettingString" - } - }, - { - "id": "bDebugMode:Options", - "text": "$SoulsyHUD_Options_Debug_Text", - "help": "$SoulsyHUD_Options_Debug_Help", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "text": "$SoulsyHUD_Maintenance_Header", - "type": "header", - "position": 1 - }, - { - "text": "$SoulsyHUD_Clear_Text", - "help": "$SoulsyHUD_Clear_Help", - "type": "text", - "valueOptions": { - "value": "clear" - }, - "action": { - "type": "CallFunction", - "function": "ClearCyclesPapyrus" - } - }, - { - "text": "$SoulsyHUD_CycleContents_Header", - "type": "header" - }, - { - "id": "pCycleToShow", - "text": "$SoulsyHUD_ChooseCycle_Text", - "help": "$SoulsyHUD_ChooseCycle_Help", - "type": "enum", - "valueOptions": { - "options": [ - "$SoulsyHUD_CycleEnum_Powers", - "$SoulsyHUD_CycleEnum_Utilities", - "$SoulsyHUD_CycleEnum_LeftHand", - "$SoulsyHUD_CycleEnum_RightHand" - ], - "sourceType": "PropertyValueInt", - "propertyName": "pCycleToShow", - "defaultValue": 0 - }, - "action": { - "type": "CallFunction", - "function": "ShowCycleEntries", - "params": ["{value}"] - } - }, - { - "id": "cycleDisplay", - "text": "$SoulsyHUD_ChosenCycle_Text", - "help": "$SoulsyHUD_ChosenCycle_Help", - "type": "menu", - "valueOptions": { - "options": [" ", " "], - "sourceType": "PropertyValueInt", - "propertyName": "pCycleItemShown", - "defaultValue": 0 - } - } - ] - }, - { - "pageDisplayName": "$SoulsyHUD_EquipSets_Page", - "cursorFillMode": "topToBottom", - "content": [ - { - "text": "$SoulsyHUD_EquipSets_Header", - "type": "header" - }, - { - "id": "iEquipSetCycleKey:Controls", - "text": "$SoulsyHUD_Controls_EquipSetCycleKey_Text", - "help": "$SoulsyHUD_Controls_EquipSetCycleKey_Help", - "type": "keymap", - "valueOptions": { - "sourceType": "ModSettingInt" - } - }, - { - "id": "bEquipSetsUnequip:Options", - "text": "$SoulsyHUD_EquipSetsUnequip_Text", - "help": "$SoulsyHUD_EquipSetsUnequip_Help", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingBool" - } - }, - { - "id": "sLastUsedSetName:Equipsets", - "text": "$SoulsyHUD_EquipSetName_Text", - "help": "$SoulsyHUD_EquipSetName_Help", - "type": "input", - "valueOptions": { - "sourceType": "ModSettingString" - } - }, - { - "text": "$SoulsyHUD_NewEquipSet_Text", - "help": "$SoulsyHUD_NewEquipSet_Help", - "type": "text", - "action": { - "type": "CallFunction", - "function": "CreateEquipSet" - } - }, - { - "text": "$SoulsyHUD_UpdateASet_Header", - "type": "header" - }, - { - "id": "pEquipSetMenuSelection", - "text": "$SoulsyHUD_EquipSetList_Text", - "help": "$SoulsyHUD_EquipSetList_Help", - "type": "menu", - "valueOptions": { - "options": ["$SoulsyHUD_NoEquipSets", " "], - "sourceType": "PropertyValueString", - "propertyName": "pEquipSetMenuSelection" - } - }, - { - "id": "sLastEditedSetName:Equipsets", - "text": "$SoulsyHUD_SelectedEquipSetName_Text", - "help": "$SoulsyHUD_SelectedEquipSetName_Help", - "type": "input" - }, - { - "id": "renameEquipSet", - "text": "$SoulsyHUD_RenameSet_Text", - "help": "$SoulsyHUD_RenameSet_Help", - "type": "text", - "action": { - "type": "CallFunction", - "function": "RenameEquipSet" - } - }, - { - "id": "updateEquipSet", - "text": "$SoulsyHUD_UpdateSet_Text", - "help": "$SoulsyHUD_UpdateSet_Help", - "type": "text", - "action": { - "type": "CallFunction", - "function": "UpdateEquipSet" - } - }, - { - "id": "removeEquipSet", - "text": "$SoulsyHUD_RemoveSet_Text", - "help": "$SoulsyHUD_RemoveSet_Help", - "type": "text", - "action": { - "type": "CallFunction", - "function": "RemoveEquipSet" - } - }, - { - "text": "$SoulsyHUD_SelectedSet_Header", - "type": "header", - "position": 1 - }, - { - "id": "pIconSourceSelection", - "text": "$SoulsyHUD_EquipSetItemList_Text", - "help": "$SoulsyHUD_EquipSetItemList_Help", - "type": "menu", - "valueOptions": { - "options": ["$SoulsyHUD_NoItems", " "], - "sourceType": "PropertyValueString", - "propertyName": "pIconSourceSelection" - } - }, - { - "id": "useSelectedItemAsIcon", - "text": "$SoulsyHUD_UseItemAsIcon_Text", - "help": "$SoulsyHUD_UseItemAsIcon_Help", - "type": "text", - "action": { - "type": "CallFunction", - "function": "UseSelectionAsIcon" - } - } - ] + "modName": "SoulsyHUD", + "displayName": "SoulsyHUD", + "minMcmVersion": 11, + "cursorFillMode": "topToBottom", + "pages": [ + { + "pageDisplayName": "$SoulsyHUD_Settings_Page", + "cursorFillMode": "topToBottom", + "content": [ + { + "text": "$SoulsyHUD_Controls_KeysHeader", + "type": "header" + }, + { + "id": "uPowerCycleKey:Controls", + "text": "$SoulsyHUD_Controls_PowerCycleKey_Text", + "help": "$SoulsyHUD_Controls_PowerCycleKey_Help", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "uLeftCycleKey:Controls", + "text": "$SoulsyHUD_Controls_LeftCycleKey_Text", + "help": "$SoulsyHUD_Controls_LeftCycleKey_Help", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "uRightCycleKey:Controls", + "text": "$SoulsyHUD_Controls_RightCycleKey_Text", + "help": "$SoulsyHUD_Controls_RightCycleKey_Help", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "text": "$SoulsyHUD_Controls_ModifiersHeader", + "type": "header" + }, + { + "id": "uHowToCycle:Controls", + "text": "$SoulsyHUD_Controls_Advance_Text", + "help": "$SoulsyHUD_Controls_Advance_Help", + "type": "enum", + "valueOptions": { + "options": [ + "$SoulsyHUD_Cycle_Enum_Hotkey", + "$SoulsyHUD_Cycle_Enum_LongPress", + "$SoulsyHUD_Cycle_Enum_Mod" + ], + "sourceType": "ModSettingInt", + "defaultValue": 0 + } + }, + { + "type": "hiddenToggle", + "text": "hidden toggle for cycle modifier hotkey", + "groupControl": 1, + "valueOptions": { + "sourceType": "PropertyValueBool", + "propertyName": "pCycleNeedsModifier" + } + }, + { + "id": "iCycleModifierKey:Controls", + "text": "$SoulsyHUD_Controls_CycleModifierKey_Text", + "help": "$SoulsyHUD_Controls_CycleModifierKey_Help", + "groupCondition": 1, + "groupBehavior": "skip", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "uHowToggleInMenus:Controls", + "text": "$SoulsyHUD_Controls_Menus_Text", + "help": "$SoulsyHUD_Controls_Menus_Help", + "type": "enum", + "valueOptions": { + "options": [ + "$SoulsyHUD_Menu_Enum_Hotkey", + "$SoulsyHUD_Menu_Enum_LongPress", + "$SoulsyHUD_Menu_Enum_Mod" + ], + "sourceType": "ModSettingInt", + "defaultValue": 0 + } + }, + { + "type": "hiddenToggle", + "text": "menu modifier hotkey", + "groupControl": 2, + "valueOptions": { + "sourceType": "PropertyValueBool", + "propertyName": "pMenuNeedsModifier" + } + }, + { + "id": "iMenuModifierKey:Controls", + "text": "$SoulsyHUD_Controls_MenuModifierKey_Text", + "help": "$SoulsyHUD_Controls_MenuModifierKey_Help", + "ignoreConflicts": true, + "groupCondition": 2, + "groupBehavior": "skip", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "bLinkToFavorites:Options", + "text": "$SoulsyHUD_Options_Favoriting_Text", + "help": "$SoulsyHUD_Options_Favoriting_Help", + "type": "toggle", + "valueOptions": { + "sourceType": "ModSettingBool" + } + }, + { + "id": "uHowToUnequip:Controls", + "text": "$SoulsyHUD_Controls_Unarmed_Text", + "help": "$SoulsyHUD_Controls_Unarmed_Help", + "type": "enum", + "valueOptions": { + "options": [ + "$SoulsyHUD_Unarmed_Enum_None", + "$SoulsyHUD_Unarmed_Enum_LongPress", + "$SoulsyHUD_Unarmed_Enum_Mod", + "$SoulsyHUD_Unarmed_Enum_Add", + "$SoulsyHUD_Unarmed_Enum_Hotkey" + ], + "sourceType": "ModSettingInt", + "defaultValue": 0 + } + }, + { + "type": "hiddenToggle", + "text": "hidden toggle for unequip modifier hotkey", + "groupControl": 3, + "valueOptions": { + "sourceType": "PropertyValueBool", + "propertyName": "pEnableUnequipModifier" + } + }, + { + "id": "iUnequipModifierKey:Controls", + "text": "$SoulsyHUD_Controls_UnequipModifierKey_Text", + "help": "$SoulsyHUD_Controls_UnequipModifierKey_Help", + "groupCondition": 3, + "groupBehavior": "skip", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "type": "hiddenToggle", + "text": "hidden toggle for unequip dedicated hotkey", + "groupControl": 4, + "valueOptions": { + "sourceType": "PropertyValueBool", + "propertyName": "pEnableUnequipHotkey" + } + }, + { + "id": "iUnequipHotkey:Controls", + "text": "$SoulsyHUD_Controls_UnequipHotkey_Text", + "help": "$SoulsyHUD_Controls_UnequipHotkey_Help", + "groupCondition": 4, + "groupBehavior": "skip", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "type": "hiddenToggle", + "text": "hidden toggle for long-press-to-match setting", + "groupControl": 5, + "valueOptions": { + "sourceType": "PropertyValueBool", + "propertyName": "pEnableLongPressMatchOption" + } + }, + { + "id": "bLongPressMatches:Controls", + "text": "$SoulsyHUD_LongPressToMatch_Text", + "help": "$SoulsyHUD_LongPressToMatch_Help", + "type": "toggle", + "valueOptions": { + "sourceType": "ModSettingBool" + }, + "groupCondition": 5, + "groupBehavior": "skip" + }, + { + "text": "$SoulsyHUD_Controls_Consumables_Header", + "type": "header", + "position": 1 + }, + { + "id": "bGroupPotions:Options", + "text": "$SoulsyHUD_Controls_GroupPotions_Text", + "help": "$SoulsyHUD_Controls_GroupPotions_Help", + "type": "toggle", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "uUtilityCycleKey:Controls", + "text": "$SoulsyHUD_Controls_UtilityCycleKey_Text", + "help": "$SoulsyHUD_Controls_UtilityCycleKey_Help", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "uHowToActivate:Controls", + "text": "$SoulsyHUD_Activate_When_Text", + "help": "$SoulsyHUD_Activate_When_Help", + "type": "enum", + "valueOptions": { + "options": [ + "$SoulsyHUD_Activate_Enum_Hotkey", + "$SoulsyHUD_Activate_Enum_LongPress", + "$SoulsyHUD_Activate_Enum_Mod" + ], + "sourceType": "ModSettingInt", + "defaultValue": 0 + } + }, + { + "type": "hiddenToggle", + "text": "hidden toggle for utility activate modifier", + "groupControl": 6, + "valueOptions": { + "sourceType": "PropertyValueBool", + "propertyName": "pEnableActivateModifier" + } + }, + { + "id": "iUtilityActivateModifier:Controls", + "text": "$SoulsyHUD_Controls_ActivateModifier_Text", + "help": "$SoulsyHUD_Controls_ActivateModifier_Help", + "groupCondition": 6, + "groupBehavior": "skip", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "type": "hiddenToggle", + "text": "hidden toggle for utility hotkey", + "groupControl": 7, + "valueOptions": { + "sourceType": "PropertyValueBool", + "propertyName": "pEnableActivateHotkey" + } + }, + { + "id": "uUtilityActivateKey:Controls", + "text": "$SoulsyHUD_Controls_ActivateKey_Text", + "help": "$SoulsyHUD_Controls_ActivateKey_Help", + "groupCondition": 7, + "groupBehavior": "skip", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "bCycleAmmo:Options", + "text": "$SoulsyHUD_Options_CycleAmmo_Text", + "help": "$SoulsyHUD_Options_CycleAmmo_Help", + "type": "toggle", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "text": "$SoulsyHUD_Gameplay_FeelHeader", + "type": "header" + }, + { + "id": "uEquipDelay:Options", + "text": "$SoulsyHUD_Options_EquipDelay_Text", + "help": "$SoulsyHUD_Options_EquipDelay_Help", + "type": "slider", + "valueOptions": { + "min": 0, + "max": 2500, + "step": 50, + "sourceType": "ModSettingInt" + } + }, + { + "id": "uLongPressMillis:Options", + "text": "$SoulsyHUD_Options_LongPress_Text", + "help": "$SoulsyHUD_Options_LongPress_Help", + "type": "slider", + "valueOptions": { + "min": 750, + "max": 2500, + "step": 50, + "sourceType": "ModSettingInt" + } + }, + { + "id": "bCyclingSlowsTime:Options", + "text": "$SoulsyHUD_Options_SlowTime_Text", + "help": "$SoulsyHUD_Options_SlowTime_Help", + "type": "toggle", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "uSlowTimeFactor:Options", + "text": "$SoulsyHUD_Options_HowSlow_Text", + "help": "$SoulsyHUD_Options_HowSlow_Help", + "type": "slider", + "valueOptions": { + "min": 10, + "max": 90, + "step": 1, + "sourceType": "ModSettingInt" + } + } + ] + }, + { + "pageDisplayName": "$SoulsyHUD_Display_Page", + "cursorFillMode": "topToBottom", + "content": [ + { + "text": "$SoulsyHUD_Display_Header", + "type": "header" + }, + { + "id": "uAnchorLocation:Options", + "text": "$SoulsyHUD_Options_AnchorLoc_Text", + "type": "enum", + "help": "$SoulsyHUD_Options_AnchorLoc_Help", + "valueOptions": { + "options": [ + "$SoulsyHUD_AnchorLoc_None", + "$SoulsyHUD_AnchorLoc_TopLeft", + "$SoulsyHUD_AnchorLoc_TopRight", + "$SoulsyHUD_AnchorLoc_BottomLeft", + "$SoulsyHUD_AnchorLoc_BottomRight", + "$SoulsyHUD_AnchorLoc_Center", + "$SoulsyHUD_AnchorLoc_CenterTop", + "$SoulsyHUD_AnchorLoc_CenterBottom", + "$SoulsyHUD_AnchorLoc_LeftCenter", + "$SoulsyHUD_AnchorLoc_RightCenter" + ], + "sourceType": "ModSettingInt", + "defaultValue": 0 + } + }, + { + "id": "bAutoFade:Options", + "text": "$SoulsyHUD_Options_Fade_Text", + "help": "$SoulsyHUD_Options_Fade_Help", + "type": "toggle", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "uFadeTime:Options", + "text": "$SoulsyHUD_Options_FadeTime_Text", + "help": "$SoulsyHUD_Options_FadeTime_Help", + "type": "slider", + "valueOptions": { + "min": 0, + "max": 5000, + "step": 100, + "sourceType": "ModSettingInt" + } + }, + { + "id": "fMaxAlpha:Options", + "text": "$SoulsyHUD_Options_MaxAlpha_Text", + "help": "$SoulsyHUD_Options_MaxAlpha_Help", + "type": "slider", + "valueOptions": { + "min": 0.2, + "max": 1.0, + "step": 0.01, + "sourceType": "ModSettingFloat", + "formatString": "{2}" + } + }, + { + "id": "uShowHideKey:Controls", + "text": "$SoulsyHUD_Controls_ShowHideKey_Text", + "help": "$SoulsyHUD_Controls_ShowHideKey_Help", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "bColorizeIcons:Options", + "text": "$SoulsyHUD_Options_Colorize_Text", + "help": "$SoulsyHUD_Options_Colorize_Help", + "type": "toggle", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "uControllerKind:Options", + "text": "$SoulsyHUD_Options_Controller_Text", + "type": "enum", + "help": "$SoulsyHUD_Options_Controller_Help", + "valueOptions": { + "options": ["$SoulsyHUD_Controls_PS", "$SoulsyHUD_Controls_Xbox"], + "sourceType": "ModSettingInt", + "defaultValue": 0 + } + }, + { + "id": "uRefreshKey:Controls", + "text": "$SoulsyHUD_Controls_RefreshKey_Text", + "help": "$SoulsyHUD_Controls_RefreshKey_Help", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "sSKSEIdentifier:Options", + "text": "$SoulsyHUD_ModIdString_Text", + "help": "$SoulsyHUD_ModIdString_Help", + "type": "input", + "valueOptions": { + "sourceType": "ModSettingString" + } + }, + { + "id": "bDebugMode:Options", + "text": "$SoulsyHUD_Options_Debug_Text", + "help": "$SoulsyHUD_Options_Debug_Help", + "type": "toggle", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "text": "$SoulsyHUD_Maintenance_Header", + "type": "header", + "position": 1 + }, + { + "text": "$SoulsyHUD_Clear_Text", + "help": "$SoulsyHUD_Clear_Help", + "type": "text", + "valueOptions": { + "value": "clear" + }, + "action": { + "type": "CallFunction", + "function": "ClearCyclesPapyrus" + } + }, + { + "text": "$SoulsyHUD_CycleContents_Header", + "type": "header" + }, + { + "id": "pCycleToShow", + "text": "$SoulsyHUD_ChooseCycle_Text", + "help": "$SoulsyHUD_ChooseCycle_Help", + "type": "enum", + "valueOptions": { + "options": [ + "$SoulsyHUD_CycleEnum_Powers", + "$SoulsyHUD_CycleEnum_Utilities", + "$SoulsyHUD_CycleEnum_LeftHand", + "$SoulsyHUD_CycleEnum_RightHand" + ], + "sourceType": "PropertyValueInt", + "propertyName": "pCycleToShow", + "defaultValue": 0 + }, + "action": { + "type": "CallFunction", + "function": "ShowCycleEntries", + "params": ["{value}"] + } + }, + { + "id": "cycleDisplay", + "text": "$SoulsyHUD_ChosenCycle_Text", + "help": "$SoulsyHUD_ChosenCycle_Help", + "type": "menu", + "valueOptions": { + "options": [" ", " "], + "sourceType": "PropertyValueInt", + "propertyName": "pCycleItemShown", + "defaultValue": 0 + } + } + ] + }, + { + "pageDisplayName": "$SoulsyHUD_EquipSets_Page", + "cursorFillMode": "topToBottom", + "content": [ + { + "text": "$SoulsyHUD_EquipSets_Header", + "type": "header" + }, + { + "id": "iEquipSetCycleKey:Controls", + "text": "$SoulsyHUD_Controls_EquipSetCycleKey_Text", + "help": "$SoulsyHUD_Controls_EquipSetCycleKey_Help", + "type": "keymap", + "valueOptions": { + "sourceType": "ModSettingInt" + } + }, + { + "id": "bEquipSetsUnequip:Options", + "text": "$SoulsyHUD_EquipSetsUnequip_Text", + "help": "$SoulsyHUD_EquipSetsUnequip_Help", + "type": "toggle", + "valueOptions": { + "sourceType": "ModSettingBool" + } + }, + { + "id": "sLastUsedSetName:Equipsets", + "text": "$SoulsyHUD_EquipSetName_Text", + "help": "$SoulsyHUD_EquipSetName_Help", + "type": "input", + "valueOptions": { + "sourceType": "ModSettingString" + } + }, + { + "text": "$SoulsyHUD_NewEquipSet_Text", + "help": "$SoulsyHUD_NewEquipSet_Help", + "type": "text", + "action": { + "type": "CallFunction", + "function": "CreateEquipSet" + } + }, + { + "text": "$SoulsyHUD_UpdateASet_Header", + "type": "header" + }, + { + "id": "pEquipSetMenuSelection", + "text": "$SoulsyHUD_EquipSetList_Text", + "help": "$SoulsyHUD_EquipSetList_Help", + "type": "menu", + "valueOptions": { + "options": ["$SoulsyHUD_NoEquipSets", " "], + "sourceType": "PropertyValueString", + "propertyName": "pEquipSetMenuSelection" + } + }, + { + "id": "sLastEditedSetName:Equipsets", + "text": "$SoulsyHUD_SelectedEquipSetName_Text", + "help": "$SoulsyHUD_SelectedEquipSetName_Help", + "type": "input" + }, + { + "id": "renameEquipSet", + "text": "$SoulsyHUD_RenameSet_Text", + "help": "$SoulsyHUD_RenameSet_Help", + "type": "text", + "action": { + "type": "CallFunction", + "function": "RenameEquipSet" + } + }, + { + "id": "updateEquipSet", + "text": "$SoulsyHUD_UpdateSet_Text", + "help": "$SoulsyHUD_UpdateSet_Help", + "type": "text", + "action": { + "type": "CallFunction", + "function": "UpdateEquipSet" + } + }, + { + "id": "removeEquipSet", + "text": "$SoulsyHUD_RemoveSet_Text", + "help": "$SoulsyHUD_RemoveSet_Help", + "type": "text", + "action": { + "type": "CallFunction", + "function": "RemoveEquipSet" + } + }, + { + "text": "$SoulsyHUD_SelectedSet_Header", + "type": "header", + "position": 1 + }, + { + "id": "pIconSourceSelection", + "text": "$SoulsyHUD_EquipSetItemList_Text", + "help": "$SoulsyHUD_EquipSetItemList_Help", + "type": "menu", + "valueOptions": { + "options": ["$SoulsyHUD_NoItems", " "], + "sourceType": "PropertyValueString", + "propertyName": "pIconSourceSelection" + } + }, + { + "id": "useSelectedItemAsIcon", + "text": "$SoulsyHUD_UseItemAsIcon_Text", + "help": "$SoulsyHUD_UseItemAsIcon_Help", + "type": "text", + "action": { + "type": "CallFunction", + "function": "UseSelectionAsIcon" + } } - ] + ] + } + ] } diff --git a/installer/core/mcm/config/SoulsyHUD/settings.ini b/installer/core/mcm/config/SoulsyHUD/settings.ini index 7964d4ca..8397784b 100644 --- a/installer/core/mcm/config/SoulsyHUD/settings.ini +++ b/installer/core/mcm/config/SoulsyHUD/settings.ini @@ -33,6 +33,7 @@ bGroupPotions = 0 bCycleAmmo = 1 bColorizeIcons = 1 bEquipSetsUnequip = 1 +uAnchorLocation = none sSKSEIdentifier = SOLS bDebugMode = 0 sLogLevel = info diff --git a/src/controller/control.rs b/src/controller/control.rs index b26d75fc..dd2888a4 100644 --- a/src/controller/control.rs +++ b/src/controller/control.rs @@ -175,6 +175,9 @@ impl Controller { } } + // Apply any new anchor relocations to the current layout. + Layout::refresh(); + self.cache.introspect(); } diff --git a/src/controller/settings.rs b/src/controller/settings.rs index 8070589b..469acf48 100644 --- a/src/controller/settings.rs +++ b/src/controller/settings.rs @@ -12,7 +12,7 @@ use once_cell::sync::Lazy; use strum::Display; use super::keys::Hotkey; -use crate::plugin::HudElement; +use crate::{layouts::shared::NamedAnchor, plugin::HudElement}; /// This is the path to players's modified settings. static SETTINGS_PATH: &str = "./data/MCM/Settings/SoulsyHUD.ini"; @@ -100,6 +100,8 @@ pub struct UserSettings { showhide: u32, /// A hotkey for re-reading the layout from toml and redrawing. uRefreshKey refresh_layout: u32, + /// Layout anchor override. uAnchorLocation + anchor_loc: NamedAnchor, /// The number of milliseconds to delay before equipping a selection. Max 2500, min 0. equip_delay_ms: u32, @@ -141,6 +143,7 @@ impl Default for UserSettings { right: 7, equipset: 9, refresh_layout: 8, + anchor_loc: NamedAnchor::None, how_to_activate: ActivationMethod::Hotkey, activate: 4, activate_modifier: -1, @@ -184,6 +187,13 @@ impl UserSettings { settings.read_from_file(SETTINGS_PATH) } + pub fn refresh_with(fpath: &str) -> Result<()> { + let mut settings = SETTINGS + .lock() + .expect("Unrecoverable runtime problem: cannot acquire settings lock."); + settings.read_from_file(fpath) + } + /// Refresh ourselves from the MCM-controlled file. pub fn read_from_file(&mut self, fpath: &str) -> Result<()> { // We'll fall back to defaults at a different level. @@ -231,6 +241,7 @@ impl UserSettings { self.showhide = read_from_ini(self.showhide, "uShowHideKey", controls); self.refresh_layout = read_from_ini(self.refresh_layout, "uRefreshKey", controls); + self.anchor_loc = read_from_ini(self.anchor_loc.clone(), "uAnchorLocation", options); self.unarmed_handling = read_from_ini(self.unarmed_handling, "uHowToUnequip", controls); self.unequip_modifier = @@ -404,6 +415,9 @@ impl UserSettings { pub fn refresh_layout(&self) -> u32 { self.refresh_layout } + pub fn anchor_loc(&self) -> &NamedAnchor { + &self.anchor_loc + } pub fn maxlen(&self) -> u32 { 20 } @@ -591,6 +605,31 @@ impl FromIniStr for String { } } +impl FromIniStr for NamedAnchor { + fn from_ini(value: &str) -> Option + where + Self: Sized, + { + if let Ok(v) = value.parse::() { + match v { + 0 => Some(NamedAnchor::None), + 1 => Some(NamedAnchor::TopLeft), + 2 => Some(NamedAnchor::TopRight), + 3 => Some(NamedAnchor::BottomLeft), + 4 => Some(NamedAnchor::BottomRight), + 5 => Some(NamedAnchor::Center), + 6 => Some(NamedAnchor::CenterTop), + 7 => Some(NamedAnchor::CenterBottom), + 8 => Some(NamedAnchor::LeftCenter), + 9 => Some(NamedAnchor::LeftCenter), + _ => Some(NamedAnchor::None), + } + } else { + None + } + } +} + // qualified so we don't collide with the macro strum::Display // We implement this so the logs contain a human-readable dump of the settings // at save game load, so people can debug. @@ -606,6 +645,7 @@ impl std::fmt::Display for UserSettings { right cycle key: {} equipset cycle key: {} refresh layout key: {} + layout anchor override: {} how_to_activate: {} activate consumables: {} activate_modifier: {} @@ -638,6 +678,7 @@ impl std::fmt::Display for UserSettings { self.right, self.equipset, self.refresh_layout, + self.anchor_loc, self.how_to_activate, self.activate, self.activate_modifier, diff --git a/src/layouts/mod.rs b/src/layouts/mod.rs index 1936aaf8..1d619615 100644 --- a/src/layouts/mod.rs +++ b/src/layouts/mod.rs @@ -17,6 +17,7 @@ use serde::{Deserialize, Serialize}; use self::shared::NamedAnchor; use crate::control::notify; use crate::controller::control::translated_key; +use crate::controller::user_settings; use crate::plugin::{LayoutFlattened, Point}; static LAYOUT_PATH: &str = "./data/SKSE/Plugins/SoulsyHUD_Layout.toml"; @@ -35,7 +36,7 @@ pub fn hud_layout() -> LayoutFlattened { layout.clone() } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug, Clone)] #[serde(untagged)] pub enum Layout { Version1(Box), @@ -121,6 +122,13 @@ impl Layout { Layout::Version2(v) => LayoutFlattened::from(&**v), } } + + pub fn anchor_point(&self) -> Point { + match self { + Layout::Version1(v) => v.anchor_point(), + Layout::Version2(v) => v.anchor_point(), + } + } } pub fn anchor_point( @@ -137,7 +145,16 @@ pub fn anchor_point( let width = size.x * global_scale; let height = size.y * global_scale; - match anchor_name { + let config = *user_settings(); + let user_pref_anchor = config.anchor_loc(); + eprintln!("{user_pref_anchor}"); + let anchor_to_use = if !matches!(user_pref_anchor, &NamedAnchor::None) { + user_pref_anchor + } else { + anchor_name + }; + + match anchor_to_use { NamedAnchor::TopLeft => Point { x: width / 2.0, y: height / 2.0, @@ -322,4 +339,26 @@ mod tests { ); assert_eq!(pointed.anchor_point(), named.anchor_point()); } + + #[test] + fn anchor_points_respect_settings() { + // override the defaults with what we need for this test + let _ = crate::controller::UserSettings::refresh_with("tests/fixtures/test-settings.ini"); + + let named = Layout::read_from_file("tests/fixtures/named-anchor.toml") + .expect("this test fixture exists and is valid"); + // this layout has bottom left as an anchor point + // the test settings override with "center" + let relocated = named.anchor_point(); + assert_eq!( + relocated, + Point { + x: 1720.0, + y: 720.0 + } + ); + + let flattened = named.flatten(); + assert_eq!(flattened.anchor, relocated); + } } diff --git a/src/layouts/shared.rs b/src/layouts/shared.rs index 5ac1b017..851d51cf 100644 --- a/src/layouts/shared.rs +++ b/src/layouts/shared.rs @@ -132,6 +132,28 @@ where } } +impl From<&str> for NamedAnchor { + fn from(s: &str) -> Self { + match s.to_lowercase().as_str() { + "top_left" => NamedAnchor::TopLeft, + "top_right" => NamedAnchor::TopRight, + "bottom_left" => NamedAnchor::BottomLeft, + "bottom_right" => NamedAnchor::BottomRight, + "center" => NamedAnchor::Center, + "center_top" => NamedAnchor::CenterTop, + "top_center" => NamedAnchor::CenterTop, + "center_bottom" => NamedAnchor::CenterBottom, + "bottom_center" => NamedAnchor::CenterBottom, + "left_center" => NamedAnchor::LeftCenter, + "center_left" => NamedAnchor::LeftCenter, + "right_center" => NamedAnchor::RightCenter, + "center_right" => NamedAnchor::RightCenter, + "none" => NamedAnchor::None, + _ => NamedAnchor::None, + } + } +} + // ---------- MeterType // We can't derive this because it is exposed to C++. diff --git a/tests/fixtures/all-types.ini b/tests/fixtures/all-types.ini index bb8fd4cc..2c7bf8d2 100644 --- a/tests/fixtures/all-types.ini +++ b/tests/fixtures/all-types.ini @@ -12,6 +12,7 @@ bBooleanStringF = false bBooleanEmpty = sString = String with spaces sStringEmpty = +uNamedAnchor = "top_left" [emptysection] diff --git a/tests/fixtures/test-settings.ini b/tests/fixtures/test-settings.ini new file mode 100644 index 00000000..b21707c3 --- /dev/null +++ b/tests/fixtures/test-settings.ini @@ -0,0 +1,34 @@ +[Options] +bCycleAmmo = 1 +bAutoFade = 1 +bGroupPotions = 1 +bDebugMode = 1 +sSKSEIdentifier = WOMP +bLinkToFavorites = 1 +bEquipSetsUnequip = 1 +sLogLevel = debug +bCyclingSlowsTime = 1 +uFadeTime = 1500 +uEquipDelay = 2500 +uLongPressMillis = 2750 +uAnchorLocation = 5 + +[Controls] +uRefreshKey = 8 +uShowHideKey = 2 +uHowToUnequip = 0 +bLongPressMatches = 1 +iUnequipModifierKey = 184 +uPowerCycleKey = 3 +uLeftCycleKey = 5 +uRightCycleKey = 7 +uUtilityCycleKey = 6 +uHowToActivate = 0 +uHowToggleInMenus = 0 +iMenuModifierKey = 42 +iUtilityActivateModifier = 274 + + +[Equipsets] +sLastEditedSetName = Mossy +sLastUsedSetName = Spiky