diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..30e7761 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,53 @@ +name: Build + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + workflow_dispatch: + +env: + BUILD_TYPE: Release + VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg-cache + VCPKG_ROOT: C:\vcpkg + +jobs: + build: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Setup vcpkg + run: | + mkdir -p ${{ env.VCPKG_DEFAULT_BINARY_CACHE }} + cd $env:VCPKG_INSTALLATION_ROOT + ./bootstrap-vcpkg.bat + ./vcpkg --version > ${{ github.workspace }}/vcpkg-version.txt + + - name: Cache vcpkg + uses: actions/cache@v5 + id: vcpkg-cache + env: + cache-name: vcpkg-cache + with: + path: ${{ env.VCPKG_DEFAULT_BINARY_CACHE }}/* + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('main/**/vcpkg.json', 'vcpkg-version.txt') }} + + - name: Configure CMake + run: cmake --preset vs2022-windows -Wno-deprecated + + - name: Build + run: cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --parallel + + - name: Install + run: cmake --install ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --prefix ${{ github.workspace }}/install + + - name: Upload Artifact + uses: actions/upload-artifact@v6 + with: + name: ${{ github.event.repository.name }} + path: ${{ github.workspace }}/install diff --git a/.gitignore b/.gitignore index 4248a0c..7055510 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,2 @@ -build/ -buildVR/ -package/ +package*/ *.7z diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d662f3..35f9596 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,12 +2,12 @@ cmake_minimum_required(VERSION 3.24) project( MCMHelper - VERSION 1.5.0 + VERSION 1.6.0 LANGUAGES CXX ) # MCM Helper public release number -set(PLUGIN_VERSION 14) +set(PLUGIN_VERSION 15) set_property(GLOBAL PROPERTY USE_FOLDERS ON) @@ -58,21 +58,6 @@ target_include_directories( ${SIMPLEINI_INCLUDE_DIRS} ) -Papyrus_Add( - "Papyrus" - GAME ${SkyrimSE_PATH} - IMPORTS - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/private" - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public" - "$ENV{SKSE64Path}/Scripts/Source" - SOURCES - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/MCM.psc" - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/SKI_ConfigMenu.psc" - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/private/MCM_ConfigBase.psc" - OPTIMIZE - ANONYMIZE -) - set(TRANSLATION_FILES "${CMAKE_CURRENT_SOURCE_DIR}/data/Interface/Translations/MCMHelper_CZECH.txt" "${CMAKE_CURRENT_SOURCE_DIR}/data/Interface/Translations/MCMHelper_ENGLISH.txt" @@ -85,17 +70,39 @@ set(TRANSLATION_FILES "${CMAKE_CURRENT_SOURCE_DIR}/data/Interface/Translations/MCMHelper_SPANISH.txt" ) -BSArchive_Add( - "BSA" - OUTPUT "MCMHelper.bsa" - FORMAT SSE - FILES - ${Papyrus_OUTPUT} - ${TRANSLATION_FILES} - PREFIX - "${CMAKE_CURRENT_SOURCE_DIR}/data" -) - -add_dependencies("BSA" "Papyrus") +if(SkyrimSE_PATH) + Papyrus_Add( + "Papyrus" + GAME ${SkyrimSE_PATH} + IMPORTS + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/private" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public" + "$ENV{SKSE64Path}/Scripts/Source" + SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/MCM.psc" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/SKI_ConfigMenu.psc" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/private/MCM_ConfigBase.psc" + OPTIMIZE + ANONYMIZE + ) + + BSArchive_Add( + "BSA" + OUTPUT "MCMHelper.bsa" + FORMAT SSE + FILES + ${Papyrus_OUTPUT} + ${TRANSLATION_FILES} + PREFIX + "${CMAKE_CURRENT_SOURCE_DIR}/data" + ) + + add_dependencies("BSA" "Papyrus") +endif() include(install_files.cmake) + +if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + file(WRITE "${CMAKE_BINARY_DIR}/.gitignore" "*") + file(WRITE "${CMAKE_BINARY_DIR}/.hgignore" "syntax: glob\n**/*") +endif() diff --git a/CMakePresets.json b/CMakePresets.json index 2aa5055..4518c7b 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -32,11 +32,11 @@ "cacheVariables": { "CMAKE_MSVC_RUNTIME_LIBRARY": { "type": "STRING", - "value": "MultiThreaded$<$:Debug>DLL" + "value": "MultiThreaded$<$:Debug>" }, "VCPKG_TARGET_TRIPLET": { "type": "STRING", - "value": "x64-windows-static-md" + "value": "x64-windows-static" } }, "hidden": true, diff --git a/data/MCM/Config/SkyUI_SE/config.json b/data/MCM/Config/SkyUI_SE/config.json index 3a3891d..27e032e 100644 --- a/data/MCM/Config/SkyUI_SE/config.json +++ b/data/MCM/Config/SkyUI_SE/config.json @@ -609,85 +609,6 @@ "step": 1, "sourceType": "ModSettingInt" } - }, - { - "type": "empty" - }, - { - "text": "$SWF Version Checking", - "type": "header" - }, - { - "id": "bMapMenu:SWFVersionCheck", - "text": "$Map Menu", - "help": "$SKI_INFO3{$On}", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingBool" - } - }, - { - "id": "bFavoritesMenu:SWFVersionCheck", - "text": "$Favorites Menu", - "help": "$SKI_INFO3{$On}", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingBool" - } - }, - { - "id": "bInventoryMenu:SWFVersionCheck", - "text": "$Inventory Menu", - "help": "$SKI_INFO3{$On}", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingBool" - } - }, - { - "id": "bMagicMenu:SWFVersionCheck", - "text": "$Magic Menu", - "help": "$SKI_INFO3{$On}", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingBool" - } - }, - { - "id": "bBarterMenu:SWFVersionCheck", - "text": "$Barter Menu", - "help": "$SKI_INFO3{$On}", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingBool" - } - }, - { - "id": "bContainerMenu:SWFVersionCheck", - "text": "$Container Menu", - "help": "$SKI_INFO3{$On}", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingBool" - } - }, - { - "id": "bCraftingMenu:SWFVersionCheck", - "text": "$Crafting Menu", - "help": "$SKI_INFO3{$On}", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingBool" - } - }, - { - "id": "bGiftMenu:SWFVersionCheck", - "text": "$Gift Menu", - "help": "$SKI_INFO3{$On}", - "type": "toggle", - "valueOptions": { - "sourceType": "ModSettingBool" - } } ] } diff --git a/data/fomod/ModuleConfig.xml b/data/fomod/ModuleConfig.xml index f9dfcbd..b24ff09 100644 --- a/data/fomod/ModuleConfig.xml +++ b/data/fomod/ModuleConfig.xml @@ -60,7 +60,7 @@ - Install a standard ESP, which uses one of the 255 normal plugin slots. + Install a standard ESP, which uses one of the 254 normal plugin slots. diff --git a/external/CommonLibSSE b/external/CommonLibSSE index 8b59b9a..e9e9e40 160000 --- a/external/CommonLibSSE +++ b/external/CommonLibSSE @@ -1 +1 @@ -Subproject commit 8b59b9a69ab670824e55df376d4176c22f0006f3 +Subproject commit e9e9e4048d608cf1ee9355b9b13e3ca9a94a7132 diff --git a/install_files.cmake b/install_files.cmake index 74cf015..e327e4c 100644 --- a/install_files.cmake +++ b/install_files.cmake @@ -13,12 +13,14 @@ install( COMPONENT ESL ) -install( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/MCMHelper.bsa" - DESTINATION "." - COMPONENT BSA -) +if(TARGET BSA) + install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/MCMHelper.bsa" + DESTINATION "." + COMPONENT BSA + ) +endif() install( FILES ${TRANSLATION_FILES} @@ -27,12 +29,14 @@ install( EXCLUDE_FROM_ALL ) -install( - FILES ${Papyrus_OUTPUT} - DESTINATION "Scripts" - COMPONENT Loose - EXCLUDE_FROM_ALL -) +if(TARGET Papyrus) + install( + FILES ${Papyrus_OUTPUT} + DESTINATION "Scripts" + COMPONENT Loose + EXCLUDE_FROM_ALL + ) +endif() install( FILES @@ -51,37 +55,39 @@ install( COMPONENT Data ) -install( - FILES - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/SKI_ConfigMenu.psc" - DESTINATION - "Source/Scripts" - COMPONENT Data -) +if(TARGET Papyrus) + install( + FILES + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/SKI_ConfigMenu.psc" + DESTINATION + "Source/Scripts" + COMPONENT Data + ) -install( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/Scripts/MCM.pex" - "${CMAKE_CURRENT_BINARY_DIR}/Scripts/MCM_ConfigBase.pex" - "${CMAKE_CURRENT_SOURCE_DIR}/data/SDK/Scripts/SKI_ConfigBase.pex" - "${CMAKE_CURRENT_SOURCE_DIR}/data/SDK/Scripts/SKI_ConfigManager.pex" - "${CMAKE_CURRENT_SOURCE_DIR}/data/SDK/Scripts/SKI_PlayerLoadGameAlias.pex" - "${CMAKE_CURRENT_SOURCE_DIR}/data/SDK/Scripts/SKI_QuestBase.pex" - DESTINATION "Scripts" - COMPONENT SDK - EXCLUDE_FROM_ALL -) + install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/Scripts/MCM.pex" + "${CMAKE_CURRENT_BINARY_DIR}/Scripts/MCM_ConfigBase.pex" + "${CMAKE_CURRENT_SOURCE_DIR}/data/SDK/Scripts/SKI_ConfigBase.pex" + "${CMAKE_CURRENT_SOURCE_DIR}/data/SDK/Scripts/SKI_ConfigManager.pex" + "${CMAKE_CURRENT_SOURCE_DIR}/data/SDK/Scripts/SKI_PlayerLoadGameAlias.pex" + "${CMAKE_CURRENT_SOURCE_DIR}/data/SDK/Scripts/SKI_QuestBase.pex" + DESTINATION "Scripts" + COMPONENT SDK + EXCLUDE_FROM_ALL + ) -install( - FILES - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/MCM.psc" - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/MCM_ConfigBase.psc" - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/SKI_ConfigBase.psc" - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/SKI_QuestBase.psc" - DESTINATION "Source/Scripts" - COMPONENT SDK - EXCLUDE_FROM_ALL -) + install( + FILES + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/MCM.psc" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/MCM_ConfigBase.psc" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/SKI_ConfigBase.psc" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/public/SKI_QuestBase.psc" + DESTINATION "Source/Scripts" + COMPONENT SDK + EXCLUDE_FROM_ALL + ) +endif() install( FILES diff --git a/scripts/public/SKI_ConfigMenu.psc b/scripts/public/SKI_ConfigMenu.psc index 458081d..83d6640 100644 --- a/scripts/public/SKI_ConfigMenu.psc +++ b/scripts/public/SKI_ConfigMenu.psc @@ -15,7 +15,9 @@ string[] _alignmentValues ; Internal float _itemXBase +float _itemYBase float _itemXBaseW +float _itemYBaseW ; -- Version 2 -- @@ -120,8 +122,12 @@ event OnConfigInit() _vertAlignmentBaseOffsets[1] = 720.0 _vertAlignmentBaseOffsets[2] = 360.0 - ; Give SKI_FavoritesManager time to initialize - Utility.Wait(5) + ; Wait for SKI_FavoritesManager to initialize + int wait_for = 10 + while wait_for && SKI_FavoritesManagerInstance.GetGroupHotkeys()[7] == 0 + Utility.Wait(0.5) + wait_for -= 1 + endWhile LoadSettings() endEvent @@ -197,7 +203,7 @@ event OnSettingChange(string a_ID) elseif a_ID == "bHelpEnabled:FavoritesMenu" SKI_FavoritesManagerInstance.ButtonHelpEnabled = GetModSettingBool(a_ID) - ; SWFVersionCheck + ;/ SWFVersionCheck elseif a_ID == "bMapMenu:SWFVersionCheck" SKI_MainInstance.MapMenuCheckEnabled = GetModSettingBool(a_ID) elseif a_ID == "bFavoritesMenu:SWFVersionCheck" @@ -214,6 +220,7 @@ event OnSettingChange(string a_ID) SKI_MainInstance.CraftingMenuCheckEnabled = GetModSettingBool(a_ID) elseif a_ID == "bGiftMenu:SWFVersionCheck" SKI_MainInstance.GiftMenuCheckEnabled = GetModSettingBool(a_ID) + /; ; Controls elseif a_ID == "iSearchKey:Controls" @@ -319,10 +326,10 @@ function Apply3DItemYOffset(float a_value) Utility.SetINIFloat("fMagic3DItemPosZWide:Interface", _fMagic3DItemPosZWide) Utility.SetINIFloat("fMagic3DItemPosZ:Interface", _fMagic3DItemPosZ) else - Utility.SetINIFloat("fInventory3DItemPosZWide:Interface", (12 + a_value)) - Utility.SetINIFloat("fInventory3DItemPosZ:Interface", (16 + a_value)) - Utility.SetINIFloat("fMagic3DItemPosZWide:Interface", (12 + a_value)) - Utility.SetINIFloat("fMagic3DItemPosZ:Interface", (16 + a_value)) + Utility.SetINIFloat("fInventory3DItemPosZWide:Interface", (_itemYBaseW + a_value)) + Utility.SetINIFloat("fInventory3DItemPosZ:Interface", (_itemYBase + a_value)) + Utility.SetINIFloat("fMagic3DItemPosZWide:Interface", (_itemYBaseW + a_value)) + Utility.SetINIFloat("fMagic3DItemPosZ:Interface", (_itemYBase + a_value)) endIf endFunction @@ -423,7 +430,7 @@ function LoadSettings() GroupIdx += 1 endWhile - ; SWFVersionCheck + ;/ SWFVersionCheck SKI_MainInstance.MapMenuCheckEnabled = GetModSettingBool("bMapMenu:SWFVersionCheck") SKI_MainInstance.FavoritesMenuCheckEnabled = GetModSettingBool("bFavoritesMenu:SWFVersionCheck") SKI_MainInstance.InventoryMenuCheckEnabled = GetModSettingBool("bInventoryMenu:SWFVersionCheck") @@ -432,6 +439,7 @@ function LoadSettings() SKI_MainInstance.ContainerMenuCheckEnabled = GetModSettingBool("bContainerMenu:SWFVersionCheck") SKI_MainInstance.CraftingMenuCheckEnabled = GetModSettingBool("bCraftingMenu:SWFVersionCheck") SKI_MainInstance.GiftMenuCheckEnabled = GetModSettingBool("bGiftMenu:SWFVersionCheck") + /; ; Controls SKI_SettingsManagerInstance.SetOverride("Input$controls$pc$search", GetModSettingInt("iSearchKey:Controls")) @@ -477,23 +485,33 @@ function ApplySettings() _fInventory3DItemPosScale = Utility.GetINIFloat("fInventory3DItemPosScale:Interface") _fMagic3DItemPosScale = Utility.GetINIFloat("fMagic3DItemPosScale:Interface") - float h = Utility.GetINIInt("iSize H:Display") - float w = Utility.GetINIInt("iSize W:Display") - float ar = w / h + float fStageCenterX = 640.0 ; Stage Center X (1280 / 2) + float fStageCenterY = 360.0 ; Stage Center Y (720 / 2) + float fStageUnitsPerUnit = 8.0 ; 1 unit 3DItemPos = 8px in 1280x720 + float fTargetX ; ItemCard Center X + float fTargetY ; ItemCard Center Y + + float fWidth = Utility.GetINIInt("iSize W:Display") as float + float fHeight = Utility.GetINIInt("iSize H:Display") as float + + float fAspect = fWidth / fHeight + + if (fAspect > 3.0) ; 32:9 (Super Ultrawide) + fTargetX = 785.5 + fTargetY = 300.0 + elseif (fAspect > 2.0) ; 21:9 (Ultrawide) + fTargetX = 858.0 + fTargetY = 275.0 + else ; 16:9 / 16:10 / 4:3 (Standard) + fTargetX = 931.225 + fTargetY = 250.0 + endif - ; Widescreen - if (ar == 1.6) ; 16:10, 1920×1200 - _itemXBaseW = -32.458335876465 - else - _itemXBaseW = -29.122497558594 - endIf + _itemXBaseW = -(fTargetX - fStageCenterX) / fStageUnitsPerUnit + _itemXBase = _itemXBaseW - ; Non-widescreen - if (ar == 1.25) ; 5:4, 1280x1024 - _itemXBase = -41.622497558594 - else - _itemXBase = -39.122497558594 - endIf + _itemYBaseW = -(fTargetY - fStageCenterY) / fStageUnitsPerUnit + _itemYBase = _itemYBaseW Apply3DItemXOffset(GetModSettingFloat("fXOffset:3DItem")) Apply3DItemYOffset(GetModSettingFloat("fYOffset:3DItem")) diff --git a/src/Config/Action.cpp b/src/Config/Action.cpp index 8e1818d..063d79e 100644 --- a/src/Config/Action.cpp +++ b/src/Config/Action.cpp @@ -85,26 +85,30 @@ void Function::SendControlEvent(bool a_up, [[maybe_unused]] float a_holdTime) } } -VMAwaitable CallFunction::Invoke(RE::BSScript::IVirtualMachine* a_vm, FunctionParam a_value) +void CallFunction::Invoke(RE::BSScript::IVirtualMachine* a_vm, FunctionParam a_value) { if (!a_vm || Function.empty()) - return {}; + return; auto object = ScriptObject::FromForm(Form, ScriptName); if (!object) - return {}; + return; auto args = FunctionArguments::Make(Params, a_value); - return a_vm->DispatchMethodCall(object, Function, args.get()); + + ScriptCallbackPtr nullCallback; + a_vm->DispatchMethodCall(object, Function, args.get(), nullCallback); } -VMAwaitable CallGlobalFunction::Invoke(RE::BSScript::IVirtualMachine* a_vm, FunctionParam a_value) +void CallGlobalFunction::Invoke(RE::BSScript::IVirtualMachine* a_vm, FunctionParam a_value) { if (!a_vm || Function.empty() || ScriptName.empty()) - return {}; + return; auto args = FunctionArguments::Make(Params, a_value); - return a_vm->DispatchStaticCall(ScriptName, Function, args.get()); + + ScriptCallbackPtr nullCallback; + a_vm->DispatchStaticCall(ScriptName, Function, args.get(), nullCallback); } void SendEvent::SendControlEvent(bool a_up, float a_holdTime) diff --git a/src/Config/Action.h b/src/Config/Action.h index 35cb043..95a84c1 100644 --- a/src/Config/Action.h +++ b/src/Config/Action.h @@ -21,7 +21,7 @@ class Function : public Action }; virtual void SendControlEvent(bool a_up, float a_holdTime) override; - virtual VMAwaitable Invoke( + virtual void Invoke( RE::BSScript::IVirtualMachine* a_vm, FunctionParam a_value = "{value}"s) = 0; @@ -33,7 +33,7 @@ class Function : public Action class CallFunction : public Function { public: - VMAwaitable Invoke(RE::BSScript::IVirtualMachine* a_vm, FunctionParam a_value) override; + void Invoke(RE::BSScript::IVirtualMachine* a_vm, FunctionParam a_value) override; RE::TESForm* Form; }; @@ -41,7 +41,7 @@ class CallFunction : public Function class CallGlobalFunction : public Function { public: - VMAwaitable Invoke(RE::BSScript::IVirtualMachine* a_vm, FunctionParam a_value) override; + void Invoke(RE::BSScript::IVirtualMachine* a_vm, FunctionParam a_value) override; }; class SendEvent : public Action diff --git a/src/Config/Control.cpp b/src/Config/Control.cpp index 958ac8e..e4ca469 100644 --- a/src/Config/Control.cpp +++ b/src/Config/Control.cpp @@ -14,12 +14,11 @@ void Control::Refresh( { } -VMAwaitable Control::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) +void Control::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) { - if (!Action) - return {}; - - return Action->Invoke(a_vm); + if (Action) { + Action->Invoke(a_vm); + } } void Control::ResetToDefault() @@ -122,12 +121,11 @@ void TextControl::Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_ RefreshFlags(a_configScript, a_optionID); } -VMAwaitable TextControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) +void TextControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) { - if (!Action) - return {}; - - return Action->Invoke(a_vm, GetValue()); + if (Action) { + Action->Invoke(a_vm, GetValue()); + } } void TextControl::ResetToDefault() @@ -163,12 +161,11 @@ void ToggleControl::Refresh(const ScriptObjectPtr& a_configScript, std::int32_t RefreshFlags(a_configScript, a_optionID); } -VMAwaitable ToggleControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) +void ToggleControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) { - if (!Action) - return {}; - - return Action->Invoke(a_vm, GetValue()); + if (Action) { + Action->Invoke(a_vm, GetValue()); + } } void ToggleControl::ResetToDefault() @@ -204,12 +201,11 @@ void SliderControl::Refresh(const ScriptObjectPtr& a_configScript, std::int32_t RefreshFlags(a_configScript, a_optionID); } -VMAwaitable SliderControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) +void SliderControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) { - if (!Action) - return {}; - - return Action->Invoke(a_vm, GetValue()); + if (Action) { + Action->Invoke(a_vm, GetValue()); + } } void SliderControl::ResetToDefault() @@ -253,12 +249,11 @@ void StepperControl::Refresh(const ScriptObjectPtr& a_configScript, std::int32_t RefreshFlags(a_configScript, a_optionID); } -VMAwaitable StepperControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) +void StepperControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) { - if (!Action) - return {}; - - return Action->Invoke(a_vm, GetValue()); + if (Action) { + Action->Invoke(a_vm, GetValue()); + } } void StepperControl::ResetToDefault() @@ -304,12 +299,11 @@ void MenuControl::Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_ RefreshFlags(a_configScript, a_optionID); } -VMAwaitable MenuControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) +void MenuControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) { - if (!Action) - return {}; - - return Action->Invoke(a_vm, GetValue()); + if (Action) { + Action->Invoke(a_vm, GetValue()); + } } void MenuControl::ResetToDefault() @@ -366,12 +360,11 @@ void EnumControl::Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_ RefreshFlags(a_configScript, a_optionID); } -VMAwaitable EnumControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) +void EnumControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) { - if (!Action) - return {}; - - return Action->Invoke(a_vm, GetValue()); + if (Action) { + Action->Invoke(a_vm, GetValue()); + } } void EnumControl::ResetToDefault() @@ -426,12 +419,11 @@ void ColorControl::Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a RefreshFlags(a_configScript, a_optionID); } -VMAwaitable ColorControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) +void ColorControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) { - if (!Action) - return {}; - - return Action->Invoke(a_vm, static_cast(GetColor())); + if (Action) { + Action->Invoke(a_vm, static_cast(GetColor())); + } } void ColorControl::ResetToDefault() @@ -467,12 +459,11 @@ void KeyMapControl::Refresh(const ScriptObjectPtr& a_configScript, std::int32_t RefreshFlags(a_configScript, a_optionID); } -VMAwaitable KeyMapControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) +void KeyMapControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) { - if (!Action) - return {}; - - return Action->Invoke(a_vm, static_cast(GetKeyCode())); + if (Action) { + Action->Invoke(a_vm, static_cast(GetKeyCode())); + } } void KeyMapControl::ResetToDefault() @@ -548,12 +539,11 @@ void InputControl::Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a RefreshFlags(a_configScript, a_optionID); } -VMAwaitable InputControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) +void InputControl::InvokeAction(RE::BSScript::IVirtualMachine* a_vm) { - if (!Action) - return {}; - - return Action->Invoke(a_vm, GetValue()); + if (Action) { + Action->Invoke(a_vm, GetValue()); + } } void InputControl::ResetToDefault() diff --git a/src/Config/Control.h b/src/Config/Control.h index 266d84f..20fb0c9 100644 --- a/src/Config/Control.h +++ b/src/Config/Control.h @@ -19,7 +19,7 @@ class Control [[nodiscard]] virtual std::int32_t Add(const ScriptObjectPtr& a_configScript) = 0; virtual void Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_optionID); - virtual VMAwaitable InvokeAction(RE::BSScript::IVirtualMachine* a_vm); + virtual void InvokeAction(RE::BSScript::IVirtualMachine* a_vm); virtual void ResetToDefault(); [[nodiscard]] virtual std::string GetInfoText() const; [[nodiscard]] virtual std::string GetValueString() const; @@ -62,7 +62,7 @@ class TextControl : public Control public: [[nodiscard]] std::int32_t Add(const ScriptObjectPtr& a_configScript) override; void Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_optionID) override; - VMAwaitable InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; + void InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; void ResetToDefault() override; [[nodiscard]] std::string GetValueString() const override; @@ -77,7 +77,7 @@ class ToggleControl : public Control public: [[nodiscard]] std::int32_t Add(const ScriptObjectPtr& a_configScript) override; void Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_optionID) override; - VMAwaitable InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; + void InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; void ResetToDefault() override; [[nodiscard]] std::string GetValueString() const override; @@ -92,7 +92,7 @@ class SliderControl : public Control public: [[nodiscard]] std::int32_t Add(const ScriptObjectPtr& a_configScript) override; void Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_optionID) override; - VMAwaitable InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; + void InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; void ResetToDefault() override; [[nodiscard]] std::string GetValueString() const override; @@ -111,7 +111,7 @@ class StepperControl : public Control public: [[nodiscard]] std::int32_t Add(const ScriptObjectPtr& a_configScript) override; void Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_optionID) override; - VMAwaitable InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; + void InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; void ResetToDefault() override; [[nodiscard]] std::string GetValueString() const override; @@ -128,7 +128,7 @@ class MenuControl : public MenuDialogControl public: [[nodiscard]] std::int32_t Add(const ScriptObjectPtr& a_configScript) override; void Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_optionID) override; - VMAwaitable InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; + void InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; void ResetToDefault() override; [[nodiscard]] std::string GetValueString() const override; @@ -145,7 +145,7 @@ class EnumControl : public MenuDialogControl public: [[nodiscard]] std::int32_t Add(const ScriptObjectPtr& a_configScript) override; void Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_optionID) override; - VMAwaitable InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; + void InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; void ResetToDefault() override; [[nodiscard]] std::string GetValueString() const override; @@ -161,7 +161,7 @@ class ColorControl : public Control public: [[nodiscard]] std::int32_t Add(const ScriptObjectPtr& a_configScript) override; void Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_optionID) override; - VMAwaitable InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; + void InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; void ResetToDefault() override; [[nodiscard]] std::string GetValueString() const override; @@ -175,7 +175,7 @@ class KeyMapControl : public Control public: [[nodiscard]] std::int32_t Add(const ScriptObjectPtr& a_configScript) override; void Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_optionID) override; - VMAwaitable InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; + void InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; void ResetToDefault() override; [[nodiscard]] std::string GetInfoText() const override; [[nodiscard]] std::string GetValueString() const override; @@ -194,7 +194,7 @@ class InputControl : public Control public: [[nodiscard]] std::int32_t Add(const ScriptObjectPtr& a_configScript) override; void Refresh(const ScriptObjectPtr& a_configScript, std::int32_t a_optionID) override; - VMAwaitable InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; + void InvokeAction(RE::BSScript::IVirtualMachine* a_vm) override; void ResetToDefault() override; [[nodiscard]] std::string GetValueString() const override; diff --git a/src/Papyrus/MCM_ConfigBase.cpp b/src/Papyrus/MCM_ConfigBase.cpp index 4ea5d06..e232c71 100644 --- a/src/Papyrus/MCM_ConfigBase.cpp +++ b/src/Papyrus/MCM_ConfigBase.cpp @@ -106,7 +106,7 @@ namespace Papyrus SettingStore::GetInstance().SetModSettingString(modName, a_settingName, a_value); } - LatentResult<> MCM_ConfigBase::OnPageReset( + void MCM_ConfigBase::OnPageReset( RE::BSScript::IVirtualMachine* a_vm, [[maybe_unused]] RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -127,7 +127,7 @@ namespace Papyrus if (config) { config->ShowPage(object, a_page); - co_await SendPageSelectEvent(a_vm, object, a_page); + SendPageSelectEvent(a_vm, object, a_page); } } @@ -143,7 +143,7 @@ namespace Papyrus UpdateInfoText(object, false); } - LatentResult<> MCM_ConfigBase::OnOptionSelect( + void MCM_ConfigBase::OnOptionSelect( RE::BSScript::IVirtualMachine* a_vm, [[maybe_unused]] RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -151,7 +151,7 @@ namespace Papyrus { const auto& configPageCache = ConfigPageCache::GetInstance(); if (a_self != configPageCache.GetCurrentForm()) - co_return; + return; const auto object = ScriptObject::FromForm(a_self, ScriptName); @@ -176,7 +176,7 @@ namespace Papyrus } } - co_await SendSettingChangeEvent(a_vm, object, toggle->ID); + SendSettingChangeEvent(a_vm, object, toggle->ID); } else if (const auto stepper = std::dynamic_pointer_cast(control)) { if (stepper->ValueSource && !stepper->Options.empty()) { @@ -187,18 +187,18 @@ namespace Papyrus stepper->Refresh(object, a_option); - co_await SendSettingChangeEvent(a_vm, object, stepper->ID); + SendSettingChangeEvent(a_vm, object, stepper->ID); } else if (const auto error = std::dynamic_pointer_cast(control)) { - co_await SkyUI::Config::ShowMessage(object, error->Error, false); + SkyUI::Config::ShowMessage(object, error->Error, false, nullptr); } if (control) { - co_await control->InvokeAction(a_vm); + control->InvokeAction(a_vm); } } - LatentResult<> MCM_ConfigBase::OnOptionDefault( + void MCM_ConfigBase::OnOptionDefault( RE::BSScript::IVirtualMachine* a_vm, [[maybe_unused]] RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -206,7 +206,7 @@ namespace Papyrus { const auto& configPageCache = ConfigPageCache::GetInstance(); if (a_self != configPageCache.GetCurrentForm()) - co_return; + return; const auto object = ScriptObject::FromForm(a_self, ScriptName); @@ -214,7 +214,7 @@ namespace Papyrus if (control) { control->ResetToDefault(); - co_await SendSettingChangeEvent(a_vm, object, control->ID); + SendSettingChangeEvent(a_vm, object, control->ID); control->Refresh(object, a_option); } } @@ -243,7 +243,7 @@ namespace Papyrus } } - LatentResult<> MCM_ConfigBase::OnOptionSliderAccept( + void MCM_ConfigBase::OnOptionSliderAccept( RE::BSScript::IVirtualMachine* a_vm, [[maybe_unused]] RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -252,7 +252,7 @@ namespace Papyrus { const auto& configPageCache = ConfigPageCache::GetInstance(); if (a_self != configPageCache.GetCurrentForm()) - co_return; + return; const auto object = ScriptObject::FromForm(a_self, ScriptName); @@ -265,9 +265,9 @@ namespace Papyrus slider->Refresh(object, a_option); - co_await SendSettingChangeEvent(a_vm, object, slider->ID); + SendSettingChangeEvent(a_vm, object, slider->ID); - co_await slider->InvokeAction(a_vm); + slider->InvokeAction(a_vm); } } @@ -315,7 +315,7 @@ namespace Papyrus } } - LatentResult<> MCM_ConfigBase::OnOptionMenuAccept( + void MCM_ConfigBase::OnOptionMenuAccept( RE::BSScript::IVirtualMachine* a_vm, [[maybe_unused]] RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -324,7 +324,7 @@ namespace Papyrus { const auto& configPageCache = ConfigPageCache::GetInstance(); if (a_self != configPageCache.GetCurrentForm()) - co_return; + return; const auto object = ScriptObject::FromForm(a_self, ScriptName); @@ -338,9 +338,9 @@ namespace Papyrus menu->Refresh(object, a_option); - co_await SendSettingChangeEvent(a_vm, object, menu->ID); + SendSettingChangeEvent(a_vm, object, menu->ID); - co_await menu->InvokeAction(a_vm); + menu->InvokeAction(a_vm); } else if (const auto menuEnum = std::dynamic_pointer_cast(control)) { if (menuEnum->ValueSource) { @@ -349,9 +349,9 @@ namespace Papyrus menuEnum->Refresh(object, a_option); - co_await SendSettingChangeEvent(a_vm, object, menuEnum->ID); + SendSettingChangeEvent(a_vm, object, menuEnum->ID); - co_await menuEnum->InvokeAction(a_vm); + menuEnum->InvokeAction(a_vm); } } @@ -377,7 +377,7 @@ namespace Papyrus } } - LatentResult<> MCM_ConfigBase::OnOptionColorAccept( + void MCM_ConfigBase::OnOptionColorAccept( RE::BSScript::IVirtualMachine* a_vm, [[maybe_unused]] RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -386,7 +386,7 @@ namespace Papyrus { const auto& configPageCache = ConfigPageCache::GetInstance(); if (a_self != configPageCache.GetCurrentForm()) - co_return; + return; const auto object = ScriptObject::FromForm(a_self, ScriptName); @@ -399,13 +399,13 @@ namespace Papyrus color->Refresh(object, a_option); - co_await SendSettingChangeEvent(a_vm, object, color->ID); + SendSettingChangeEvent(a_vm, object, color->ID); - co_await color->InvokeAction(a_vm); + color->InvokeAction(a_vm); } } - LatentResult<> MCM_ConfigBase::OnOptionKeyMapChange( + void MCM_ConfigBase::OnOptionKeyMapChange( RE::BSScript::IVirtualMachine* a_vm, [[maybe_unused]] RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -416,15 +416,33 @@ namespace Papyrus { const auto& configPageCache = ConfigPageCache::GetInstance(); if (a_self != configPageCache.GetCurrentForm()) - co_return; + return; const auto object = ScriptObject::FromForm(a_self, ScriptName); const auto control = configPageCache.GetControl(a_option); if (const auto keymap = std::dynamic_pointer_cast(control)) { - - bool confirm = true; + std::function updateKey = [=](bool confirm) + { + if (confirm) { + if (keymap->ValueSource) { + // Keycodes are normally unsigned ints, but SkyUI will send -1 to indicate + // a key being unmapped; the double cast fixes this + const auto iKeyCode = static_cast(a_keyCode); + keymap->ValueSource->SetValue(static_cast(iKeyCode)); + } + else if (!keymap->ID.empty()) { + const auto modName = FormUtil::GetModName(a_self); + auto& keybindManager = KeybindManager::GetInstance(); + keybindManager.Register(a_keyCode, modName, keymap->ID); + keybindManager.CommitKeybinds(); + } + + keymap->Refresh(object, a_option); + SendSettingChangeEvent(a_vm, object, keymap->ID); + } + }; if (!a_conflictControl.empty() && !keymap->IgnoreConflicts && a_keyCode != keymap->GetKeyCode() && a_keyCode != static_cast(-1)) { @@ -443,28 +461,13 @@ namespace Papyrus msg = fmt::format("$MCM_KeyAlreadyMapped{{{}}}"sv, conflictControl); } - confirm = co_await SkyUI::Config::ShowMessage(object, msg); + SkyUI::Config::ShowMessage(object, msg, updateKey); } - - if (confirm) { - if (keymap->ValueSource) { - // Keycodes are normally unsigned ints, but SkyUI will send -1 to indicate a - // key being unmapped; the double cast fixes this - const auto iKeyCode = static_cast(a_keyCode); - keymap->ValueSource->SetValue(static_cast(iKeyCode)); - } - else if (!keymap->ID.empty()) { - const auto modName = FormUtil::GetModName(a_self); - auto& keybindManager = KeybindManager::GetInstance(); - keybindManager.Register(a_keyCode, modName, keymap->ID); - keybindManager.CommitKeybinds(); - } - - keymap->Refresh(object, a_option); - co_await SendSettingChangeEvent(a_vm, object, keymap->ID); - - co_await keymap->InvokeAction(a_vm); + else { + updateKey(true); } + + keymap->InvokeAction(a_vm); } } @@ -489,7 +492,7 @@ namespace Papyrus } } - LatentResult<> MCM_ConfigBase::OnOptionInputAccept( + void MCM_ConfigBase::OnOptionInputAccept( RE::BSScript::IVirtualMachine* a_vm, [[maybe_unused]] RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -498,7 +501,7 @@ namespace Papyrus { const auto& configPageCache = ConfigPageCache::GetInstance(); if (a_self != configPageCache.GetCurrentForm()) - co_return; + return; const auto object = ScriptObject::FromForm(a_self, ScriptName); @@ -511,9 +514,9 @@ namespace Papyrus input->Refresh(object, a_option); - co_await SendSettingChangeEvent(a_vm, object, input->ID); + SendSettingChangeEvent(a_vm, object, input->ID); - co_await input->InvokeAction(a_vm); + input->InvokeAction(a_vm); } } @@ -573,7 +576,7 @@ namespace Papyrus } } - VMAwaitable MCM_ConfigBase::SendSettingChangeEvent( + void MCM_ConfigBase::SendSettingChangeEvent( RE::BSScript::IVirtualMachine* a_vm, ScriptObjectPtr a_object, std::string a_ID) @@ -583,22 +586,24 @@ namespace Papyrus UpdateInfoText(a_object, true); if (a_ID.empty()) { - return {}; + return; } + ScriptCallbackPtr nullCallback; ScriptArgs args{ RE::MakeFunctionArguments(std::move(a_ID)) }; - return a_vm->DispatchMethodCall(a_object, "OnSettingChange"sv, args.get()); + a_vm->DispatchMethodCall(a_object, "OnSettingChange"sv, args.get(), nullCallback); } - VMAwaitable MCM_ConfigBase::SendPageSelectEvent( + void MCM_ConfigBase::SendPageSelectEvent( RE::BSScript::IVirtualMachine* a_vm, ScriptObjectPtr a_object, std::string a_page) { assert(a_vm); + ScriptCallbackPtr nullCallback; ScriptArgs args{ RE::MakeFunctionArguments(std::move(a_page)) }; - return a_vm->DispatchMethodCall(a_object, "OnPageSelect"sv, args.get()); + a_vm->DispatchMethodCall(a_object, "OnPageSelect"sv, args.get(), nullCallback); } bool MCM_ConfigBase::RegisterFuncs(RE::BSScript::IVirtualMachine* a_vm) diff --git a/src/Papyrus/MCM_ConfigBase.h b/src/Papyrus/MCM_ConfigBase.h index fef5932..845ee5a 100644 --- a/src/Papyrus/MCM_ConfigBase.h +++ b/src/Papyrus/MCM_ConfigBase.h @@ -51,7 +51,7 @@ namespace Papyrus // SkyUI Overrides - static LatentResult<> OnPageReset( + static void OnPageReset( RE::BSScript::IVirtualMachine* a_vm, RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -59,13 +59,13 @@ namespace Papyrus static void OnOptionHighlight(RE::TESQuest* a_self, std::int32_t a_option); - static LatentResult<> OnOptionSelect( + static void OnOptionSelect( RE::BSScript::IVirtualMachine* a_vm, RE::VMStackID a_stackID, RE::TESQuest* a_self, std::int32_t a_option); - static LatentResult<> OnOptionDefault( + static void OnOptionDefault( RE::BSScript::IVirtualMachine* a_vm, RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -73,7 +73,7 @@ namespace Papyrus static void OnOptionSliderOpen(RE::TESQuest* a_self, std::int32_t a_option); - static LatentResult<> OnOptionSliderAccept( + static void OnOptionSliderAccept( RE::BSScript::IVirtualMachine* a_vm, RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -82,7 +82,7 @@ namespace Papyrus static void OnOptionMenuOpen(RE::TESQuest* a_self, std::int32_t a_option); - static LatentResult<> OnOptionMenuAccept( + static void OnOptionMenuAccept( RE::BSScript::IVirtualMachine* a_vm, RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -91,14 +91,14 @@ namespace Papyrus static void OnOptionColorOpen(RE::TESQuest* a_self, std::int32_t a_option); - static LatentResult<> OnOptionColorAccept( + static void OnOptionColorAccept( RE::BSScript::IVirtualMachine* a_vm, RE::VMStackID a_stackID, RE::TESQuest* a_self, std::int32_t a_option, std::uint32_t a_color); - static LatentResult<> OnOptionKeyMapChange( + static void OnOptionKeyMapChange( RE::BSScript::IVirtualMachine* a_vm, RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -109,7 +109,7 @@ namespace Papyrus static void OnOptionInputOpen(RE::TESQuest* a_self, std::int32_t a_option); - static LatentResult<> OnOptionInputAccept( + static void OnOptionInputAccept( RE::BSScript::IVirtualMachine* a_vm, RE::VMStackID a_stackID, RE::TESQuest* a_self, @@ -126,12 +126,12 @@ namespace Papyrus static void UpdateInfoText(const ScriptObjectPtr& a_object, bool a_forceUpdate); - [[nodiscard]] static VMAwaitable SendSettingChangeEvent( + static void SendSettingChangeEvent( RE::BSScript::IVirtualMachine* a_vm, ScriptObjectPtr a_object, std::string a_ID); - [[nodiscard]] static VMAwaitable SendPageSelectEvent( + static void SendPageSelectEvent( RE::BSScript::IVirtualMachine* a_vm, ScriptObjectPtr a_object, std::string a_page); diff --git a/src/Script/SkyUI.cpp b/src/Script/SkyUI.cpp index 35b564f..a748812 100644 --- a/src/Script/SkyUI.cpp +++ b/src/Script/SkyUI.cpp @@ -663,58 +663,67 @@ namespace SkyUI SetString(a_object, "_inputStartText"sv, a_text); } - Co::Task Config::ShowMessage(const ScriptObjectPtr& a_object, std::string_view a_message) + void Config::ShowMessage( + const ScriptObjectPtr& a_object, + std::string_view a_message, + std::function a_callback) { - return ShowMessage(a_object, a_message, true, "$Accept"sv, "$Cancel"sv); + ShowMessage(a_object, a_message, true, "$Accept"sv, "$Cancel"sv, a_callback); } - Co::Task Config::ShowMessage( + void Config::ShowMessage( const ScriptObjectPtr& a_object, std::string_view a_message, - bool a_withCancel) + bool a_withCancel, + std::function a_callback) { - return ShowMessage(a_object, a_message, a_withCancel, "$Accept"sv, "$Cancel"sv); + ShowMessage(a_object, a_message, a_withCancel, "$Accept"sv, "$Cancel"sv, a_callback); } - Co::Task Config::ShowMessage( + void Config::ShowMessage( const ScriptObjectPtr& a_object, std::string_view a_message, - std::string_view a_acceptLabel) + std::string_view a_acceptLabel, + std::function a_callback) { - return ShowMessage(a_object, a_message, false, a_acceptLabel, ""sv); + ShowMessage(a_object, a_message, false, a_acceptLabel, ""sv, a_callback); } - Co::Task Config::ShowMessage( + void Config::ShowMessage( const ScriptObjectPtr& a_object, std::string_view a_message, std::string_view a_acceptLabel, - std::string_view a_cancelLabel) + std::string_view a_cancelLabel, + std::function a_callback) { - return ShowMessage(a_object, a_message, true, a_acceptLabel, a_cancelLabel); + ShowMessage(a_object, a_message, true, a_acceptLabel, a_cancelLabel, a_callback); } - Co::Task Config::ShowMessage( + void Config::ShowMessage( const ScriptObjectPtr& a_object, std::string_view a_message, bool a_withCancel, std::string_view a_acceptLabel, - std::string_view a_cancelLabel) + std::string_view a_cancelLabel, + std::function a_callback) { if (GetBool(a_object, "_waitForMessage"sv)) { Error(a_object, "Called ShowMessage() while another message was already open"sv); - co_return false; + if (a_callback) + a_callback(false); + return; } const auto skyrimVM = RE::SkyrimVM::GetSingleton(); const auto vm = skyrimVM ? skyrimVM->impl : nullptr; if (!vm) - co_return false; + return; const auto ui = RE::UI::GetSingleton(); const auto menu = ui ? ui->GetMenu() : nullptr; auto movie = menu ? menu->uiMovie : nullptr; if (!movie) - co_return false; + return; SetBool(a_object, "_waitForMessage"sv, true); SetBool(a_object, "_messageResult"sv, false); @@ -724,13 +733,46 @@ namespace SkyUI RE::GFxValue params[]{ a_message, a_acceptLabel, a_withCancel ? a_cancelLabel : ""sv }; movie->Invoke(MENU_ROOT ".showMessageDialog", nullptr, params, 3); - while (GetBool(a_object, "_waitForMessage"sv)) { + struct Awaiter : RE::BSScript::IStackCallbackFunctor + { + ScriptObjectPtr self; + std::function callback; + + Awaiter(ScriptObjectPtr a_self, std::function a_callback) : + self(a_self), + callback(a_callback) + {} + + virtual void operator()([[maybe_unused]] RE::BSScript::Variable a_result) override + { + const auto skyrimVM = RE::SkyrimVM::GetSingleton(); + const auto vm = skyrimVM ? skyrimVM->impl : nullptr; + + if (!GetBool(self, "_waitForMessage"sv)) { + UnregisterForModEvent(self, "SKICP_messageDialogClosed"sv); + if (callback) + callback(GetBool(self, "_messageResult"sv)); + return; + } + + auto loopCallback = ScriptCallbackPtr{ new Awaiter{ self, callback } }; + + if (vm) { + ScriptArgs args{ RE::MakeFunctionArguments(0.1f) }; + vm->DispatchStaticCall("Utility"sv, "WaitMenuMode"sv, args.get(), loopCallback); + } + } + + virtual void SetObject([[maybe_unused]] const ScriptObjectPtr& a_object) override + {} + }; + + auto waitCallback = ScriptCallbackPtr{ new Awaiter{ a_object, a_callback } }; + + if (vm) { ScriptArgs args{ RE::MakeFunctionArguments(0.1f) }; - co_await vm->DispatchStaticCall("Utility"sv, "WaitMenuMode"sv, args.get()); + vm->DispatchStaticCall("Utility"sv, "WaitMenuMode"sv, args.get(), waitCallback); } - - UnregisterForModEvent(a_object, "SKICP_messageDialogClosed"sv); - co_return GetBool(a_object, "_messageResult"sv); } void Config::Error(const ScriptObjectPtr& a_object, std::string_view a_msg) diff --git a/src/Script/SkyUI.h b/src/Script/SkyUI.h index dc2060e..3422ebf 100644 --- a/src/Script/SkyUI.h +++ b/src/Script/SkyUI.h @@ -1,6 +1,5 @@ #pragma once -#include "Co/Task.h" #include "Script/ScriptObject.h" #define MENU_ROOT "_root.ConfigPanelFader.configPanel" @@ -234,32 +233,37 @@ namespace SkyUI const ScriptObjectPtr& a_object, std::string_view a_text); - static Co::Task ShowMessage( + static void ShowMessage( const ScriptObjectPtr& a_object, - std::string_view a_message); + std::string_view a_message, + std::function a_callback); - static Co::Task ShowMessage( + static void ShowMessage( const ScriptObjectPtr& a_object, std::string_view a_message, - bool a_withCancel); + bool a_withCancel, + std::function a_callback); - static Co::Task ShowMessage( + static void ShowMessage( const ScriptObjectPtr& a_object, std::string_view a_message, - std::string_view a_acceptLabel); + std::string_view a_acceptLabel, + std::function a_callback); - static Co::Task ShowMessage( + static void ShowMessage( const ScriptObjectPtr& a_object, std::string_view a_message, std::string_view a_acceptLabel, - std::string_view a_cancelLabel); + std::string_view a_cancelLabel, + std::function a_callback); - static Co::Task ShowMessage( + static void ShowMessage( const ScriptObjectPtr& a_object, std::string_view a_message, bool a_withCancel, std::string_view a_acceptLabel, - std::string_view a_cancelLabel); + std::string_view a_cancelLabel, + std::function a_callback); private: static void Error(const ScriptObjectPtr& a_object, std::string_view a_msg);