diff --git a/soh/soh/Enhancements/randomizer/SeedContext.cpp b/soh/soh/Enhancements/randomizer/SeedContext.cpp index 5a2eb77857..9ac56f7770 100644 --- a/soh/soh/Enhancements/randomizer/SeedContext.cpp +++ b/soh/soh/Enhancements/randomizer/SeedContext.cpp @@ -13,6 +13,7 @@ #include "soh/util.h" #include "../kaleido.h" #include "soh/Enhancements/randomizer/Traps.h" +#include "soh/Enhancements/randomizer/3drando/random.hpp" #include "soh/Enhancements/randomizer/randomizer.h" #include @@ -330,9 +331,9 @@ void Context::CreateItemOverrides() { // If this is an ice trap, store the disguise model in iceTrapModels const auto itemLoc = GetItemLocation(locKey); if (itemLoc->GetPlacedRandomizerGet() == RG_ICE_TRAP) { - ItemOverride val(locKey, Traps::GetTrapTrickModel()); + ItemOverride val(locKey, Traps::GetTrapTrickModel(&rando_state)); iceTrapModels[locKey] = val.LooksLike(); - val.SetTrickName(Traps::GetTrapName(val.LooksLike())); + val.SetTrickName(Traps::GetTrapName(val.LooksLike(), &rando_state)); // If this is ice trap is in a shop, change the name based on what the model will look like overrides[locKey] = val; } diff --git a/soh/soh/Enhancements/randomizer/Traps.cpp b/soh/soh/Enhancements/randomizer/Traps.cpp index d6334ba3a7..8c55d10314 100644 --- a/soh/soh/Enhancements/randomizer/Traps.cpp +++ b/soh/soh/Enhancements/randomizer/Traps.cpp @@ -4,6 +4,8 @@ #include "soh/Enhancements/randomizer/static_data.h" #include "soh/ShipUtils.h" +#include "soh/Enhancements/randomizer/3drando/random.hpp" + #include static std::array, RG_MAX> trickNameTable; // Table of trick names for ice traps @@ -1418,7 +1420,7 @@ static void InitTrickNames() { } // Generate a fake name for the ice trap based on the item it's displayed as -Text Rando::Traps::GetTrapName(uint16_t id) { +Text Rando::Traps::GetTrapName(uint16_t id, uint64_t* state) { // If the trick names table has not been initialized, do so if (!initTrickNames) { InitTrickNames(); @@ -1431,19 +1433,19 @@ Text Rando::Traps::GetTrapName(uint16_t id) { } // Randomly get the easy, medium, or hard name for the given item id - return ShipUtils::RandomElement(trickNameTable[id]); + return ShipUtils::RandomElement(trickNameTable[id], state); } -RandomizerGet Rando::Traps::GetTrapTrickModel() { +RandomizerGet Rando::Traps::GetTrapTrickModel(uint64_t* state) { auto ctx = Rando::Context::GetInstance(); - RandomizerGet trickModel = ShipUtils::RandomElementFromSet(ctx->possibleIceTrapModels); + RandomizerGet trickModel = ShipUtils::RandomElementFromSet(ctx->possibleIceTrapModels, state); if (trickModel == RG_EMPTY_BOTTLE) { - trickModel = ShipUtils::RandomElement(Rando::StaticData::normalBottles); + trickModel = ShipUtils::RandomElement(Rando::StaticData::normalBottles, state); } else if (trickModel == RG_GUARD_HOUSE_KEY) { - trickModel = ShipUtils::RandomElement(Rando::StaticData::overworldKeys); + trickModel = ShipUtils::RandomElement(Rando::StaticData::overworldKeys, state); } else if (trickModel == RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) { - trickModel = ShipUtils::RandomElement(Rando::StaticData::beanSouls); + trickModel = ShipUtils::RandomElement(Rando::StaticData::beanSouls, state); } return trickModel; @@ -1451,17 +1453,9 @@ RandomizerGet Rando::Traps::GetTrapTrickModel() { bool Rando::Traps::ShouldJunkItemBeTrap() { auto ctx = Rando::Context::GetInstance(); - - if (ctx->GetOption(RSK_ICE_TRAP_PERCENT).Is(0)) { - return false; - } - - if (ctx->GetOption(RSK_ICE_TRAP_PERCENT).Is(100) || - ShipUtils::Random(0, 100) < ctx->GetOption(RSK_ICE_TRAP_PERCENT).Get()) { - return true; - } - - return false; + return ctx->GetOption(RSK_ICE_TRAP_PERCENT).IsNot(0) && + (ctx->GetOption(RSK_ICE_TRAP_PERCENT).Is(100) || + Random(0, 100) < ctx->GetOption(RSK_ICE_TRAP_PERCENT).Get()); } static const char* const englishIceTrapMessages[] = { diff --git a/soh/soh/Enhancements/randomizer/Traps.h b/soh/soh/Enhancements/randomizer/Traps.h index cf8f8905ce..dbb4fb6a74 100644 --- a/soh/soh/Enhancements/randomizer/Traps.h +++ b/soh/soh/Enhancements/randomizer/Traps.h @@ -11,8 +11,8 @@ namespace Rando { namespace Traps { -Text GetTrapName(uint16_t id); -RandomizerGet GetTrapTrickModel(); +Text GetTrapName(uint16_t id, uint64_t* state = nullptr); +RandomizerGet GetTrapTrickModel(uint64_t* state = nullptr); bool ShouldJunkItemBeTrap(); void BuildIceTrapMessage(CustomMessage& msg, GetItemEntry getItemEntry); } // namespace Traps diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index e0b8c2f394..552c602c8b 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -1,13 +1,11 @@ #include "settings.h" -#include "soh/Enhancements/randomizer/randomizerTypes.h" #include "trial.h" #include "dungeon.h" -#include "soh/ShipUtils.h" - +#include "soh/Enhancements/randomizer/randomizerTypes.h" +#include "soh/Enhancements/randomizer/3drando/random.hpp" #include "soh/OTRGlobals.h" #include - #include #include @@ -2628,7 +2626,7 @@ void Context::FinalizeSettings(const std::set& excludedLocation case RO_MQ_SET_RANDOM: // 50% per dungeon, rolled separatly so people can either have a linear distribtuion // or a bell curve for the number of MQ dungeons per seed. - if (ShipUtils::Random(0, 2)) { + if (Random(0, 2)) { dungeon->SetMQ(); mqSet += 1; } @@ -2695,13 +2693,13 @@ void Context::FinalizeSettings(const std::set& excludedLocation if (randMQOption.size() > 0) { // Figure out how many dungeons to select, rolling the random number if needed if (mOptions[RSK_MQ_DUNGEON_RANDOM].Is(RO_MQ_DUNGEONS_RANDOM_NUMBER)) { - mqToSet = ShipUtils::Random(0, static_cast(randMQOption.size()) + 1); + mqToSet = Random(0, static_cast(randMQOption.size()) + 1); } else if (mqCount > mqSet) { mqToSet = std::min(mqCount - mqSet, static_cast(randMQOption.size())); } // we only need to shuffle if we're not using them all if (mqToSet <= static_cast(randMQOption.size()) && mqToSet > 0) { - ShipUtils::Shuffle(randMQOption); + Shuffle(randMQOption); } for (uint8_t i = 0; i < mqToSet; i++) { dungeons[randMQOption[i]]->SetMQ(); @@ -2750,8 +2748,8 @@ void Context::FinalizeSettings(const std::set& excludedLocation if (mOptions[RSK_KEYRINGS].Is(RO_KEYRINGS_RANDOM) || mOptions[RSK_KEYRINGS].Is(RO_KEYRINGS_COUNT)) { const uint32_t keyRingCount = mOptions[RSK_KEYRINGS].Is(RO_KEYRINGS_COUNT) ? mOptions[RSK_KEYRINGS_RANDOM_COUNT].Get() - : ShipUtils::Random(0, static_cast(keyrings.size())); - ShipUtils::Shuffle(keyrings); + : Random(0, static_cast(keyrings.size())); + Shuffle(keyrings); for (size_t i = 0; i < keyRingCount; i++) { keyrings[i]->Set(RO_KEYRING_FOR_DUNGEON_ON); } @@ -2760,50 +2758,49 @@ void Context::FinalizeSettings(const std::set& excludedLocation } } if (mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && - ShipUtils::Random(0, 2) == 0)) { + (mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 0)) { this->GetDungeon(BOTTOM_OF_THE_WELL)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_FOREST_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_FOREST_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { + (mOptions[RSK_KEYRINGS_FOREST_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 0)) { this->GetDungeon(FOREST_TEMPLE)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_FIRE_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_FIRE_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { + (mOptions[RSK_KEYRINGS_FIRE_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 0)) { this->GetDungeon(FIRE_TEMPLE)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_WATER_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_WATER_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { + (mOptions[RSK_KEYRINGS_WATER_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 0)) { this->GetDungeon(WATER_TEMPLE)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { + (mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 0)) { this->GetDungeon(SPIRIT_TEMPLE)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_SHADOW_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_SHADOW_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { + (mOptions[RSK_KEYRINGS_SHADOW_TEMPLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 0)) { this->GetDungeon(SHADOW_TEMPLE)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_GTG].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_GTG].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { + (mOptions[RSK_KEYRINGS_GTG].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 0)) { this->GetDungeon(GERUDO_TRAINING_GROUND)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_GANONS_CASTLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || - (mOptions[RSK_KEYRINGS_GANONS_CASTLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && ShipUtils::Random(0, 2) == 0)) { + (mOptions[RSK_KEYRINGS_GANONS_CASTLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 0)) { this->GetDungeon(GANONS_CASTLE)->SetKeyRing(); } } auto trials = this->GetTrials()->GetTrialList(); - ShipUtils::Shuffle(trials); + Shuffle(trials); for (const auto trial : trials) { trial->SetAsSkipped(); } if (mOptions[RSK_GANONS_TRIALS].Is(RO_GANONS_TRIALS_SKIP)) { mOptions[RSK_TRIAL_COUNT].Set(0); } else if (mOptions[RSK_GANONS_TRIALS].Is(RO_GANONS_TRIALS_RANDOM_NUMBER)) { - mOptions[RSK_TRIAL_COUNT].Set(ShipUtils::Random( - 0, static_cast(Rando::Settings::GetInstance()->GetOption(RSK_TRIAL_COUNT).GetOptionCount()))); + mOptions[RSK_TRIAL_COUNT].Set( + Random(0, static_cast(Rando::Settings::GetInstance()->GetOption(RSK_TRIAL_COUNT).GetOptionCount()))); } for (uint8_t i = 0; i < mOptions[RSK_TRIAL_COUNT].Get(); i++) { trials[i]->SetAsRequired(); @@ -2845,7 +2842,7 @@ void Context::FinalizeSettings(const std::set& excludedLocation } if (mOptions[RSK_STARTING_AGE].Is(RO_AGE_RANDOM)) { - if (const uint32_t choice = ShipUtils::Random(0, 2); choice == 0) { + if (const uint32_t choice = Random(0, 2); choice == 0) { mOptions[RSK_SELECTED_STARTING_AGE].Set(RO_AGE_CHILD); } else { mOptions[RSK_SELECTED_STARTING_AGE].Set(RO_AGE_ADULT); @@ -2970,7 +2967,7 @@ void Settings::RandomizeAllSettings() { continue; } - uint8_t randomIndex = ShipUtils::Random(0, static_cast(option.GetOptionCount())); + uint8_t randomIndex = Random(0, static_cast(option.GetOptionCount())); option.SetContextIndex(randomIndex); if (!option.GetCVarName().empty()) {