diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 5d7a290c0..38ca7c646 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -1026,7 +1026,7 @@ void GenerateItemPool() { } //Gerudo Fortress - if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN)) { + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FREE)) { ctx->PlaceItemInLocation(RC_GF_NORTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); @@ -1071,7 +1071,7 @@ void GenerateItemPool() { } //Gerudo Membership Card - if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) && ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_OPEN)) { + if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) && ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_FREE)) { AddItemToMainPool(RG_GERUDO_MEMBERSHIP_CARD); ctx->possibleIceTrapModels.push_back(RG_GERUDO_MEMBERSHIP_CARD); } else if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp index db7058f33..529c47fd2 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp @@ -16,7 +16,7 @@ void RegionTable_Init_GerudoValley() { Entrance(RR_GV_UPPER_STREAM, {[]{return true;}}), Entrance(RR_GV_CRATE_LEDGE, {[]{return logic->IsChild || logic->CanUse(RG_LONGSHOT);}}), Entrance(RR_GV_GROTTO_LEDGE, {[]{return true;}}), - Entrance(RR_GV_FORTRESS_SIDE, {[]{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) || logic->CarpenterRescue)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}}), + Entrance(RR_GV_FORTRESS_SIDE, {[]{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FREE) || logic->CarpenterRescue)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}}), }); areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, { @@ -64,7 +64,7 @@ void RegionTable_Init_GerudoValley() { //Exits Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}), Entrance(RR_GV_UPPER_STREAM, {[]{return true;}}), - Entrance(RR_GERUDO_VALLEY, {[]{return logic->IsChild || logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) || logic->CarpenterRescue;}}), + Entrance(RR_GERUDO_VALLEY, {[]{return logic->IsChild || logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FREE) || logic->CarpenterRescue;}}), Entrance(RR_GV_CARPENTER_TENT, {[]{return logic->IsAdult;}}), Entrance(RR_GV_STORMS_GROTTO, {[]{return logic->IsAdult && logic->CanOpenStormsGrotto();}}), Entrance(RR_GV_CRATE_LEDGE, {[]{return false;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index a665c4eea..58409d0ec 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -139,14 +139,11 @@ static void WriteShuffledEntrance(std::string sphereString, Entrance* entrance) // Writes the settings (without excluded locations, starting inventory and tricks) to the spoilerLog document. static void WriteSettings() { auto ctx = Rando::Context::GetInstance(); - auto allOptionGroups = ctx->GetSettings()->GetOptionGroups(); - for (const Rando::OptionGroup& optionGroup : allOptionGroups) { - if (optionGroup.GetContainsType() == Rando::OptionGroupType::DEFAULT && optionGroup.PrintInSpoiler()) { - for (Rando::Option* option : optionGroup.GetOptions()) { - std::string settingName = optionGroup.GetName() + ":" + option->GetName(); - jsonData["settings"][settingName] = option->GetSelectedOptionText(); - } - } + std::array options = ctx->GetSettings()->GetAllOptions(); + for (const Rando::Option& option : options) { + if (option.GetName() != ""){ + jsonData["settings"][option.GetName()] = option.GetSelectedOptionText(); + } } } diff --git a/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp b/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp index 035259fdb..dea7042c5 100644 --- a/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp @@ -61,7 +61,7 @@ void GenerateStartingInventory() { AddItemToInventory(RG_GANONS_CASTLE_BOSS_KEY); } - if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) && !ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FREE) && !ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { AddItemToInventory(RG_GERUDO_MEMBERSHIP_CARD); } diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index da76be1d3..72f493977 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1124,7 +1124,7 @@ namespace Rando { bool Logic::CanFinishGerudoFortress(){ return (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_NORMAL) && SmallKeys(RR_GERUDO_FORTRESS, 4) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && (HasItem(RG_GERUDO_MEMBERSHIP_CARD) || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))) || (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST) && SmallKeys(RR_GERUDO_FORTRESS, 1) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD))) || - ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN); + ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FREE); } bool Logic::CanStandingShield(){ diff --git a/soh/soh/Enhancements/randomizer/option.cpp b/soh/soh/Enhancements/randomizer/option.cpp index 08195276d..f5f9d1cba 100644 --- a/soh/soh/Enhancements/randomizer/option.cpp +++ b/soh/soh/Enhancements/randomizer/option.cpp @@ -178,6 +178,15 @@ void Option::RemoveFlag(const int imFlag_) { imFlags &= ~imFlag_; } +void Option::SetContextIndexFromText(const std::string text) { + if (optionsTextToVar.contains(text)){ + SetContextIndex(optionsTextToVar[text]); + } else { + SPDLOG_ERROR("Option {} does not have a var named {}.", name, text); + assert(false); + } +} + Option::Option(uint8_t var_, std::string name_, std::vector options_, OptionCategory category_, std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_, bool defaultHidden_, int imFlags_) @@ -186,6 +195,7 @@ Option::Option(uint8_t var_, std::string name_, std::vector options defaultOption(defaultOption_), defaultHidden(defaultHidden_), imFlags(imFlags_) { menuSelection = contextSelection = defaultOption; hidden = defaultHidden; + PopulateTextToNum(); SetFromCVar(); } Option::Option(bool var_, std::string name_, std::vector options_, const OptionCategory category_, @@ -196,6 +206,7 @@ Option::Option(bool var_, std::string name_, std::vector options_, defaultOption(defaultOption_), defaultHidden(defaultHidden_), imFlags(imFlags_) { menuSelection = contextSelection = defaultOption; hidden = defaultHidden; + PopulateTextToNum(); SetFromCVar(); } @@ -333,6 +344,12 @@ bool Option::RenderSlider() { return changed; } +void Option::PopulateTextToNum(){ + for (uint8_t count = 0; count < options.size(); count++){ + optionsTextToVar[options[count]] = count; + } +} + TrickOption::TrickOption(const RandomizerCheckQuest quest_, const RandomizerArea area_, std::set tags_, const bool glitch_, const std::string& name_, std::string description_) : Option(false, name_, {"Disabled", "Enabled"}, OptionCategory::Setting, "", std::move(description_), WidgetType::Checkbox, 0, false, IMFLAG_NONE), @@ -363,26 +380,26 @@ const std::set& TrickOption::GetTags() const { } OptionGroup::OptionGroup(std::string name, std::vector options, const OptionGroupType groupType, - const bool printInSpoiler, const WidgetContainerType containerType, std::string description) - : mName(std::move(name)), mOptions(std::move(options)), mGroupType(groupType), mPrintInSpoiler(printInSpoiler), + const WidgetContainerType containerType, std::string description) + : mName(std::move(name)), mOptions(std::move(options)), mGroupType(groupType), mContainerType(containerType), mDescription(std::move(description)) { } OptionGroup::OptionGroup(std::string name, std::vector subGroups, const OptionGroupType groupType, - const bool printInSpoiler, const WidgetContainerType containerType, std::string description) - : mName(std::move(name)), mSubGroups(std::move(subGroups)), mGroupType(groupType), mPrintInSpoiler(printInSpoiler), + const WidgetContainerType containerType, std::string description) + : mName(std::move(name)), mSubGroups(std::move(subGroups)), mGroupType(groupType), mContainsType(OptionGroupType::SUBGROUP), mContainerType(containerType), mDescription(std::move(description)) { } -OptionGroup OptionGroup::SubGroup(std::string name, std::vector options, const bool printInSpoiler, +OptionGroup OptionGroup::SubGroup(std::string name, std::vector options, const WidgetContainerType containerType, std::string description) { - return {std::move(name), std::move(options), OptionGroupType::SUBGROUP, printInSpoiler, containerType, + return {std::move(name), std::move(options), OptionGroupType::SUBGROUP, containerType, std::move(description)}; } -OptionGroup OptionGroup::SubGroup(std::string name, std::vector subGroups, const bool printInSpoiler, +OptionGroup OptionGroup::SubGroup(std::string name, std::vector subGroups, const WidgetContainerType containerType, std::string description) { - return {std::move(name), std::move(subGroups), OptionGroupType::SUBGROUP, printInSpoiler, containerType, + return {std::move(name), std::move(subGroups), OptionGroupType::SUBGROUP, containerType, std::move(description)}; } @@ -398,10 +415,6 @@ const std::vector& OptionGroup::GetSubGroups() const { return mSubGroups; } -bool OptionGroup::PrintInSpoiler() const { - return mPrintInSpoiler; -} - OptionGroupType OptionGroup::GetGroupType() const { return mGroupType; } diff --git a/soh/soh/Enhancements/randomizer/option.h b/soh/soh/Enhancements/randomizer/option.h index 5b7eb5b9d..cc34338d8 100644 --- a/soh/soh/Enhancements/randomizer/option.h +++ b/soh/soh/Enhancements/randomizer/option.h @@ -56,9 +56,9 @@ class Option { * @param options_ A vector of value names for this Option. This vector should have a size of 2. * The name corresponding to the selected index for this option will be printed to the spoiler/patch file. * @param category_ The desired `OptionCategory` for this option. - * @param cvarName_ The name ofthe CVar this option should correspond with. Set as an empty string to not + * @param cvarName_ The name of the CVar this option should correspond with. Set as an empty string to not * link to any Cvar. - * @param description_ A description of what this option affects. Will be rendered in a toolip in ImGui. + * @param description_ A description of what this option affects. Will be rendered in a tooltip in ImGui. * Can be left as an empty string if desired, no tooltip will be rendered. * @param widgetType_ What type of widget should be rendered. Should probably be `Checkbox` but technically * `Combobox` or `Slider` would render and function correctly. @@ -305,6 +305,8 @@ class Option { void SetFlag(int imFlag_); void RemoveFlag(int imFlag_); + void SetContextIndexFromText(std::string text); + protected: Option(uint8_t var_, std::string name_, std::vector options_, OptionCategory category_, std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_, @@ -318,6 +320,7 @@ protected: bool RenderTristateCheckbox(); bool RenderCombobox(); bool RenderSlider(); + void PopulateTextToNum(); std::variant var; std::string name; std::vector options; @@ -335,6 +338,7 @@ protected: bool disabled = false; UIWidgets::CheckboxGraphics disabledGraphic = UIWidgets::CheckboxGraphics::Cross; std::string disabledText; + std::unordered_map optionsTextToVar = {}; }; class TrickOption : public Option { @@ -416,13 +420,11 @@ class OptionGroup { * @param options A vector of Option pointers * @param groupType `DEFAULT` if this group is not contained within any other groups, `SUBGROUP` if it is a * subgroup of another group. - * @param printInSpoiler Whether or not to print the contents of this group to the spoiler/patch file. * @param containerType Specifies the type of container this widget should render as in ImGui. * @param description A description that can appear in a tooltip in ImGui. */ OptionGroup(std::string name, std::vector options, OptionGroupType groupType = OptionGroupType::DEFAULT, - bool printInSpoiler = true, WidgetContainerType containerType = WidgetContainerType::BASIC, - std::string description = ""); + WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = ""); /** * @brief Construct a new Option Group containing a list of `OptionGroup` pointers. @@ -431,13 +433,11 @@ class OptionGroup { * @param subGroups A vector of OptionGroup pointers that will be subgroups of this group. * @param groupType `DEFAULT` if this group is not contained within any other groups, `SUBGROUP` if it is a * subgroup of another group. - * @param printInSpoiler Whether or not to print the contents of this group to spoiler/patch file. * @param containerType Specifies the type of container this widget should render as in ImGui. * @param description A description that can appear in a tooltip in ImGui. */ OptionGroup(std::string name, std::vector subGroups, OptionGroupType groupType = OptionGroupType::DEFAULT, - bool printInSpoiler = true, WidgetContainerType containerType = WidgetContainerType::BASIC, - std::string description = ""); + WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = ""); /** * @brief Convenience function for constructing an OptionGroup of groupType `SUBGROUP` with @@ -445,13 +445,11 @@ class OptionGroup { * * @param name The name of this option group. Appears in the spoiler/patch file. * @param options A vector of Option pointers. - * @param printInSpoiler Whether or not to print the options of this group to the spoiler/patch file. * @param containerType Specifies the type of container this widget should render as in ImGui. * @param description A description that can appear in a tooltip in ImGui. * @return OptionGroup */ - static OptionGroup SubGroup(std::string name, std::vector options, bool printInSpoiler = true, - WidgetContainerType containerType = WidgetContainerType::BASIC, + static OptionGroup SubGroup(std::string name, std::vector options, WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = ""); /** @@ -460,13 +458,11 @@ class OptionGroup { * * @param name The name of this option group. Appears in the spoiler/patch file. * @param subGroups A vector of OptionGroup pointers. - * @param printInSpoiler Whether or not to print the options of this group to the spoiler/patch file. * @param containerType Specifies the type of container this widget should render as in ImGui. * @param description A description that can appear in a tooltip in ImGui. * @return OptionGroup */ - static OptionGroup SubGroup(std::string name, std::vector subGroups, bool printInSpoiler = true, - WidgetContainerType containerType = WidgetContainerType::BASIC, + static OptionGroup SubGroup(std::string name, std::vector subGroups, WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = ""); /** @@ -490,15 +486,6 @@ class OptionGroup { */ const std::vector& GetSubGroups() const; - /** - * @brief Returns whether or not this `OptionGroup`'s contents should be printed to the - * spoiler/patch file. - * - * @return true - * @return false - */ - bool PrintInSpoiler() const; - /** * @brief Get the Group Type of this `OptionGroup`. `DEFAULT` means this group is not contained * within any other groups, while `SUBGROUP` means that it is contained within at least one other. @@ -532,7 +519,6 @@ class OptionGroup { std::vector mOptions; std::vector mSubGroups; OptionGroupType mGroupType = OptionGroupType::DEFAULT; - bool mPrintInSpoiler = true; OptionGroupType mContainsType = OptionGroupType::DEFAULT; WidgetContainerType mContainerType = WidgetContainerType::BASIC; std::string mDescription; diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 405620849..c2abfc72b 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -43,14 +43,15 @@ void Settings::CreateOptionDescriptions() { "Choose which age Link will start as.\n\n" "Starting as adult means you start with the Master Sword in your inventory.\n" "The child option is forcefully set if it would conflict with other options."; - mOptionDescriptions[RSK_GERUDO_FORTRESS] = "Sets the amount of carpenters required to repair the bridge " - "in Gerudo Valley.\n" + mOptionDescriptions[RSK_GERUDO_FORTRESS] = "Sets the state of the carpenters captured by Gerudo " + "in Gerudo Fortress, and with it the number of guards that spawn.\n" "\n" "Normal - All 4 carpenters are required to be saved.\n" "\n" "Fast - Only the bottom left carpenter requires rescuing.\n" "\n" - "Open - The bridge is repaired from the start.\n" + "Free - The bridge is repaired from the start, and Nabooru cannot spawn.\n" + "If the Gerudo Membership Card isn't shuffled, you start with it.\n" "\n" "Only \"Normal\" is compatible with Gerudo Fortress Key Rings."; mOptionDescriptions[RSK_RAINBOW_BRIDGE] = diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 70a8e19d6..e5b6df090 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4198,7 +4198,7 @@ typedef enum { typedef enum { RO_GF_NORMAL, RO_GF_FAST, - RO_GF_OPEN, + RO_GF_FREE, } RandoOptionGerudoFortress; //Kakariko Gate settings (closed/open) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index 5d3a62b86..27d2845fe 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -206,7 +206,7 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) != RO_GANON_BOSS_KEY_KAK_TOKENS) && // 100 skull reward ganon boss key (location.GetRCType() != RCTYPE_GF_KEY && location.GetRandomizerCheck() != RC_GF_GERUDO_MEMBERSHIP_CARD || - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL) == RO_GF_OPEN && + (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL) == RO_GF_FREE && location.GetRCType() != RCTYPE_GF_KEY && location.GetRandomizerCheck() != RC_GF_GERUDO_MEMBERSHIP_CARD) || (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL) == RO_GF_FAST && ((location.GetRandomizerCheck() == RC_GF_GERUDO_MEMBERSHIP_CARD && diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index a9d9e72dc..98a0d4c3f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1185,7 +1185,7 @@ void LoadSettings() { fortressFast = false; fortressNormal = false; switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_FORTRESS)) { - case RO_GF_OPEN: + case RO_GF_FREE: showGerudoFortressKeys = false; showGerudoCard = false; break; diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index fd23feb04..4876af321 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -453,7 +453,7 @@ extern "C" void Randomizer_InitSaveFile() { } if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_FAST || - Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_OPEN) { + Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_FREE) { Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(1)); Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(2)); Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(3)); @@ -471,7 +471,7 @@ extern "C" void Randomizer_InitSaveFile() { gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0F); } - if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_OPEN) { + if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_FREE) { Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(0)); gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x01); // heard yell and unlocked door gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x05); diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index e13a32cfa..405af139c 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -110,13 +110,13 @@ void Settings::CreateOptions() { mOptions[RSK_DOOR_OF_TIME] = Option::U8("Door of Time", {"Closed", "Song only", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DoorOfTime"), mOptionDescriptions[RSK_DOOR_OF_TIME], WidgetType::Combobox); mOptions[RSK_ZORAS_FOUNTAIN] = Option::U8("Zora's Fountain", {"Closed", "Closed as child", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ZorasFountain"), mOptionDescriptions[RSK_ZORAS_FOUNTAIN]); mOptions[RSK_SLEEPING_WATERFALL] = Option::U8("Sleeping Waterfall", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), mOptionDescriptions[RSK_SLEEPING_WATERFALL]); - mOptions[RSK_GERUDO_FORTRESS] = Option::U8("Gerudo Fortress", {"Normal", "Fast", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoFortress"), mOptionDescriptions[RSK_GERUDO_FORTRESS]); + mOptions[RSK_GERUDO_FORTRESS] = Option::U8("Fortress Carpenters", {"Normal", "Fast", "Free"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoFortress"), mOptionDescriptions[RSK_GERUDO_FORTRESS]); mOptions[RSK_RAINBOW_BRIDGE] = Option::U8("Rainbow Bridge", {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Greg"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RainbowBridge"), mOptionDescriptions[RSK_RAINBOW_BRIDGE], WidgetType::Combobox, RO_BRIDGE_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT] = Option::U8("Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StoneCount"), "", WidgetType::Slider, 3, true); - mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT] = Option::U8("Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MedallionCount"), "", WidgetType::Slider, 6, true); - mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT] = Option::U8("Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RewardCount"), "", WidgetType::Slider, 9, true); - mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT] = Option::U8("Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DungeonCount"), "", WidgetType::Slider, 8, true); - mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT] = Option::U8("Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TokenCount"), "", WidgetType::Slider, 100, true); + mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT] = Option::U8("Bridge Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StoneCount"), "", WidgetType::Slider, 3, true); + mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT] = Option::U8("Bridge Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MedallionCount"), "", WidgetType::Slider, 6, true); + mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT] = Option::U8("Bridge Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RewardCount"), "", WidgetType::Slider, 9, true); + mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT] = Option::U8("Bridge Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DungeonCount"), "", WidgetType::Slider, 8, true); + mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT] = Option::U8("Bridge Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TokenCount"), "", WidgetType::Slider, 100, true); mOptions[RSK_BRIDGE_OPTIONS] = Option::U8("Bridge Reward Options", {"Standard Rewards", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), mOptionDescriptions[RSK_BRIDGE_OPTIONS], WidgetType::Combobox, RO_BRIDGE_STANDARD_REWARD, false, IMFLAG_NONE); mOptions[RSK_GANONS_TRIALS] = Option::U8("Ganon's Trials", {"Skip", "Set Number", "Random Number"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrial"), mOptionDescriptions[RSK_GANONS_TRIALS], WidgetType::Combobox, RO_GANONS_TRIALS_SET_NUMBER); mOptions[RSK_TRIAL_COUNT] = Option::U8("Ganon's Trials Count", {NumOpts(0, 6)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrialCount"), mOptionDescriptions[RSK_TRIAL_COUNT], WidgetType::Slider, 6, true); @@ -146,44 +146,44 @@ void Settings::CreateOptions() { mOptions[RSK_MQ_DUNGEON_RANDOM] = Option::U8("MQ Dungeon Setting", {"None", "Set Number", "Random", "Selection Only"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeons"), mOptionDescriptions[RSK_MQ_DUNGEON_RANDOM], WidgetType::Combobox, RO_MQ_DUNGEONS_NONE, true, IMFLAG_NONE); mOptions[RSK_MQ_DUNGEON_COUNT] = Option::U8("MQ Dungeon Count", {NumOpts(0, 12)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonCount"), "", WidgetType::Slider, 12, true, IMFLAG_NONE); mOptions[RSK_MQ_DUNGEON_SET] = Option::Bool("Set Dungeon Quests", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsSelection"), mOptionDescriptions[RSK_MQ_DUNGEON_SET], WidgetType::Checkbox, false, false, IMFLAG_NONE); - mOptions[RSK_MQ_DEKU_TREE] = Option::U8("Deku Tree", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDekuTree"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_DODONGOS_CAVERN] = Option::U8("Dodongo's Cavern", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDodongosCavern"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_JABU_JABU] = Option::U8("Jabu-Jabu's Belly", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsJabuJabu"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_FOREST_TEMPLE] = Option::U8("Forest Temple", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsForestTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_FIRE_TEMPLE] = Option::U8("Fire Temple", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsFireTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_WATER_TEMPLE] = Option::U8("Water Temple", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsWaterTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_SPIRIT_TEMPLE] = Option::U8("Spirit Temple", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsSpiritTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_SHADOW_TEMPLE] = Option::U8("Shadow Temple", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsShadowTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_BOTTOM_OF_THE_WELL] = Option::U8("Bottom of the Well", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsBottomOfTheWell"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_ICE_CAVERN] = Option::U8("Ice Cavern", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsIceCavern"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_GTG] = Option::U8("Gerudo Training Grounds", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGTG"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_GANONS_CASTLE] = Option::U8("Ganon's Castle", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGanonsCastle"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA); + mOptions[RSK_MQ_DEKU_TREE] = Option::U8("Deku Tree Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDekuTree"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_DODONGOS_CAVERN] = Option::U8("Dodongo's Cavern Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDodongosCavern"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_JABU_JABU] = Option::U8("Jabu-Jabu's Belly Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsJabuJabu"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_FOREST_TEMPLE] = Option::U8("Forest Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsForestTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_FIRE_TEMPLE] = Option::U8("Fire Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsFireTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_WATER_TEMPLE] = Option::U8("Water Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsWaterTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_SPIRIT_TEMPLE] = Option::U8("Spirit Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsSpiritTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_SHADOW_TEMPLE] = Option::U8("Shadow Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsShadowTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_BOTTOM_OF_THE_WELL] = Option::U8("Bottom of the Well Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsBottomOfTheWell"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_ICE_CAVERN] = Option::U8("Ice Cavern Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsIceCavern"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_GTG] = Option::U8("Gerudo Training Grounds Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGTG"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_GANONS_CASTLE] = Option::U8("Ganon's Castle Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGanonsCastle"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA); mOptions[RSK_SHUFFLE_DUNGEON_REWARDS] = Option::U8("Shuffle Dungeon Rewards", {"End of Dungeons", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS], WidgetType::Combobox, RO_DUNGEON_REWARDS_END_OF_DUNGEON); mOptions[RSK_LINKS_POCKET] = Option::U8("Link's Pocket", {"Dungeon Reward", "Advancement", "Anything", "Nothing"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocket"), "", WidgetType::Combobox, RO_LINKS_POCKET_DUNGEON_REWARD); mOptions[RSK_SHUFFLE_SONGS] = Option::U8("Shuffle Songs", {"Song Locations", "Dungeon Rewards", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSongs"), mOptionDescriptions[RSK_SHUFFLE_SONGS], WidgetType::Combobox, RO_SONG_SHUFFLE_SONG_LOCATIONS); - mOptions[RSK_SHOPSANITY] = Option::U8("Shopsanity", {"Off", "Specific Count", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), mOptionDescriptions[RSK_SHOPSANITY], WidgetType::Combobox, RO_SHOPSANITY_OFF); - mOptions[RSK_SHOPSANITY_COUNT] = Option::U8("Shopsanity Item Count", {NumOpts(0, 7/*8*/)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityCount"), mOptionDescriptions[RSK_SHOPSANITY_COUNT], WidgetType::Slider, 0, false, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES] = Option::U8("Shopsanity Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), mOptionDescriptions[RSK_SHOPSANITY_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE] = Option::U8("Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); - mOptions[RSK_SHOPSANITY_PRICES_RANGE_1] = Option::U8("Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_RANGE_2] = Option::U8("Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT] = Option::U8("No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY] = Option::U8("Shop Shuffle", {"Off", "Specific Count", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), mOptionDescriptions[RSK_SHOPSANITY], WidgetType::Combobox, RO_SHOPSANITY_OFF); + mOptions[RSK_SHOPSANITY_COUNT] = Option::U8("Shops Item Count", {NumOpts(0, 7/*8*/)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityCount"), mOptionDescriptions[RSK_SHOPSANITY_COUNT], WidgetType::Slider, 0, false, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES] = Option::U8("Shops Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), mOptionDescriptions[RSK_SHOPSANITY_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE] = Option::U8("Shops Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); + mOptions[RSK_SHOPSANITY_PRICES_RANGE_1] = Option::U8("Shops Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_RANGE_2] = Option::U8("Shops Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT] = Option::U8("Shops No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Shops Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Shops Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Shops Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Shops Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE] = Option::Bool("Shops Affordable Prices", CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE]); - mOptions[RSK_SHUFFLE_TOKENS] = Option::U8("Tokensanity", {"Off", "Dungeons", "Overworld", "All Tokens"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleTokens"), mOptionDescriptions[RSK_SHUFFLE_TOKENS], WidgetType::Combobox, RO_TOKENSANITY_OFF); - mOptions[RSK_SHUFFLE_SCRUBS] = Option::U8("Scrub Shuffle", {"Off", "One-Time Only", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), mOptionDescriptions[RSK_SHUFFLE_SCRUBS], WidgetType::Combobox, RO_SCRUBS_OFF); - mOptions[RSK_SCRUBS_PRICES] = Option::U8("Scrub Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPrices"), mOptionDescriptions[RSK_SCRUBS_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE] = Option::U8("Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), mOptionDescriptions[RSK_SCRUBS_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); - mOptions[RSK_SCRUBS_PRICES_RANGE_1] = Option::U8("Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_RANGE_2] = Option::U8("Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT] = Option::U8("No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsGiantWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHUFFLE_TOKENS] = Option::U8("Token Shuffle", {"Off", "Dungeons", "Overworld", "All Tokens"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleTokens"), mOptionDescriptions[RSK_SHUFFLE_TOKENS], WidgetType::Combobox, RO_TOKENSANITY_OFF); + mOptions[RSK_SHUFFLE_SCRUBS] = Option::U8("Scrubs Shuffle", {"Off", "One-Time Only", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), mOptionDescriptions[RSK_SHUFFLE_SCRUBS], WidgetType::Combobox, RO_SCRUBS_OFF); + mOptions[RSK_SCRUBS_PRICES] = Option::U8("Scrubs Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPrices"), mOptionDescriptions[RSK_SCRUBS_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE] = Option::U8("Scrubs Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), mOptionDescriptions[RSK_SCRUBS_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); + mOptions[RSK_SCRUBS_PRICES_RANGE_1] = Option::U8("Scrubs Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_RANGE_2] = Option::U8("Scrubs Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT] = Option::U8("Scrubs No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Scrubs Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Scrubs Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Scrubs Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsGiantWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Scrubs Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); mOptions[RSK_SCRUBS_PRICES_AFFORDABLE] = Option::Bool("Scrubs Affordable Prices", CVAR_RANDOMIZER_SETTING("ScrubsPricesAffordable"), mOptionDescriptions[RSK_SCRUBS_PRICES_AFFORDABLE]); mOptions[RSK_SHUFFLE_BEEHIVES] = Option::Bool("Shuffle Beehives", CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), mOptionDescriptions[RSK_SHUFFLE_BEEHIVES]); mOptions[RSK_SHUFFLE_COWS] = Option::Bool("Shuffle Cows", CVAR_RANDOMIZER_SETTING("ShuffleCows"), mOptionDescriptions[RSK_SHUFFLE_COWS]); @@ -199,14 +199,14 @@ void Settings::CreateOptions() { mOptions[RSK_SHUFFLE_FISHING_POLE] = Option::Bool("Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]); mOptions[RSK_SHUFFLE_MERCHANTS] = Option::U8("Shuffle Merchants", {"Off", "Bean Merchant Only", "All But Beans", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), mOptionDescriptions[RSK_SHUFFLE_MERCHANTS], WidgetType::Combobox, RO_SHUFFLE_MERCHANTS_OFF, IMFLAG_NONE); mOptions[RSK_MERCHANT_PRICES] = Option::U8("Merchant Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPrices"), mOptionDescriptions[RSK_MERCHANT_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE] = Option::U8("Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"), mOptionDescriptions[RSK_MERCHANT_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); - mOptions[RSK_MERCHANT_PRICES_RANGE_1] = Option::U8("Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_RANGE_2] = Option::U8("Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT] = Option::U8("No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE] = Option::U8("Merchant Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"), mOptionDescriptions[RSK_MERCHANT_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); + mOptions[RSK_MERCHANT_PRICES_RANGE_1] = Option::U8("Merchant Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_RANGE_2] = Option::U8("Merchant Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT] = Option::U8("Merchant No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Merchant Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Merchant Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Merchant Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Merchant Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); mOptions[RSK_MERCHANT_PRICES_AFFORDABLE] = Option::Bool("Merchant Affordable Prices", CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"), mOptionDescriptions[RSK_MERCHANT_PRICES_AFFORDABLE]); mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES] = Option::Bool("Shuffle Frog Song Rupees", CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES]); mOptions[RSK_SHUFFLE_ADULT_TRADE] = Option::Bool("Shuffle Adult Trade", CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]); @@ -219,16 +219,16 @@ void Settings::CreateOptions() { mOptions[RSK_FISHSANITY_POND_COUNT] = Option::U8("Pond Fish Count", {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), mOptionDescriptions[RSK_FISHSANITY_POND_COUNT], WidgetType::Slider, 0, true, IMFLAG_NONE); mOptions[RSK_FISHSANITY_AGE_SPLIT] = Option::Bool("Pond Age Split", CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT]); mOptions[RSK_SHUFFLE_MAPANDCOMPASS] = Option::U8("Maps/Compasses", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), mOptionDescriptions[RSK_SHUFFLE_MAPANDCOMPASS], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); - mOptions[RSK_KEYSANITY] = Option::U8("Small Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Keysanity"), mOptionDescriptions[RSK_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); + mOptions[RSK_KEYSANITY] = Option::U8("Small Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Keysanity"), mOptionDescriptions[RSK_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); mOptions[RSK_GERUDO_KEYS] = Option::U8("Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoKeys"), mOptionDescriptions[RSK_GERUDO_KEYS], WidgetType::Combobox, RO_GERUDO_KEYS_VANILLA); - mOptions[RSK_BOSS_KEYSANITY] = Option::U8("Boss Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BossKeysanity"), mOptionDescriptions[RSK_BOSS_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); + mOptions[RSK_BOSS_KEYSANITY] = Option::U8("Boss Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BossKeysanity"), mOptionDescriptions[RSK_BOSS_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); mOptions[RSK_GANONS_BOSS_KEY] = Option::U8("Ganon's Boss Key", {"Vanilla", "Own Dungeon", "Start With", "Any Dungeon", "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Stones", "LACS-Medallions", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens", "100 GS Reward", "Triforce Hunt"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), mOptionDescriptions[RSK_GANONS_BOSS_KEY], WidgetType::Combobox, RO_GANON_BOSS_KEY_VANILLA); - mOptions[RSK_LACS_STONE_COUNT] = Option::U8("Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsStoneCount"), "", WidgetType::Slider, 3, true); - mOptions[RSK_LACS_MEDALLION_COUNT] = Option::U8("Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsMedallionCount"), "", WidgetType::Slider, 6, true); - mOptions[RSK_LACS_REWARD_COUNT] = Option::U8("Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardCount"), "", WidgetType::Slider, 9, true); - mOptions[RSK_LACS_DUNGEON_COUNT] = Option::U8("Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsDungeonCount"), "", WidgetType::Slider, 8, true); - mOptions[RSK_LACS_TOKEN_COUNT] = Option::U8("Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsTokenCount"), "", WidgetType::Slider, 100, true); - mOptions[RSK_LACS_OPTIONS] = Option::U8("LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), "", WidgetType::Combobox, RO_LACS_STANDARD_REWARD); + mOptions[RSK_LACS_STONE_COUNT] = Option::U8("GCBK Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsStoneCount"), "", WidgetType::Slider, 3, true); + mOptions[RSK_LACS_MEDALLION_COUNT] = Option::U8("GCBK Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsMedallionCount"), "", WidgetType::Slider, 6, true); + mOptions[RSK_LACS_REWARD_COUNT] = Option::U8("GCBK Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardCount"), "", WidgetType::Slider, 9, true); + mOptions[RSK_LACS_DUNGEON_COUNT] = Option::U8("GCBK Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsDungeonCount"), "", WidgetType::Slider, 8, true); + mOptions[RSK_LACS_TOKEN_COUNT] = Option::U8("GCBK Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsTokenCount"), "", WidgetType::Slider, 100, true); + mOptions[RSK_LACS_OPTIONS] = Option::U8("GCBK LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), "", WidgetType::Combobox, RO_LACS_STANDARD_REWARD); mOptions[RSK_KEYRINGS] = Option::U8("Key Rings", {"Off", "Random", "Count", "Selection"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), mOptionDescriptions[RSK_KEYRINGS], WidgetType::Combobox, RO_KEYRINGS_OFF); mOptions[RSK_KEYRINGS_RANDOM_COUNT] = Option::U8("Keyring Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), "", WidgetType::Slider, 8); mOptions[RSK_KEYRINGS_GERUDO_FORTRESS] = Option::U8("Gerudo Fortress Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"), "", WidgetType::TristateCheckbox, 0); @@ -304,7 +304,7 @@ void Settings::CreateOptions() { mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW] = Option::Bool("Start with Nocturne of Shadow", CVAR_RANDOMIZER_SETTING("StartingNocturneOfShadow"), "", IMFLAG_NONE); mOptions[RSK_STARTING_PRELUDE_OF_LIGHT] = Option::Bool("Start with Prelude of Light", CVAR_RANDOMIZER_SETTING("StartingPreludeOfLight")); mOptions[RSK_STARTING_SKULLTULA_TOKEN] = Option::U8("Gold Skulltula Tokens", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSkulltulaToken"), "", WidgetType::Slider); - mOptions[RSK_STARTING_HEARTS] = Option::U8("Hearts", {NumOpts(1, 20)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingHearts"), "", WidgetType::Slider, 2); + mOptions[RSK_STARTING_HEARTS] = Option::U8("Starting Hearts", {NumOpts(1, 20)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingHearts"), "", WidgetType::Slider, 2); // TODO: Remainder of Starting Items mOptions[RSK_LOGIC_RULES] = Option::U8("Logic", {"Glitchless", "Glitched", "No Logic", "Vanilla"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LogicRules"), mOptionDescriptions[RSK_LOGIC_RULES], WidgetType::Combobox, RO_LOGIC_GLITCHLESS); mOptions[RSK_ALL_LOCATIONS_REACHABLE] = Option::Bool("All Locations Reachable", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), mOptionDescriptions[RSK_ALL_LOCATIONS_REACHABLE], WidgetType::Checkbox, RO_GENERIC_ON); @@ -312,6 +312,8 @@ void Settings::CreateOptions() { mOptions[RSK_DAMAGE_MULTIPLIER] = Option::U8("Damage Multiplier", {"x1/2", "x1", "x2", "x4", "x8", "x16", "OHKO"}, OptionCategory::Setting, "", "", WidgetType::Slider, RO_DAMAGE_MULTIPLIER_DEFAULT); // clang-format on + StaticData::optionNameToEnum = PopulateOptionNameToEnum(); + mExcludeLocationsOptionsAreas.reserve(RCAREA_INVALID); mTrickOptions[RT_ACUTE_ANGLE_CLIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Acute angle clip", "Enables locations requiring jumpslash clips through walls which meet at an acute angle."); @@ -684,7 +686,7 @@ void Settings::CreateOptions() { &mTrickOptions[RT_GANON_MQ_FIRE_TRIAL], &mTrickOptions[RT_GANON_MQ_SHADOW_TRIAL], &mTrickOptions[RT_GANON_MQ_LIGHT_TRIAL], - }, false); + }); for (int i = 0; i < RT_MAX; i++) { auto& trick = mTrickOptions[i]; if (!trick.GetName().empty()) { @@ -699,7 +701,7 @@ void Settings::CreateOptions() { &mOptions[RSK_DOOR_OF_TIME], &mOptions[RSK_ZORAS_FOUNTAIN], &mOptions[RSK_SLEEPING_WATERFALL], - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_WORLD_IMGUI] = OptionGroup::SubGroup("World Settings", { &mOptions[RSK_STARTING_AGE], &mOptions[RSK_GERUDO_FORTRESS], @@ -730,7 +732,7 @@ void Settings::CreateOptions() { &mOptions[RSK_TRIFORCE_HUNT], &mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL], &mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED] - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_ENTRANCES_IMGUI] = OptionGroup::SubGroup("Shuffle Entrances", { &mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], &mOptions[RSK_SHUFFLE_BOSS_ENTRANCES], @@ -747,12 +749,12 @@ void Settings::CreateOptions() { &mOptions[RSK_MIX_OVERWORLD_ENTRANCES], &mOptions[RSK_MIX_INTERIOR_ENTRANCES], &mOptions[RSK_MIX_GROTTO_ENTRANCES] - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_WORLD_IMGUI_TABLE] = OptionGroup::SubGroup("World", { &mOptionGroups[RSG_AREA_ACCESS_IMGUI], &mOptionGroups[RSG_WORLD_IMGUI], &mOptionGroups[RSG_SHUFFLE_ENTRANCES_IMGUI], - }, false, WidgetContainerType::TABLE); + }, WidgetContainerType::TABLE); mOptionGroups[RSG_SHUFFLE_ITEMS_IMGUI] = OptionGroup::SubGroup("Shuffle Items", { &mOptions[RSK_SHUFFLE_SONGS], &mOptions[RSK_SHUFFLE_TOKENS], @@ -769,7 +771,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_FISHING_POLE], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = OptionGroup::SubGroup("Shuffle NPCs & Merchants", { &mOptions[RSK_SHOPSANITY], &mOptions[RSK_SHOPSANITY_COUNT], @@ -814,7 +816,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BOSS_SOULS], - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI] = OptionGroup::SubGroup("Shuffle Dungeon Items", { &mOptions[RSK_SHUFFLE_DUNGEON_REWARDS], &mOptions[RSK_SHUFFLE_MAPANDCOMPASS], @@ -839,12 +841,12 @@ void Settings::CreateOptions() { &mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL], &mOptions[RSK_KEYRINGS_GTG], &mOptions[RSK_KEYRINGS_GANONS_CASTLE], - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_ITEMS_IMGUI_TABLE] = OptionGroup::SubGroup("Items", { &mOptionGroups[RSG_SHUFFLE_ITEMS_IMGUI], &mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI], &mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI], - }, false, WidgetContainerType::TABLE); + }, WidgetContainerType::TABLE); mOptionGroups[RSG_TIMESAVERS_IMGUI] = OptionGroup::SubGroup("Timesavers", { &mOptions[RSK_CUCCO_COUNT], &mOptions[RSK_BIG_POE_COUNT], @@ -853,14 +855,14 @@ void Settings::CreateOptions() { &mOptions[RSK_SKIP_EPONA_RACE], &mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG] - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI] = OptionGroup::SubGroup("", { &mOptions[RSK_ITEM_POOL], &mOptions[RSK_ICE_TRAPS], &mOptions[RSK_GOSSIP_STONE_HINTS], &mOptions[RSK_HINT_CLARITY], &mOptions[RSK_HINT_DISTRIBUTION], - }, false, WidgetContainerType::SECTION); + }, WidgetContainerType::SECTION); mOptionGroups[RSG_EXTRA_HINTS_IMGUI] = OptionGroup::SubGroup("Extra Hints", { &mOptions[RSK_TOT_ALTAR_HINT], &mOptions[RSK_GANONDORF_HINT], @@ -887,11 +889,11 @@ void Settings::CreateOptions() { &mOptions[RSK_KAK_50_SKULLS_HINT], &mOptions[RSK_KAK_100_SKULLS_HINT], &mOptions[RSK_MASK_SHOP_HINT] - }, false, WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones."); + }, WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones."); mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN] = OptionGroup::SubGroup("Item Pool & Hints", std::initializer_list{ &mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI], &mOptionGroups[RSG_EXTRA_HINTS_IMGUI], - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_ADDITIONAL_FEATURES_IMGUI] = OptionGroup::SubGroup("Additional Features", { &mOptions[RSK_FULL_WALLETS], &mOptions[RSK_BOMBCHUS_IN_LOGIC], @@ -900,25 +902,25 @@ void Settings::CreateOptions() { &mOptions[RSK_SUNLIGHT_ARROWS], &mOptions[RSK_INFINITE_UPGRADES], &mOptions[RSK_SKELETON_KEY], - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_GAMEPLAY_IMGUI_TABLE] = OptionGroup::SubGroup("Gameplay", { &mOptionGroups[RSG_TIMESAVERS_IMGUI], &mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN], &mOptionGroups[RSG_ADDITIONAL_FEATURES_IMGUI] - }, false, WidgetContainerType::TABLE); + }, WidgetContainerType::TABLE); mOptionGroups[RSG_STARTING_EQUIPMENT_IMGUI] = OptionGroup::SubGroup("Starting Equipment", { &mOptions[RSK_LINKS_POCKET], &mOptions[RSK_STARTING_KOKIRI_SWORD], &mOptions[RSK_STARTING_MASTER_SWORD], &mOptions[RSK_STARTING_DEKU_SHIELD] - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_STARTING_ITEMS_IMGUI] = OptionGroup::SubGroup("Starting Items", { &mOptions[RSK_STARTING_OCARINA], &mOptions[RSK_STARTING_STICKS], &mOptions[RSK_STARTING_NUTS], &mOptions[RSK_STARTING_SKULLTULA_TOKEN], &mOptions[RSK_STARTING_HEARTS], - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_STARTING_NORMAL_SONGS_IMGUI] = OptionGroup::SubGroup("Normal Songs", { &mOptions[RSK_STARTING_ZELDAS_LULLABY], &mOptions[RSK_STARTING_EPONAS_SONG], @@ -926,7 +928,7 @@ void Settings::CreateOptions() { &mOptions[RSK_STARTING_SUNS_SONG], &mOptions[RSK_STARTING_SONG_OF_TIME], &mOptions[RSK_STARTING_SONG_OF_STORMS], - }, false, WidgetContainerType::SECTION); + }, WidgetContainerType::SECTION); mOptionGroups[RSG_STARTING_WARP_SONGS_IMGUI] = OptionGroup::SubGroup("Warp Songs", { &mOptions[RSK_STARTING_MINUET_OF_FOREST], &mOptions[RSK_STARTING_BOLERO_OF_FIRE], @@ -934,16 +936,16 @@ void Settings::CreateOptions() { &mOptions[RSK_STARTING_REQUIEM_OF_SPIRIT], &mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW], &mOptions[RSK_STARTING_PRELUDE_OF_LIGHT] - }, false, WidgetContainerType::SECTION); + }, WidgetContainerType::SECTION); mOptionGroups[RSG_STARTING_SONGS_IMGUI] = OptionGroup::SubGroup("Starting Songs", std::initializer_list({ &mOptionGroups[RSG_STARTING_NORMAL_SONGS_IMGUI], &mOptionGroups[RSG_STARTING_WARP_SONGS_IMGUI], - }), false, WidgetContainerType::COLUMN); + }), WidgetContainerType::COLUMN); mOptionGroups[RSG_STARTING_INVENTORY_IMGUI_TABLE] = OptionGroup::SubGroup("Starting Inventory", { &mOptionGroups[RSG_STARTING_EQUIPMENT_IMGUI], &mOptionGroups[RSG_STARTING_ITEMS_IMGUI], &mOptionGroups[RSG_STARTING_SONGS_IMGUI] - }, false, WidgetContainerType::TABLE); + }, WidgetContainerType::TABLE); mOptionGroups[RSG_OPEN] = OptionGroup("Open Settings", { &mOptions[RSK_FOREST], &mOptions[RSK_KAK_GATE], @@ -1089,7 +1091,7 @@ void Settings::CreateOptions() { &mOptions[RSK_STARTING_OCARINA], &mOptions[RSK_STARTING_KOKIRI_SWORD], &mOptions[RSK_STARTING_DEKU_SHIELD] - }, false); + }); mOptionGroups[RSG_STARTING_SONGS] = OptionGroup::SubGroup("Ocarina Songs", { &mOptions[RSK_STARTING_ZELDAS_LULLABY], &mOptions[RSK_STARTING_EPONAS_SONG], @@ -1104,19 +1106,19 @@ void Settings::CreateOptions() { &mOptions[RSK_STARTING_REQUIEM_OF_SPIRIT], &mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW], &mOptions[RSK_STARTING_PRELUDE_OF_LIGHT], - }, false); + }); mOptionGroups[RSG_STARTING_OTHER] = OptionGroup::SubGroup("Other", { &mOptions[RSK_STARTING_STICKS], &mOptions[RSK_STARTING_NUTS], &mOptions[RSK_FULL_WALLETS], &mOptions[RSK_STARTING_SKULLTULA_TOKEN], &mOptions[RSK_STARTING_HEARTS], - }, false); + }); mOptionGroups[RSG_STARTING_INVENTORY] = OptionGroup("Starting Inventory", { &mOptionGroups[RSG_STARTING_ITEMS], &mOptionGroups[RSG_STARTING_SONGS], &mOptionGroups[RSG_STARTING_OTHER], - }, OptionGroupType::DEFAULT, false); + }, OptionGroupType::DEFAULT); mOptionGroups[RSG_TIMESAVERS] = OptionGroup("Timesaver Settings", { &mOptions[RSK_SKIP_CHILD_STEALTH], &mOptions[RSK_SKIP_CHILD_ZELDA], @@ -1168,38 +1170,38 @@ void Settings::CreateOptions() { &mOptions[RSK_ICE_TRAPS] })); // TODO: Progressive Goron Sword, Remove Double Defense - mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST] = OptionGroup::SubGroup("Kokiri Forest", mExcludeLocationsOptionsAreas[RCAREA_KOKIRI_FOREST], false); - mOptionGroups[RSG_EXCLUDES_LOST_WOODS] = OptionGroup::SubGroup("Lost Woods", mExcludeLocationsOptionsAreas[RCAREA_LOST_WOODS], false); - mOptionGroups[RSG_EXCLUDES_SACRED_FOREST_MEADOW] = OptionGroup::SubGroup("Sacred Forest Meadow", mExcludeLocationsOptionsAreas[RCAREA_SACRED_FOREST_MEADOW], false); - mOptionGroups[RSG_EXCLUDES_DEKU_TREE] = OptionGroup::SubGroup("Deku Tree", mExcludeLocationsOptionsAreas[RCAREA_DEKU_TREE], false); - mOptionGroups[RSG_EXCLUDES_FOREST_TEMPLE] = OptionGroup::SubGroup("Forest Temple", mExcludeLocationsOptionsAreas[RCAREA_FOREST_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_KAKARIKO_VILLAGE] = OptionGroup::SubGroup("Kakariko Village", mExcludeLocationsOptionsAreas[RCAREA_KAKARIKO_VILLAGE], false); - mOptionGroups[RSG_EXCLUDES_GRAVEYARD] = OptionGroup::SubGroup("Graveyard", mExcludeLocationsOptionsAreas[RCAREA_GRAVEYARD], false); - mOptionGroups[RSG_EXCLUDES_BOTTOM_OF_THE_WELL] = OptionGroup::SubGroup("Bottom of the Well", mExcludeLocationsOptionsAreas[RCAREA_BOTTOM_OF_THE_WELL], false); - mOptionGroups[RSG_EXCLUDES_SHADOW_TEMPLE] = OptionGroup::SubGroup("Shadow Temple", mExcludeLocationsOptionsAreas[RCAREA_SHADOW_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_TRAIL] = OptionGroup::SubGroup("Death Mountain Trail", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_TRAIL], false); - mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_CRATER] = OptionGroup::SubGroup("Death Mountain Crater", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_CRATER], false); - mOptionGroups[RSG_EXCLUDES_GORON_CITY] = OptionGroup::SubGroup("Goron City", mExcludeLocationsOptionsAreas[RCAREA_GORON_CITY], false); - mOptionGroups[RSG_EXCLUDES_DODONGOS_CAVERN] = OptionGroup::SubGroup("Dodongo's Cavern", mExcludeLocationsOptionsAreas[RCAREA_DODONGOS_CAVERN], false); - mOptionGroups[RSG_EXCLUDES_FIRE_TEMPLE] = OptionGroup::SubGroup("Fire Temple", mExcludeLocationsOptionsAreas[RCAREA_FIRE_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_ZORAS_RIVER] = OptionGroup::SubGroup("Zora's River", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_RIVER], false); - mOptionGroups[RSG_EXCLUDES_ZORAS_DOMAIN] = OptionGroup::SubGroup("Zora's Domain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_DOMAIN], false); - mOptionGroups[RSG_EXCLUDES_ZORAS_FOUNTAIN] = OptionGroup::SubGroup("Zora's Fountain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_FOUNTAIN], false); - mOptionGroups[RSG_EXCLUDES_JABU_JABU] = OptionGroup::SubGroup("Jabu Jabu's Belly", mExcludeLocationsOptionsAreas[RCAREA_JABU_JABUS_BELLY], false); - mOptionGroups[RSG_EXCLUDES_ICE_CAVERN] = OptionGroup::SubGroup("Ice Cavern", mExcludeLocationsOptionsAreas[RCAREA_ICE_CAVERN], false); - mOptionGroups[RSG_EXCLUDES_HYRULE_FIELD] = OptionGroup::SubGroup("Hyrule Field", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_FIELD], false); - mOptionGroups[RSG_EXCLUDES_LON_LON_RANCH] = OptionGroup::SubGroup("Lon Lon Ranch", mExcludeLocationsOptionsAreas[RCAREA_LON_LON_RANCH], false); - mOptionGroups[RSG_EXCLUDES_LAKE_HYLIA] = OptionGroup::SubGroup("Lake Hylia", mExcludeLocationsOptionsAreas[RCAREA_LAKE_HYLIA], false); - mOptionGroups[RSG_EXCLUDES_WATER_TEMPLE] = OptionGroup::SubGroup("Water Temple", mExcludeLocationsOptionsAreas[RCAREA_WATER_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_GERUDO_VALLEY] = OptionGroup::SubGroup("Gerudo Valley", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_VALLEY], false); - mOptionGroups[RSG_EXCLUDES_GERUDO_FORTRESS] = OptionGroup::SubGroup("Gerudo Fortress", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_FORTRESS], false); - mOptionGroups[RSG_EXCLUDES_HAUNTED_WASTELAND] = OptionGroup::SubGroup("Haunted Wasteland", mExcludeLocationsOptionsAreas[RCAREA_WASTELAND], false); - mOptionGroups[RSG_EXCLUDES_DESERT_COLOSSUS] = OptionGroup::SubGroup("Desert Colossus", mExcludeLocationsOptionsAreas[RCAREA_DESERT_COLOSSUS], false); - mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUNDS] = OptionGroup::SubGroup("Gerudo Training Grounds", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_TRAINING_GROUND], false); - mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE] = OptionGroup::SubGroup("Spirit Temple", mExcludeLocationsOptionsAreas[RCAREA_SPIRIT_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE] = OptionGroup::SubGroup("Hyrule Castle", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_CASTLE], false); - mOptionGroups[RSG_EXCLUDES_MARKET] = OptionGroup::SubGroup("Market", mExcludeLocationsOptionsAreas[RCAREA_MARKET], false); - mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE] = OptionGroup::SubGroup("Ganon's Castle", mExcludeLocationsOptionsAreas[RCAREA_GANONS_CASTLE], false); + mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST] = OptionGroup::SubGroup("Kokiri Forest", mExcludeLocationsOptionsAreas[RCAREA_KOKIRI_FOREST]); + mOptionGroups[RSG_EXCLUDES_LOST_WOODS] = OptionGroup::SubGroup("Lost Woods", mExcludeLocationsOptionsAreas[RCAREA_LOST_WOODS]); + mOptionGroups[RSG_EXCLUDES_SACRED_FOREST_MEADOW] = OptionGroup::SubGroup("Sacred Forest Meadow", mExcludeLocationsOptionsAreas[RCAREA_SACRED_FOREST_MEADOW]); + mOptionGroups[RSG_EXCLUDES_DEKU_TREE] = OptionGroup::SubGroup("Deku Tree", mExcludeLocationsOptionsAreas[RCAREA_DEKU_TREE]); + mOptionGroups[RSG_EXCLUDES_FOREST_TEMPLE] = OptionGroup::SubGroup("Forest Temple", mExcludeLocationsOptionsAreas[RCAREA_FOREST_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_KAKARIKO_VILLAGE] = OptionGroup::SubGroup("Kakariko Village", mExcludeLocationsOptionsAreas[RCAREA_KAKARIKO_VILLAGE]); + mOptionGroups[RSG_EXCLUDES_GRAVEYARD] = OptionGroup::SubGroup("Graveyard", mExcludeLocationsOptionsAreas[RCAREA_GRAVEYARD]); + mOptionGroups[RSG_EXCLUDES_BOTTOM_OF_THE_WELL] = OptionGroup::SubGroup("Bottom of the Well", mExcludeLocationsOptionsAreas[RCAREA_BOTTOM_OF_THE_WELL]); + mOptionGroups[RSG_EXCLUDES_SHADOW_TEMPLE] = OptionGroup::SubGroup("Shadow Temple", mExcludeLocationsOptionsAreas[RCAREA_SHADOW_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_TRAIL] = OptionGroup::SubGroup("Death Mountain Trail", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_TRAIL]); + mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_CRATER] = OptionGroup::SubGroup("Death Mountain Crater", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_CRATER]); + mOptionGroups[RSG_EXCLUDES_GORON_CITY] = OptionGroup::SubGroup("Goron City", mExcludeLocationsOptionsAreas[RCAREA_GORON_CITY]); + mOptionGroups[RSG_EXCLUDES_DODONGOS_CAVERN] = OptionGroup::SubGroup("Dodongo's Cavern", mExcludeLocationsOptionsAreas[RCAREA_DODONGOS_CAVERN]); + mOptionGroups[RSG_EXCLUDES_FIRE_TEMPLE] = OptionGroup::SubGroup("Fire Temple", mExcludeLocationsOptionsAreas[RCAREA_FIRE_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_ZORAS_RIVER] = OptionGroup::SubGroup("Zora's River", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_RIVER]); + mOptionGroups[RSG_EXCLUDES_ZORAS_DOMAIN] = OptionGroup::SubGroup("Zora's Domain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_DOMAIN]); + mOptionGroups[RSG_EXCLUDES_ZORAS_FOUNTAIN] = OptionGroup::SubGroup("Zora's Fountain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_FOUNTAIN]); + mOptionGroups[RSG_EXCLUDES_JABU_JABU] = OptionGroup::SubGroup("Jabu Jabu's Belly", mExcludeLocationsOptionsAreas[RCAREA_JABU_JABUS_BELLY]); + mOptionGroups[RSG_EXCLUDES_ICE_CAVERN] = OptionGroup::SubGroup("Ice Cavern", mExcludeLocationsOptionsAreas[RCAREA_ICE_CAVERN]); + mOptionGroups[RSG_EXCLUDES_HYRULE_FIELD] = OptionGroup::SubGroup("Hyrule Field", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_FIELD]); + mOptionGroups[RSG_EXCLUDES_LON_LON_RANCH] = OptionGroup::SubGroup("Lon Lon Ranch", mExcludeLocationsOptionsAreas[RCAREA_LON_LON_RANCH]); + mOptionGroups[RSG_EXCLUDES_LAKE_HYLIA] = OptionGroup::SubGroup("Lake Hylia", mExcludeLocationsOptionsAreas[RCAREA_LAKE_HYLIA]); + mOptionGroups[RSG_EXCLUDES_WATER_TEMPLE] = OptionGroup::SubGroup("Water Temple", mExcludeLocationsOptionsAreas[RCAREA_WATER_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_GERUDO_VALLEY] = OptionGroup::SubGroup("Gerudo Valley", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_VALLEY]); + mOptionGroups[RSG_EXCLUDES_GERUDO_FORTRESS] = OptionGroup::SubGroup("Gerudo Fortress", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_FORTRESS]); + mOptionGroups[RSG_EXCLUDES_HAUNTED_WASTELAND] = OptionGroup::SubGroup("Haunted Wasteland", mExcludeLocationsOptionsAreas[RCAREA_WASTELAND]); + mOptionGroups[RSG_EXCLUDES_DESERT_COLOSSUS] = OptionGroup::SubGroup("Desert Colossus", mExcludeLocationsOptionsAreas[RCAREA_DESERT_COLOSSUS]); + mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUNDS] = OptionGroup::SubGroup("Gerudo Training Grounds", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_TRAINING_GROUND]); + mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE] = OptionGroup::SubGroup("Spirit Temple", mExcludeLocationsOptionsAreas[RCAREA_SPIRIT_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE] = OptionGroup::SubGroup("Hyrule Castle", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_CASTLE]); + mOptionGroups[RSG_EXCLUDES_MARKET] = OptionGroup::SubGroup("Market", mExcludeLocationsOptionsAreas[RCAREA_MARKET]); + mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE] = OptionGroup::SubGroup("Ganon's Castle", mExcludeLocationsOptionsAreas[RCAREA_GANONS_CASTLE]); mOptionGroups[RSG_EXCLUDES] = OptionGroup::SubGroup("Exclude Locations", { &mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST], &mOptionGroups[RSG_EXCLUDES_LOST_WOODS], @@ -1233,7 +1235,7 @@ void Settings::CreateOptions() { &mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE], &mOptionGroups[RSG_EXCLUDES_MARKET], &mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE], - }, false); + }); mOptionGroups[RSG_DETAILED_LOGIC] = OptionGroup("Detailed Logic Settings", { &mOptionGroups[RSG_LOGIC], &mOptionGroups[RSG_TRICKS], @@ -1260,210 +1262,14 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_GOSSIP_STONE_HINTS], }; +} -//RANDOTODO refactor OptionGroups so we can actually make maintainable enum conversion. - mSpoilerfileSettingNameToEnum = { - { "Logic Options:Logic", RSK_LOGIC_RULES }, - { "Open Settings:Forest", RSK_FOREST }, - { "Open Settings:Kakariko Gate", RSK_KAK_GATE }, - { "Open Settings:Door of Time", RSK_DOOR_OF_TIME }, - { "Open Settings:Zora's Fountain", RSK_ZORAS_FOUNTAIN }, - { "Open Settings:Sleeping Waterfall", RSK_SLEEPING_WATERFALL }, - { "World Settings:Starting Age", RSK_STARTING_AGE }, - { "Open Settings:Gerudo Fortress", RSK_GERUDO_FORTRESS }, - { "Open Settings:Rainbow Bridge", RSK_RAINBOW_BRIDGE }, - { "Open Settings:Stone Count", RSK_RAINBOW_BRIDGE_STONE_COUNT }, - { "Open Settings:Medallion Count", RSK_RAINBOW_BRIDGE_MEDALLION_COUNT }, - { "Open Settings:Reward Count", RSK_RAINBOW_BRIDGE_REWARD_COUNT }, - { "Open Settings:Dungeon Count", RSK_RAINBOW_BRIDGE_DUNGEON_COUNT }, - { "Open Settings:Token Count", RSK_RAINBOW_BRIDGE_TOKEN_COUNT }, - { "Open Settings:Bridge Reward Options", RSK_BRIDGE_OPTIONS }, - { "Open Settings:Ganon's Trials", RSK_GANONS_TRIALS }, - { "Open Settings:Ganon's Trials Count", RSK_TRIAL_COUNT }, - { "Start with Ocarina", RSK_STARTING_OCARINA }, - { "Shuffle Settings:Shuffle Ocarinas", RSK_SHUFFLE_OCARINA }, - { "Shuffle Settings:Shuffle Ocarina Buttons", RSK_SHUFFLE_OCARINA_BUTTONS }, - { "Shuffle Settings:Shuffle Swim", RSK_SHUFFLE_SWIM }, - { "Start with Deku Shield", RSK_STARTING_DEKU_SHIELD }, - { "Start with Kokiri Sword", RSK_STARTING_KOKIRI_SWORD }, - { "Start with Master Sword", RSK_STARTING_MASTER_SWORD }, - { "Start with Zelda's Lullaby", RSK_STARTING_ZELDAS_LULLABY }, - { "Start with Epona's Song", RSK_STARTING_EPONAS_SONG }, - { "Start with Saria's Song", RSK_STARTING_SARIAS_SONG }, - { "Start with Sun's Song", RSK_STARTING_SUNS_SONG }, - { "Start with Song of Time", RSK_STARTING_SONG_OF_TIME }, - { "Start with Song of Storms", RSK_STARTING_SONG_OF_STORMS }, - { "Start with Minuet of Forest", RSK_STARTING_MINUET_OF_FOREST }, - { "Start with Bolero of Fire", RSK_STARTING_BOLERO_OF_FIRE }, - { "Start with Serenade of Water", RSK_STARTING_SERENADE_OF_WATER }, - { "Start with Requiem of Spirit", RSK_STARTING_REQUIEM_OF_SPIRIT }, - { "Start with Nocturne of Shadow", RSK_STARTING_NOCTURNE_OF_SHADOW }, - { "Start with Prelude of Light", RSK_STARTING_PRELUDE_OF_LIGHT }, - { "Shuffle Settings:Shuffle Kokiri Sword", RSK_SHUFFLE_KOKIRI_SWORD }, - { "Shuffle Settings:Shuffle Master Sword", RSK_SHUFFLE_MASTER_SWORD }, - { "Shuffle Settings:Shuffle Child's Wallet", RSK_SHUFFLE_CHILD_WALLET }, - { "Shuffle Settings:Include Tycoon Wallet", RSK_INCLUDE_TYCOON_WALLET }, - { "Shuffle Settings:Shuffle Dungeon Rewards", RSK_SHUFFLE_DUNGEON_REWARDS }, - { "Shuffle Settings:Shuffle Songs", RSK_SHUFFLE_SONGS }, - { "Shuffle Settings:Tokensanity", RSK_SHUFFLE_TOKENS }, - { "Shuffle Settings:Shopsanity", RSK_SHOPSANITY }, - { "Shuffle Settings:Shopsanity Specific Count", RSK_SHOPSANITY_COUNT }, - { "Shuffle Settings:Shopsanity Prices", RSK_SHOPSANITY_PRICES }, - { "Shuffle Settings:Shopsanity Fixed Amount", RSK_SHOPSANITY_PRICES_FIXED_PRICE }, - { "Shuffle Settings:Shopsanity Range 1", RSK_SHOPSANITY_PRICES_RANGE_1 }, - { "Shuffle Settings:Shopsanity Range 2", RSK_SHOPSANITY_PRICES_RANGE_2 }, - { "Shuffle Settings:Shopsanity No Wallet Weight", RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT }, - { "Shuffle Settings:Shopsanity Child Wallet Weight", RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT }, - { "Shuffle Settings:Shopsanity Adult Wallet Weight", RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT }, - { "Shuffle Settings:Shopsanity Giants Wallet Weight", RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT }, - { "Shuffle Settings:Shopsanity Tycoon Wallet Weight", RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT }, - { "Shuffle Settings:Shopsanity Affordable Prices", RSK_SHOPSANITY_PRICES_AFFORDABLE }, - { "Shuffle Settings:Scrub Shuffle", RSK_SHUFFLE_SCRUBS }, - { "Shuffle Settings:Scrubs Prices", RSK_SCRUBS_PRICES }, - { "Shuffle Settings:Scrubs Fixed Amount", RSK_SCRUBS_PRICES_FIXED_PRICE }, - { "Shuffle Settings:Scrubs Range 1", RSK_SCRUBS_PRICES_RANGE_1 }, - { "Shuffle Settings:Scrubs Range 2", RSK_SCRUBS_PRICES_RANGE_2 }, - { "Shuffle Settings:Scrubs No Wallet Weight", RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT }, - { "Shuffle Settings:Scrubs Child Wallet Weight", RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT }, - { "Shuffle Settings:Scrubs Adult Wallet Weight", RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT }, - { "Shuffle Settings:Scrubs Giants Wallet Weight", RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT }, - { "Shuffle Settings:Scrubs Tycoon Wallet Weight", RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT }, - { "Shuffle Settings:Scrubs Affordable Prices", RSK_SCRUBS_PRICES_AFFORDABLE }, - { "Shuffle Settings:Beehive Shuffle", RSK_SHUFFLE_BEEHIVES }, - { "Shuffle Settings:Shuffle Cows", RSK_SHUFFLE_COWS }, - { "Shuffle Settings:Shuffle Weird Egg", RSK_SHUFFLE_WEIRD_EGG }, - { "Shuffle Settings:Shuffle Gerudo Membership Card", RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD }, - { "Shuffle Settings:Shuffle Frog Song Rupees", RSK_SHUFFLE_FROG_SONG_RUPEES }, - { "Item Pool Settings:Item Pool", RSK_ITEM_POOL }, - { "Item Pool Settings:Ice Traps", RSK_ICE_TRAPS }, - { "Miscellaneous Settings:Gossip Stone Hints", RSK_GOSSIP_STONE_HINTS }, - { "Miscellaneous Settings:ToT Altar Hint", RSK_TOT_ALTAR_HINT }, - { "Miscellaneous Settings:Ganondorf Hint", RSK_GANONDORF_HINT }, - { "Miscellaneous Settings:Sheik Light Arrow Hint", RSK_SHEIK_LA_HINT }, - { "Miscellaneous Settings:Dampe's Diary Hint", RSK_DAMPES_DIARY_HINT }, - { "Miscellaneous Settings:Greg the Rupee Hint", RSK_GREG_HINT }, - { "Miscellaneous Settings:Hyrule Loach Hint", RSK_LOACH_HINT }, - { "Miscellaneous Settings:Saria's Hint", RSK_SARIA_HINT }, - { "Miscellaneous Settings:Frog Ocarina Game Hint", RSK_FROGS_HINT }, - { "Miscellaneous Settings:Ocarina of Time Hint", RSK_OOT_HINT }, - { "Miscellaneous Settings:10 GS Hint", RSK_KAK_10_SKULLS_HINT }, - { "Miscellaneous Settings:20 GS Hint", RSK_KAK_20_SKULLS_HINT }, - { "Miscellaneous Settings:30 GS Hint", RSK_KAK_30_SKULLS_HINT }, - { "Miscellaneous Settings:40 GS Hint", RSK_KAK_40_SKULLS_HINT }, - { "Miscellaneous Settings:50 GS Hint", RSK_KAK_50_SKULLS_HINT }, - { "Miscellaneous Settings:100 GS Hint", RSK_KAK_100_SKULLS_HINT }, - { "Miscellaneous Settings:Mask Shop Hint", RSK_MASK_SHOP_HINT }, - { "Miscellaneous Settings:Biggoron's Hint", RSK_BIGGORON_HINT }, - { "Miscellaneous Settings:Big Poes Hint", RSK_BIG_POES_HINT }, - { "Miscellaneous Settings:Chickens Hint", RSK_CHICKENS_HINT }, - { "Miscellaneous Settings:Malon Hint", RSK_MALON_HINT }, - { "Miscellaneous Settings:Horseback Archery Hint", RSK_HBA_HINT }, - { "Miscellaneous Settings:Warp Song Hints", RSK_WARP_SONG_HINTS }, - { "Miscellaneous Settings:Scrub Hint Text", RSK_SCRUB_TEXT_HINT }, - { "Miscellaneous Settings:Merchant Hint Text", RSK_MERCHANT_TEXT_HINT }, - { "Miscellaneous Settings:Fishing Pole Hint", RSK_FISHING_POLE_HINT }, - { "Miscellaneous Settings:Hint Clarity", RSK_HINT_CLARITY }, - { "Miscellaneous Settings:Hint Distribution", RSK_HINT_DISTRIBUTION }, - { "Shuffle Dungeon Items:Maps/Compasses", RSK_SHUFFLE_MAPANDCOMPASS }, - { "Shuffle Dungeon Items:Small Keys", RSK_KEYSANITY }, - { "Shuffle Dungeon Items:Gerudo Fortress Keys", RSK_GERUDO_KEYS }, - { "Shuffle Dungeon Items:Boss Keys", RSK_BOSS_KEYSANITY }, - { "Shuffle Dungeon Items:Ganon's Boss Key", RSK_GANONS_BOSS_KEY }, - { "Timesaver Settings:Skip Child Stealth", RSK_SKIP_CHILD_STEALTH }, - { "Timesaver Settings:Skip Child Zelda", RSK_SKIP_CHILD_ZELDA }, - { "Start with Sticks", RSK_STARTING_STICKS }, - { "Start with Nuts", RSK_STARTING_NUTS }, - { "Full Wallets", RSK_FULL_WALLETS }, - { "Timesaver Settings:Cuccos to return", RSK_CUCCO_COUNT }, - { "Timesaver Settings:Big Poe Target Count", RSK_BIG_POE_COUNT }, - { "Timesaver Settings:Skip Epona Race", RSK_SKIP_EPONA_RACE }, - { "Timesaver Settings:Complete Mask Quest", RSK_COMPLETE_MASK_QUEST }, - { "Timesaver Settings:Skip Scarecrow's Song", RSK_SKIP_SCARECROWS_SONG }, - { "Timesaver Settings:Enable Glitch-Useful Cutscenes", RSK_ENABLE_GLITCH_CUTSCENES }, - { "Logic Options:Night Skulltula's Expect Sun's Song", RSK_SKULLS_SUNS_SONG }, - { "Shuffle Settings:Shuffle Adult Trade", RSK_SHUFFLE_ADULT_TRADE }, - { "Shuffle Settings:Shuffle Merchants", RSK_SHUFFLE_MERCHANTS }, - { "Shuffle Settings:Merchant Prices", RSK_MERCHANT_PRICES }, - { "Shuffle Settings:Merchant Fixed Amount", RSK_MERCHANT_PRICES_FIXED_PRICE }, - { "Shuffle Settings:Merchant Range 1", RSK_MERCHANT_PRICES_RANGE_1 }, - { "Shuffle Settings:Merchant Range 2", RSK_MERCHANT_PRICES_RANGE_2 }, - { "Shuffle Settings:Merchant No Wallet Weight", RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT }, - { "Shuffle Settings:Merchant Child Wallet Weight", RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT }, - { "Shuffle Settings:Merchant Adult Wallet Weight", RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT }, - { "Shuffle Settings:Merchant Giants Wallet Weight", RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT }, - { "Shuffle Settings:Merchant Tycoon Wallet Weight", RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT }, - { "Shuffle Settings:Merchant Affordable Prices", RSK_MERCHANT_PRICES_AFFORDABLE }, - { "Miscellaneous Settings:Blue Fire Arrows", RSK_BLUE_FIRE_ARROWS }, - { "Miscellaneous Settings:Sunlight Arrows", RSK_SUNLIGHT_ARROWS }, - // TODO: Ammo Drop settings - { "World Settings:Bombchu Drops", RSK_ENABLE_BOMBCHU_DROPS }, - { "World Settings:Bombchus in Logic", RSK_BOMBCHUS_IN_LOGIC }, - { "Shuffle Settings:Link's Pocket", RSK_LINKS_POCKET }, - { "World Settings:MQ Dungeon Setting", RSK_MQ_DUNGEON_RANDOM }, - { "World Settings:MQ Dungeon Count", RSK_MQ_DUNGEON_COUNT }, - { "World Settings:Set Dungeon Quests", RSK_MQ_DUNGEON_SET }, - { "Shuffle Dungeon Quest:Deku Tree", RSK_MQ_DEKU_TREE }, - { "Shuffle Dungeon Quest:Dodongo's Cavern", RSK_MQ_DODONGOS_CAVERN }, - { "Shuffle Dungeon Quest:Jabu-Jabu's Belly", RSK_MQ_JABU_JABU }, - { "Shuffle Dungeon Quest:Forest Temple", RSK_MQ_FOREST_TEMPLE }, - { "Shuffle Dungeon Quest:Fire Temple", RSK_MQ_FIRE_TEMPLE }, - { "Shuffle Dungeon Quest:Water Temple", RSK_MQ_WATER_TEMPLE }, - { "Shuffle Dungeon Quest:Spirit Temple", RSK_MQ_SPIRIT_TEMPLE }, - { "Shuffle Dungeon Quest:Shadow Temple", RSK_MQ_SHADOW_TEMPLE }, - { "Shuffle Dungeon Quest:Bottom of the Well", RSK_MQ_BOTTOM_OF_THE_WELL }, - { "Shuffle Dungeon Quest:Ice Cavern", RSK_MQ_ICE_CAVERN }, - { "Shuffle Dungeon Quest:GTG", RSK_MQ_GTG }, - { "Shuffle Dungeon Quest:Ganon's Castle", RSK_MQ_GANONS_CASTLE }, - { "Shuffle Dungeon Items:Stone Count", RSK_LACS_STONE_COUNT }, - { "Shuffle Dungeon Items:Medallion Count", RSK_LACS_MEDALLION_COUNT }, - { "Shuffle Dungeon Items:Reward Count", RSK_LACS_REWARD_COUNT }, - { "Shuffle Dungeon Items:Dungeon Count", RSK_LACS_DUNGEON_COUNT }, - { "Shuffle Dungeon Items:Token Count", RSK_LACS_TOKEN_COUNT }, - { "Shuffle Dungeon Items:LACS Reward Options", RSK_LACS_OPTIONS }, - { "Shuffle Dungeon Items:Key Rings", RSK_KEYRINGS }, - { "Shuffle Dungeon Items:Keyring Dungeon Count", RSK_KEYRINGS_RANDOM_COUNT }, - { "Shuffle Dungeon Items:Gerudo Fortress Keyring", RSK_KEYRINGS_GERUDO_FORTRESS }, - { "Shuffle Dungeon Items:Forest Temple Keyring", RSK_KEYRINGS_FOREST_TEMPLE }, - { "Shuffle Dungeon Items:Fire Temple Keyring", RSK_KEYRINGS_FIRE_TEMPLE }, - { "Shuffle Dungeon Items:Water Temple Keyring", RSK_KEYRINGS_WATER_TEMPLE }, - { "Shuffle Dungeon Items:Spirit Temple Keyring", RSK_KEYRINGS_SPIRIT_TEMPLE }, - { "Shuffle Dungeon Items:Shadow Temple Keyring", RSK_KEYRINGS_SHADOW_TEMPLE }, - { "Shuffle Dungeon Items:Bottom of the Well Keyring", RSK_KEYRINGS_BOTTOM_OF_THE_WELL }, - { "Shuffle Dungeon Items:GTG Keyring", RSK_KEYRINGS_GTG }, - { "Shuffle Dungeon Items:Ganon's Castle Keyring", RSK_KEYRINGS_GANONS_CASTLE }, - { "World Settings:Shuffle Entrances", RSK_SHUFFLE_ENTRANCES }, - { "World Settings:Dungeon Entrances", RSK_SHUFFLE_DUNGEON_ENTRANCES }, - { "World Settings:Overworld Entrances", RSK_SHUFFLE_OVERWORLD_ENTRANCES }, - { "World Settings:Interior Entrances", RSK_SHUFFLE_INTERIOR_ENTRANCES }, - { "World Settings:Grottos Entrances", RSK_SHUFFLE_GROTTO_ENTRANCES }, - { "World Settings:Owl Drops", RSK_SHUFFLE_OWL_DROPS }, - { "World Settings:Warp Songs", RSK_SHUFFLE_WARP_SONGS }, - { "World Settings:Overworld Spawns", RSK_SHUFFLE_OVERWORLD_SPAWNS }, - { "World Settings:Mixed Entrance Pools", RSK_MIXED_ENTRANCE_POOLS }, - { "World Settings:Mix Dungeons", RSK_MIX_DUNGEON_ENTRANCES }, - { "World Settings:Mix Bosses", RSK_MIX_BOSS_ENTRANCES }, - { "World Settings:Mix Overworld", RSK_MIX_OVERWORLD_ENTRANCES }, - { "World Settings:Mix Interiors", RSK_MIX_INTERIOR_ENTRANCES }, - { "World Settings:Mix Grottos", RSK_MIX_GROTTO_ENTRANCES }, - { "World Settings:Decouple Entrances", RSK_DECOUPLED_ENTRANCES }, - { "Gold Skulltula Tokens", RSK_STARTING_SKULLTULA_TOKEN }, - { "Hearts", RSK_STARTING_HEARTS }, - { "Logic Options:All Locations Reachable", RSK_ALL_LOCATIONS_REACHABLE }, - { "World Settings:Boss Entrances", RSK_SHUFFLE_BOSS_ENTRANCES }, - { "Shuffle Settings:Shuffle 100 GS Reward", RSK_SHUFFLE_100_GS_REWARD }, - { "World Settings:Triforce Hunt", RSK_TRIFORCE_HUNT }, - { "World Settings:Triforce Hunt Total Pieces", RSK_TRIFORCE_HUNT_PIECES_TOTAL }, - { "World Settings:Triforce Hunt Required Pieces", RSK_TRIFORCE_HUNT_PIECES_REQUIRED }, - { "Shuffle Settings:Shuffle Boss Souls", RSK_SHUFFLE_BOSS_SOULS }, - { "Shuffle Settings:Fishsanity", RSK_FISHSANITY }, - { "Shuffle Settings:Pond Fish Count", RSK_FISHSANITY_POND_COUNT }, - { "Shuffle Settings:Split Pond Fish", RSK_FISHSANITY_AGE_SPLIT }, - { "Shuffle Settings:Shuffle Fishing Pole", RSK_SHUFFLE_FISHING_POLE }, - { "Miscellaneous Settings:Infinite Upgrades", RSK_INFINITE_UPGRADES }, - { "Miscellaneous Settings:Skeleton Key", RSK_SKELETON_KEY }, - { "Shuffle Settings:Shuffle Deku Stick Bag", RSK_SHUFFLE_DEKU_STICK_BAG }, - { "Shuffle Settings:Shuffle Deku Nut Bag", RSK_SHUFFLE_DEKU_NUT_BAG }, - }; +std::unordered_map Settings::PopulateOptionNameToEnum(){ + std::unordered_map output = {}; + for (size_t count = 0; count < RSK_MAX; count++) { + output[mOptions[count].GetName()] = static_cast(count); + } + return output; } Option& Settings::GetOption(const RandomizerSettingKey key) { @@ -2601,619 +2407,12 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) { nlohmann::json settingsJson = spoilerFileJson["settings"]; for (auto it = settingsJson.begin(); it != settingsJson.end(); ++it) { // todo load into cvars for UI - - if (mSpoilerfileSettingNameToEnum.contains(it.key())) { - std::string numericValueString; - // this is annoying but the same strings are used in different orders - // and i don't want the spoilerfile to just have numbers instead of - // human readable settings values so it'll have to do for now - switch (const RandomizerSettingKey index = mSpoilerfileSettingNameToEnum[it.key()]) { - case RSK_LOGIC_RULES: - if (it.value() == "Glitchless") { - mOptions[index].SetContextIndex(RO_LOGIC_GLITCHLESS); - } else if (it.value() == "No Logic") { - mOptions[index].SetContextIndex(RO_LOGIC_NO_LOGIC); - } else if (it.value() == "Vanilla") { - mOptions[index].SetContextIndex(RO_LOGIC_VANILLA); - } - break; - case RSK_FOREST: - if (it.value() == "Closed") { - mOptions[index].SetContextIndex(RO_FOREST_CLOSED); - } else if (it.value() == "Open") { - mOptions[index].SetContextIndex(RO_FOREST_OPEN); - } else if (it.value() == "Closed Deku") { - mOptions[index].SetContextIndex(RO_FOREST_CLOSED_DEKU); - } - break; - case RSK_KAK_GATE: - if (it.value() == "Closed") { - mOptions[index].SetContextIndex(RO_KAK_GATE_CLOSED); - } else if (it.value() == "Open") { - mOptions[index].SetContextIndex(RO_KAK_GATE_OPEN); - } - break; - case RSK_DOOR_OF_TIME: - if (it.value() == "Open") { - mOptions[index].SetContextIndex(RO_DOOROFTIME_OPEN); - } else if (it.value() == "Song only") { - mOptions[index].SetContextIndex(RO_DOOROFTIME_SONGONLY); - } else if (it.value() == "Closed") { - mOptions[index].SetContextIndex(RO_DOOROFTIME_CLOSED); - } - break; - case RSK_ZORAS_FOUNTAIN: - if (it.value() == "Closed") { - mOptions[index].SetContextIndex(RO_ZF_CLOSED); - } else if (it.value() == "Closed as child") { - mOptions[index].SetContextIndex(RO_ZF_CLOSED_CHILD); - } else if (it.value() == "Open") { - mOptions[index].SetContextIndex(RO_ZF_OPEN); - } - break; - case RSK_SLEEPING_WATERFALL: - if (it.value() == "Closed") { - mOptions[index].SetContextIndex(RO_WATERFALL_CLOSED); - } else if (it.value() == "Open") { - mOptions[index].SetContextIndex(RO_WATERFALL_OPEN); - } - break; - case RSK_STARTING_AGE: - if (it.value() == "Child") { - mOptions[index].SetContextIndex(RO_AGE_CHILD); - } else if (it.value() == "Adult") { - mOptions[index].SetContextIndex(RO_AGE_ADULT); - } - break; - case RSK_GERUDO_FORTRESS: - if (it.value() == "Normal") { - mOptions[index].SetContextIndex(RO_GF_NORMAL); - } else if (it.value() == "Fast") { - mOptions[index].SetContextIndex(RO_GF_FAST); - } else if (it.value() == "Open") { - mOptions[index].SetContextIndex(RO_GF_OPEN); - } - break; - case RSK_RAINBOW_BRIDGE: - if (it.value() == "Vanilla") { - mOptions[index].SetContextIndex(RO_BRIDGE_VANILLA); - } else if (it.value() == "Always open") { - mOptions[index].SetContextIndex(RO_BRIDGE_ALWAYS_OPEN); - } else if (it.value() == "Stones") { - mOptions[index].SetContextIndex(RO_BRIDGE_STONES); - } else if (it.value() == "Medallions") { - mOptions[index].SetContextIndex(RO_BRIDGE_MEDALLIONS); - } else if (it.value() == "Dungeon rewards") { - mOptions[index].SetContextIndex(RO_BRIDGE_DUNGEON_REWARDS); - } else if (it.value() == "Dungeons") { - mOptions[index].SetContextIndex(RO_BRIDGE_DUNGEONS); - } else if (it.value() == "Tokens") { - mOptions[index].SetContextIndex(RO_BRIDGE_TOKENS); - } else if (it.value() == "Greg") { - mOptions[index].SetContextIndex(RO_BRIDGE_GREG); - } - break; - case RSK_BRIDGE_OPTIONS: - if (it.value() == "Standard Rewards") { - mOptions[index].SetContextIndex(RO_BRIDGE_STANDARD_REWARD); - } else if (it.value() == "Greg as Reward") { - mOptions[index].SetContextIndex(RO_BRIDGE_GREG_REWARD); - } else if (it.value() == "Greg as Wildcard") { - mOptions[index].SetContextIndex(RO_BRIDGE_WILDCARD_REWARD); - } - break; - case RSK_LACS_OPTIONS: - if (it.value() == "Standard Reward") { - mOptions[index].SetContextIndex(RO_LACS_STANDARD_REWARD); - } else if (it.value() == "Greg as Reward") { - mOptions[index].SetContextIndex(RO_LACS_GREG_REWARD); - } else if (it.value() == "Greg as Wildcard") { - mOptions[index].SetContextIndex(RO_LACS_WILDCARD_REWARD); - } - break; - case RSK_DAMAGE_MULTIPLIER: - if (it.value() == "x1/2") { - mOptions[index].SetContextIndex(RO_DAMAGE_MULTIPLIER_HALF); - } else if (it.value() == "x1") { - mOptions[index].SetContextIndex(RO_DAMAGE_MULTIPLIER_DEFAULT); - } else if (it.value() == "x2") { - mOptions[index].SetContextIndex(RO_DAMAGE_MULTIPLIER_DOUBLE); - } else if (it.value() == "x4") { - mOptions[index].SetContextIndex(RO_DAMAGE_MULTIPLIER_QUADRUPLE); - } else if (it.value() == "x8") { - mOptions[index].SetContextIndex(RO_DAMAGE_MULTIPLIER_OCTUPLE); - } else if (it.value() == "x16") { - mOptions[index].SetContextIndex(RO_DAMAGE_MULTIPLIER_SEXDECUPLE); - } else if (it.value() == "OHKO") { - mOptions[index].SetContextIndex(RO_DAMAGE_MULTIPLIER_OHKO); - } - break; - case RSK_RAINBOW_BRIDGE_STONE_COUNT: - case RSK_RAINBOW_BRIDGE_MEDALLION_COUNT: - case RSK_RAINBOW_BRIDGE_REWARD_COUNT: - case RSK_RAINBOW_BRIDGE_DUNGEON_COUNT: - case RSK_RAINBOW_BRIDGE_TOKEN_COUNT: - case RSK_TRIAL_COUNT: - case RSK_LACS_STONE_COUNT: - case RSK_LACS_MEDALLION_COUNT: - case RSK_LACS_REWARD_COUNT: - case RSK_LACS_DUNGEON_COUNT: - case RSK_LACS_TOKEN_COUNT: - case RSK_KEYRINGS_RANDOM_COUNT: - case RSK_CUCCO_COUNT: - case RSK_FISHSANITY_POND_COUNT: - case RSK_STARTING_SKULLTULA_TOKEN: - case RSK_SHOPSANITY_COUNT: - numericValueString = it.value(); - mOptions[index].SetContextIndex(std::stoi(numericValueString)); - break; - // Same as the above section, but the indexes are off by one from the text - // (i.e. 10 Big Poes is index 9). - case RSK_BIG_POE_COUNT: - case RSK_TRIFORCE_HUNT_PIECES_TOTAL: - case RSK_TRIFORCE_HUNT_PIECES_REQUIRED: - case RSK_STARTING_HEARTS: - numericValueString = it.value(); - mOptions[index].SetContextIndex(std::stoi(numericValueString) - 1); - break; - case RSK_GANONS_TRIALS: - if (it.value() == "Skip") { - mOptions[index].SetContextIndex(RO_GANONS_TRIALS_SKIP); - } else if (it.value() == "Set Number") { - mOptions[index].SetContextIndex(RO_GANONS_TRIALS_SET_NUMBER); - } else if (it.value() == "Random Number") { - mOptions[index].SetContextIndex(RO_GANONS_TRIALS_RANDOM_NUMBER); - } - case RSK_SHOPSANITY: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_SHOPSANITY_OFF); - } else if (it.value() == "Specific Count") { - mOptions[index].SetContextIndex(RO_SHOPSANITY_SPECIFIC_COUNT); - } else if (it.value() == "Random") { - mOptions[index].SetContextIndex(RO_SHOPSANITY_RANDOM); - } - break; - case RSK_SHOPSANITY_PRICES: - case RSK_SCRUBS_PRICES: - case RSK_MERCHANT_PRICES: - if (it.value() == "Vanilla") { - mOptions[index].SetContextIndex(RO_PRICE_VANILLA); - } else if (it.value() == "Cheap Balanced") { - mOptions[index].SetContextIndex(RO_PRICE_CHEAP_BALANCED); - } else if (it.value() == "Balanced") { - mOptions[index].SetContextIndex(RO_PRICE_BALANCED); - } else if (it.value() == "Fixed") { - mOptions[index].SetContextIndex(RO_PRICE_FIXED); - } else if (it.value() == "Range") { - mOptions[index].SetContextIndex(RO_PRICE_RANGE); - } else if (it.value() == "Set By Wallet") { - mOptions[index].SetContextIndex(RO_PRICE_SET_BY_WALLET); - } - break; - case RSK_SHUFFLE_SCRUBS: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_SCRUBS_OFF); - } else if (it.value() == "Major Items Only") { - mOptions[index].SetContextIndex(RO_SCRUBS_MAJOR_ONLY); - } else if (it.value() == "All") { - mOptions[index].SetContextIndex(RO_SCRUBS_ALL); - } - break; - case RSK_SHUFFLE_FISHING_POLE: - case RSK_FISHSANITY_AGE_SPLIT: - case RSK_FISHING_POLE_HINT: - case RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD: - case RSK_SHUFFLE_BEEHIVES: - case RSK_SHUFFLE_COWS: - case RSK_SHUFFLE_ADULT_TRADE: - case RSK_SHUFFLE_KOKIRI_SWORD: - case RSK_SHUFFLE_WEIRD_EGG: - case RSK_SHUFFLE_FROG_SONG_RUPEES: - case RSK_SHUFFLE_100_GS_REWARD: - case RSK_SHUFFLE_OCARINA: - case RSK_SHUFFLE_OCARINA_BUTTONS: - case RSK_SHUFFLE_SWIM: - case RSK_SHUFFLE_CHILD_WALLET: - case RSK_INCLUDE_TYCOON_WALLET: - case RSK_STARTING_DEKU_SHIELD: - case RSK_STARTING_KOKIRI_SWORD: - case RSK_STARTING_ZELDAS_LULLABY: - case RSK_STARTING_EPONAS_SONG: - case RSK_STARTING_SARIAS_SONG: - case RSK_STARTING_SUNS_SONG: - case RSK_STARTING_SONG_OF_TIME: - case RSK_STARTING_SONG_OF_STORMS: - case RSK_STARTING_MINUET_OF_FOREST: - case RSK_STARTING_BOLERO_OF_FIRE: - case RSK_STARTING_SERENADE_OF_WATER: - case RSK_STARTING_REQUIEM_OF_SPIRIT: - case RSK_STARTING_NOCTURNE_OF_SHADOW: - case RSK_STARTING_PRELUDE_OF_LIGHT: - case RSK_COMPLETE_MASK_QUEST: - case RSK_SKIP_SCARECROWS_SONG: - case RSK_ENABLE_GLITCH_CUTSCENES: - case RSK_SKULLS_SUNS_SONG: - case RSK_BLUE_FIRE_ARROWS: - case RSK_SUNLIGHT_ARROWS: - case RSK_INFINITE_UPGRADES: - case RSK_SKELETON_KEY: - case RSK_BOMBCHUS_IN_LOGIC: - case RSK_TOT_ALTAR_HINT: - case RSK_GANONDORF_HINT: - case RSK_SHEIK_LA_HINT: - case RSK_DAMPES_DIARY_HINT: - case RSK_GREG_HINT: - case RSK_LOACH_HINT: - case RSK_SARIA_HINT: - case RSK_FROGS_HINT: - case RSK_OOT_HINT: - case RSK_KAK_10_SKULLS_HINT: - case RSK_KAK_20_SKULLS_HINT: - case RSK_KAK_30_SKULLS_HINT: - case RSK_KAK_40_SKULLS_HINT: - case RSK_KAK_50_SKULLS_HINT: - case RSK_KAK_100_SKULLS_HINT: - case RSK_MASK_SHOP_HINT: - case RSK_BIGGORON_HINT: - case RSK_BIG_POES_HINT: - case RSK_CHICKENS_HINT: - case RSK_MALON_HINT: - case RSK_HBA_HINT: - case RSK_WARP_SONG_HINTS: - case RSK_SCRUB_TEXT_HINT: - case RSK_MERCHANT_TEXT_HINT: - case RSK_SHUFFLE_ENTRANCES: - case RSK_SHUFFLE_OVERWORLD_ENTRANCES: - case RSK_SHUFFLE_GROTTO_ENTRANCES: - case RSK_SHUFFLE_OWL_DROPS: - case RSK_SHUFFLE_WARP_SONGS: - case RSK_SHUFFLE_OVERWORLD_SPAWNS: - case RSK_MIXED_ENTRANCE_POOLS: - case RSK_MIX_DUNGEON_ENTRANCES: - case RSK_MIX_BOSS_ENTRANCES: - case RSK_MIX_OVERWORLD_ENTRANCES: - case RSK_MIX_INTERIOR_ENTRANCES: - case RSK_MIX_GROTTO_ENTRANCES: - case RSK_DECOUPLED_ENTRANCES: - case RSK_SHOPSANITY_PRICES_AFFORDABLE: - case RSK_SCRUBS_PRICES_AFFORDABLE: - case RSK_MERCHANT_PRICES_AFFORDABLE: - case RSK_ALL_LOCATIONS_REACHABLE: - case RSK_TRIFORCE_HUNT: - case RSK_MQ_DUNGEON_SET: - case RSK_SHUFFLE_DEKU_NUT_BAG: - case RSK_SHUFFLE_DEKU_STICK_BAG: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_GENERIC_OFF); - } else if (it.value() == "On") { - mOptions[index].SetContextIndex(RO_GENERIC_ON); - } - break; - case RSK_KEYRINGS: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_KEYRINGS_OFF); - } else if (it.value() == "Random") { - mOptions[index].SetContextIndex(RO_KEYRINGS_RANDOM); - } else if (it.value() == "Count") { - mOptions[index].SetContextIndex(RO_KEYRINGS_COUNT); - } else if (it.value() == "Selection") { - mOptions[index].SetContextIndex(RO_KEYRINGS_SELECTION); - } - break; - case RSK_KEYRINGS_GERUDO_FORTRESS: - case RSK_KEYRINGS_FOREST_TEMPLE: - case RSK_KEYRINGS_FIRE_TEMPLE: - case RSK_KEYRINGS_WATER_TEMPLE: - case RSK_KEYRINGS_SHADOW_TEMPLE: - case RSK_KEYRINGS_SPIRIT_TEMPLE: - case RSK_KEYRINGS_BOTTOM_OF_THE_WELL: - case RSK_KEYRINGS_GTG: - case RSK_KEYRINGS_GANONS_CASTLE: - if (it.value() == "No") { - mOptions[index].SetContextIndex(RO_KEYRING_FOR_DUNGEON_OFF); - } else if (it.value() == "Random") { - mOptions[index].SetContextIndex(RO_KEYRING_FOR_DUNGEON_RANDOM); - } else if (it.value() == "Yes") { - mOptions[index].SetContextIndex(RO_KEYRING_FOR_DUNGEON_ON); - } - break; - case RSK_SHUFFLE_MERCHANTS: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_SHUFFLE_MERCHANTS_OFF); - } else if (it.value() == "Beans Only") { - mOptions[index].SetContextIndex(RO_SHUFFLE_MERCHANTS_BEANS_ONLY); - } else if (it.value() == "All but Beans") { - mOptions[index].SetContextIndex(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS); - } else if (it.value() == "All") { - mOptions[index].SetContextIndex(RO_SHUFFLE_MERCHANTS_ALL); - } - break; - // Uses Ammo Drops option for now. "Off" not yet implemented - // TODO: Change to Ammo Drops - case RSK_ENABLE_BOMBCHU_DROPS: - if (it.value() == "Yes") { - mOptions[index].SetContextIndex(RO_AMMO_DROPS_ON); - // } else if (it.value() == "On + Bombchu") { - // mOptions[index].SetContextIndex(RO_AMMO_DROPS_ON_PLUS_BOMBCHU); - } else if (it.value() == "No") { - mOptions[index].SetContextIndex(RO_AMMO_DROPS_OFF); - } - break; - case RSK_FISHSANITY: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_FISHSANITY_OFF); - } else if (it.value() == "Shuffle Fishing Pond") { - mOptions[index].SetContextIndex(RO_FISHSANITY_POND); - } else if (it.value() == "Shuffle Overworld Fish") { - mOptions[index].SetContextIndex(RO_FISHSANITY_OVERWORLD); - } else if (it.value() == "Shuffle Both") { - mOptions[index].SetContextIndex(RO_FISHSANITY_BOTH); - } - break; - case RSK_SHUFFLE_BOSS_SOULS: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_BOSS_SOULS_OFF); - } else if (it.value() == "On") { - mOptions[index].SetContextIndex(RO_BOSS_SOULS_ON); - } else if (it.value() == "On + Ganon") { - mOptions[index].SetContextIndex(RO_BOSS_SOULS_ON_PLUS_GANON); - } - case RSK_STARTING_OCARINA: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_STARTING_OCARINA_OFF); - } else if (it.value() == "Fairy Ocarina") { - mOptions[index].SetContextIndex(RO_STARTING_OCARINA_FAIRY); - } - break; - case RSK_ITEM_POOL: - if (it.value() == "Plentiful") { - mOptions[index].SetContextIndex(RO_ITEM_POOL_PLENTIFUL); - } else if (it.value() == "Balanced") { - mOptions[index].SetContextIndex(RO_ITEM_POOL_BALANCED); - } else if (it.value() == "Scarce") { - mOptions[index].SetContextIndex(RO_ITEM_POOL_SCARCE); - } else if (it.value() == "Minimal") { - mOptions[index].SetContextIndex(RO_ITEM_POOL_MINIMAL); - } - break; - case RSK_ICE_TRAPS: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_ICE_TRAPS_OFF); - } else if (it.value() == "Normal") { - mOptions[index].SetContextIndex(RO_ICE_TRAPS_NORMAL); - } else if (it.value() == "Extra") { - mOptions[index].SetContextIndex(RO_ICE_TRAPS_EXTRA); - } else if (it.value() == "Mayhem") { - mOptions[index].SetContextIndex(RO_ICE_TRAPS_MAYHEM); - } else if (it.value() == "Onslaught") { - mOptions[index].SetContextIndex(RO_ICE_TRAPS_ONSLAUGHT); - } - break; - case RSK_GOSSIP_STONE_HINTS: - if (it.value() == "No Hints") { - mOptions[index].SetContextIndex(RO_GOSSIP_STONES_NONE); - } else if (it.value() == "Need Nothing") { - mOptions[index].SetContextIndex(RO_GOSSIP_STONES_NEED_NOTHING); - } else if (it.value() == "Mask of Truth") { - mOptions[index].SetContextIndex(RO_GOSSIP_STONES_NEED_TRUTH); - } else if (it.value() == "Stone of Agony") { - mOptions[index].SetContextIndex(RO_GOSSIP_STONES_NEED_STONE); - } - break; - case RSK_HINT_CLARITY: - if (it.value() == "Obscure") { - mOptions[index].SetContextIndex(RO_HINT_CLARITY_OBSCURE); - } else if (it.value() == "Ambiguous") { - mOptions[index].SetContextIndex(RO_HINT_CLARITY_AMBIGUOUS); - } else if (it.value() == "Clear") { - mOptions[index].SetContextIndex(RO_HINT_CLARITY_CLEAR); - } - break; - case RSK_HINT_DISTRIBUTION: - if (it.value() == "Useless") { - mOptions[index].SetContextIndex(RO_HINT_DIST_USELESS); - } else if (it.value() == "Balanced") { - mOptions[index].SetContextIndex(RO_HINT_DIST_BALANCED); - } else if (it.value() == "Strong") { - mOptions[index].SetContextIndex(RO_HINT_DIST_STRONG); - } else if (it.value() == "Very Strong") { - mOptions[index].SetContextIndex(RO_HINT_DIST_VERY_STRONG); - } - break; - case RSK_GERUDO_KEYS: - if (it.value() == "Vanilla") { - mOptions[index].SetContextIndex(RO_GERUDO_KEYS_VANILLA); - } else if (it.value() == "Any Dungeon") { - mOptions[index].SetContextIndex(RO_GERUDO_KEYS_ANY_DUNGEON); - } else if (it.value() == "Overworld") { - mOptions[index].SetContextIndex(RO_GERUDO_KEYS_OVERWORLD); - } else if (it.value() == "Anywhere") { - mOptions[index].SetContextIndex(RO_GERUDO_KEYS_ANYWHERE); - } - break; - case RSK_KEYSANITY: - case RSK_BOSS_KEYSANITY: - case RSK_SHUFFLE_MAPANDCOMPASS: - if (it.value() == "Start With") { - mOptions[index].SetContextIndex(RO_DUNGEON_ITEM_LOC_STARTWITH); - } else if (it.value() == "Vanilla") { - mOptions[index].SetContextIndex(RO_DUNGEON_ITEM_LOC_VANILLA); - } else if (it.value() == "Own Dungeon") { - mOptions[index].SetContextIndex(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); - } else if (it.value() == "Any Dungeon") { - mOptions[index].SetContextIndex(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON); - } else if (it.value() == "Overworld") { - mOptions[index].SetContextIndex(RO_DUNGEON_ITEM_LOC_OVERWORLD); - } else if (it.value() == "Anywhere") { - mOptions[index].SetContextIndex(RO_DUNGEON_ITEM_LOC_ANYWHERE); - } - break; - case RSK_GANONS_BOSS_KEY: - if (it.value() == "Vanilla") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_VANILLA); - } else if (it.value() == "Own dungeon") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_OWN_DUNGEON); - } else if (it.value() == "Start with") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_STARTWITH); - } else if (it.value() == "Any Dungeon") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_ANY_DUNGEON); - } else if (it.value() == "Overworld") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_OVERWORLD); - } else if (it.value() == "Anywhere") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_ANYWHERE); - } else if (it.value() == "LACS-Vanilla") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_LACS_VANILLA); - } else if (it.value() == "LACS-Stones") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_LACS_STONES); - } else if (it.value() == "LACS-Medallions") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_LACS_MEDALLIONS); - } else if (it.value() == "LACS-Rewards") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_LACS_REWARDS); - } else if (it.value() == "LACS-Dungeons") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_LACS_DUNGEONS); - } else if (it.value() == "LACS-Tokens") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_LACS_TOKENS); - } else if (it.value() == "100 GS Reward") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_KAK_TOKENS); - } else if (it.value() == "Triforce Hunt") { - mOptions[index].SetContextIndex(RO_GANON_BOSS_KEY_TRIFORCE_HUNT); - } - break; - case RSK_MQ_DUNGEON_RANDOM: - if (it.value() == "None") { - mOptions[index].SetContextIndex(RO_MQ_DUNGEONS_NONE); - } else if (it.value() == "Random Number") { - mOptions[index].SetContextIndex(RO_MQ_DUNGEONS_RANDOM_NUMBER); - } else if (it.value() == "Set Number") { - mOptions[index].SetContextIndex(RO_MQ_DUNGEONS_SET_NUMBER); - } else if (it.value() == "Selection Only") { - mOptions[index].SetContextIndex(RO_MQ_DUNGEONS_SELECTION); - } - break; - case RSK_STARTING_STICKS: - case RSK_STARTING_NUTS: - case RSK_FULL_WALLETS: - if (it.value() == "No") { - mOptions[index].SetContextIndex(RO_GENERIC_NO); - } else if (it.value() == "Yes") { - mOptions[index].SetContextIndex(RO_GENERIC_YES); - } - break; - case RSK_SKIP_CHILD_ZELDA: - case RSK_SKIP_CHILD_STEALTH: - case RSK_SKIP_EPONA_RACE: - if (it.value() == "Don't Skip") { - mOptions[index].SetContextIndex(RO_GENERIC_DONT_SKIP); - } else if (it.value() == "Skip") { - mOptions[index].SetContextIndex(RO_GENERIC_SKIP); - } - break; - case RSK_SHUFFLE_DUNGEON_REWARDS: - if (it.value() == "End of dungeons") { - mOptions[index].SetContextIndex(RO_DUNGEON_REWARDS_END_OF_DUNGEON); - } else if (it.value() == "Any dungeon") { - mOptions[index].SetContextIndex(RO_DUNGEON_REWARDS_ANY_DUNGEON); - } else if (it.value() == "Overworld") { - mOptions[index].SetContextIndex(RO_DUNGEON_REWARDS_OVERWORLD); - } else if (it.value() == "Anywhere") { - mOptions[index].SetContextIndex(RO_DUNGEON_REWARDS_ANYWHERE); - } - break; - case RSK_SHUFFLE_SONGS: - if (it.value() == "Song locations") { - mOptions[index].SetContextIndex(RO_SONG_SHUFFLE_SONG_LOCATIONS); - } else if (it.value() == "Dungeon rewards") { - mOptions[index].SetContextIndex(RO_SONG_SHUFFLE_DUNGEON_REWARDS); - } else if (it.value() == "Anywhere") { - mOptions[index].SetContextIndex(RO_SONG_SHUFFLE_ANYWHERE); - } - break; - case RSK_SHUFFLE_TOKENS: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_TOKENSANITY_OFF); - } else if (it.value() == "Dungeons") { - mOptions[index].SetContextIndex(RO_TOKENSANITY_DUNGEONS); - } else if (it.value() == "Overworld") { - mOptions[index].SetContextIndex(RO_TOKENSANITY_OVERWORLD); - } else if (it.value() == "All Tokens") { - mOptions[index].SetContextIndex(RO_TOKENSANITY_ALL); - } - break; - case RSK_LINKS_POCKET: - if (it.value() == "Dungeon Reward") { - mOptions[index].SetContextIndex(RO_LINKS_POCKET_DUNGEON_REWARD); - } else if (it.value() == "Advancement") { - mOptions[index].SetContextIndex(RO_LINKS_POCKET_ADVANCEMENT); - } else if (it.value() == "Anything") { - mOptions[index].SetContextIndex(RO_LINKS_POCKET_ANYTHING); - } else if (it.value() == "Nothing") { - mOptions[index].SetContextIndex(RO_LINKS_POCKET_NOTHING); - } - break; - case RSK_MQ_DUNGEON_COUNT: - numericValueString = it.value(); - mOptions[index].SetContextIndex(std::stoi(numericValueString)); - break; - case RSK_SHUFFLE_DUNGEON_ENTRANCES: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF); - } else if (it.value() == "On") { - mOptions[index].SetContextIndex(RO_DUNGEON_ENTRANCE_SHUFFLE_ON); - } else if (it.value() == "On + Ganon") { - mOptions[index].SetContextIndex(RO_DUNGEON_ENTRANCE_SHUFFLE_ON_PLUS_GANON); - } - break; - case RSK_SHUFFLE_BOSS_ENTRANCES: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF); - } else if (it.value() == "Age Restricted") { - mOptions[index].SetContextIndex(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_AGE_RESTRICTED); - } else if (it.value() == "Full") { - mOptions[index].SetContextIndex(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_FULL); - } - break; - case RSK_SHUFFLE_INTERIOR_ENTRANCES: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF); - } else if (it.value() == "Simple") { - mOptions[index].SetContextIndex(RO_INTERIOR_ENTRANCE_SHUFFLE_SIMPLE); - } else if (it.value() == "All") { - mOptions[index].SetContextIndex(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL); - } - break; - case RSK_SHUFFLE_CHEST_MINIGAME: - if (it.value() == "Off") { - mOptions[index].SetContextIndex(RO_CHEST_GAME_OFF); - } else if (it.value() == "On (Separate)") { - mOptions[index].SetContextIndex(RO_CHEST_GAME_SINGLE_KEYS); - } else if (it.value() == "On (Pack)") { - mOptions[index].SetContextIndex(RO_CHEST_GAME_PACK); - } - break; - case RSK_MQ_DEKU_TREE: - case RSK_MQ_DODONGOS_CAVERN: - case RSK_MQ_JABU_JABU: - case RSK_MQ_FOREST_TEMPLE: - case RSK_MQ_FIRE_TEMPLE: - case RSK_MQ_WATER_TEMPLE: - case RSK_MQ_SPIRIT_TEMPLE: - case RSK_MQ_SHADOW_TEMPLE: - case RSK_MQ_BOTTOM_OF_THE_WELL: - case RSK_MQ_ICE_CAVERN: - case RSK_MQ_GTG: - case RSK_MQ_GANONS_CASTLE: - if (it.value() == "Vanilla") { - mOptions[index].SetContextIndex(RO_MQ_SET_VANILLA); - } else if (it.value() == "Master Quest") { - mOptions[index].SetContextIndex(RO_MQ_SET_MQ); - } else if (it.value() == "Random") { - mOptions[index].SetContextIndex(RO_MQ_SET_RANDOM); - } - break; - default: - SPDLOG_DEBUG("No string to enum conversion for option: %s", it.key()); - break; - } + //RANDOTODO handle numeric value to options conversion better than brute froce + if (StaticData::optionNameToEnum.contains(it.key())) { + auto test = it.key(); + auto test2 = it.value(); + const RandomizerSettingKey index = StaticData::optionNameToEnum[it.key()]; + mOptions[index].SetContextIndexFromText(it.value()); } } diff --git a/soh/soh/Enhancements/randomizer/settings.h b/soh/soh/Enhancements/randomizer/settings.h index 8bb484b16..90613cf14 100644 --- a/soh/soh/Enhancements/randomizer/settings.h +++ b/soh/soh/Enhancements/randomizer/settings.h @@ -25,6 +25,14 @@ class Settings { */ void CreateOptions(); + /** + * @brief Populates the map used to translate strings into RandomiserSettingKeys + * + * @return std::unordered_map + */ + + std::unordered_map PopulateOptionNameToEnum(); + /** * @brief Get a reference to the `Option` corresponding to the provided RandomizerSettingKey. * @@ -192,7 +200,6 @@ class Settings { std::array mOptionGroups = {}; std::array mTrickOptions = {}; std::vector> mExcludeLocationsOptionsAreas = {}; - std::unordered_map mSpoilerfileSettingNameToEnum; RandoOptionStartingAge mResolvedStartingAge = RO_AGE_CHILD; RandoOptionLACSCondition mLACSCondition = RO_LACS_VANILLA; std::string mHash; diff --git a/soh/soh/Enhancements/randomizer/static_data.cpp b/soh/soh/Enhancements/randomizer/static_data.cpp index 15697d9e0..84da0d3c1 100644 --- a/soh/soh/Enhancements/randomizer/static_data.cpp +++ b/soh/soh/Enhancements/randomizer/static_data.cpp @@ -251,7 +251,8 @@ std::unordered_map StaticData::hintNameToEnum = {}; std::unordered_map StaticData::hintTypeNameToEnum = {}; std::unordered_map StaticData::areaNameToEnum = {}; std::unordered_map StaticData::trialNameToEnum = {}; -std::unordered_map StaticData::locationNameToEnum = {}; //is filled in context based on location table, not touching that because of VB +std::unordered_map StaticData::optionNameToEnum = {}; +std::unordered_map StaticData::locationNameToEnum = {}; //is filled in context based on location table std::unordered_map StaticData::stoneParamsToHint{ {0x1, RH_ZF_FAIRY_GOSSIP_STONE}, diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index 5ff0f1d26..7aade57de 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -61,6 +61,7 @@ class StaticData { static std::unordered_map areaNameToEnum; static std::unordered_map trialData; static std::unordered_map trialNameToEnum; + static std::unordered_map optionNameToEnum; static std::unordered_map staticHintInfoMap; static std::unordered_map stoneParamsToHint; static std::unordered_map grottoChestParamsToHint;