From 1ae6d306faf324c8b7c04c47728e6fa0db20e11f Mon Sep 17 00:00:00 2001 From: Glought Date: Sat, 15 Nov 2025 06:53:24 -0800 Subject: [PATCH 1/6] Add the ability to Randomize All Music and sfx based on file Rando seed. Add "Randomize All Music and Sound Effects Mode" Combobox The Options are : - Disabled: No music or sound effects are randomized. - On New Scene: Randomizes when you enter a new scene. - On Rando Gen Only: Randomizes only when you generate a new randomizer - On File Load: Randomizes on File Load. - On File Load (Seeded):Randomizes on file load based on the current randomizer seed/file. Removed "Randomize All Music and Sound Effects on Randomizer Generation" checkbox. Removed "Randomize All Music and Sound Effects on New Scene" checkbox. --- soh/soh/Enhancements/audio/AudioEditor.cpp | 88 ++++++++++++++++------ soh/soh/Enhancements/audio/AudioEditor.h | 1 + soh/soh/Enhancements/enhancementTypes.h | 8 ++ 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index fa07272183a..77c0dee5a22 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -33,8 +33,7 @@ static WidgetInfo leadingMusic; static WidgetInfo displaySeqName; static WidgetInfo ovlDuration; static WidgetInfo voicePitch; -static WidgetInfo randoMusicOnSceneChange; -static WidgetInfo randomAudioOnSeedGen; +static WidgetInfo randomAudioGenModes; static WidgetInfo lowerOctaves; namespace SohGui { @@ -78,6 +77,14 @@ size_t AuthenticCountBySequenceType(SeqType type) { } } +static const std::unordered_map audioRandomizerModes = { + { RANDOMIZE_OFF, "Disabled" }, + { RANDOMIZE_ON_NEW_SCENE, "On New Scene" }, + { RANDOMIZE_ON_RANDO_GEN_ONLY, "On Rando Gen Only" }, + { RANDOMIZE_ON_FILE_LOAD, "On File Load" }, + { RANDOMIZE_ON_FILE_LOAD_SEEDED, "On File Load (Seeded)" }, +}; + // Grabs the current BGM sequence ID and replays it // which will lookup the proper override, or reset back to vanilla void ReplayCurrentBGM() { @@ -100,9 +107,19 @@ void UpdateCurrentBGM(u16 seqKey, SeqType seqType) { } } -void RandomizeGroup(SeqType type) { +void RandomizeGroup(SeqType type, bool manual = true) { std::vector values; + if (!manual) { + if (IS_RANDO && CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED || + IS_RANDO && CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + + uint32_t finalSeed = type + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() + : static_cast(gSaveContext.ship.stats.fileCreatedAt)); + Random_Init(finalSeed); + } + } + // An empty IncludedSequences set means that the AudioEditor window has never been drawn if (AudioCollection::Instance->GetIncludedSequences().empty()) { AudioCollection::Instance->InitializeShufflePool(); @@ -478,16 +495,29 @@ void DrawTypeChip(SeqType type, std::string sequenceName) { void AudioEditorRegisterOnSceneInitHook() { GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { - if (gSaveContext.gameMode != GAMEMODE_END_CREDITS && CVarGetInteger(CVAR_AUDIO("RandomizeAllOnNewScene"), 0)) { - AudioEditor_RandomizeAll(); + if (gSaveContext.gameMode != GAMEMODE_END_CREDITS && + CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_NEW_SCENE) { + + AudioEditor_AutoRandomizeAll(); } }); } void AudioEditorRegisterOnGenerationCompletionHook() { GameInteractor::Instance->RegisterGameHook([]() { - if (CVarGetInteger(CVAR_AUDIO("RandomizeAllOnRandoGen"), 0)) { - AudioEditor_RandomizeAll(); + if (CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + + AudioEditor_AutoRandomizeAll(); + } + }); +} + +void AudioEditorRegisterOnLoadGameHook() { + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + if (CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD || + CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED) { + + AudioEditor_AutoRandomizeAll(); } }); } @@ -495,6 +525,7 @@ void AudioEditorRegisterOnGenerationCompletionHook() { void AudioEditor::InitElement() { AudioEditorRegisterOnSceneInitHook(); AudioEditorRegisterOnGenerationCompletionHook(); + AudioEditorRegisterOnLoadGameHook(); } void AudioEditor::DrawElement() { @@ -556,8 +587,7 @@ void AudioEditor::DrawElement() { UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { CVarSetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0f); } - SohGui::mSohMenu->MenuDrawItem(randoMusicOnSceneChange, ImGui::GetContentRegionAvail().x, THEME_COLOR); - SohGui::mSohMenu->MenuDrawItem(randomAudioOnSeedGen, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(randomAudioGenModes, ImGui::GetContentRegionAvail().x, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(lowerOctaves, ImGui::GetContentRegionAvail().x, THEME_COLOR); } ImGui::EndChild(); @@ -774,6 +804,15 @@ void AudioEditor_RandomizeAll() { ReplayCurrentBGM(); } +void AudioEditor_AutoRandomizeAll() { + for (auto type : allTypes) { + RandomizeGroup(type, false); + } + + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ReplayCurrentBGM(); +} + void AudioEditor_RandomizeGroup(SeqType group) { RandomizeGroup(group); @@ -865,22 +904,21 @@ void RegisterAudioWidgets() { .Size(ImVec2(300.0f, 0.0f))); SohGui::mSohMenu->AddSearchWidget({ voicePitch, "Enhancements", "Audio Editor", "Audio Options" }); - randoMusicOnSceneChange = { .name = "Randomize All Music and Sound Effects on New Scene", - .type = WidgetType::WIDGET_CVAR_CHECKBOX }; - randoMusicOnSceneChange.CVar(CVAR_AUDIO("RandomizeAllOnNewScene")) - .Options(CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Enables randomizing all unlocked music and sound effects when you enter a new scene.")); - SohGui::mSohMenu->AddSearchWidget({ randoMusicOnSceneChange, "Enhancements", "Audio Editor", "Audio Options" }); - - randomAudioOnSeedGen = { .name = "Randomize All Music and Sound Effects on Randomizer Generation", - .type = WidgetType::WIDGET_CVAR_CHECKBOX }; - randomAudioOnSeedGen.CVar(CVAR_AUDIO("RandomizeAllOnRandoGen")) - .Options(CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Enables randomizing all unlocked music and sound effects when you generate a new " - "randomizer. Respects locks already in place.")); - SohGui::mSohMenu->AddSearchWidget({ randomAudioOnSeedGen, "Enhancements", "Audio Editor", "Audio Options" }); + randomAudioGenModes = { .name = "Randomize All Music and Sound Effects Mode", + .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + randomAudioGenModes.CVar(CVAR_AUDIO("RandomizeAudioGenModes")) + .Options( + ComboboxOptions() + .DefaultIndex(RANDOMIZE_OFF) + .ComboMap(audioRandomizerModes) + .Tooltip( + "Set when the music and sound effects is automaticly randomized:\n" + "- Disabled: No music or sound effects are randomized\n" + "- On New Scene : Randomizes when you enter a new scene.\n" + "- On Rando Gen Only: Randomizes only when you generate a new randomizer.\n" + "- On File Load: Randomizes on File Load.\n" + "- On File Load (Seeded): Randomizes on file load based on the current randomizer seed/file.\n")); + SohGui::mSohMenu->AddSearchWidget({ randomAudioGenModes, "Enhancements", "Audio Editor", "Audio Options" }); lowerOctaves = { .name = "Lower Octaves of Unplayable High Notes", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; lowerOctaves.CVar(CVAR_AUDIO("ExperimentalOctaveDrop")) diff --git a/soh/soh/Enhancements/audio/AudioEditor.h b/soh/soh/Enhancements/audio/AudioEditor.h index ca3636d9a84..b05c7b88e2e 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.h +++ b/soh/soh/Enhancements/audio/AudioEditor.h @@ -18,6 +18,7 @@ class AudioEditor final : public Ship::GuiWindow { }; void AudioEditor_RandomizeAll(); +void AudioEditor_AutoRandomizeAll(); void AudioEditor_RandomizeGroup(SeqType group); void AudioEditor_ResetAll(); void AudioEditor_ResetGroup(SeqType group); diff --git a/soh/soh/Enhancements/enhancementTypes.h b/soh/soh/Enhancements/enhancementTypes.h index bd025115b90..be0a3990f3a 100644 --- a/soh/soh/Enhancements/enhancementTypes.h +++ b/soh/soh/Enhancements/enhancementTypes.h @@ -123,4 +123,12 @@ typedef enum { WATERFALL_NEVER, } SleepingWaterfallType; +typedef enum { + RANDOMIZE_OFF, + RANDOMIZE_ON_NEW_SCENE, + RANDOMIZE_ON_RANDO_GEN_ONLY, + RANDOMIZE_ON_FILE_LOAD, + RANDOMIZE_ON_FILE_LOAD_SEEDED, +} RandomizeOnMode; + #endif From 4d02c9865965bb4c63832f9d751b2b98d8b98ba5 Mon Sep 17 00:00:00 2001 From: Glought Date: Sun, 16 Nov 2025 05:35:44 -0800 Subject: [PATCH 2/6] Add the ability to Randomize All cosmetics based on file rando seed. Add "Randomize All Cosmetics Mode" Combobox The Options are : - Disabled: No cosmetics are randomized. - On New Scene: Randomizes when you enter a new scene. - On Rando Gen Only: Randomizes only when you generate a new randomizer - On File Load: Randomizes on File Load. - On File Load (Seeded):Randomizes on file load based on the current randomizer seed/file. Removed "Randomize All on Randomizer Generation" checkbox. Removed "Randomize All on New Scene" checkbox. --- .../cosmetics/CosmeticsEditor.cpp | 101 +++++++++++++++--- .../Enhancements/cosmetics/CosmeticsEditor.h | 1 + soh/soh/SohGui/UIWidgets.cpp | 15 +++ soh/soh/SohGui/UIWidgets.hpp | 2 + 4 files changed, 107 insertions(+), 12 deletions(-) diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 94222b0b715..79e62063f67 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -13,9 +13,11 @@ #include "soh/SohGui/SohGui.hpp" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/enhancementTypes.h" extern "C" { #include "z64.h" +#include "z64save.h" #include "macros.h" #include "soh/cvar_prefixes.h" #include "objects/object_link_boy/object_link_boy.h" @@ -47,6 +49,7 @@ extern "C" { #include "objects/object_gi_rabit_mask/object_gi_rabit_mask.h" #include "overlays/ovl_Magic_Wind/ovl_Magic_Wind.h" +extern SaveContext gSaveContext; extern PlayState* gPlayState; void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction); void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const char* patchName, int destinationIndex, @@ -96,6 +99,14 @@ std::map groupLabels = { { COSMETICS_GROUP_MESSAGE, "Message" }, }; +static const std::unordered_map cosmeticsRandomizerModes = { + { RANDOMIZE_OFF, "Disabled" }, + { RANDOMIZE_ON_NEW_SCENE, "On New Scene" }, + { RANDOMIZE_ON_RANDO_GEN_ONLY, "On Rando Gen Only" }, + { RANDOMIZE_ON_FILE_LOAD, "On File Load" }, + { RANDOMIZE_ON_FILE_LOAD_SEEDED, "On File Load (Seeded)" }, +}; + typedef struct { const char* cvar; const char* valuesCvar; @@ -2093,8 +2104,25 @@ void ApplySideEffects(CosmeticOption& cosmeticOption) { } } -void RandomizeColor(CosmeticOption& cosmeticOption) { - ImVec4 randomColor = GetRandomValue(); +void RandomizeColor(CosmeticOption& cosmeticOption, bool manual = true) { + ImVec4 randomColor; + + if (!manual && IS_RANDO && + CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED || + !manual && IS_RANDO && + CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + + uint32_t finalSeed = cosmeticOption.defaultColor.r + cosmeticOption.defaultColor.g + + cosmeticOption.defaultColor.b + cosmeticOption.defaultColor.a + + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() + : static_cast(gSaveContext.ship.stats.fileCreatedAt)); + Random_Init(finalSeed); + + randomColor = GetRandomValue(finalSeed); + } else { + randomColor = GetRandomValue(); + } + Color_RGBA8 newColor; newColor.r = static_cast(randomColor.x * 255.0f); newColor.g = static_cast(randomColor.y * 255.0f); @@ -2372,17 +2400,17 @@ void CosmeticsEditorWindow::DrawElement() { .Step(0.01f) .Size(ImVec2(300.0f, 0.0f)) .Color(THEME_COLOR)); - ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); - UIWidgets::CVarCheckbox("Randomize All on New Scene", CVAR_COSMETIC("RandomizeAllOnNewScene"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Enables randomizing all unlocked cosmetics when you enter a new scene.")); - ImGui::EndDisabled(); - UIWidgets::CVarCheckbox( - "Randomize All on Randomizer Generation", CVAR_COSMETIC("RandomizeAllOnRandoGen"), - UIWidgets::CheckboxOptions() + UIWidgets::CVarCombobox( + "Randomize All Cosmetics Mode", CVAR_COSMETIC("RandomizeCosmeticsGenModes"), cosmeticsRandomizerModes, + UIWidgets::ComboboxOptions() + .DefaultIndex(RANDOMIZE_OFF) .Color(THEME_COLOR) - .Tooltip("Enables randomizing all unlocked cosmetics when you generate a new randomizer.")); + .Tooltip("Set when the cosmetics is automaticly randomized:\n" + "- Disabled: No cosmetics are randomized\n" + "- On New Scene : Randomizes when you enter a new scene.\n" + "- On Rando Gen Only: Randomizes only when you generate a new randomizer.\n" + "- On File Load: Randomizes on File Load.\n" + "- On File Load (Seeded): Randomizes on file load based on the current randomizer seed/file.\n")); UIWidgets::CVarCheckbox( "Advanced Mode", CVAR_COSMETIC("AdvancedMode"), UIWidgets::CheckboxOptions() @@ -2573,6 +2601,38 @@ void CosmeticsEditorWindow::DrawElement() { UIWidgets::PopStyleTabs(); } +void RegisterOnLoadGameHook() { + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + if (CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD || + CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED) { + + CosmeticsEditor_AutoRandomizeAll(); + } else { + ApplyOrResetCustomGfxPatches(); + } + }); +} + +void RegisterOnGameFrameUpdateHook() { + GameInteractor::Instance->RegisterGameHook([]() { CosmeticsUpdateTick(); }); +} + +void Cosmetics_RegisterOnSceneInitHook() { + GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { + if (CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_NEW_SCENE) { + CosmeticsEditor_AutoRandomizeAll(); + } + }); +} + +void CosmeticsEditorRegisterOnGenerationCompletionHook() { + GameInteractor::Instance->RegisterGameHook([]() { + if (CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + CosmeticsEditor_AutoRandomizeAll(); + } + }); +} + void CosmeticsEditorWindow::InitElement() { // Convert the `current color` into the format that the ImGui color picker expects for (auto& [id, cosmeticOption] : cosmeticOptions) { @@ -2588,6 +2648,11 @@ void CosmeticsEditorWindow::InitElement() { Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); ApplyAuthenticGfxPatches(); + + RegisterOnLoadGameHook(); + RegisterOnGameFrameUpdateHook(); + Cosmetics_RegisterOnSceneInitHook(); + CosmeticsEditorRegisterOnGenerationCompletionHook(); } void CosmeticsEditor_RandomizeAll() { @@ -2602,6 +2667,18 @@ void CosmeticsEditor_RandomizeAll() { ApplyOrResetCustomGfxPatches(); } +void CosmeticsEditor_AutoRandomizeAll() { + for (auto& [id, cosmeticOption] : cosmeticOptions) { + if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && + (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0))) { + RandomizeColor(cosmeticOption, false); + } + } + + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ApplyOrResetCustomGfxPatches(); +} + void CosmeticsEditor_RandomizeGroup(CosmeticGroup group) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h index e10583081d7..7da88bdbc6b 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h @@ -55,6 +55,7 @@ static ImGuiTableColumnFlags FlagsCell = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort; void CosmeticsEditor_RandomizeAll(); +void CosmeticsEditor_AutoRandomizeAll(); void CosmeticsEditor_RandomizeGroup(CosmeticGroup group); void CosmeticsEditor_ResetAll(); void CosmeticsEditor_ResetGroup(CosmeticGroup group); diff --git a/soh/soh/SohGui/UIWidgets.cpp b/soh/soh/SohGui/UIWidgets.cpp index ca5b4be9b86..9a054735289 100644 --- a/soh/soh/SohGui/UIWidgets.cpp +++ b/soh/soh/SohGui/UIWidgets.cpp @@ -1170,6 +1170,21 @@ ImVec4 GetRandomValue() { return NewColor; } +ImVec4 GetRandomValue(uint32_t seed) { +#if !defined(__SWITCH__) && !defined(__WIIU__) + std::mt19937 rng(seed); +#else + std::mt19937_64 rng(seed); +#endif + std::uniform_int_distribution dist(0, 255 - 1); + + ImVec4 NewColor; + NewColor.x = (float)(dist(rng)) / 255.0f; + NewColor.y = (float)(dist(rng)) / 255.0f; + NewColor.z = (float)(dist(rng)) / 255.0f; + return NewColor; +} + Color_RGBA8 RGBA8FromVec(ImVec4 vec) { Color_RGBA8 color = { vec.x * 255, vec.y * 255, vec.z * 255, vec.w * 255 }; return color; diff --git a/soh/soh/SohGui/UIWidgets.hpp b/soh/soh/SohGui/UIWidgets.hpp index 95590b1ce5c..9dacf95fcc2 100644 --- a/soh/soh/SohGui/UIWidgets.hpp +++ b/soh/soh/SohGui/UIWidgets.hpp @@ -1047,7 +1047,9 @@ void DrawFlagArray8Mask(const std::string& name, uint8_t& flags, Colors color = void InsertHelpHoverText(const std::string& text); void InsertHelpHoverText(const char* text); } // namespace UIWidgets + ImVec4 GetRandomValue(); +ImVec4 GetRandomValue(uint32_t seed); Color_RGBA8 RGBA8FromVec(ImVec4 vec); ImVec4 VecFromRGBA8(Color_RGBA8 color); From 4673fa6d86ee65210df1ddf145c740a7f37bc6ba Mon Sep 17 00:00:00 2001 From: Glought Date: Tue, 18 Nov 2025 18:09:02 -0800 Subject: [PATCH 3/6] Renamed "Randomize All Music and Sound Effects Mode" to "Automatically Randomize All Music and Sound Effects" Renamed "Randomize All Cosmetics Mode" to "Automatically Randomize All Cosmetics" --- soh/soh/Enhancements/audio/AudioEditor.cpp | 2 +- soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index 77c0dee5a22..5c571558a6f 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -904,7 +904,7 @@ void RegisterAudioWidgets() { .Size(ImVec2(300.0f, 0.0f))); SohGui::mSohMenu->AddSearchWidget({ voicePitch, "Enhancements", "Audio Editor", "Audio Options" }); - randomAudioGenModes = { .name = "Randomize All Music and Sound Effects Mode", + randomAudioGenModes = { .name = "Automatically Randomize All Music and Sound Effects", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; randomAudioGenModes.CVar(CVAR_AUDIO("RandomizeAudioGenModes")) .Options( diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 79e62063f67..26c223d0664 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -2401,7 +2401,7 @@ void CosmeticsEditorWindow::DrawElement() { .Size(ImVec2(300.0f, 0.0f)) .Color(THEME_COLOR)); UIWidgets::CVarCombobox( - "Randomize All Cosmetics Mode", CVAR_COSMETIC("RandomizeCosmeticsGenModes"), cosmeticsRandomizerModes, + "Automatically Randomize All Cosmetics", CVAR_COSMETIC("RandomizeCosmeticsGenModes"), cosmeticsRandomizerModes, UIWidgets::ComboboxOptions() .DefaultIndex(RANDOMIZE_OFF) .Color(THEME_COLOR) From a9f6883c5da5260de20f7801c467579f4af9ed9a Mon Sep 17 00:00:00 2001 From: Glought Date: Sun, 23 Nov 2025 17:23:04 -0800 Subject: [PATCH 4/6] Fixed issue where Cosmetics Editor "Automatically Randomize All Cosmetics" was set to "On File Load (Seeded)" and Audio Editor "Automatically Randomize All Music and Sound Effects" set to "On File Load" causing the audio editor to get seeded by the cosmetics setting. --- soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 26c223d0664..84e75d10a90 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -2116,7 +2116,6 @@ void RandomizeColor(CosmeticOption& cosmeticOption, bool manual = true) { cosmeticOption.defaultColor.b + cosmeticOption.defaultColor.a + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : static_cast(gSaveContext.ship.stats.fileCreatedAt)); - Random_Init(finalSeed); randomColor = GetRandomValue(finalSeed); } else { From 49be5ba52be238758df60f10ffe6474d95c4053d Mon Sep 17 00:00:00 2001 From: Glought Date: Wed, 3 Dec 2025 13:25:07 -0800 Subject: [PATCH 5/6] Updated CosmeticsEditor to match PR-5900 --- .../cosmetics/CosmeticsEditor.cpp | 58 ++++++------------- 1 file changed, 18 insertions(+), 40 deletions(-) diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 84e75d10a90..8c2f8dde290 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -2600,38 +2600,10 @@ void CosmeticsEditorWindow::DrawElement() { UIWidgets::PopStyleTabs(); } -void RegisterOnLoadGameHook() { - GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { - if (CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD || - CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED) { - - CosmeticsEditor_AutoRandomizeAll(); - } else { - ApplyOrResetCustomGfxPatches(); - } - }); -} - void RegisterOnGameFrameUpdateHook() { GameInteractor::Instance->RegisterGameHook([]() { CosmeticsUpdateTick(); }); } -void Cosmetics_RegisterOnSceneInitHook() { - GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { - if (CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_NEW_SCENE) { - CosmeticsEditor_AutoRandomizeAll(); - } - }); -} - -void CosmeticsEditorRegisterOnGenerationCompletionHook() { - GameInteractor::Instance->RegisterGameHook([]() { - if (CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { - CosmeticsEditor_AutoRandomizeAll(); - } - }); -} - void CosmeticsEditorWindow::InitElement() { // Convert the `current color` into the format that the ImGui color picker expects for (auto& [id, cosmeticOption] : cosmeticOptions) { @@ -2647,11 +2619,6 @@ void CosmeticsEditorWindow::InitElement() { Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); ApplyAuthenticGfxPatches(); - - RegisterOnLoadGameHook(); - RegisterOnGameFrameUpdateHook(); - Cosmetics_RegisterOnSceneInitHook(); - CosmeticsEditorRegisterOnGenerationCompletionHook(); } void CosmeticsEditor_RandomizeAll() { @@ -2714,13 +2681,25 @@ void CosmeticsEditor_ResetGroup(CosmeticGroup group) { } void RegisterCosmeticHooks() { - COND_HOOK(OnSceneInit, CVarGetInteger(CVAR_COSMETIC("RandomizeAllOnNewScene"), 0), - [](s16 sceneNum) { CosmeticsEditor_RandomizeAll(); }); + COND_HOOK(OnGenerationCompletion, + CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), RANDOMIZE_OFF) == RANDOMIZE_ON_RANDO_GEN_ONLY, + []() { CosmeticsEditor_AutoRandomizeAll(); }); + + COND_HOOK(OnLoadGame, CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), RANDOMIZE_OFF) == RANDOMIZE_OFF, + [](s32 fileNum) { ApplyOrResetCustomGfxPatches(); }); + + COND_HOOK(OnLoadGame, + CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), RANDOMIZE_OFF) == RANDOMIZE_ON_FILE_LOAD, + [](s32 fileNum) { CosmeticsEditor_AutoRandomizeAll(); }); - COND_HOOK(OnGenerationCompletion, CVarGetInteger(CVAR_COSMETIC("RandomizeAllOnRandoGen"), 0), - []() { CosmeticsEditor_RandomizeAll(); }); + COND_HOOK(OnLoadGame, + CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), RANDOMIZE_OFF) == + RANDOMIZE_ON_FILE_LOAD_SEEDED, + [](s32 fileNum) { CosmeticsEditor_AutoRandomizeAll(); }); - COND_HOOK(OnLoadGame, true, [](int32_t fileNum) { ApplyOrResetCustomGfxPatches(); }); + COND_HOOK(OnSceneInit, + CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), RANDOMIZE_OFF) == RANDOMIZE_ON_NEW_SCENE, + [](s16 sceneNum) { CosmeticsEditor_AutoRandomizeAll(); }); COND_HOOK(OnGameFrameUpdate, true, CosmeticsUpdateTick); } @@ -2740,7 +2719,6 @@ void RegisterCosmeticWidgets() { } static RegisterShipInitFunc initFunc(RegisterCosmeticHooks, { - CVAR_COSMETIC("RandomizeAllOnNewScene"), - CVAR_COSMETIC("RandomizeAllOnRandoGen"), + CVAR_COSMETIC("RandomizeCosmeticsGenModes"), }); static RegisterMenuInitFunc menuInitFunc(RegisterCosmeticWidgets); From 5a956b8cb8a72a409d91a2ba5763c086c0dca653 Mon Sep 17 00:00:00 2001 From: Glought Date: Sat, 27 Dec 2025 18:16:36 -0800 Subject: [PATCH 6/6] Renamed the "Disabled" option in "audioRandomizerModes" to "Manual" and changed the tooltip to "Manual: Manually randomize music or sound effects by pressing the 'Randomize all Groups' button" Renamed the "Disabled" option in "cosmeticsRandomizerModes" to "Manual" and changed the tooltip to "Manual: Manually randomize cosmetics by pressing the 'Randomize all' button" Removed the "IS_RANDO" in "AudioEditor.cpp: RandomizeGroup" and "CosmeticsEditor.cpp: RandomizeColor" if statements so "On File Load (Seeded)" can be used in Vanilla (minor issue on first load will have a false seed of 0 till the player saves for the first time making the true seed). --- soh/soh/Enhancements/audio/AudioEditor.cpp | 9 +++++---- soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp | 10 ++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index 5c571558a6f..d951f5eb4d2 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -78,7 +78,7 @@ size_t AuthenticCountBySequenceType(SeqType type) { } static const std::unordered_map audioRandomizerModes = { - { RANDOMIZE_OFF, "Disabled" }, + { RANDOMIZE_OFF, "Manual" }, { RANDOMIZE_ON_NEW_SCENE, "On New Scene" }, { RANDOMIZE_ON_RANDO_GEN_ONLY, "On Rando Gen Only" }, { RANDOMIZE_ON_FILE_LOAD, "On File Load" }, @@ -111,8 +111,8 @@ void RandomizeGroup(SeqType type, bool manual = true) { std::vector values; if (!manual) { - if (IS_RANDO && CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED || - IS_RANDO && CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + if (CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED || + CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { uint32_t finalSeed = type + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : static_cast(gSaveContext.ship.stats.fileCreatedAt)); @@ -913,7 +913,8 @@ void RegisterAudioWidgets() { .ComboMap(audioRandomizerModes) .Tooltip( "Set when the music and sound effects is automaticly randomized:\n" - "- Disabled: No music or sound effects are randomized\n" + "- Manual: Manually randomize music or sound effects by pressing the 'Randomize all Groups' " + "button\n" "- On New Scene : Randomizes when you enter a new scene.\n" "- On Rando Gen Only: Randomizes only when you generate a new randomizer.\n" "- On File Load: Randomizes on File Load.\n" diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 8c2f8dde290..3a475516bad 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -100,7 +100,7 @@ std::map groupLabels = { }; static const std::unordered_map cosmeticsRandomizerModes = { - { RANDOMIZE_OFF, "Disabled" }, + { RANDOMIZE_OFF, "Manual" }, { RANDOMIZE_ON_NEW_SCENE, "On New Scene" }, { RANDOMIZE_ON_RANDO_GEN_ONLY, "On Rando Gen Only" }, { RANDOMIZE_ON_FILE_LOAD, "On File Load" }, @@ -2107,10 +2107,8 @@ void ApplySideEffects(CosmeticOption& cosmeticOption) { void RandomizeColor(CosmeticOption& cosmeticOption, bool manual = true) { ImVec4 randomColor; - if (!manual && IS_RANDO && - CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED || - !manual && IS_RANDO && - CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + if (!manual && CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED || + !manual && CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { uint32_t finalSeed = cosmeticOption.defaultColor.r + cosmeticOption.defaultColor.g + cosmeticOption.defaultColor.b + cosmeticOption.defaultColor.a + @@ -2405,7 +2403,7 @@ void CosmeticsEditorWindow::DrawElement() { .DefaultIndex(RANDOMIZE_OFF) .Color(THEME_COLOR) .Tooltip("Set when the cosmetics is automaticly randomized:\n" - "- Disabled: No cosmetics are randomized\n" + "- Manual: Manually randomize cosmetics by pressing the 'Randomize all' button\n" "- On New Scene : Randomizes when you enter a new scene.\n" "- On Rando Gen Only: Randomizes only when you generate a new randomizer.\n" "- On File Load: Randomizes on File Load.\n"