From 7004c1fc4f78fd95af604db9c14ee78f7fd0a9db Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 20 Oct 2025 10:51:33 -0700 Subject: [PATCH 1/3] Fix GS not being marked as collected when not shuffled. (#5861) --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index df950a35f..04ce7f1c8 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -249,11 +249,15 @@ void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) { return; if (flagType == FLAG_GS_TOKEN && - Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) + Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) { + Rando::Context::GetInstance()->GetItemLocation(rc)->SetCheckStatus(RCSHOW_COLLECTED); return; + } auto loc = Rando::Context::GetInstance()->GetItemLocation(rc); - if (loc == nullptr || loc->HasObtained() || loc->GetPlacedRandomizerGet() == RG_NONE) + if (loc == nullptr || loc->HasObtained() || loc->GetPlacedRandomizerGet() == RG_NONE) { + Rando::Context::GetInstance()->GetItemLocation(rc)->SetCheckStatus(RCSHOW_COLLECTED); return; + } SPDLOG_INFO("Queuing RC: {}", static_cast(rc)); randomizerQueuedChecks.push(rc); From 8d441f3ae523ce1a5e9b8621b93a59ce72f82f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 20 Oct 2025 17:51:43 +0000 Subject: [PATCH 2/3] fix rando hints for bridge requirements (#5857) --- soh/soh/Enhancements/randomizer/3drando/hints.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index d8a3f67ee..33c8335fc 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -227,9 +227,10 @@ uint8_t StonesRequiredBySettings() { } if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) { stones = std::max({ stones, ctx->GetOption(RSK_LACS_STONE_COUNT).Get() }); - } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) { + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) { stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - 6) }); - } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS)) { + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS) && + ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - 6) }); } return stones; @@ -247,12 +248,12 @@ uint8_t MedallionsRequiredBySettings() { medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get() - 3; } if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) { - medallions = std::max({ medallions, ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get() }); + medallions = std::max(medallions, ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get()); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) { - medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - 3) }); + medallions = std::max(medallions, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - 3)); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { - medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - 3) }); + medallions = std::max(medallions, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - 3)); } return medallions; } @@ -264,7 +265,7 @@ uint8_t TokensRequiredBySettings() { tokens = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get(); } if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) { - tokens = std::max({ tokens, ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get() }); + tokens = std::max(tokens, ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get()); } return tokens; } From dc5e9686c0a5c1b4f1cdf285ad8bf581be6233e1 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 20 Oct 2025 10:51:56 -0700 Subject: [PATCH 3/3] Mod Menu Tweaks (#5844) * Fix mod order retention. Remove mods in the CVar that no longer exist. * Rework mod list init for enabled-by-default with extension changing to disable. * Rework entire system for default enabled. Disabled mods are renamed for sake of saving a CVar. Menu now has an edit mode, cancel button, and apply & close. Move Enable Alternate Assets to be Enable Mods in the mod menu. Couple small fixes in the item tracker. * Try to fix Mac. * Remove disabling for Enable Mods while editing. Add info about load order in relation to the list. * Fix archives being added multiple times across multiple init passes. * Add full-row drag and drop. Swap columns. Add information about dragging to header. * Remove enable/disable flow, and setup the menu to only handle load order. Change AltAssets to default on. Move menu to Settings tab. Move tab hotkey widget to mod menu. Fix alt assets migrator value. * Reverse list order for priority on top. * Remove ExtensionType. --- soh/soh/Enhancements/mod_menu.cpp | 312 +++++++++++++----- .../randomizer/randomizer_item_tracker.cpp | 5 +- soh/soh/OTRGlobals.cpp | 6 +- soh/soh/SohGui/SohMenuEnhancements.cpp | 15 - soh/soh/SohGui/SohMenuSettings.cpp | 14 +- soh/soh/config/ConfigMigrators.h | 2 +- 6 files changed, 242 insertions(+), 112 deletions(-) diff --git a/soh/soh/Enhancements/mod_menu.cpp b/soh/soh/Enhancements/mod_menu.cpp index feb412350..3051efe74 100644 --- a/soh/soh/Enhancements/mod_menu.cpp +++ b/soh/soh/Enhancements/mod_menu.cpp @@ -1,17 +1,32 @@ -#include "mod_menu.h" -#include -#include -#include "soh/SohGui/SohGui.hpp" -#include "soh/OTRGlobals.h" -#include "soh/resource/type/Skeleton.h" #include #include #include +#include +#include + +#include "mod_menu.h" +#include "soh/OTRGlobals.h" +#include "soh/resource/type/Skeleton.h" +#include "soh/SohGui/MenuTypes.h" +#include "soh/SohGui/SohMenu.h" +#include "soh/SohGui/SohGui.hpp" + std::vector enabledModFiles; std::vector disabledModFiles; +std::vector unsupportedFiles; +std::map filePaths; +static int dragSourceIndex = -1; +static int dragTargetIndex = -1; -#define CVAR_ENABLED_MODS_NAME CVAR_GENERAL("EnabledMods") +namespace SohGui { +extern std::shared_ptr mSohMenu; +} + +static WidgetInfo enableModsWidget; +static WidgetInfo tabHotkeyWidget; + +#define CVAR_ENABLED_MODS_NAME CVAR_SETTING("EnabledMods") #define CVAR_ENABLED_MODS_DEFAULT "" #define CVAR_ENABLED_MODS_VALUE CVarGetString(CVAR_ENABLED_MODS_NAME, CVAR_ENABLED_MODS_DEFAULT) @@ -42,6 +57,42 @@ void SetEnabledModsCVarValue() { CVarSetString(CVAR_ENABLED_MODS_NAME, s.c_str()); } +void AfterModChange() { + // disabled mods are always sorted + std::sort(disabledModFiles.begin(), disabledModFiles.end(), [](const std::string& a, const std::string& b) { + return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), + [](char c1, char c2) { return std::tolower(c1) < std::tolower(c2); }); + }); +} + +void ModsPostDragAndDrop() { + if (dragTargetIndex != -1) { + std::string file = enabledModFiles[dragSourceIndex]; + enabledModFiles.erase(enabledModFiles.begin() + dragSourceIndex); + enabledModFiles.insert(enabledModFiles.begin() + dragTargetIndex, file); + dragTargetIndex = dragSourceIndex = -1; + AfterModChange(); + } +} + +void ModsHandleDragAndDrop(std::vector& objectList, int targetIndex, const std::string& itemName, + ImGuiDragDropFlags flags = ImGuiDragDropFlags_SourceAllowNullID) { + if (ImGui::BeginDragDropSource(flags)) { + ImGui::SetDragDropPayload("DragMove", &targetIndex, sizeof(uint32_t)); + ImGui::Text("Move %s", itemName.c_str()); + ImGui::EndDragDropSource(); + } + + if (ImGui::BeginDragDropTarget()) { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DragMove")) { + IM_ASSERT(payload->DataSize == sizeof(uint32_t)); + dragSourceIndex = *(const int*)payload->Data; + dragTargetIndex = targetIndex; + } + ImGui::EndDragDropTarget(); + } +} + std::vector GetEnabledModsFromCVar() { std::string enabledModsCVarValue = CVAR_ENABLED_MODS_VALUE; return StringHelper::Split(enabledModsCVarValue, SEPARATOR); @@ -55,58 +106,71 @@ std::shared_ptr GetArchiveManager() { return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager(); } -void UpdateModFiles(bool init = false) { - if (init) { +bool IsValidExtension(std::string extension) { + if ( +#ifdef INCLUDE_MPQ_SUPPORT + // .mpq doesn't make sense to support because all tools to make such mods output OTR + StringHelper::IEquals(extension, ".otr") /*|| StringHelper::IEquals(extension, ".mpq")*/ || +#endif + // .zip needs to be excluded because mods are most often distributed in zip archives + // and thus could contain .otr/o2r files + StringHelper::IEquals(extension, ".o2r") /*|| StringHelper::IEquals(extension, ".zip")*/) { + return true; + } + return false; +} + +void UpdateModFiles(bool init = false, bool reset = false) { + if (init || reset) { enabledModFiles.clear(); + enabledModFiles = GetEnabledModsFromCVar(); } disabledModFiles.clear(); - std::vector enabledMods = GetEnabledModsFromCVar(); + unsupportedFiles.clear(); + filePaths.clear(); std::string modsPath = Ship::Context::LocateFileAcrossAppDirs("mods", appShortName); + bool changed = false; if (modsPath.length() > 0 && std::filesystem::exists(modsPath)) { + std::vector enabledFiles; if (std::filesystem::is_directory(modsPath)) { for (const std::filesystem::directory_entry& p : std::filesystem::recursive_directory_iterator( modsPath, std::filesystem::directory_options::follow_directory_symlink)) { - std::string extension = p.path().extension().string(); - if ( -#ifndef EXCLUDE_MPQ_SUPPORT - StringHelper::IEquals(extension, ".otr") || StringHelper::IEquals(extension, ".mpq") || -#endif - StringHelper::IEquals(extension, ".o2r") || StringHelper::IEquals(extension, ".zip")) { - std::string path = p.path().generic_string(); - bool shouldBeEnabled = std::find(enabledMods.begin(), enabledMods.end(), path) != enabledMods.end(); - - if (shouldBeEnabled) { - if (init) { - enabledModFiles.push_back(path); - GetArchiveManager()->AddArchive(path); - } + if (p.is_directory()) { + continue; + } + std::string filename = + p.path().filename().generic_string().substr(0, p.path().filename().generic_string().rfind(".")); + std::string extension = p.path().extension().generic_string(); + if (!IsValidExtension(extension)) { + continue; + } + bool enabled = + std::find(enabledModFiles.begin(), enabledModFiles.end(), filename) != enabledModFiles.end(); + if (!enabled) { + enabledModFiles.push_back(filename); + changed = true; + } + filePaths.emplace(filename, p.path()); + } + if (init) { + std::vector enabledTemp(enabledModFiles); + for (std::string mod : enabledTemp) { + if (filePaths.contains(mod)) { + GetArchiveManager()->AddArchive(filePaths.at(mod).generic_string()); } else { - disabledModFiles.push_back(path); + enabledModFiles.erase(std::find(enabledModFiles.begin(), enabledModFiles.end(), mod)); } } } } } + if (changed) { + SetEnabledModsCVarValue(); + } } extern "C" void gfx_texture_cache_clear(); -void AfterModChange() { - SetEnabledModsCVarValue(); - // TODO: runtime changes - /* - gfx_texture_cache_clear(); - SOH::SkeletonPatcher::ClearSkeletons(); - */ - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - - // disabled mods are always sorted - std::sort(disabledModFiles.begin(), disabledModFiles.end(), [](const std::string& a, const std::string& b) { - return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), - [](char c1, char c2) { return std::tolower(c1) < std::tolower(c2); }); - }); -} - void EnableMod(std::string file) { disabledModFiles.erase(std::find(disabledModFiles.begin(), disabledModFiles.end(), file)); enabledModFiles.insert(enabledModFiles.begin(), file); @@ -139,39 +203,30 @@ void DrawMods(bool enabled) { bool madeAnyChange = false; int switchFromIndex = -1; int switchToIndex = -1; + uint32_t index = 0; - for (int i = 0; i < selectedModFiles.size(); i += 1) { + for (int i = selectedModFiles.size() - 1; i >= 0; i--) { std::string file = selectedModFiles[i]; - if (UIWidgets::StateButton((file + "_left_right").c_str(), enabled ? ICON_FA_ARROW_LEFT : ICON_FA_ARROW_RIGHT, - ImVec2(25, 25), UIWidgets::ButtonOptions().Color(THEME_COLOR))) { - if (enabled) { - DisableMod(file); - } else { - EnableMod(file); - } + if (enabled) { + ImGui::BeginGroup(); } + // if (UIWidgets::StateButton((file + "_left_right").c_str(), enabled ? ICON_FA_ARROW_RIGHT : + // ICON_FA_ARROW_LEFT, + // ImVec2(25, 25), UIWidgets::ButtonOptions().Color(THEME_COLOR))) { + // if (enabled) { + // DisableMod(file); + // } else { + // EnableMod(file); + // } + // } // it's not relevant to reorder disabled mods if (enabled) { - ImGui::SameLine(); - if (i == 0) { - ImGui::BeginDisabled(); - } - if (UIWidgets::StateButton((file + "_up").c_str(), ICON_FA_ARROW_UP, ImVec2(25, 25), - UIWidgets::ButtonOptions().Color(THEME_COLOR))) { - madeAnyChange = true; - switchFromIndex = i; - switchToIndex = i - 1; - } - if (i == 0) { - ImGui::EndDisabled(); - } - - ImGui::SameLine(); + // ImGui::SameLine(); if (i == selectedModFiles.size() - 1) { ImGui::BeginDisabled(); } - if (UIWidgets::StateButton((file + "_down").c_str(), ICON_FA_ARROW_DOWN, ImVec2(25, 25), + if (UIWidgets::StateButton((file + "_up").c_str(), ICON_FA_ARROW_UP, ImVec2(25, 25), UIWidgets::ButtonOptions().Color(THEME_COLOR))) { madeAnyChange = true; switchFromIndex = i; @@ -180,9 +235,31 @@ void DrawMods(bool enabled) { if (i == selectedModFiles.size() - 1) { ImGui::EndDisabled(); } + + ImGui::SameLine(); + if (i == 0) { + ImGui::BeginDisabled(); + } + if (UIWidgets::StateButton((file + "_down").c_str(), ICON_FA_ARROW_DOWN, ImVec2(25, 25), + UIWidgets::ButtonOptions().Color(THEME_COLOR))) { + madeAnyChange = true; + switchFromIndex = i; + switchToIndex = i - 1; + } + if (i == 0) { + ImGui::EndDisabled(); + } } - DrawModInfo(file); + DrawModInfo(filePaths.at(file).filename().generic_string()); + if (enabled) { + ImGui::EndGroup(); + ModsHandleDragAndDrop(selectedModFiles, i, file); + } + } + + if (enabled) { + ModsPostDragAndDrop(); } if (madeAnyChange) { @@ -191,22 +268,61 @@ void DrawMods(bool enabled) { } } -void ModMenuWindow::DrawElement() { - ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); +bool editing = false; - const ImVec4 yellow = ImVec4(1, 1, 0, 1); +void ModMenuWindow::DrawElement() { + SohGui::mSohMenu->MenuDrawItem(enableModsWidget, 200, THEME_COLOR); + ImGui::SameLine(); + SohGui::mSohMenu->MenuDrawItem(tabHotkeyWidget, 200, THEME_COLOR); ImGui::TextColored( - yellow, "Mods are currently not reloaded at runtime.\nClose and re-open Ship for the changes to take effect."); + UIWidgets::ColorValues.at(UIWidgets::Colors::Yellow), + "Mods are currently not reloaded at runtime. Close and re-open Ship for the changes to take effect.\n" + "Drag ordering for the enabled list is available.\nMod priority is top to bottom. They override mods listed " + "below them."); - if (UIWidgets::Button("Update", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { - UpdateModFiles(); + // if (UIWidgets::Button( + // "Update", UIWidgets::ButtonOptions({ { .disabled = editing, .disabledTooltip = "Currently editing..." } + // }) + // .Size(UIWidgets::Sizes::Inline) + // .Color(THEME_COLOR))) { + // UpdateModFiles(); + // } + // ImGui::SameLine(); + if (UIWidgets::Button("Edit", + UIWidgets::ButtonOptions({ { .disabled = editing, .disabledTooltip = "Already editing..." } }) + .Size(UIWidgets::Sizes::Inline) + .Color(THEME_COLOR))) { + editing = true; } - UIWidgets::Tooltip("Re-check the mods folder for new files"); - + if (editing) { + ImGui::SameLine(); + if (UIWidgets::Button("Cancel", UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline))) { + editing = false; + UpdateModFiles(false, true); + } + ImGui::SameLine(); + if (UIWidgets::Button("Apply & Close", + UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { + SohGui::RegisterPopup("Apply & Close", + "Application currently requires a restart. Save the mod info and close SoH?", "Close", + "Cancel", [&]() { + // TODO: runtime changes + SetEnabledModsCVarValue(); + // TODO: runtime changes + /* + gfx_texture_cache_clear(); + SOH::SkeletonPatcher::ClearSkeletons(); + */ + Ship::Context::GetInstance()->GetConsoleVariables()->Save(); + Ship::Context::GetInstance()->GetWindow()->Close(); + }); + } + } + ImGui::BeginDisabled(!editing); if (ImGui::BeginTable("tableMods", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { - ImGui::TableSetupColumn("Disabled Mods", ImGuiTableColumnFlags_WidthStretch, 200.0f); ImGui::TableSetupColumn("Enabled Mods", ImGuiTableColumnFlags_WidthStretch, 200.0f); + // ImGui::TableSetupColumn("Disabled Mods", ImGuiTableColumnFlags_WidthStretch, 200.0f); ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::TableHeadersRow(); ImGui::PopItemFlag(); @@ -214,26 +330,52 @@ void ModMenuWindow::DrawElement() { ImGui::TableNextColumn(); - if (ImGui::BeginChild("Disabled Mods", ImVec2(0, -8))) { - DrawMods(false); - - ImGui::EndChild(); - } - - ImGui::TableNextColumn(); - if (ImGui::BeginChild("Enabled Mods", ImVec2(0, -8))) { DrawMods(true); ImGui::EndChild(); } + /*ImGui::TableNextColumn(); + + if (ImGui::BeginChild("Disabled Mods", ImVec2(0, -8))) { + DrawMods(false); + + ImGui::EndChild(); + }*/ + ImGui::EndTable(); } - ImGui::EndDisabled(); } void ModMenuWindow::InitElement() { UpdateModFiles(true); -} \ No newline at end of file +} + +void RegisterModMenuWidgets() { + enableModsWidget = { .name = "Enable Mods", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + enableModsWidget.CVar(CVAR_SETTING("AltAssets")) + .RaceDisable(false) + .Options(UIWidgets::CheckboxOptions({ { .disabledTooltip = "Temporarily disabled while editing mods list." } }) + .Color(THEME_COLOR) + .Tooltip("Toggle mods. For graphics mods, this means toggling between default and mod graphics.") + .DefaultValue(true)) + .PreFunc([&](WidgetInfo& info) { + auto options = std::static_pointer_cast(info.options); + options->disabled = editing; + }); + SohGui::mSohMenu->AddSearchWidget({ enableModsWidget, "Settings", "Mod Menu", "Top", "alternat assets" }); + + tabHotkeyWidget = { .name = "Mods Tab Hotkey", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + tabHotkeyWidget.CVar(CVAR_SETTING("Mods.AlternateAssetsHotkey")) + .RaceDisable(false) + .Options(UIWidgets::CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Allows pressing the Tab key to toggle mods") + .DefaultValue(true)); + SohGui::mSohMenu->AddSearchWidget( + { enableModsWidget, "Settings", "Mod Menu", "Top", "alternat assets tab hotkey" }); +} + +static RegisterMenuInitFunc menuInitFunc(RegisterModMenuWidgets); diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index f019432eb..0935ce46c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -2116,9 +2116,8 @@ void RegisterItemTrackerWidgets() { hookshotIdentWidget.CVar(CVAR_SETTING("FreeLook.Enabled")) .Options(CheckboxOptions() .Color(THEME_COLOR) - .Tooltip("Shows an 'H' or an 'L' to more easiely distinguish between Hookshot and Longshot.")); - SohGui::mSohMenu->AddSearchWidget( - { hookshotIdentWidget, "Settings", "Controls", "Camera Controls", "longshot icon" }); + .Tooltip("Shows an 'H' or an 'L' to more easily distinguish between Hookshot and Longshot.")); + SohGui::mSohMenu->AddSearchWidget({ hookshotIdentWidget, "Randomizer", "Item Tracker", "General Settings" }); } static RegisterMenuInitFunc menuInitFunc(RegisterItemTrackerWidgets); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index ad4beb829..cbcc926d9 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -299,7 +299,7 @@ void OTRGlobals::Initialize() { // tell LUS to reserve 3 SoH specific threads (Game, Audio, Save) context->InitResourceManager(OTRFiles, {}, 3); - prevAltAssets = CVarGetInteger(CVAR_SETTING("AltAssets"), 0); + prevAltAssets = CVarGetInteger(CVAR_SETTING("AltAssets"), 1); context->GetResourceManager()->SetAltAssetsEnabled(prevAltAssets); auto controlDeck = std::make_shared(std::vector({ @@ -1482,7 +1482,7 @@ extern "C" void Graph_StartFrame() { #endif case KbScancode::LUS_KB_TAB: { if (CVarGetInteger(CVAR_SETTING("Mods.AlternateAssetsHotkey"), 1)) { - CVarSetInteger(CVAR_SETTING("AltAssets"), !CVarGetInteger(CVAR_SETTING("AltAssets"), 0)); + CVarSetInteger(CVAR_SETTING("AltAssets"), !CVarGetInteger(CVAR_SETTING("AltAssets"), 1)); } break; } @@ -1570,7 +1570,7 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) { } } - bool curAltAssets = CVarGetInteger(CVAR_SETTING("AltAssets"), 0); + bool curAltAssets = CVarGetInteger(CVAR_SETTING("AltAssets"), 1); if (prevAltAssets != curAltAssets) { prevAltAssets = curAltAssets; Ship::Context::GetInstance()->GetResourceManager()->SetAltAssetsEnabled(curAltAssets); diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 2b660fb94..639d7469b 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -537,12 +537,6 @@ void SohMenu::AddMenuEnhancements() { path.column = SECTION_COLUMN_1; AddWidget(path, "Mods", WIDGET_SEPARATOR_TEXT); - AddWidget(path, "Use Alternate Assets", WIDGET_CVAR_CHECKBOX) - .CVar(CVAR_SETTING("AltAssets")) - .RaceDisable(false) - .Options(CheckboxOptions().Tooltip( - "Toggle between standard assets and alternate assets. Usually mods will indicate if " - "this setting has to be used or not.")); AddWidget(path, "Disable Bomb Billboarding", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("DisableBombBillboarding")) .RaceDisable(false) @@ -1908,15 +1902,6 @@ void SohMenu::AddMenuEnhancements() { .CVar(timer.timeEnable) .Callback([](WidgetInfo& info) { TimeDisplayUpdateDisplayOptions(); }); } - - // Mod Menu - path.sidebarName = "Mod Menu"; - AddSidebarEntry("Enhancements", path.sidebarName, 1); - AddWidget(path, "Popout Mod Menu Window", WIDGET_WINDOW_BUTTON) - .CVar(CVAR_WINDOW("ModMenu")) - .WindowName("Mod Menu") - .HideInSearch(true) - .Options(WindowButtonOptions().Tooltip("Enables the separate Mod Menu Window.")); } } // namespace SohGui diff --git a/soh/soh/SohGui/SohMenuSettings.cpp b/soh/soh/SohGui/SohMenuSettings.cpp index 925ab113d..35abc38a3 100644 --- a/soh/soh/SohGui/SohMenuSettings.cpp +++ b/soh/soh/SohGui/SohMenuSettings.cpp @@ -178,11 +178,6 @@ void SohMenu::AddMenuSettings() { .RaceDisable(false) .Options(CheckboxOptions().Tooltip( "Search input box gets autofocus when visible. Does not affect using other widgets.")); - AddWidget(path, "Alt Assets Tab hotkey", WIDGET_CVAR_CHECKBOX) - .CVar(CVAR_SETTING("Mods.AlternateAssetsHotkey")) - .RaceDisable(false) - .Options( - CheckboxOptions().Tooltip("Allows pressing the Tab key to toggle alternate assets").DefaultValue(true)); AddWidget(path, "Open App Files Folder", WIDGET_BUTTON) .RaceDisable(false) .Callback([](WidgetInfo& info) { @@ -505,6 +500,15 @@ void SohMenu::AddMenuSettings() { }); }) .Options(ButtonOptions().Tooltip("Displays a test notification.")); + + // Mod Menu + path.sidebarName = "Mod Menu"; + AddSidebarEntry("Settings", path.sidebarName, 1); + AddWidget(path, "Popout Mod Menu Window", WIDGET_WINDOW_BUTTON) + .CVar(CVAR_WINDOW("ModMenu")) + .WindowName("Mod Menu") + .HideInSearch(true) + .Options(WindowButtonOptions().Tooltip("Enables the separate Mod Menu Window.")); } } // namespace SohGui diff --git a/soh/soh/config/ConfigMigrators.h b/soh/soh/config/ConfigMigrators.h index 54a0dc236..fd88317f3 100644 --- a/soh/soh/config/ConfigMigrators.h +++ b/soh/soh/config/ConfigMigrators.h @@ -1503,7 +1503,7 @@ std::vector version3Migrations = { { MigrationAction::Rename, "gOpenMenuBar", "gSettings.OpenMenuBar" }, { MigrationAction::Rename, "gRandomizeSkipChildStealth", "gRandoSettings.SkipChildStealth" }, { MigrationAction::Rename, "gRandomizeExcludedLocations", "gRandoSettings.ExcludedLocations" }, - { MigrationAction::Rename, "gAltAssets", "gEnhancements.AltAssets" }, + { MigrationAction::Rename, "gAltAssets", "gSettings.AltAssets" }, { MigrationAction::Rename, "gMSAAValue", "gSettings.MSAAValue" }, { MigrationAction::Rename, "gInternalResolution", "gSettings.InternalResolution" }, { MigrationAction::Rename, "gTextureFilter", "gSettings.TextureFilter" },