From 8513fd8800b4d3fe253174f2158ccb6c1ef60f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= <159546+serprex@users.noreply.github.com> Date: Sun, 12 Apr 2026 18:25:05 +0000 Subject: [PATCH] fix cosmetic/audio randomizing options being seeded when they shouldn't be (#6481) --- soh/soh/Enhancements/audio/AudioEditor.cpp | 15 ++++++----- .../cosmetics/CosmeticsEditor.cpp | 26 +++++++++++-------- soh/soh/SohGui/UIWidgets.cpp | 11 +------- soh/soh/SohGui/UIWidgets.hpp | 3 +-- 4 files changed, 26 insertions(+), 29 deletions(-) diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index e82f85ee1..6139da7c0 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -109,19 +109,22 @@ void UpdateCurrentBGM(u16 seqKey, SeqType seqType) { } } -static uint64_t seeded_audio_state = 0; - void RandomizeGroup(SeqType type, bool manual = true) { std::vector values; + uint64_t localRngState = 0; + uint64_t* shuffleState = nullptr; + if (!manual) { - if (CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED || - CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + int randomizeMode = CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0); + if (randomizeMode == RANDOMIZE_ON_FILE_LOAD_SEEDED || randomizeMode == RANDOMIZE_ON_RANDO_GEN_ONLY) { uint32_t finalSeed = type + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : static_cast(gSaveContext.ship.stats.fileCreatedAt)); - ShipUtils::RandInit(finalSeed, &seeded_audio_state); + ShipUtils::RandInit(finalSeed, &localRngState); + shuffleState = &localRngState; } + // For RANDOMIZE_ON_NEW_SCENE, shuffleState remains nullptr, which uses the global RNG } // An empty IncludedSequences set means that the AudioEditor window has never been drawn @@ -141,7 +144,7 @@ void RandomizeGroup(SeqType type, bool manual = true) { if (!values.size()) return; } - ShipUtils::Shuffle(values, &seeded_audio_state); + ShipUtils::Shuffle(values, shuffleState); for (const auto& [seqId, seqData] : AudioCollection::Instance->GetAllSequences()) { const std::string cvarKey = AudioCollection::Instance->GetCvarKey(seqData.sfxKey); const std::string cvarLockKey = AudioCollection::Instance->GetCvarLockKey(seqData.sfxKey); diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index b378486c7..a02a65887 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -2104,24 +2104,28 @@ void ApplySideEffects(CosmeticOption& cosmeticOption) { } } -static uint64_t seeded_cosmetics_state = 0; - void RandomizeColor(CosmeticOption& cosmeticOption, bool manual = true) { ImVec4 randomColor; - if (!manual && CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED || - !manual && CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + uint64_t local_seed_state = 0; + uint64_t* randomState = nullptr; - 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)); + if (!manual) { + int randomizeMode = CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0); + if (randomizeMode == RANDOMIZE_ON_FILE_LOAD_SEEDED || randomizeMode == RANDOMIZE_ON_RANDO_GEN_ONLY) { - randomColor = GetRandomValue(finalSeed, &seeded_cosmetics_state); - } else { - randomColor = GetRandomValue(); + 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)); + + randomState = &local_seed_state; + ShipUtils::RandInit(finalSeed, randomState); + } + // For RANDOMIZE_ON_NEW_SCENE, randomState remains nullptr, which uses the global RNG } + randomColor = GetRandomValue(randomState); Color_RGBA8 newColor; newColor.r = static_cast(randomColor.x * 255.0f); newColor.g = static_cast(randomColor.y * 255.0f); diff --git a/soh/soh/SohGui/UIWidgets.cpp b/soh/soh/SohGui/UIWidgets.cpp index ee5c39057..fff4da0ef 100644 --- a/soh/soh/SohGui/UIWidgets.cpp +++ b/soh/soh/SohGui/UIWidgets.cpp @@ -1250,16 +1250,7 @@ bool CVarBtnSelector(const char* label, const char* cvarName, const BtnSelectorO } } // namespace UIWidgets -ImVec4 GetRandomValue() { - ImVec4 NewColor; - NewColor.x = (float)ShipUtils::RandomDouble(); - NewColor.y = (float)ShipUtils::RandomDouble(); - NewColor.z = (float)ShipUtils::RandomDouble(); - return NewColor; -} - -ImVec4 GetRandomValue(uint32_t seed, uint64_t* state) { - ShipUtils::RandInit(seed, state); +ImVec4 GetRandomValue(uint64_t* state) { ImVec4 NewColor; NewColor.x = (float)ShipUtils::RandomDouble(state); NewColor.y = (float)ShipUtils::RandomDouble(state); diff --git a/soh/soh/SohGui/UIWidgets.hpp b/soh/soh/SohGui/UIWidgets.hpp index 927b2d271..494974f45 100644 --- a/soh/soh/SohGui/UIWidgets.hpp +++ b/soh/soh/SohGui/UIWidgets.hpp @@ -1089,8 +1089,7 @@ void InsertHelpHoverText(const std::string& text); void InsertHelpHoverText(const char* text); } // namespace UIWidgets -ImVec4 GetRandomValue(); -ImVec4 GetRandomValue(uint32_t seed, uint64_t* state = nullptr); +ImVec4 GetRandomValue(uint64_t* state = nullptr); Color_RGBA8 RGBA8FromVec(ImVec4 vec); ImVec4 VecFromRGBA8(Color_RGBA8 color);