Lang Improvements (#7130)

Massively optimize Lang::Translate & add Lang::TryTranslate.
Move all rando option text to lang json.

In the future we should have something like .TranslationTooltip() that takes the translation string to use instead of .Tooltip() as that'd allow us to change language at runtime.
This commit is contained in:
Pepe20129
2026-08-31 21:24:11 +02:00
committed by GitHub
parent 3175ea9c20
commit 8ca5ca60aa
11 changed files with 2368 additions and 1346 deletions
File diff suppressed because it is too large Load Diff
+60 -26
View File
@@ -17,16 +17,18 @@ extern std::shared_ptr<SohMenu> mSohMenu;
}
static bool initialized = false;
static std::map<std::string, nlohmann::json> langs;
static std::unordered_map<std::string, nlohmann::json> langs;
static std::unordered_map<std::string, std::string> cache;
#define LANGUAGE_CVAR CVAR_SETTING("Language")
#define DEFAULT_LANGUAGE "en_US"
std::string Lang::Translate(const char* path) {
std::variant<std::reference_wrapper<const std::string>, Lang::Error> Lang::TryTranslate(const char* path) {
if (!initialized) {
SPDLOG_ERROR("Tried to obtain a translation before the translation data is initialized");
assert(false);
return "ERROR: Language data not initialized yet";
return Lang::Error::LanguageDataNotInitialized;
}
std::string currentLang = CVarGetString(LANGUAGE_CVAR, DEFAULT_LANGUAGE);
@@ -40,59 +42,90 @@ std::string Lang::Translate(const char* path) {
if (!langs.contains(currentLang)) {
SPDLOG_ERROR("Default language ({}) doesn't exist", DEFAULT_LANGUAGE);
assert(false);
return "ERROR: Language data not found";
return Lang::Error::LanguageDataNotFound;
}
CVarSetString(LANGUAGE_CVAR, DEFAULT_LANGUAGE);
SPDLOG_WARN("Fallback to default language ({}) was succesful", DEFAULT_LANGUAGE);
}
nlohmann::json currentLangData = langs[currentLang];
std::string stringPath = std::string(path);
std::vector<std::string> segments = SohUtils::StringSplit(std::string(path), ".");
if (cache.contains(stringPath)) {
return cache[stringPath];
}
const nlohmann::json* currentLangData = &langs.at(currentLang);
std::vector<std::string> segments = SohUtils::StringSplit(stringPath, ".");
std::string lastSegment = segments[segments.size() - 1];
segments.pop_back();
for (const auto& segment : segments) {
if (!currentLangData.contains(segment)) {
SPDLOG_WARN("Current language ({}) doesn't have data for the requested path ({})", currentLang.c_str(),
path);
return std::string(path);
if (!currentLangData->contains(segment)) {
return Lang::Error::PathDataNotFound;
}
currentLangData = currentLangData[segment];
currentLangData = &currentLangData->at(segment);
}
if (!currentLangData.contains(lastSegment)) {
SPDLOG_WARN("Current language ({}) doesn't have data for the requested path ({})", currentLang.c_str(), path);
return std::string(path);
if (!currentLangData->contains(lastSegment)) {
return Lang::Error::PathDataNotFound;
}
if (currentLangData[lastSegment].is_string()) {
return currentLangData[lastSegment].get<std::string>();
if (currentLangData->at(lastSegment).is_string()) {
const std::string& translatedString = currentLangData->at(lastSegment).get_ref<const std::string&>();
cache[stringPath] = translatedString;
return cache[stringPath];
}
if (currentLangData[lastSegment].is_array()) {
if (currentLangData->at(lastSegment).is_array()) {
std::string translatedString = "";
for (const auto& item : currentLangData[lastSegment]) {
for (const auto& item : currentLangData->at(lastSegment)) {
if (!item.is_string()) {
SPDLOG_WARN("Current language ({}) has an array with a non-string at the requested path ({})",
currentLang.c_str(), path);
return std::string(path);
return Lang::Error::PathInvalidValue;
}
translatedString += item.get<std::string>();
translatedString += item.get_ref<const std::string&>();
}
return translatedString;
cache[stringPath] = translatedString;
return cache[stringPath];
}
SPDLOG_WARN("Current language ({}) doesn't have either a string or an array at the requested path ({})",
currentLang.c_str(), path);
return std::string(path);
return Lang::Error::PathInvalidValue;
}
const std::string errorMessage =
"[ERROR] Couldn't retrieve language data for this item, check the log for more information.";
const std::string& Lang::Translate(const char* path) {
auto value = Lang::TryTranslate(path);
if (std::holds_alternative<std::reference_wrapper<const std::string>>(value)) {
return std::get<std::reference_wrapper<const std::string>>(value);
} else if (std::holds_alternative<Lang::Error>(value)) {
switch (std::get<Lang::Error>(value)) {
case Lang::Error::PathDataNotFound:
SPDLOG_WARN("Current language ({}) doesn't have data for the requested path ({})",
CVarGetString(LANGUAGE_CVAR, DEFAULT_LANGUAGE), path);
break;
case Lang::Error::PathInvalidValue:
SPDLOG_WARN("Current language ({}) has an array with a non-string at the requested path ({})",
CVarGetString(LANGUAGE_CVAR, DEFAULT_LANGUAGE), path);
break;
default:
break;
}
return errorMessage;
} else {
assert(false);
return errorMessage;
}
}
void Lang::LoadLangs() {
@@ -121,6 +154,7 @@ void LanguageCustomWidget(WidgetInfo& info) {
id.c_str())
.c_str())) {
CVarSetString(LANGUAGE_CVAR, id.c_str());
cache.clear();
}
}
}
+12 -1
View File
@@ -1,8 +1,19 @@
#pragma once
#include <string>
#include <variant>
namespace Lang {
std::string Translate(const char* path);
enum Error {
LanguageDataNotInitialized,
LanguageDataNotFound,
PathDataNotFound,
PathInvalidValue,
};
// TODO: Upgrade to std::expected when we update to C++ 23
std::variant<std::reference_wrapper<const std::string>, Lang::Error> TryTranslate(const char* path);
const std::string& Translate(const char* path);
void LoadLangs();
} // namespace Lang
@@ -41,7 +41,7 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
}
for (Rando::Option* option : optionGroup.GetOptions()) {
if (option->IsCategory(Rando::OptionCategory::Setting)) {
if (option->GetCategory() != Rando::OptionCategory::Toggle) {
if (option->GetOptionCount() > 0) {
if (i >= RSG_EXCLUDES_KOKIRI_FOREST && i <= RSG_EXCLUDES_GANONS_CASTLE) {
auto locationOption = static_cast<Rando::LocationOption*>(option);
+2 -2
View File
@@ -65,7 +65,7 @@ class Location {
actorParams(actorParams_), shortName(std::move(shortName_)), spoilerName(std::move(spoilerName_)),
hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_),
collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) {
excludedOption = LocationOption(rc, spoilerName);
excludedOption = LocationOption(rc);
}
Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_,
@@ -77,7 +77,7 @@ class Location {
actorParams(actorParams_), shortName(shortName_), spoilerName(SpoilerNameFromShortName(shortName_, area_)),
hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_),
collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) {
excludedOption = LocationOption(rc, spoilerName);
excludedOption = LocationOption(rc);
}
static std::string SpoilerNameFromShortName(std::string shortName, RandomizerCheckArea area) {
+110 -67
View File
@@ -10,16 +10,13 @@ extern std::shared_ptr<SohMenu> mSohMenu;
}
namespace Rando {
Option Option::Bool(RandomizerSettingKey key_, std::string name_, std::vector<std::string> options_,
const OptionCategory category_, std::string cvarName_, std::string description_,
WidgetType widgetType_, const uint8_t defaultOption_, const bool defaultHidden_,
WidgetFunc callback_, int imFlags_) {
Option Option::Bool(RandomizerSettingKey key_, std::vector<std::string> options_, const OptionCategory category_,
std::string cvarName_, WidgetType widgetType_, const uint8_t defaultOption_,
const bool defaultHidden_, WidgetFunc callback_, int imFlags_) {
return { static_cast<size_t>(key_),
std::move(name_),
std::move(options_),
category_,
std::move(cvarName_),
std::move(description_),
widgetType_,
defaultOption_,
defaultHidden_,
@@ -27,22 +24,19 @@ Option Option::Bool(RandomizerSettingKey key_, std::string name_, std::vector<st
imFlags_ };
}
Option Option::Bool(RandomizerSettingKey key_, std::string name_, std::string cvarName_, std::string description_,
const int imFlags_, const WidgetType widgetType_, const bool defaultOption_, WidgetFunc callback_) {
return Option(key_, std::move(name_), { "Off", "On" }, OptionCategory::Setting, std::move(cvarName_),
std::move(description_), widgetType_, defaultOption_, false, callback_, imFlags_);
Option Option::Bool(RandomizerSettingKey key_, std::string cvarName_, const int imFlags_, const WidgetType widgetType_,
const bool defaultOption_, WidgetFunc callback_) {
return Option(key_, { "Off", "On" }, OptionCategory::Setting, std::move(cvarName_), widgetType_, defaultOption_,
false, callback_, imFlags_);
}
Option Option::U8(RandomizerSettingKey key_, std::string name_, std::vector<std::string> options_,
const OptionCategory category_, std::string cvarName_, std::string description_,
WidgetType widgetType_, const uint8_t defaultOption_, const bool defaultHidden_, WidgetFunc callback_,
int imFlags_) {
Option Option::U8(RandomizerSettingKey key_, std::vector<std::string> options_, const OptionCategory category_,
std::string cvarName_, WidgetType widgetType_, const uint8_t defaultOption_,
const bool defaultHidden_, WidgetFunc callback_, int imFlags_) {
return { static_cast<size_t>(key_),
std::move(name_),
std::move(options_),
category_,
std::move(cvarName_),
std::move(description_),
widgetType_,
defaultOption_,
defaultHidden_,
@@ -50,11 +44,6 @@ Option Option::U8(RandomizerSettingKey key_, std::string name_, std::vector<std:
imFlags_ };
}
Option Option::LogicTrick(RandomizerTrick rt_, std::string name_) {
return Option(rt_, std::move(name_), { "Disabled", "Enabled" }, OptionCategory::Setting, "", "",
WIDGET_CVAR_CHECKBOX, 0, false, nullptr, IMFLAG_NONE);
}
OptionValue::OptionValue(uint8_t val) : mVal(val) {
}
@@ -78,12 +67,93 @@ RandomizerSettingKey Option::GetKey() const {
return static_cast<RandomizerSettingKey>(key);
}
#pragma region Lang
#define RANDO_ENUM_ITEM(enum) { enum, #enum },
std::unordered_map<RandomizerSettingKey, std::string> settingNames = {
#include "randomizerEnums/RandomizerSettingKey.h"
};
std::unordered_map<RandomizerTrick, std::string> trickNames = {
#include "randomizerEnums/RandomizerTrick.h"
};
#undef RANDO_ENUM_ITEM
const static std::string namePostfix = ".name";
const static std::string descriptionPostfix = ".description";
const static std::string settingPrefix = "randomizer.settings.";
const static std::string trickPrefix = "randomizer.tricks.";
const static std::string empty = "";
const static std::string error = "[ERROR]";
static const std::string& MakeSettingName(RandomizerSettingKey key) {
std::string settingNamePart = settingNames[key].substr(4);
std::transform(settingNamePart.begin(), settingNamePart.end(), settingNamePart.begin(), ::tolower);
return Lang::Translate((settingPrefix + settingNamePart + namePostfix).c_str());
}
static const std::string& MakeSettingDescription(RandomizerSettingKey key) {
std::string settingNamePart = settingNames[key].substr(4);
std::transform(settingNamePart.begin(), settingNamePart.end(), settingNamePart.begin(), ::tolower);
auto result = Lang::TryTranslate((settingPrefix + settingNamePart + descriptionPostfix).c_str());
if (std::holds_alternative<std::reference_wrapper<const std::string>>(result)) {
return std::get<std::reference_wrapper<const std::string>>(result);
} else if (std::holds_alternative<Lang::Error>(result)) {
return empty;
} else {
assert(false);
return error;
}
}
static const std::string& MakeTrickName(RandomizerTrick key) {
std::string trickNamePart = trickNames[key].substr(3);
std::transform(trickNamePart.begin(), trickNamePart.end(), trickNamePart.begin(), ::tolower);
return Lang::Translate((trickPrefix + trickNamePart + namePostfix).c_str());
}
static const std::string& MakeTrickDescription(RandomizerTrick key) {
std::string trickNamePart = trickNames[key].substr(3);
std::transform(trickNamePart.begin(), trickNamePart.end(), trickNamePart.begin(), ::tolower);
return Lang::Translate((trickPrefix + trickNamePart + descriptionPostfix).c_str());
}
#pragma endregion
const static std::string todo = "TODO";
const std::string& Option::GetName() const {
return name;
switch (this->GetCategory()) {
case OptionCategory::Setting:
case OptionCategory::Toggle:
return MakeSettingName(static_cast<RandomizerSettingKey>(this->key));
case OptionCategory::Trick:
return MakeTrickName(static_cast<RandomizerTrick>(this->key));
case OptionCategory::LocationExclusion:
return todo;
default:
assert(false);
return error;
}
}
const std::string& Option::GetDescription() const {
return description;
switch (this->GetCategory()) {
case OptionCategory::Setting:
case OptionCategory::Toggle:
return MakeSettingDescription(static_cast<RandomizerSettingKey>(this->key));
case OptionCategory::Trick:
return MakeTrickDescription(static_cast<RandomizerTrick>(this->key));
case OptionCategory::LocationExclusion:
return todo;
default:
assert(false);
return error;
}
}
uint8_t Option::GetOptionIndex() const {
@@ -143,8 +213,8 @@ void Option::Disable(std::string text) {
}
}
bool Option::IsCategory(const OptionCategory category) const {
return category == this->category;
OptionCategory Option::GetCategory() const {
return this->category;
}
void Option::AddFlag(const int imFlag_) {
@@ -159,18 +229,17 @@ uint8_t Option::GetValueFromText(const std::string text) {
if (optionsTextToVar.contains(text)) {
return optionsTextToVar[text];
} else {
SPDLOG_ERROR("Option {} does not have a var named {}.", name, text);
SPDLOG_ERROR("Option {} does not have a var named {}.", this->GetName(), text);
assert(false);
}
return defaultOption;
}
Option::Option(size_t key_, std::string name_, std::vector<std::string> options_, OptionCategory category_,
std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_,
bool defaultHidden_, WidgetFunc callback_, int imFlags_)
: key(key_), name(std::move(name_)), options(std::move(options_)), category(category_),
cvarName(std::move(cvarName_)), description(std::move(description_)), widgetType(widgetType_),
defaultOption(defaultOption_), defaultHidden(defaultHidden_), imFlags(imFlags_), callback(callback_) {
Option::Option(size_t key_, std::vector<std::string> options_, OptionCategory category_, std::string cvarName_,
WidgetType widgetType_, uint8_t defaultOption_, bool defaultHidden_, WidgetFunc callback_, int imFlags_)
: key(key_), options(std::move(options_)), category(category_), cvarName(std::move(cvarName_)),
widgetType(widgetType_), defaultOption(defaultOption_), defaultHidden(defaultHidden_), imFlags(imFlags_),
callback(callback_) {
contextSelection = defaultOption;
hidden = defaultHidden;
for (size_t i = 0; i < options.size(); i++) {
@@ -184,7 +253,7 @@ Option::Option(size_t key_, std::string name_, std::vector<std::string> options_
// labelPosition = UIWidgets::LabelPositions::Near;
// }
widgetOptions = std::make_shared<UIWidgets::CheckboxOptions>(
UIWidgets::CheckboxOptions().DefaultValue(defaultOption).Tooltip(description.c_str()));
UIWidgets::CheckboxOptions().DefaultValue(defaultOption).Tooltip(this->GetDescription()));
break;
case WIDGET_CVAR_COMBOBOX:
labelPosition = UIWidgets::LabelPositions::Above;
@@ -194,7 +263,7 @@ Option::Option(size_t key_, std::string name_, std::vector<std::string> options_
widgetOptions = std::make_shared<UIWidgets::ComboboxOptions>(UIWidgets::ComboboxOptions()
.DefaultIndex(defaultOption)
.ComboMap(optionsMap)
.Tooltip(description.c_str())
.Tooltip(this->GetDescription())
.LabelPosition(labelPosition));
break;
case WIDGET_CVAR_SLIDER_INT:
@@ -205,7 +274,7 @@ Option::Option(size_t key_, std::string name_, std::vector<std::string> options_
widgetOptions =
std::make_shared<UIWidgets::IntSliderOptions>(UIWidgets::IntSliderOptions()
.DefaultValue(defaultOption)
.Tooltip(description.c_str())
.Tooltip(this->GetDescription())
.Min(0)
.Max(static_cast<int32_t>(options.size() - 1))
.Format(options[defaultOption].c_str())
@@ -218,13 +287,13 @@ Option::Option(size_t key_, std::string name_, std::vector<std::string> options_
}
void Option::AddWidget(WidgetPath& path) {
auto widget = SohGui::mSohMenu->AddWidget(path, name + "##Randomizer", widgetType)
auto widget = SohGui::mSohMenu->AddWidget(path, this->GetName() + "##Randomizer", widgetType)
.Callback(callback)
.PreFunc([this](WidgetInfo& info) {
info.isHidden = this->IsHidden();
info.options->disabled = this->disabled;
info.options->disabledTooltip = this->disabledText.c_str();
info.options->tooltip = this->description.c_str();
info.options->tooltip = this->GetDescription();
if (info.type == WIDGET_CVAR_SLIDER_INT) {
UIWidgets::IntSliderOptions* sliderOpts =
(UIWidgets::IntSliderOptions*)info.options.get();
@@ -266,8 +335,8 @@ void Option::RunCallback() {
}
}
LocationOption::LocationOption(RandomizerCheck key_, const std::string& name_)
: Option(key_, name_, { "Included", "Excluded" }, OptionCategory::Setting, "", "", WIDGET_CVAR_CHECKBOX,
LocationOption::LocationOption(RandomizerCheck key_)
: Option(key_, { "Included", "Excluded" }, OptionCategory::LocationExclusion, "", WIDGET_CVAR_CHECKBOX,
RO_LOCATION_INCLUDE, false, nullptr, IMFLAG_NONE) {
}
@@ -275,36 +344,10 @@ RandomizerCheck LocationOption::GetKey() const {
return static_cast<RandomizerCheck>(key);
}
#define RANDO_ENUM_ITEM(enum) { enum, #enum },
std::unordered_map<RandomizerTrick, std::string> trickNames = {
#include "randomizerEnums/RandomizerTrick.h"
};
#undef RANDO_ENUM_ITEM
const static std::string trickPrefix = "randomizer.tricks.";
static std::string MakeTrickName(RandomizerTrick key) {
const static std::string namePostfix = ".name";
std::string trickNamePart = trickNames[key].substr(3);
std::transform(trickNamePart.begin(), trickNamePart.end(), trickNamePart.begin(), ::tolower);
return Lang::Translate((trickPrefix + trickNamePart + namePostfix).c_str());
}
static std::string MakeTrickDescription(RandomizerTrick key) {
const static std::string descriptionPostfix = ".description";
std::string trickNamePart = trickNames[key].substr(3);
std::transform(trickNamePart.begin(), trickNamePart.end(), trickNamePart.begin(), ::tolower);
return Lang::Translate((trickPrefix + trickNamePart + descriptionPostfix).c_str());
}
TrickSetting::TrickSetting(RandomizerTrick key_, const RandomizerCheckQuest quest_, const RandomizerArea area_,
std::set<Tricks::Tag> tags_, const std::string nameTag_)
: Option(key_, MakeTrickName(key_), { "Disabled", "Enabled" }, OptionCategory::Setting, "",
MakeTrickDescription(key_), WIDGET_CVAR_CHECKBOX, 0, false, nullptr, IMFLAG_NONE),
: Option(key_, { "Disabled", "Enabled" }, OptionCategory::Trick, "", WIDGET_CVAR_CHECKBOX, 0, false, nullptr,
IMFLAG_NONE),
mQuest(quest_), mArea(area_), mNameTag(nameTag_), mTags(std::move(tags_)) {
}
+16 -37
View File
@@ -26,8 +26,10 @@ enum ImGuiMenuFlags {
enum class OptionCategory {
Setting, /** An option that typically affects the logic/item pool/etc. of the seed. Typically gets written out to
the spoiler file. */
Toggle, /** An option that typically affects other options rather than affecting the seed directly. i.e. A toggle
for randomizing the values of other options. */
Trick, /** A trick option */
LocationExclusion, /** A location exclusion option */
Toggle, /** An option that typically affects other options rather than affecting the seed directly. i.e. A toggle
for randomizing the values of other options. */
};
class OptionValue {
@@ -96,14 +98,11 @@ class Option {
* @brief Constructs a boolean option. This overload of this function typically requires more
* options to be specified rather than left as default.
*
* @param name_ The name of the option. Appears in the spoiler/patch file.
* @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 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 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.
* @param defaultOption_ The default index that should be selected.
@@ -111,11 +110,10 @@ class Option {
* @param imFlags_ (see ImGuiMenuFlags type) flags that can modify how this option is rendered.
* @return Option
*/
static Option Bool(RandomizerSettingKey key_, std::string name_,
std::vector<std::string> options_ = { "Off", "On" },
static Option Bool(RandomizerSettingKey key_, std::vector<std::string> options_ = { "Off", "On" },
OptionCategory category_ = OptionCategory::Setting, std::string cvarName_ = "",
std::string description_ = "", WidgetType widgetType_ = WIDGET_CVAR_CHECKBOX,
uint8_t defaultOption_ = 0, bool defaultHidden_ = false, WidgetFunc callback_ = nullptr,
WidgetType widgetType_ = WIDGET_CVAR_CHECKBOX, uint8_t defaultOption_ = 0,
bool defaultHidden_ = false, WidgetFunc callback_ = nullptr,
int imFlags_ = IMFLAG_SEPARATOR_BOTTOM);
/**
@@ -125,19 +123,15 @@ class Option {
* when using this overload. If you want your option to have different value names, use the other overload.
*
* @param key_ The RandomizerSettingKey of this option.
* @param name_ The name of the option. Appears in the spoiler/patch file.
* @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 tooltip in ImGui.
* Can be left as an empty string if desired, no tooltip will be rendered.
* @param imFlags_ (see ImGuiMenuFlags type) flags that can modify how this option is rendered.
* @param widgetType_ What type of widget should be rendered. Should probably be `Checkbox` but technically
* `Combobox` or `Slider` would render and function correctly.
* @param defaultOption_ The defaulted selected index for this Option.
* @return Option
*/
static Option Bool(RandomizerSettingKey key_, std::string name_, std::string cvarName_,
std::string description_ = "", int imFlags_ = IMFLAG_SEPARATOR_BOTTOM,
static Option Bool(RandomizerSettingKey key_, std::string cvarName_, int imFlags_ = IMFLAG_SEPARATOR_BOTTOM,
WidgetType widgetType_ = WIDGET_CVAR_CHECKBOX, bool defaultOption_ = false,
WidgetFunc callback_ = nullptr);
@@ -145,14 +139,11 @@ class Option {
* @brief Constructs a U8 Option.
*
* @param key_ The RandomizerSettingKey for this option.
* @param name_ The name of this Option. Appears in the spoiler/patch file.
* @param options_ A vector of value names for this Option. 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
* link to any Cvar.
* @param description_ A description of what this option affects. Will be rendered in a toolip 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. Defaults to `Combobox`, but if you use NumOpts
* to make the `options_` vector you should probably set this to `Slider`. `Slider` will technically work for
* any value of `options_` but may be odd/unclear semantically speaking.
@@ -162,20 +153,12 @@ class Option {
* @param imFlags_ (see ImGuiMenuFlags type) flags that can modify how this option is rendered.
* @return Option
*/
static Option U8(RandomizerSettingKey key_, std::string name_, std::vector<std::string> options_,
static Option U8(RandomizerSettingKey key_, std::vector<std::string> options_,
OptionCategory category_ = OptionCategory::Setting, std::string cvarName_ = "",
std::string description_ = "", WidgetType widgetType_ = WIDGET_CVAR_COMBOBOX,
uint8_t defaultOption_ = 0, bool defaultHidden_ = false, WidgetFunc callback_ = nullptr,
WidgetType widgetType_ = WIDGET_CVAR_COMBOBOX, uint8_t defaultOption_ = 0,
bool defaultHidden_ = false, WidgetFunc callback_ = nullptr,
int imFlags_ = IMFLAG_SEPARATOR_BOTTOM);
/**
* @brief A convenience function for constructing the Option for a trick.
*
* @param name_ The name of the trick. Appears in the spoiler/patch file.
* @return Option
*/
static Option LogicTrick(RandomizerTrick rt_, std::string name_);
/**
* @brief Get the size of the options array.
*
@@ -280,11 +263,10 @@ class Option {
* the option is "Disabled".
*
* @param text The tooltip text explaining why the option is disabled.
* @param graphic What graphic to display in a disabled checkbox. Defaults to an
* "X" symbol.
*/
void Disable(std::string text);
bool IsCategory(OptionCategory category) const;
OptionCategory GetCategory() const;
void AddWidget(WidgetPath& path);
@@ -297,20 +279,17 @@ class Option {
void RunCallback();
protected:
Option(size_t key_, std::string name_, std::vector<std::string> options_, OptionCategory category_,
std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_,
bool defaultHidden_, WidgetFunc callback_, int imFlags_);
Option(size_t key_, std::vector<std::string> options_, OptionCategory category_, std::string cvarName_,
WidgetType widgetType_, uint8_t defaultOption_, bool defaultHidden_, WidgetFunc callback_, int imFlags_);
size_t key;
private:
void PopulateTextToNum();
std::string name;
std::vector<std::string> options;
uint8_t contextSelection = 0;
bool hidden = false;
OptionCategory category = OptionCategory::Setting;
std::string cvarName;
std::string description;
WidgetType widgetType;
uint8_t defaultOption = false;
bool defaultHidden = false;
@@ -327,7 +306,7 @@ class Option {
class LocationOption : public Option {
public:
LocationOption() = default;
LocationOption(RandomizerCheck key_, const std::string& name_);
LocationOption(RandomizerCheck key_);
RandomizerCheck GetKey() const;
};
@@ -1,896 +0,0 @@
#include "settings.h"
namespace Rando {
void Settings::CreateOptionDescriptions() {
mOptionDescriptions[RSK_FOREST] =
"Determines if Kokiri Forest can be left for the Lost Woods bridge or the Deku Tree.\n"
"\n"
"On - Kokiri Sword & Deku Shield are required to access "
"the Deku Tree, and completing the Deku Tree is required to "
"access the Lost Woods Bridge Exit.\n"
"\n"
"Deku Only - Kokiri boy no longer blocks the path to the Bridge "
"but Mido still requires the Kokiri Sword and Deku Shield "
"to access the tree.\n"
"\n"
"Off - Mido no longer blocks the path to the Deku Tree. Kokiri "
"boy no longer blocks the path out of the forest.";
mOptionDescriptions[RSK_DOOR_OF_TIME] = "Closed - The Ocarina of Time, the Song of Time and all "
"three Spiritual Stones are required to open the Door of Time.\n"
"\n"
"Song only - Play the Song of Time in front of the Door of "
"Time to open it.\n"
"\n"
"Open - The Door of Time is permanently open with no requirements.";
mOptionDescriptions[RSK_ZORAS_FOUNTAIN] = "Closed - King Zora obstructs the way to Zora's Fountain. "
"Ruto's Letter must be shown as child Link in order to move "
"him in both time periods.\n"
"\n"
"Closed as child - Ruto's Letter is only required to move King Zora "
"as child Link. Zora's Fountain starts open as adult.\n"
"\n"
"Open - King Zora has already mweeped out of the way in both "
"time periods. Ruto's Letter is removed from the item pool.";
mOptionDescriptions[RSK_SLEEPING_WATERFALL] = "Closed - Sleeping Waterfall obstructs the entrance to Zora's "
"Domain. Zelda's Lullaby must be played in order to open it "
"(but only once; then it stays open in both time periods).\n"
"\n"
"Open - Sleeping Waterfall is always open. "
"Link may always enter Zora's Domain.";
mOptionDescriptions[RSK_JABU_OPEN] = "Closed - A fish is required to open Jabu-Jabu's mouth.\n\n"
"Open - Jabu-Jabu's mouth opens without the need for a fish.";
mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS] =
"Add locks to all wooden overworld doors, requiring specific small keys to open them";
mOptionDescriptions[RSK_STARTING_AGE] =
"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 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"
"Free - Bridge is repaired from 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 Keyrings.";
mOptionDescriptions[RSK_RAINBOW_BRIDGE] =
"Alters the requirements to open the bridge to Ganon's Castle.\n"
"\n"
"Vanilla - Obtain the Shadow Medallion, Spirit Medallion and Light Arrows.\n"
"\n"
"Always open - No requirements.\n"
"\n"
"Stones - Obtain the specified amount of Spiritual Stones.\n"
"\n"
"Medallions - Obtain the specified amount of medallions.\n"
"\n"
"Dungeon rewards - Obtain the specified total sum of Spiritual "
"Stones or medallions.\n"
"\n"
"Dungeons - Complete the specified amount of dungeons. Dungeons "
"are considered complete after stepping into the blue warp after "
"the boss.\n"
"\n"
"Tokens - Obtain the specified amount of Skulltula tokens.\n"
"\n"
"Greg - Find Greg the Green Rupee.";
mOptionDescriptions[RSK_BRIDGE_OPTIONS] =
"Standard Rewards - Greg does not change logic, Greg does not help open the bridge, max "
"number of rewards on slider does not change.\n"
"\n"
"Greg as Reward - Greg does change logic (can be part of expected path for opening "
"bridge), Greg helps open bridge, max number of rewards on slider increases by 1 to "
"account for Greg.\n"
"\n"
"Greg as Wildcard - Greg does not change logic, Greg helps open the bridge, max number of "
"rewards on slider does not change.";
mOptionDescriptions[RSK_GANONS_TRIALS] =
"Sets the number of Ganon's Trials required to dispel the barrier.\n"
"\n"
"Skip - No Trials are required and the barrier is already dispelled.\n"
"\n"
"Set Number - Select a number of trials that will be required from the "
"slider below. Which specific trials you need to complete will be random.\n"
"\n"
"Random Number - A random number and set of trials will be required.";
mOptionDescriptions[RSK_TRIAL_COUNT] = "Set the number of trials required to enter Ganon's Tower.";
mOptionDescriptions[RSK_MEDALLION_LOCKED_TRIALS] =
"Doors to trials will be barred until their corresponding medallion is acquired.";
mOptionDescriptions[RSK_MQ_DUNGEON_RANDOM] =
"Sets the number of Master Quest Dungeons that are shuffled into the pool.\n"
"\n"
"None - All Dungeons will be their Vanilla versions.\n"
"\n"
"Set Number - Select a number of dungeons that will be their Master Quest versions "
"using the slider below. Which dungeons are set to be the Master Quest variety will be random.\n"
"\n"
"Random Number - A random number and set of dungeons will be their Master Quest varieties.\n"
"\n"
"Selection Only - Specify which dungeons are Vanilla, Master Quest or a 50/50 between the two.\n"
"Differs from Random Number in that they are rolled individually, making the exact total a bell curve.";
mOptionDescriptions[RSK_MQ_DUNGEON_SET] =
"Choose specific Dungeons to be Master Quest or Vanilla.\n"
"\n"
"If Master Quest Dungeons is set to Set Number or Random, the dungeons chosen "
"to be Master Quest here will count towards that total. Any Dungeons set to Vanilla "
"here will be guaranteed to be Vanilla. If Set Number is higher than the number of dungeons "
"set to either MQ or Random here, you will have fewer MQ Dungeons than the number you "
"set.";
mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL] =
"The number of Triforce pieces that will be placed in the world. Set to 0 to disable Triforce Hunt.\n"
"\n"
"Triforce Pieces can be used as a requirement for the Rainbow Bridge, Ganon's Boss Key, Ganon's Soul, or the "
"win condition. Keep in mind seed generation can fail if more pieces are placed than there are junk items in "
"the item pool.";
mOptionDescriptions[RSK_WINCON_TRIFORCE_COUNT] = "The number of Triforce pieces required to win the game.";
mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_LOCATION] =
"Any dungeon - Triforce pieces can only appear inside of any dungeon.\n"
"\n"
"Overworld - Triforce pieces can only appear outside of dungeons.\n"
"\n"
"Anywhere - Triforce pieces can appear anywhere in the world.";
mOptionDescriptions[RSK_SHUFFLE_DUNGEON_ENTRANCES] =
"Shuffle the pool of dungeon entrances, including Bottom of the Well, Ice Cavern and Gerudo Training Ground.\n"
"\n"
"Shuffling Ganon's Castle can be enabled separately.\n"
"\n"
"Additionally, the entrances of Deku Tree, Fire Temple, Bottom of the Well and Gerudo Training Ground are "
"opened for both child and adult.\n"
"\n"
"- Deku Tree will be open for adult after Mido has seen child Link with a sword and a shield.\n"
"- Bottom of the Well will be open for adult after playing Song of Storms to the Windmill guy as child.\n"
"- Gerudo Training Ground will be open for child after adult has paid to open the gate once.";
mOptionDescriptions[RSK_SHUFFLE_BOSS_ENTRANCES] =
"Shuffle the pool of dungeon boss entrances. This affects the boss rooms of all stone and medallion dungeons.\n"
"\n"
"Age Restricted - Shuffle the entrances of child and adult boss rooms separately.\n"
"\n"
"Full - Shuffle the entrances of all boss rooms together. Child may be expected to defeat Phantom Ganon and/or "
"Bongo Bongo.";
mOptionDescriptions[RSK_SHUFFLE_GANONS_TOWER_ENTRANCE] =
"Shuffle the entrance from Ganon's Castle to Ganon's Tower into the pool of boss entrances.";
mOptionDescriptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES] =
"Shuffle the pool of Overworld entrances, which corresponds to almost all loading zones between overworld "
"areas.\n"
"\n"
"Some entrances are unshuffled to avoid issues:\n"
"- Hyrule Castle Courtyard and Garden entrance\n"
"- Both Market Back Alley entrances\n"
"- Gerudo Valley to Lake Hylia (unless entrances are decoupled)";
mOptionDescriptions[RSK_SHUFFLE_INTERIOR_ENTRANCES] =
"Shuffle the pool of interior entrances which contains most Houses and all Great Fairies.\n"
"\n"
"All - An extended version of 'Simple' with some extra places:\n"
"- Windmill\n"
"- Link's House\n"
"- Temple of Time\n"
"- Kakariko Potion Shop";
mOptionDescriptions[RSK_SHUFFLE_THIEVES_HIDEOUT_ENTRANCES] =
"Shuffle the pool of entrances between Gerudo Fortress & Thieves' Hideout.";
mOptionDescriptions[RSK_SHUFFLE_GROTTO_ENTRANCES] =
"Shuffle the pool of grotto entrances, including all graves, small Fairy fountains and the Deku Theatre.";
mOptionDescriptions[RSK_SHUFFLE_OWL_DROPS] = "Randomize where Kaepora Gaebora (the Owl) drops you when you talk "
"to him at Lake Hylia or at the top of Death Mountain Trail.";
mOptionDescriptions[RSK_SHUFFLE_WARP_SONGS] = "Randomize where each of the 6 warp songs leads to.";
mOptionDescriptions[RSK_SHUFFLE_OVERWORLD_SPAWNS] =
"Randomize where you start as Child or Adult when loading a save in the Overworld. This "
"means you may not necessarily spawn inside Link's House or Temple of Time.\n"
"\n"
"This stays consistent after saving and loading the game again.\n"
"\n"
"Keep in mind you may need to temporarily disable the \"Remember Save Location\" time saver to "
"be able to use the spawn positions, especially if they are the only logical way to get to certain areas.";
mOptionDescriptions[RSK_DECOUPLED_ENTRANCES] =
"Decouple entrances when shuffling them. This means you are no longer guaranteed "
"to end up back where you came from when you go back through an entrance.\n"
"\n"
"This also adds the one-way entrance from Gerudo Valley to Lake Hylia in the pool of "
"overworld entrances when they are shuffled.";
mOptionDescriptions[RSK_MIXED_ENTRANCE_POOLS] =
"Shuffle entrances into a mixed pool instead of separate ones. Has no effect on pools whose "
"entrances aren't shuffled, and \"Shuffle Boss Entrances\" must be set to \"Full\" to include them.\n"
"\n"
"For example, enabling the settings to shuffle grotto, dungeon, and overworld entrances and "
"selecting grotto and dungeon entrances here will allow a dungeon to be inside a grotto or "
"vice versa, while overworld entrances are shuffled in their own separate pool and indoors stay vanilla.";
mOptionDescriptions[RSK_MIX_DUNGEON_ENTRANCES] = "Dungeon entrances will be part of the mixed pool.";
mOptionDescriptions[RSK_MIX_BOSS_ENTRANCES] = "Boss entrances will be part of the mixed pool.";
mOptionDescriptions[RSK_MIX_OVERWORLD_ENTRANCES] = "Overworld entrances will be part of the mixed pool.";
mOptionDescriptions[RSK_MIX_INTERIOR_ENTRANCES] = "Interior entrances will be part of the mixed pool.";
mOptionDescriptions[RSK_MIX_GROTTO_ENTRANCES] = "Grotto entrances will be part of the mixed pool.";
mOptionDescriptions[RSK_SHUFFLE_SONGS] =
"Off - Songs will appear at their vanilla locations.\n"
"\n"
"Song locations - Songs will only appear at locations that normally teach songs.\n"
"\n"
"Dungeon rewards - Songs appear after beating a major dungeon boss.\n"
"The 4 remaining songs are located at:\n"
" - Zelda's Lullaby location\n"
" - Ice Cavern's Serenade of Water location\n"
" - Bottom of the Well Lens of Truth location\n"
" - Gerudo Training Ground's Ice Arrows location\n"
"\n"
"Anywhere - Songs can appear at any location.";
mOptionDescriptions[RSK_SHUFFLE_TOKENS] = "Shuffles Golden Skulltula Tokens into the item pool. This means "
"Golden Skulltulas can contain other items as well.\n"
"\n"
"Off - GS tokens will not be shuffled.\n"
"\n"
"Dungeons - Only shuffle GS tokens that are within dungeons.\n"
"\n"
"Overworld - Only shuffle GS tokens that are outside of dungeons.\n"
"\n"
"All Tokens - Shuffle all 100 GS tokens.";
mOptionDescriptions[RSK_SKULLS_SUNS_SONG] = "All Golden Skulltulas that require nighttime to appear will only be "
"expected to be collected after getting Sun's Song.";
mOptionDescriptions[RSK_SHUFFLE_KOKIRI_SWORD] =
"Shuffles the Kokiri Sword into the item pool.\n"
"\n"
"This will require the use of sticks until the Kokiri Sword is found.";
mOptionDescriptions[RSK_SHUFFLE_MASTER_SWORD] =
"Shuffles the Master Sword into the item pool.\n"
"\n"
"Adult Link will start with a second free item instead of the Master Sword.\n"
"If you haven't found the Master Sword before facing Ganon, you won't receive it during the fight.";
mOptionDescriptions[RSK_SWORDLESS_EPONA_ITEMS] =
"Restores the vanilla glitch that lets a swordless player use C-button items (bottles, bombs, "
"magic, etc.) while riding Epona.\n"
"\n"
"When disabled, the B button is forced to the bow and the C buttons are disabled while swordless "
"on Epona, blocking the glitch.";
mOptionDescriptions[RSK_SHUFFLE_CHILD_WALLET] = "Enabling this shuffles the Child's Wallet into the item pool.\n"
"\n"
"You will not be able to carry any rupees until you find a wallet.";
mOptionDescriptions[RSK_INCLUDE_TYCOON_WALLET] = "Enabling this adds an extra Progressive Wallet to the pool and "
"adds a new 999 capacity tier after Giant's Wallet.\n";
mOptionDescriptions[RSK_SHUFFLE_OCARINA] =
"Enabling this shuffles the Fairy Ocarina and the Ocarina of Time into the item pool.\n"
"\n"
"This will require finding an Ocarina before being able to play songs.";
mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS] =
"Enabling this shuffles the Ocarina buttons into the item pool.\n"
"\n"
"This will require finding the buttons before being able to use them in songs.";
mOptionDescriptions[RSK_SHUFFLE_SWIM] =
"Shuffles the ability to Swim into the item pool as a progressive upgrade before Silver Scale.\n"
"The ability to swim has to be found as an item (you can still be underwater with iron boots).\n"
"\n"
"If you enter a water entrance without swim you will be respawned on land to prevent infinite death loops.\n"
"If you void out in the Water Temple you will immediately be kicked out to prevent a softlock.";
mOptionDescriptions[RSK_SHUFFLE_GRAB] =
"Shuffle the ability to grab as a progressive upgrade before Goron Bracelet.";
mOptionDescriptions[RSK_SHUFFLE_CLIMB] = "Shuffle the ability to climb ladders into the item pool.";
mOptionDescriptions[RSK_SHUFFLE_CRAWL] = "Shuffles the ability to use crawlspaces into the item pool.";
mOptionDescriptions[RSK_SHUFFLE_SPEAK] =
"Shuffle the ability to speak to NPCs. 6 jabbernuts will be shuffled:\nDeku, Gerudo, Goron, Hylian, Kokiri, "
"Zora\nKaepora Gaebora speaks any language.";
mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST] =
"Shuffles the ability to open chests into the item pool.\n"
"\n"
"Progressive shuffles two copies: first only opens small chests, second also opens big chests.";
mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG] =
"Vanilla: Malon gives the Weird Egg at Hyrule Castle.\n"
"\n"
"Shuffled: shuffles Weird Egg into item pool.\n"
"\n"
"Skip Waking Talon: Talon is already awake and back at Lon Lon Ranch with Malon.";
mOptionDescriptions[RSK_SHUFFLE_ZELDAS_LETTER] =
"Shuffles Zelda's Letter into the item pool; meeting Zelda gives a random item instead.\n"
"\n"
"Required to open the Kakariko gate and Happy Mask Shop. Starting with the letter starts with the gate "
"opened.\n"
"\n"
"Meeting Zelda still triggers Saria at Sacred Forest Meadow.\n"
"\n"
"When disabled, \"Start with Zelda's Letter\" skips child Zelda: you also get the item Impa would give.";
mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD] =
"Shuffles the Gerudo Membership Card into the item pool.\n"
"\n"
"The Gerudo Card is required to enter the Gerudo Training Ground, opening "
"the gate to Haunted Wasteland and the Horseback Archery minigame.";
mOptionDescriptions[RSK_SHUFFLE_POTS] =
"Pots will drop a randomized item the first time they're broken and collected. This does not include the "
"flying pots."
" Pots will have a different appearance when they hold a randomized item.\n"
"With this option enabled, Ganon's Boss Key door is moved further up the stairs to\n"
"allow access to the pots before obtaining Ganon's Boss Key.\n"
"\n"
"Off - Pots will not be shuffled.\n"
"\n"
"Dungeons - Only shuffle pots that are within dungeons.\n"
"\n"
"Overworld - Only shuffle pots that are outside of dungeons.\n"
"\n"
"All pots - Shuffle all pots.";
mOptionDescriptions[RSK_SHUFFLE_CRATES] =
"Crates will drop a randomized item the first time they're broken and collected. "
"Crates will have a different appearance when they hold a randomized item.\n"
"\n"
"Off - Crates will not be shuffled.\n"
"\n"
"Dungeons - Only shuffle crates that are within dungeons.\n"
"\n"
"Overworld - Only shuffle crates that are outside of dungeons.\n"
"\n"
"All Crates - Shuffle all crates.";
mOptionDescriptions[RSK_SHUFFLE_TREES] =
"Trees will contain randomized items which are dropped the first time the player rolls into one.\n"
"Trees will have a special appearance when carrying randomized items.\n"
"\nSome trees are dependent on Link's age, such as some trees in Hyrule Field.\nTwo trees at Hyrule Castle are "
"only shuffled with No Logic.";
mOptionDescriptions[RSK_SHUFFLE_BUSHES] =
"Bushes in Hyrule Field & Zora's Fountain will contain randomized items when first walked through.";
mOptionDescriptions[RSK_SHUFFLE_ICICLES] =
"Stalagmites and stalactites in the Ice Cavern and Ganon's Castle will contain randomized items when broken.\n"
"Icicles will have a halo around them when carrying randomized items.";
mOptionDescriptions[RSK_SHUFFLE_RED_ICE] =
"Red Ice will give randomized items when melted.\n"
"Red Ice will have a particle effect inside it when it holds a randomized item";
mOptionDescriptions[RSK_SHUFFLE_SIGNS] = "Signs and readable pedestals, plinths, altars, and graves will grant a "
"randomized item the first time they are read. "
"Signs will have a particle effect when they hold a randomized item.\n"
"\n"
"Off - Signs will not be shuffled.\n"
"\n"
"Dungeons - Only shuffle signs that are within dungeons.\n"
"\n"
"Overworld - Only shuffle signs that are outside of dungeons.\n"
"\n"
"All Signs - Shuffle all signs.";
mOptionDescriptions[RSK_SHUFFLE_WONDER_ITEMS] =
"Wonder items will drop a randomized item the first time they're collected. "
"Wonder items will be marked with swirling particles.\n"
"\n"
"Off - Wonder items will not be shuffled.\n"
"\n"
"Dungeons - Only shuffle wonder items that are within dungeons.\n"
"\n"
"Overworld - Only shuffle wonder items that are outside of dungeons.\n"
"\n"
"All Wonder Items - Shuffle all wonder items.";
mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE] = "Shuffles the fishing pole into the item pool.\n"
"\n"
"The fishing pole is required to play the fishing pond minigame.";
mOptionDescriptions[RSK_INFINITE_UPGRADES] =
"Adds upgrades that hold infinite quantities of items (bombs, arrows, etc.).\n"
"\n"
"Progressive - The infinite upgrades are obtained after getting the last normal capacity upgrade.\n"
"\n"
"Condensed Progressive - The infinite upgrades are obtained as the first capacity upgrade (doesn't apply to "
"the infinite wallet or to infinite magic).";
mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG] = "Shuffles the Deku Stick bag into the item pool.\n"
"\n"
"The Deku Stick bag is required to hold Deku Sticks.";
mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG] = "Shuffles the Deku Nut bag into the item pool.\n"
"\n"
"The Deku Nut bag is required to hold Deku Nuts.";
mOptionDescriptions[RSK_SHOPSANITY] =
"Off - All shop items will be the same as vanilla.\n"
"\n"
"Specific Count - Vanilla shop items will be shuffled among different shops, and "
"each shop will contain a specific number (0-7) of non-vanilla shop items.\n"
"\n"
"Random - Vanilla shop items will be shuffled among different shops, and "
"each shop will contain a random number (1-7) of non-vanilla shop items.";
mOptionDescriptions[RSK_SHOPSANITY_COUNT] =
"0 Items - Vanilla shop items will be shuffled among different shops.\n"
"\n"
"1-7 Items - Vanilla shop items will be shuffled among different shops, and "
"each shop will contain 1-7 non-vanilla shop items.\n"
"\n"
"8 Items - All shops will contain 8 non-vanilla shop items. "
"Only available with No Logic, since logic otherwise requires at least one buyable refill per shop.\n";
mOptionDescriptions[RSK_SHOPSANITY_PRICES] =
"Vanilla - The same price as the item it replaced.\n"
"Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers.\n"
"Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers.\n"
"Fixed - A fixed number.\n"
"Range - A random point between specific ranges.\n"
"Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if "
"that wallet is chosen.";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE] = "The price for Shopsanity checks.";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_1] =
"The first part of the inclusive range of prices to allow for Shopsanity checks.";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_2] =
"The second part of the inclusive range of prices to allow for Shopsanity checks.";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT] = "The chance for Shopsanity checks to be free.";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT] =
"The chance for Shopsanity checks to be purchasable with Child's Wallet (1-99).";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT] =
"The chance for Shopsanity checks to be purchasable with Adult's Wallet (100-200).";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT] =
"The chance for Shopsanity checks to be purchasable with Giant's Wallet (201-500).";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT] =
"The chance for Shopsanity checks to be purchasable with Tycoon Wallet (500+).";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE] =
"After choosing a price, set it to the affordable amount based on the wallet required.\n\n"
"Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n"
"Use this to enable wallet tier locking, but make shop items not as expensive as they could be.";
mOptionDescriptions[RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL] =
"Non-randomized shields and tunics sold in shops cannot be purchased until you have first found a shield "
"elsewhere. "
"Regions containing a shield or tunic will not be hinted foolish.";
mOptionDescriptions[RSK_FISHSANITY] =
"Off - Fish will not be shuffled. No changes will be made to fishing behavior.\n\n"
"Shuffle only Hyrule Loach - Allows you to earn an item by catching the Hyrule Loach at the fishing pond and "
"giving it to the owner.\n\n"
"Shuffle Fishing Pond - The fishing pond's fish will be shuffled. Catching a fish in the fishing pond will "
"grant a reward.\n\n"
"Shuffle Overworld Fish - Fish in generic grottos and Zora's Domain will be shuffled. Catching a fish in a "
"bottle will give a reward.\n\n"
"Shuffle Both - Both overworld fish and fish in the fishing pond will be shuffled.";
mOptionDescriptions[RSK_FISHSANITY_POND_COUNT] =
"The number of fish to randomize in the fishing pool.\n\n"
"If set to maximum, each fish will have a unique check, including a Hyrule Loach which appears only as child, "
"and "
"uncaught fish will be given a visual indicator to distinguish from already-caught fish.\n\n"
"Otherwise, any fish caught in the pond will give a reward, until all rewards have been given.";
mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT] =
"Enabling this will split the fishing pond fish by age, making fishing pond fish grant different rewards as "
"child and adult.\n\n"
"If disabled, then the child pond will be shuffled and shared between both ages.\n\n"
"Note that, as child, there is a second loach available in the pond!";
mOptionDescriptions[RSK_SHUFFLE_SCRUBS] =
"Off - Scrubs will not be shuffled. The 3 Scrubs that give one-time items in the "
"vanilla game (PoH, Deku Nut capacity, and Deku Stick capacity) will not spawn.\n"
"\n"
"One-Time Only - Only the 3 Scrubs that give one-time items in the "
"vanilla game are shuffled.\n"
"\n"
"All - All Scrubs are shuffled.";
mOptionDescriptions[RSK_SCRUBS_PRICES] =
"Vanilla - The same price as the item it replaced.\n"
"Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers.\n"
"Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers.\n"
"Fixed - A fixed number.\n"
"Range - A random point between specific ranges.\n"
"Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if "
"that wallet is chosen.";
mOptionDescriptions[RSK_SCRUBS_PRICES_FIXED_PRICE] = "The price for Scrub checks.";
mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_1] =
"The first part of the inclusive range of prices to allow for Scrub checks.";
mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_2] =
"The second part of the inclusive range of prices to allow for Scrub checks.";
mOptionDescriptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT] = "The chance for Scrub checks to be free.";
mOptionDescriptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT] =
"The chance for Scrub checks to be purchasable with Child's Wallet (1-99).";
mOptionDescriptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT] =
"The chance for Scrub checks to be purchasable with Adult's Wallet (100-200).";
mOptionDescriptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT] =
"The chance for Scrub checks to be purchasable with Giant's Wallet (201-500).";
mOptionDescriptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT] =
"The chance for Scrub checks to be purchasable with Tycoon Wallet (500+).";
mOptionDescriptions[RSK_SCRUBS_PRICES_AFFORDABLE] =
"After choosing a price, set it to the affordable amount based on the wallet required.\n\n"
"Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n"
"Use this to enable wallet tier locking, but make scrub items not as expensive as they could be.";
mOptionDescriptions[RSK_SHUFFLE_BEEHIVES] = "Beehives give a randomized item from the pool when broken.";
mOptionDescriptions[RSK_SHUFFLE_COWS] =
"Cows give a randomized item from the pool upon performing Epona's Song in front of them.";
mOptionDescriptions[RSK_SHUFFLE_MERCHANTS] =
"This setting governs if the Bean Salesman, Medigoron, Granny and the Carpet Salesman "
"sell a random item.\n"
"Beans Only - Only the Bean Salesman will have a check, and a pack of Magic Beans will be added "
"to the item pool.\n"
"All But Beans - Medigoron, Granny and the Carpet Salesman will have checks, "
"a Giant's Knife and a pack of Bombchus will be added to the item pool, and "
"one of the bottles will contain a Blue Potion.\n"
"All - Apply both effects.\n"
"\n"
"Granny's item will only be offered after you have traded in the Odd Mushroom when Shuffle Adult Trade is on. "
"Otherwise when off, you will need to have found the Claim Check to buy her item (simulating that the trade "
"quest "
"is complete).";
mOptionDescriptions[RSK_MERCHANT_PRICES] =
"Vanilla - The same price as the Check in vanilla, 60 for the Bean Salesman.\n"
"Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers.\n"
"Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers.\n"
"Fixed - A fixed number.\n"
"Range - A random point between specific ranges.\n"
"Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if "
"that wallet is chosen.";
mOptionDescriptions[RSK_MERCHANT_PRICES_FIXED_PRICE] = "The price for Merchant checks.";
mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_1] =
"The first part of the inclusive range of prices to allow for Merchant checks.";
mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_2] =
"The second part of the inclusive range of prices to allow for Merchant checks.";
mOptionDescriptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT] = "The chance for Merchant checks to be free.";
mOptionDescriptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT] =
"The chance for Merchant checks to be purchasable with Child's Wallet (1-99).";
mOptionDescriptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT] =
"The chance for Merchant checks to be purchasable with Adult's Wallet (100-200).";
mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT] =
"The chance for Merchant checks to be purchasable with Giant's Wallet (201-500).";
mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT] =
"The chance for Merchant checks to be purchasable with Tycoon Wallet (500+).";
mOptionDescriptions[RSK_MERCHANT_PRICES_AFFORDABLE] =
"After choosing a price, set it to the affordable amount based on the wallet required.\n\n"
"Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n"
"Use this to enable wallet tier locking, but make merchant items not as expensive as they could be.";
mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES] = "Shuffles 5 Purple Rupees into the item pool, and allows\n"
"you to earn items by playing songs at the Frog Choir.\n"
"\n"
"This setting does not affect the item earned from playing\n"
"the Song of Storms and the frog song minigame.";
mOptionDescriptions[RSK_SHUFFLE_BEGGAR] =
"Shuffle the rewards the Beggar gives for selling bugs, fish, and Blue Fire.\n"
"The Beggar will give separate rewards to child and adult.";
mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE] =
"Adds all of the adult trade quest items into the pool, each of which "
"can be traded for a unique reward.\n"
"\n"
"You will be able to choose which of your owned adult trade items is visible "
"in the inventory by selecting the item with A and using the control stick or "
"D-pad.\n"
"\n"
"If disabled, only the Claim Check will be found in the pool.";
mOptionDescriptions[RSK_SHUFFLE_CHEST_MINIGAME] =
"Shuffles the contents of the Market Treasure Chest Game, including the item you pay "
"the host for. Both chests in every room can be opened, and the locked doors are opened "
"with keys found elsewhere instead of keys won in the game.\n"
"\n"
"Six Chest Game Small Keys are added to the pool, or a single keyring holding all six "
"if the Chest Minigame Keyring is selected under Keyrings.";
mOptionDescriptions[RSK_EARLY_GRANNYS_SHOP] =
"Makes Granny's Potion Shop available from start, rather than requiring the Claim Check to be found first.\n"
"\n"
"This only applies when Shuffle Adult Trade is disabled. With Shuffle Adult "
"Trade enabled, Granny still requires trading the Odd Mushroom as usual.";
mOptionDescriptions[RSK_SHUFFLE_100_GS_REWARD] =
"Shuffle the item the cursed rich man in the House of Skulltula gives when you "
"have collected all 100 Gold Skulltula Tokens.\n"
"\n"
"You can still talk to him multiple times to get Huge Rupees.";
mOptionDescriptions[RSK_SHUFFLE_FREESTANDING] =
"Freestanding rupees & hearts are shuffled into random items. "
"Freestanding heart pieces and small keys are already shuffled by default.\n"
"\n"
"Off - freestanding rupees & hearts will not be shuffled.\n"
"\n"
"Dungeons - Only shuffle freestanding rupees & hearts that are within dungeons.\n"
"\n"
"Overworld - Only shuffle freestanding rupees & hearts that are outside of dungeons.\n"
"\n"
"All Items - Shuffle all freestanding rupees & hearts.";
mOptionDescriptions[RSK_SHUFFLE_SILVER] =
"Silver rupees will be shuffled.\n"
"Items will be added to the pool, which completes the silver rupee puzzles,\n"
"while silver rupee locations will be random items.\n"
"Off - Silver rupees won't be shuffled.\n"
"\n"
"On - Silver rupees will be individually spread out.\n"
"\n"
"Wallet - Silver rupees are shuffled as wallets, a single check to set the flag for collecting them.\n"
"\n"
"Start With - Silver rupees are still replaced with items, but all silver rupee flags start set.";
mOptionDescriptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES] =
"Shuffle fairies in fountain locations. "
"This includes the sets of fairies found in Ganon's Castle and the Desert Oasis.";
mOptionDescriptions[RSK_SHUFFLE_STONE_FAIRIES] = "Shuffle fairies from gossip stone locations.";
mOptionDescriptions[RSK_SHUFFLE_BEAN_FAIRIES] = "Shuffle fairies from magic bean locations.";
mOptionDescriptions[RSK_SHUFFLE_SONG_FAIRIES] =
"Shuffle fairy spots. These are spots where a big fairy is revealed by a song."
"\n"
"This excludes gossip stones and magic bean locations.";
mOptionDescriptions[RSK_SHUFFLE_BUTTERFLY_FAIRIES] = "Shuffle fairies from butterfly locations.";
mOptionDescriptions[RSK_SHUFFLE_GRASS] = "Grass will drop a randomized item the first time it's cut and collected. "
"Grass will have a different appearance when it holds a randomized item.\n"
"\n"
"Off - Grass will not be shuffled.\n"
"\n"
"Dungeons - Only shuffle grass that is within dungeons.\n"
"\n"
"Overworld - Only shuffle grass that is outside of dungeons.\n"
"\n"
"All Grass - Shuffle all grass.";
mOptionDescriptions[RSK_SHUFFLE_ROCKS] = "Shuffle rock locations.";
mOptionDescriptions[RSK_SHUFFLE_BOULDERS] = "Shuffle boulder locations.";
mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS] =
"Shuffles the location of Spiritual Stones and medallions.\n"
"Vanilla - Spiritual Stones and medallions will be given by their respective boss.\n"
"\n"
"End of dungeons - Spiritual Stones and medallions will be given as rewards "
"for beating major dungeons. Link will always start with one stone or medallion.\n"
"\n"
"Any dungeon - Spiritual Stones and medallions can be found inside any dungeon.\n"
"\n"
"Overworld - Spiritual Stones and medallions can only be found outside of dungeons.\n"
"\n"
"Anywhere - Spiritual Stones and medallions can appear anywhere.";
mOptionDescriptions[RSK_SHUFFLE_MAPANDCOMPASS] =
"Start with - You will start with Maps & Compasses from all dungeons.\n"
"\n"
"Vanilla - Maps & Compasses will appear in their vanilla locations.\n"
"\n"
"Own dungeon - Maps & Compasses can only appear in their respective dungeon.\n"
"\n"
"Any dungeon - Maps & Compasses can only appear inside of any dungeon.\n"
"\n"
"Overworld - Maps & Compasses can only appear outside of dungeons.\n"
"\n"
"Anywhere - Maps & Compasses can appear anywhere in the world.";
mOptionDescriptions[RSK_KEYSANITY] =
"Start with - You will start with all Small Keys from all dungeons.\n"
"\n"
"Vanilla - Small Keys will appear in their vanilla locations. "
"You start with 3 keys in Spirit Temple MQ because the vanilla key layout is not beatable in logic.\n"
"\n"
"Own dungeon - Small Keys can only appear in their respective dungeon. "
"If Fire Temple is not a Master Quest dungeon, the door to the Boss Key chest will be unlocked.\n"
"\n"
"Any dungeon - Small Keys can only appear inside of any dungeon.\n"
"\n"
"Overworld - Small Keys can only appear outside of dungeons.\n"
"\n"
"Anywhere - Small Keys can appear anywhere in the world.";
mOptionDescriptions[RSK_KEYRINGS] =
"Keyrings will replace all small keys from a particular dungeon with a single keyring that awards all keys for "
"its associated dungeon.\n"
"\n"
"Off - No dungeons will have their keys replaced with keyrings.\n"
"\n"
"Random - A random amount of dungeons will have their keys replaced with keyrings.\n"
"\n"
"Count - A specified amount of randomly selected dungeons will have their keys replaced with keyrings.\n"
"\n"
"Selection - Hand select which dungeons will have their keys replaced with keyrings\n"
"(can also be left as random, in which case each one will have a 50% chance of being a keyring).\n"
"\n"
"Selecting keyring for dungeons will have no effect if Small Keys are set to Start With or Vanilla.\n"
"\n"
"The maximum amount of Keyrings that can be selected by Random or Count is 8, plus one if "
"Gerudo Fortress Carpenters is set to Normal and Gerudo Fortress Keys is set to anything "
"other than Vanilla, plus one if Shuffle Chest Minigame is on.";
mOptionDescriptions[RSK_GERUDO_KEYS] =
"Vanilla - Thieves' Hideout Keys will appear in their vanilla locations.\n"
"\n"
"Any dungeon - Thieves' Hideout Keys can only appear inside of any dungeon.\n"
"\n"
"Overworld - Thieves' Hideout Keys can only appear outside of dungeons.\n"
"\n"
"Anywhere - Thieves' Hideout Keys can appear anywhere in the world.";
mOptionDescriptions[RSK_BOSS_KEYSANITY] = "Start with - You will start with Boss Keys from all dungeons.\n"
"\n"
"Vanilla - Boss Keys will appear in their vanilla locations.\n"
"\n"
"Own dungeon - Boss Keys can only appear in their respective dungeon.\n"
"\n"
"Any dungeon - Boss Keys can only appear inside of any dungeon.\n"
"\n"
"Overworld - Boss Keys can only appear outside of dungeons.\n"
"\n"
"Anywhere - Boss Keys can appear anywhere in the world.";
mOptionDescriptions[RSK_GANONS_BOSS_KEY] =
"Vanilla - Ganon's Boss Key will appear in the vanilla location.\n"
"\n"
"Own dungeon - Ganon's Boss Key can appear anywhere inside Ganon's Castle.\n"
"\n"
"Start with - Places Ganon's Boss Key in your starting inventory.\n"
"\n"
"Any dungeon - Ganon's Boss Key can only appear inside of any dungeon.\n"
"\n"
"Overworld - Ganon's Boss Key can only appear outside of dungeons.\n"
"\n"
"Anywhere - Ganon's Boss Key can appear anywhere in the world.\n"
"\n"
"Trigger - These settings put the boss key on a trigger, "
"granting the key once the requirements are met:\n"
"- Stones: Obtain the specified amount of Spiritual Stones.\n"
"- Medallions: Obtain the specified amount of medallions.\n"
"- Dungeon rewards: Obtain the specified total sum of Spiritual Stones or medallions.\n"
"- Dungeons: Complete the specified amount of dungeons. Dungeons are considered complete after stepping into "
"the blue warp after the boss.\n"
"- Tokens: Obtain the specified amount of Skulltula tokens.";
mOptionDescriptions[RSK_GBK_OPTIONS] =
"Standard Rewards - Greg does not change logic, Greg does not help obtain GBK, max "
"number of rewards on slider does not change.\n"
"\n"
"Greg as Reward - Greg does change logic (can be part of expected path for obtaining "
"GBK), Greg helps obtain GBK, max number of rewards on slider increases by 1 to "
"account for Greg.\n"
"\n"
"Greg as Wildcard - Greg does not change logic, Greg helps obtain GBK, max number of "
"rewards on slider does not change.";
mOptionDescriptions[RSK_GANONS_SOUL_OPTIONS] =
"Standard Rewards - Greg does not change logic, Greg does not help obtain Ganon's Soul, max "
"number of rewards on slider does not change.\n"
"\n"
"Greg as Reward - Greg does change logic (can be part of expected path for obtaining "
"Ganon's Soul), Greg helps obtain Ganon's Soul, max number of rewards on slider increases by 1 to "
"account for Greg.\n"
"\n"
"Greg as Wildcard - Greg does not change logic, Greg helps obtain Ganon's Soul, max number of "
"rewards on slider does not change.";
mOptionDescriptions[RSK_BIG_POE_COUNT] = "The Poe collector will give a reward for turning in this many Big Poes.";
mOptionDescriptions[RSK_SKIP_CHILD_STEALTH] =
"The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards.";
mOptionDescriptions[RSK_SKIP_EPONA_RACE] = "Epona can be summoned with Epona's Song without needing to race Ingo.";
mOptionDescriptions[RSK_SHUFFLE_MASKS] =
"The Happy Mask Shop never opens, masks are shuffled with the rest of the items.";
mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG] =
"Start with the ability to summon Pierre the Scarecrow. Pulling out an Ocarina in the usual locations will "
"automatically summon him.\n"
"With \"Shuffle Ocarina Buttons\" enabled, you'll need at least two Ocarina buttons to summon him.";
mOptionDescriptions[RSK_SKIP_PLANTING_BEANS] = "Beans will be planted once you find beans.\n"
"If bean souls are shuffled, you must still find the soul.";
mOptionDescriptions[RSK_ITEM_POOL] = "Sets how many major items appear in the item pool.\n"
"\n"
"Plentiful - Extra major items are added to the pool.\n"
"\n"
"Balanced - Original item pool.\n"
"\n"
"Scarce - Some excess items are removed, including health upgrades.\n"
"\n"
"Minimal - Most excess items are removed.";
mOptionDescriptions[RSK_BASE_ICE_TRAPS] =
"Sets if ice traps that exist in vanilla are shuffled into the item pool.\n"
"If this is on, 1 Trap will always be added to the pool,\n"
"an additional trap will be added if the Gerudo Training Ground\n"
"is NOT Master Quest,\n"
"and 4 more will be added if Ganon's Castle is NOT Master Quest.";
mOptionDescriptions[RSK_ADDITIONAL_ICE_TRAPS] =
"Sets how many more Ice Traps will be added to the item pool,\n"
"assuming there is enough space after placing Progression Items.\n\n"
"You do not need to have base ice traps on for this setting to work.";
mOptionDescriptions[RSK_ICE_TRAP_PERCENT] =
"If set above 0, each Junk item has that chance of being replaced with an extra Ice Trap.";
mOptionDescriptions[RSK_GOSSIP_STONE_HINTS] =
"Allows Gossip Stones to provide hints on item locations. Hints mentioning "
"\"Way of the Hero\" indicate a location that holds an item required to beat "
"the seed.\n"
"\n"
"No hints - No hints will be given at all.\n"
"\n"
"Need Nothing - Hints are always available from Gossip Stones.\n"
"\n"
"Need Stone of Agony - Hints are only available after obtaining the Stone of Agony.\n"
"\n"
"Need Mask of Truth - Hints are only available whilst wearing the Mask of Truth.\n";
mOptionDescriptions[RSK_HINT_CLARITY] =
"Sets the difficulty of hints.\n"
"\n"
"Obscure - Hints are unique for each item, but the writing may be cryptic.\n"
"Ex: Kokiri Sword > a butter knife\n"
"\n"
"Ambiguous - Hints are clearly written, but may refer to more than one item.\n"
"Ex: Kokiri Sword > a sword\n"
"\n"
"Clear - Hints are clearly written and are unique for each item.\n"
"Ex: Kokiri Sword > the Kokiri Sword";
mOptionDescriptions[RSK_HINT_DISTRIBUTION] = "Sets how many hints will be useful.\n"
"\n"
"Useless - Only junk hints.\n"
"\n"
"Balanced - Recommended hint spread.\n"
"\n"
"Strong - More useful hints.\n"
"\n"
"Very Strong - Many powerful hints.";
mOptionDescriptions[RSK_TOT_ALTAR_HINT] =
"Reading the Temple of Time altar as child will tell you the locations of the Spiritual Stones.\n"
"Reading the Temple of Time altar as adult will tell you the locations of the medallions, as well as the "
"conditions for building the Rainbow Bridge and getting the Boss Key for Ganon's Castle.";
mOptionDescriptions[RSK_GANONDORF_HINT] =
"Talking to Ganondorf in his boss room will tell you the location of the Light Arrows and Master Sword. "
"If this option is enabled and Ganondorf is reachable without these items, Gossip Stones will never hint the "
"appropriate items."; // RANDOTODO make this hint text about no dupe hints a global hint for static hints. Add
// to navi?
mOptionDescriptions[RSK_SHEIK_LA_HINT] =
"Talking to Sheik inside Ganon's Castle will tell you the location of the Light Arrows. "
"If this option is enabled and Sheik is reachable without Light Arrows, Gossip Stones will never hint the "
"Light Arrows.";
mOptionDescriptions[RSK_DAMPES_DIARY_HINT] =
"Reading the diary of Dampé the gravekeeper as adult will tell you the location of one of the Hookshots.";
mOptionDescriptions[RSK_GREG_HINT] =
"Talking to the chest game owner after buying a key will tell you the location of Greg the Green Rupee.";
mOptionDescriptions[RSK_LOACH_HINT] = "Talking to the fishing pond owner and asking to talk about something will "
"tell you the reward for the Hyrule Loach.";
mOptionDescriptions[RSK_BOSS_KEY_HINT] =
"Navi will tell you where the Boss Key can be found when prompted at a boss door.";
mOptionDescriptions[RSK_SARIA_HINT] = "Talking to Saria either in person or through Saria's Song will tell you the "
"location of a progressive magic meter.";
mOptionDescriptions[RSK_MIDO_HINT] = "Talking to Mido as child will tell you the location of the Kokiri Sword.";
mOptionDescriptions[RSK_FISHING_POLE_HINT] =
"Talking to the fishing pond owner without the fishing pole will tell you its location.";
mOptionDescriptions[RSK_OOT_HINT] =
"Sheik in the Temple of Time will tell you the item and song on the Ocarina of Time.";
mOptionDescriptions[RSK_FROGS_HINT] = "Standing near the pedestal for the frogs in Zora's River will tell you the "
"reward for the frogs' Ocarina game.";
mOptionDescriptions[RSK_BIGGORON_HINT] =
"Talking to Biggoron will tell you the item he will give you in exchange for the Claim Check.";
mOptionDescriptions[RSK_BIG_POES_HINT] = "Talking to the Poe Collector in the Market Guardhouse while adult will "
"tell you what you receive for handing in Big Poes.";
mOptionDescriptions[RSK_CHICKENS_HINT] =
"Talking to Anju as a child will tell you the item she will give you for delivering her cuccos to the pen.";
mOptionDescriptions[RSK_MALON_HINT] = "Talking to Malon as adult will tell you the item on \"Link's cow\", the cow "
"you win from beating her time on the Lon Lon Obstacle Course.";
mOptionDescriptions[RSK_HBA_HINT] =
"Talking to the Horseback Archery Gerudo in Gerudo Fortress, or the nearby sign, will tell you what you win "
"for scoring 1000 and 1500 points on Horseback Archery.";
mOptionDescriptions[RSK_WARP_SONG_HINTS] = "Playing a warp song will tell you where it leads. (If warp song "
"destinations are vanilla, this is always enabled.)";
mOptionDescriptions[RSK_SCRUB_TEXT_HINT] = "Business scrubs will reveal the identity of what they're selling.";
mOptionDescriptions[RSK_MERCHANT_TEXT_HINT] =
"Merchants will reveal the identity of what they're selling (Shops are not affected by this setting).";
mOptionDescriptions[RSK_KAK_10_SKULLS_HINT] =
"Talking to the Cursed Resident in the Skulltula House who is saved after 10 tokens will tell you the reward.";
mOptionDescriptions[RSK_KAK_20_SKULLS_HINT] =
"Talking to the Cursed Resident in the Skulltula House who is saved after 20 tokens will tell you the reward.";
mOptionDescriptions[RSK_KAK_30_SKULLS_HINT] =
"Talking to the Cursed Resident in the Skulltula House who is saved after 30 tokens will tell you the reward.";
mOptionDescriptions[RSK_KAK_40_SKULLS_HINT] =
"Talking to the Cursed Resident in the Skulltula House who is saved after 40 tokens will tell you the reward.";
mOptionDescriptions[RSK_KAK_50_SKULLS_HINT] =
"Talking to the Cursed Resident in the Skulltula House who is saved after 50 tokens will tell you the reward.";
mOptionDescriptions[RSK_KAK_100_SKULLS_HINT] =
"Talking to the Cursed Resident in the Skulltula House who is saved after 100 tokens will tell you the reward.";
mOptionDescriptions[RSK_MASK_SHOP_HINT] =
"Reading the mask shop sign will tell you rewards from showing masks at the Deku Theatre.";
mOptionDescriptions[RSK_FULL_WALLETS] = "Start with a full wallet. All wallet upgrades come filled with rupees.";
mOptionDescriptions[RSK_BOMBCHU_BAG] =
"None - Bombchus have vanilla behavior, any Bombchu requirement is filled by Bomb Bag + a renewable source of "
"Bombchus.\n\n"
"Single Bag - Bombchus require their own bag to be found before use. 5 of them are added to the pool "
"(6 if the Carpet Merchant is shuffled). The first Bombchu Bag you find will be a Bag containing 20 chus, "
"and subsequent bags will be replaced with Bombchu Ammo refills. Once found, they can be replenished at "
"shops selling refills, Bombchu Bowling and the carpet merchant. Bombchu Bowling is opened by obtaining "
"the Bombchu Bag.\n\n"
"Progressive Bags - 3 Bombchu Bags are added to the pool, the first one will unlock Bombchus with a capacity "
"of 20. The second one will upgrade this capacity to 30, and the final one will upgrade the capacity to the "
"usual 50.\n\n"
"Bombchu Bowling is opened by obtaining the first Bombchu bag.";
mOptionDescriptions[RSK_LINKS_POCKET] =
"Dungeon Reward - Link will start with a Spiritual Stone or Medallion, and specific options will open up.\n\n"
"Advancement - Link will start with a useful item.\n\n"
"Anything - Link will start with a random item.\n\n"
"Nothing - Link will not start with a bonus item.";
mOptionDescriptions[RSK_LINKS_POCKET_REWARD] =
"Any Reward - Link starts with a random Spiritual Stone or Medallion.\n\n"
"Stone - Link starts with a random Spiritual Stone.\n\n"
"Any Medallion - Link starts with a random Medallion.\n\n"
"Light Medallion - Link starts with the Light Medallion.";
mOptionDescriptions[RSK_ENABLE_BOMBCHU_DROPS] = "Once you obtain a Bombchu Bag, refills will sometimes replace "
"Bomb drops that would spawn."
"\n"
"If you have Bombchu Bag disabled, you will need a Bomb Bag "
"and existing Bombchus for Bombchus to drop.";
mOptionDescriptions[RSK_PROGRESSIVE_GORON_SWORD] =
"Giant's Knife and Biggoron's Sword are shuffled as one progressive item: the first copy is the "
"breakable Giant's Knife, the second is Biggoron's Sword.\n"
"\n"
"Starting with Biggoron's Sword still starts you with both.\n"
"Medigoron only repairs broken Giant's Knife.";
mOptionDescriptions[RSK_BLUE_FIRE_ARROWS] =
"Ice Arrows act like Blue Fire, making them able to melt red ice. "
"Item placement logic will respect this option, so it might be required to use this to progress.";
mOptionDescriptions[RSK_SKELETON_KEY] =
"Adds a new item called the \"Skeleton Key\"; it unlocks every dungeon door locked by a small key.";
mOptionDescriptions[RSK_SUNLIGHT_ARROWS] =
"Light Arrows can be used to light up the sun switches instead of using the Mirror Shield. "
"Item placement logic will respect this option, so it might be required to use this to progress.";
mOptionDescriptions[RSK_ROCS_FEATHER] =
"Adds Roc's Feather to the item pool. Roc's Feather is a custom item granting the player a jump on demand. "
"The jump can also be used when already in mid-air. Roc's Feather is not considered by logic.";
mOptionDescriptions[RSK_SLINGBOW_BREAK_BEEHIVES] =
"Allows Slingshot and Bow to break beehives when Beehive Shuffle is turned on.";
mOptionDescriptions[RSK_LOGIC_RULES] =
"Glitchless - No glitches are required, but may require some minor tricks. Additional tricks may be enabled "
"and disabled below.\n"
"\n"
"No logic - Item placement is completely random. MAY BE IMPOSSIBLE TO BEAT.";
mOptionDescriptions[RSK_ALL_LOCATIONS_REACHABLE] = "When this option is enabled, the randomizer will "
"guarantee that every item is obtainable and every "
"location is reachable. When disabled, only "
"required items and locations to beat the game "
"will be guaranteed reachable.";
mOptionDescriptions[RSK_SHUFFLE_BEAN_SOULS] =
"Shuffle 10 bean souls which must be found to spawn the corresponding soil/plant.";
mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS] =
"Shuffles 8 boss souls (one for each blue warp dungeon). A boss will not appear until you collect its "
"respective soul.";
}
} // namespace Rando
+309 -309
View File
@@ -181,25 +181,24 @@ void Settings::HandleStartingAgeUI() {
}
void Settings::CreateOptions() {
CreateOptionDescriptions();
// clang-format off
OPT_U8(RSK_FOREST, "Closed Forest", {"On", "Deku Only", "Off"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ClosedForest"), mOptionDescriptions[RSK_FOREST], WIDGET_CVAR_COMBOBOX, RO_CLOSED_FOREST_ON);
OPT_U8(RSK_FOREST, {"On", "Deku Only", "Off"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ClosedForest"), WIDGET_CVAR_COMBOBOX, RO_CLOSED_FOREST_ON);
OPT_CALLBACK(RSK_FOREST, {
HandleStartingAgeUI();
});
OPT_U8(RSK_DOOR_OF_TIME, "Door of Time", {"Closed", "Song only", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DoorOfTime"), mOptionDescriptions[RSK_DOOR_OF_TIME], WIDGET_CVAR_COMBOBOX);
OPT_U8(RSK_DOOR_OF_TIME, {"Closed", "Song only", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DoorOfTime"), WIDGET_CVAR_COMBOBOX);
OPT_CALLBACK(RSK_DOOR_OF_TIME, {
HandleStartingAgeUI();
});
OPT_U8(RSK_ZORAS_FOUNTAIN, "Zora's Fountain", {"Closed", "Closed as child", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ZorasFountain"), mOptionDescriptions[RSK_ZORAS_FOUNTAIN]);
OPT_U8(RSK_SLEEPING_WATERFALL, "Sleeping Waterfall", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), mOptionDescriptions[RSK_SLEEPING_WATERFALL]);
OPT_U8(RSK_JABU_OPEN, "Jabu-Jabu", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("JabuJabu"), mOptionDescriptions[RSK_JABU_OPEN]);
OPT_BOOL(RSK_LOCK_OVERWORLD_DOORS, "Lock Overworld Doors", CVAR_RANDOMIZER_SETTING("LockOverworldDoors"), mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS]);
OPT_U8(RSK_GERUDO_FORTRESS, "Fortress Carpenters", {"Normal", "Fast", "Free"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FortressCarpenters"), mOptionDescriptions[RSK_GERUDO_FORTRESS]);
OPT_U8(RSK_ZORAS_FOUNTAIN, {"Closed", "Closed as child", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ZorasFountain"));
OPT_U8(RSK_SLEEPING_WATERFALL, {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SleepingWaterfall"));
OPT_U8(RSK_JABU_OPEN, {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("JabuJabu"));
OPT_BOOL(RSK_LOCK_OVERWORLD_DOORS, CVAR_RANDOMIZER_SETTING("LockOverworldDoors"));
OPT_U8(RSK_GERUDO_FORTRESS, {"Normal", "Fast", "Free"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FortressCarpenters"));
OPT_CALLBACK(RSK_GERUDO_FORTRESS, {
HandleKeyringUI();
});
OPT_U8(RSK_RAINBOW_BRIDGE, "Rainbow Bridge", {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Triforce Pieces", "Greg"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RainbowBridge"), mOptionDescriptions[RSK_RAINBOW_BRIDGE], WIDGET_CVAR_COMBOBOX, RO_BRIDGE_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_RAINBOW_BRIDGE, {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Triforce Pieces", "Greg"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RainbowBridge"), WIDGET_CVAR_COMBOBOX, RO_BRIDGE_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_CALLBACK(RSK_RAINBOW_BRIDGE, {
mOptions[RSK_BRIDGE_OPTIONS].Hide();
mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].Hide();
@@ -243,13 +242,13 @@ void Settings::CreateOptions() {
break;
}
});
OPT_U8(RSK_RAINBOW_BRIDGE_STONE_COUNT, "Bridge Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StoneCount"), "", WIDGET_CVAR_SLIDER_INT, 3, true);
OPT_U8(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT, "Bridge Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MedallionCount"), "", WIDGET_CVAR_SLIDER_INT, 6, true);
OPT_U8(RSK_RAINBOW_BRIDGE_REWARD_COUNT, "Bridge Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RewardCount"), "", WIDGET_CVAR_SLIDER_INT, 9, true);
OPT_U8(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT, "Bridge Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DungeonCount"), "", WIDGET_CVAR_SLIDER_INT, 8, true);
OPT_U8(RSK_RAINBOW_BRIDGE_TOKEN_COUNT, "Bridge Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TokenCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_RAINBOW_BRIDGE_TRIFORCE_COUNT, "Bridge Triforce Piece Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforcePieceCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_BRIDGE_OPTIONS, "Bridge Reward Options", {"Standard Rewards", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), mOptionDescriptions[RSK_BRIDGE_OPTIONS], WIDGET_CVAR_COMBOBOX, RO_BRIDGE_STANDARD_REWARD, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_RAINBOW_BRIDGE_STONE_COUNT, {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StoneCount"), WIDGET_CVAR_SLIDER_INT, 3, true);
OPT_U8(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT, {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MedallionCount"), WIDGET_CVAR_SLIDER_INT, 6, true);
OPT_U8(RSK_RAINBOW_BRIDGE_REWARD_COUNT, {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RewardCount"), WIDGET_CVAR_SLIDER_INT, 9, true);
OPT_U8(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT, {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DungeonCount"), WIDGET_CVAR_SLIDER_INT, 8, true);
OPT_U8(RSK_RAINBOW_BRIDGE_TOKEN_COUNT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TokenCount"), WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_RAINBOW_BRIDGE_TRIFORCE_COUNT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforcePieceCount"), WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_BRIDGE_OPTIONS, {"Standard Rewards", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), WIDGET_CVAR_COMBOBOX, RO_BRIDGE_STANDARD_REWARD, false, nullptr, IMFLAG_NONE);
OPT_CALLBACK(RSK_BRIDGE_OPTIONS, {
const uint8_t bridgeOpt = CVarGetInteger(CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), RO_BRIDGE_STANDARD_REWARD);
if (bridgeOpt == RO_BRIDGE_GREG_REWARD) {
@@ -264,7 +263,7 @@ void Settings::CreateOptions() {
mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8));
}
});
OPT_U8(RSK_GANONS_TRIALS, "Ganon's Trials", {"Skip", "Set Number", "Random Number"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrial"), mOptionDescriptions[RSK_GANONS_TRIALS], WIDGET_CVAR_COMBOBOX, RO_GANONS_TRIALS_SET_NUMBER);
OPT_U8(RSK_GANONS_TRIALS, {"Skip", "Set Number", "Random Number"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrial"), WIDGET_CVAR_COMBOBOX, RO_GANONS_TRIALS_SET_NUMBER);
OPT_CALLBACK(RSK_GANONS_TRIALS, {
// Only show the trial count slider if Trials is set to Set Number
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SET_NUMBER) ==
@@ -274,12 +273,12 @@ void Settings::CreateOptions() {
mOptions[RSK_TRIAL_COUNT].Hide();
}
});
OPT_U8(RSK_TRIAL_COUNT, "Ganon's Trials Count", {NumOpts(0, 6)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrialCount"), mOptionDescriptions[RSK_TRIAL_COUNT], WIDGET_CVAR_SLIDER_INT, 6, true);
OPT_BOOL(RSK_MEDALLION_LOCKED_TRIALS, "Medallion Locked Trials", CVAR_RANDOMIZER_SETTING("MedallionLockedTrials"), mOptionDescriptions[RSK_MEDALLION_LOCKED_TRIALS]);
OPT_U8(RSK_STARTING_AGE, "Starting Age", {"Child", "Adult", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingAge"), mOptionDescriptions[RSK_STARTING_AGE], WIDGET_CVAR_COMBOBOX, RO_AGE_CHILD);
OPT_U8(RSK_SELECTED_STARTING_AGE, "Selected Starting Age", {"Child", "Adult"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SelectedStartingAge"), mOptionDescriptions[RSK_STARTING_AGE], WIDGET_CVAR_COMBOBOX, RO_AGE_CHILD);
OPT_BOOL(RSK_SHUFFLE_ENTRANCES, "Shuffle Entrances");
OPT_U8(RSK_SHUFFLE_DUNGEON_ENTRANCES, "Dungeon Entrances", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), mOptionDescriptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], WIDGET_CVAR_COMBOBOX, RO_DUNGEON_ENTRANCE_SHUFFLE_OFF);
OPT_U8(RSK_TRIAL_COUNT, {NumOpts(0, 6)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrialCount"), WIDGET_CVAR_SLIDER_INT, 6, true);
OPT_BOOL(RSK_MEDALLION_LOCKED_TRIALS, CVAR_RANDOMIZER_SETTING("MedallionLockedTrials"));
OPT_U8(RSK_STARTING_AGE, {"Child", "Adult", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingAge"), WIDGET_CVAR_COMBOBOX, RO_AGE_CHILD);
OPT_U8(RSK_SELECTED_STARTING_AGE, {"Child", "Adult"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SelectedStartingAge"), WIDGET_CVAR_COMBOBOX, RO_AGE_CHILD);
OPT_BOOL(RSK_SHUFFLE_ENTRANCES, "");
OPT_U8(RSK_SHUFFLE_DUNGEON_ENTRANCES, {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), WIDGET_CVAR_COMBOBOX, RO_DUNGEON_ENTRANCE_SHUFFLE_OFF);
OPT_CALLBACK(RSK_SHUFFLE_DUNGEON_ENTRANCES, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) ==
RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
@@ -289,7 +288,7 @@ void Settings::CreateOptions() {
mOptions[RSK_MIX_DUNGEON_ENTRANCES].Unhide();
}
});
OPT_U8(RSK_SHUFFLE_BOSS_ENTRANCES, "Boss Entrances", {"Off", "Age Restricted", "Full"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), mOptionDescriptions[RSK_SHUFFLE_BOSS_ENTRANCES], WIDGET_CVAR_COMBOBOX, RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF);
OPT_U8(RSK_SHUFFLE_BOSS_ENTRANCES, {"Off", "Age Restricted", "Full"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), WIDGET_CVAR_COMBOBOX, RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF);
OPT_CALLBACK(RSK_SHUFFLE_BOSS_ENTRANCES, {
HandleMixedEntrancePoolsUI();
@@ -307,8 +306,8 @@ void Settings::CreateOptions() {
mOptions[RSK_MIX_BOSS_ENTRANCES].Unhide();
}
});
OPT_BOOL(RSK_SHUFFLE_GANONS_TOWER_ENTRANCE, "Ganon's Tower Entrance", CVAR_RANDOMIZER_SETTING("ShuffleGanonTowerEntrance"), mOptionDescriptions[RSK_SHUFFLE_GANONS_TOWER_ENTRANCE]);
OPT_BOOL(RSK_SHUFFLE_OVERWORLD_ENTRANCES, "Overworld Entrances", CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), mOptionDescriptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES]);
OPT_BOOL(RSK_SHUFFLE_GANONS_TOWER_ENTRANCE, CVAR_RANDOMIZER_SETTING("ShuffleGanonTowerEntrance"));
OPT_BOOL(RSK_SHUFFLE_OVERWORLD_ENTRANCES, CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"));
OPT_CALLBACK(RSK_SHUFFLE_OVERWORLD_ENTRANCES, {
HandleMixedEntrancePoolsUI();
@@ -318,10 +317,10 @@ void Settings::CreateOptions() {
} else {
mOptions[RSK_MIX_OVERWORLD_ENTRANCES].Unhide();
}
HandleStartingAgeUI();
});
OPT_U8(RSK_SHUFFLE_INTERIOR_ENTRANCES, "Interior Entrances", {"Off", "Simple", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), mOptionDescriptions[RSK_SHUFFLE_INTERIOR_ENTRANCES], WIDGET_CVAR_COMBOBOX, RO_INTERIOR_ENTRANCE_SHUFFLE_OFF);
OPT_U8(RSK_SHUFFLE_INTERIOR_ENTRANCES, {"Off", "Simple", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), WIDGET_CVAR_COMBOBOX, RO_INTERIOR_ENTRANCE_SHUFFLE_OFF);
OPT_CALLBACK(RSK_SHUFFLE_INTERIOR_ENTRANCES, {
HandleMixedEntrancePoolsUI();
@@ -331,10 +330,10 @@ void Settings::CreateOptions() {
} else {
mOptions[RSK_MIX_INTERIOR_ENTRANCES].Unhide();
}
HandleStartingAgeUI();
});
OPT_BOOL(RSK_SHUFFLE_THIEVES_HIDEOUT_ENTRANCES, "Thieves' Hideout Entrances", CVAR_RANDOMIZER_SETTING("ShuffleThievesHideoutEntrances"), mOptionDescriptions[RSK_SHUFFLE_THIEVES_HIDEOUT_ENTRANCES]);
OPT_BOOL(RSK_SHUFFLE_THIEVES_HIDEOUT_ENTRANCES, CVAR_RANDOMIZER_SETTING("ShuffleThievesHideoutEntrances"));
OPT_CALLBACK(RSK_SHUFFLE_THIEVES_HIDEOUT_ENTRANCES, {
HandleMixedEntrancePoolsUI();
@@ -346,7 +345,7 @@ void Settings::CreateOptions() {
mOptions[RSK_MIX_THIEVES_HIDEOUT_ENTRANCES].Unhide();
}
});
OPT_BOOL(RSK_SHUFFLE_GROTTO_ENTRANCES, "Grottos Entrances", CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"), mOptionDescriptions[RSK_SHUFFLE_GROTTO_ENTRANCES]);
OPT_BOOL(RSK_SHUFFLE_GROTTO_ENTRANCES, CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"));
OPT_CALLBACK(RSK_SHUFFLE_GROTTO_ENTRANCES, {
HandleMixedEntrancePoolsUI();
@@ -356,11 +355,11 @@ void Settings::CreateOptions() {
} else {
mOptions[RSK_MIX_GROTTO_ENTRANCES].Unhide();
}
HandleStartingAgeUI();
});
OPT_BOOL(RSK_SHUFFLE_OWL_DROPS, "Owl Drops", CVAR_RANDOMIZER_SETTING("ShuffleOwlDrops"), mOptionDescriptions[RSK_SHUFFLE_OWL_DROPS]);
OPT_BOOL(RSK_SHUFFLE_WARP_SONGS, "Warp Songs", CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"), mOptionDescriptions[RSK_SHUFFLE_WARP_SONGS]);
OPT_BOOL(RSK_SHUFFLE_OWL_DROPS, CVAR_RANDOMIZER_SETTING("ShuffleOwlDrops"));
OPT_BOOL(RSK_SHUFFLE_WARP_SONGS, CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"));
OPT_CALLBACK(RSK_SHUFFLE_WARP_SONGS, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"), RO_GENERIC_ON)) {
mOptions[RSK_WARP_SONG_HINTS].Enable();
@@ -368,11 +367,11 @@ void Settings::CreateOptions() {
mOptions[RSK_WARP_SONG_HINTS].Disable("This option is disabled since warp song locations are not shuffled.");
}
});
OPT_BOOL(RSK_SHUFFLE_OVERWORLD_SPAWNS, "Overworld Spawns", CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"), mOptionDescriptions[RSK_SHUFFLE_OVERWORLD_SPAWNS]);
OPT_BOOL(RSK_SHUFFLE_OVERWORLD_SPAWNS, CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"));
OPT_CALLBACK(RSK_SHUFFLE_OVERWORLD_SPAWNS, {
HandleStartingAgeUI();
});
OPT_BOOL(RSK_MIXED_ENTRANCE_POOLS, "Mixed Entrance Pools", CVAR_RANDOMIZER_SETTING("MixedEntrances"), mOptionDescriptions[RSK_MIXED_ENTRANCE_POOLS]);
OPT_BOOL(RSK_MIXED_ENTRANCE_POOLS, CVAR_RANDOMIZER_SETTING("MixedEntrances"));
OPT_CALLBACK(RSK_MIXED_ENTRANCE_POOLS, {
// Show mixed entrance pool options if mixed entrance pools are enabled, but only the ones that aren't off
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MixedEntrances"), RO_GENERIC_OFF) == RO_GENERIC_OFF ||
@@ -407,23 +406,23 @@ void Settings::CreateOptions() {
}
}
});
OPT_BOOL(RSK_MIX_DUNGEON_ENTRANCES, "Mix Dungeons", CVAR_RANDOMIZER_SETTING("MixDungeons"), mOptionDescriptions[RSK_MIX_DUNGEON_ENTRANCES], IMFLAG_NONE);
OPT_BOOL(RSK_MIX_BOSS_ENTRANCES, "Mix Bosses", CVAR_RANDOMIZER_SETTING("MixBosses"), mOptionDescriptions[RSK_MIX_BOSS_ENTRANCES], IMFLAG_NONE);
OPT_BOOL(RSK_MIX_OVERWORLD_ENTRANCES, "Mix Overworld", CVAR_RANDOMIZER_SETTING("MixOverworld"), mOptionDescriptions[RSK_MIX_OVERWORLD_ENTRANCES], IMFLAG_NONE);
OPT_BOOL(RSK_MIX_INTERIOR_ENTRANCES, "Mix Interiors", CVAR_RANDOMIZER_SETTING("MixInteriors"), mOptionDescriptions[RSK_MIX_INTERIOR_ENTRANCES], IMFLAG_NONE);
OPT_BOOL(RSK_MIX_THIEVES_HIDEOUT_ENTRANCES, "Mix Thieves' Hideout", CVAR_RANDOMIZER_SETTING("MixThievesHideout"), mOptionDescriptions[RSK_MIX_THIEVES_HIDEOUT_ENTRANCES]);
OPT_BOOL(RSK_MIX_GROTTO_ENTRANCES, "Mix Grottos", CVAR_RANDOMIZER_SETTING("MixGrottos"), mOptionDescriptions[RSK_MIX_GROTTO_ENTRANCES]);
OPT_BOOL(RSK_DECOUPLED_ENTRANCES, "Decouple Entrances", CVAR_RANDOMIZER_SETTING("DecoupleEntrances"), mOptionDescriptions[RSK_DECOUPLED_ENTRANCES]);
OPT_BOOL(RSK_MIX_DUNGEON_ENTRANCES, CVAR_RANDOMIZER_SETTING("MixDungeons"), IMFLAG_NONE);
OPT_BOOL(RSK_MIX_BOSS_ENTRANCES, CVAR_RANDOMIZER_SETTING("MixBosses"), IMFLAG_NONE);
OPT_BOOL(RSK_MIX_OVERWORLD_ENTRANCES, CVAR_RANDOMIZER_SETTING("MixOverworld"), IMFLAG_NONE);
OPT_BOOL(RSK_MIX_INTERIOR_ENTRANCES, CVAR_RANDOMIZER_SETTING("MixInteriors"), IMFLAG_NONE);
OPT_BOOL(RSK_MIX_THIEVES_HIDEOUT_ENTRANCES, CVAR_RANDOMIZER_SETTING("MixThievesHideout"));
OPT_BOOL(RSK_MIX_GROTTO_ENTRANCES, CVAR_RANDOMIZER_SETTING("MixGrottos"));
OPT_BOOL(RSK_DECOUPLED_ENTRANCES, CVAR_RANDOMIZER_SETTING("DecoupleEntrances"));
OPT_CALLBACK(RSK_DECOUPLED_ENTRANCES, {
HandleStartingAgeUI();
});
OPT_U8(RSK_BOMBCHU_BAG, "Bombchu Bag", {"None", "Single Bag", "Progressive Bags"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BombchuBag"), mOptionDescriptions[RSK_BOMBCHU_BAG], WIDGET_CVAR_COMBOBOX, RO_BOMBCHU_BAG_NONE);
OPT_U8(RSK_ENABLE_BOMBCHU_DROPS, "Bombchu Drops", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), mOptionDescriptions[RSK_ENABLE_BOMBCHU_DROPS], WIDGET_CVAR_COMBOBOX, RO_AMMO_DROPS_ON);
OPT_BOOL(RSK_PROGRESSIVE_GORON_SWORD, "Progressive Goron Sword", CVAR_RANDOMIZER_SETTING("ProgressiveGoronSword"), mOptionDescriptions[RSK_PROGRESSIVE_GORON_SWORD]);
OPT_U8(RSK_BOMBCHU_BAG, {"None", "Single Bag", "Progressive Bags"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BombchuBag"), WIDGET_CVAR_COMBOBOX, RO_BOMBCHU_BAG_NONE);
OPT_U8(RSK_ENABLE_BOMBCHU_DROPS, {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), WIDGET_CVAR_COMBOBOX, RO_AMMO_DROPS_ON);
OPT_BOOL(RSK_PROGRESSIVE_GORON_SWORD, CVAR_RANDOMIZER_SETTING("ProgressiveGoronSword"));
// TODO: AmmoDrops and/or HeartDropRefill, combine with/separate Ammo Drops from Bombchu Drops?
// Triforce Hunt: the total piece count is the on/off control. Zero disables the hunt entirely; any
// positive value adds that many Triforce Pieces to the pool and unlocks the pieces-location option.
OPT_U8(RSK_TRIFORCE_HUNT_PIECES_TOTAL, "Triforce Hunt Total Pieces", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL], WIDGET_CVAR_SLIDER_INT, 0, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_TRIFORCE_HUNT_PIECES_TOTAL, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), WIDGET_CVAR_SLIDER_INT, 0, false, nullptr, IMFLAG_NONE);
OPT_CALLBACK(RSK_TRIFORCE_HUNT_PIECES_TOTAL, {
const uint8_t triforceTotal = CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), 0);
if (triforceTotal == 0) {
@@ -444,8 +443,8 @@ void Settings::CreateOptions() {
mOptions[RSK_WINCON_TRIFORCE_COUNT].ChangeOptions(NumOpts(0, triforceTotal));
}
});
OPT_U8(RSK_TRIFORCE_HUNT_PIECES_LOCATION, "Triforce Hunt Pieces Location", {"Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHuntPiecesLocation"), mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_LOCATION], WIDGET_CVAR_COMBOBOX, RO_TRIFORCE_HUNT_LOCATION_ANYWHERE);
OPT_U8(RSK_MQ_DUNGEON_RANDOM, "MQ Dungeon Setting", {"None", "Set Number", "Random", "Selection Only"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeons"), mOptionDescriptions[RSK_MQ_DUNGEON_RANDOM], WIDGET_CVAR_COMBOBOX, RO_MQ_DUNGEONS_NONE, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_TRIFORCE_HUNT_PIECES_LOCATION, {"Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHuntPiecesLocation"), WIDGET_CVAR_COMBOBOX, RO_TRIFORCE_HUNT_LOCATION_ANYWHERE);
OPT_U8(RSK_MQ_DUNGEON_RANDOM, {"None", "Set Number", "Random", "Selection Only"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeons"), WIDGET_CVAR_COMBOBOX, RO_MQ_DUNGEONS_NONE, false, nullptr, IMFLAG_NONE);
OPT_CALLBACK(RSK_MQ_DUNGEON_RANDOM, {
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE)) {
// If No MQ Dungeons, add a separator after the combobx and hide
@@ -506,8 +505,8 @@ void Settings::CreateOptions() {
mOptions[RSK_MQ_GANONS_CASTLE].Hide();
}
});
OPT_U8(RSK_MQ_DUNGEON_COUNT, "MQ Dungeon Count", {NumOpts(0, MAX_MQ_DUNGEON_COUNT)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonCount"), "", WIDGET_CVAR_SLIDER_INT, MAX_MQ_DUNGEON_COUNT, true, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_MQ_DUNGEON_SET, "Set Dungeon Quests", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsSelection"), mOptionDescriptions[RSK_MQ_DUNGEON_SET], WIDGET_CVAR_CHECKBOX, false, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_DUNGEON_COUNT, {NumOpts(0, MAX_MQ_DUNGEON_COUNT)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonCount"), WIDGET_CVAR_SLIDER_INT, MAX_MQ_DUNGEON_COUNT, true, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_MQ_DUNGEON_SET, {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsSelection"), WIDGET_CVAR_CHECKBOX, false, false, nullptr, IMFLAG_NONE);
OPT_CALLBACK(RSK_MQ_DUNGEON_SET, {
// Controls whether or not to show the selectors for individual dungeons.
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) != RO_MQ_DUNGEONS_NONE &&
@@ -542,19 +541,19 @@ void Settings::CreateOptions() {
mOptions[RSK_MQ_GANONS_CASTLE].Hide();
}
});
OPT_U8(RSK_MQ_DEKU_TREE, "Deku Tree Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDekuTree"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_DODONGOS_CAVERN, "Dodongo's Cavern Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDodongosCavern"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_JABU_JABU, "Jabu-Jabu's Belly Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsJabuJabu"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_FOREST_TEMPLE, "Forest Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsForestTemple"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_FIRE_TEMPLE, "Fire Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsFireTemple"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_WATER_TEMPLE, "Water Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsWaterTemple"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_SPIRIT_TEMPLE, "Spirit Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsSpiritTemple"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_SHADOW_TEMPLE, "Shadow Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsShadowTemple"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_BOTTOM_OF_THE_WELL, "Bottom of the Well Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsBottomOfTheWell"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_ICE_CAVERN, "Ice Cavern Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsIceCavern"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_GTG, "Gerudo Training Ground Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGTG"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_GANONS_CASTLE, "Ganon's Castle Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGanonsCastle"), "", WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA);
OPT_U8(RSK_SHUFFLE_DUNGEON_REWARDS, "Shuffle Dungeon Rewards", {"Vanilla", "End of Dungeons", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS], WIDGET_CVAR_COMBOBOX, RO_DUNGEON_REWARDS_END_OF_DUNGEON);
OPT_U8(RSK_MQ_DEKU_TREE, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDekuTree"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_DODONGOS_CAVERN, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDodongosCavern"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_JABU_JABU, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsJabuJabu"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_FOREST_TEMPLE, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsForestTemple"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_FIRE_TEMPLE, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsFireTemple"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_WATER_TEMPLE, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsWaterTemple"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_SPIRIT_TEMPLE, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsSpiritTemple"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_SHADOW_TEMPLE, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsShadowTemple"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_BOTTOM_OF_THE_WELL, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsBottomOfTheWell"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_ICE_CAVERN, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsIceCavern"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_GTG, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGTG"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MQ_GANONS_CASTLE, {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGanonsCastle"), WIDGET_CVAR_COMBOBOX, RO_MQ_SET_VANILLA);
OPT_U8(RSK_SHUFFLE_DUNGEON_REWARDS, {"Vanilla", "End of Dungeons", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), WIDGET_CVAR_COMBOBOX, RO_DUNGEON_REWARDS_END_OF_DUNGEON);
OPT_CALLBACK(RSK_SHUFFLE_DUNGEON_REWARDS, {
// Link's Pocket - Disabled when Dungeon Rewards are shuffled to End of Dungeon
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) ==
@@ -582,22 +581,22 @@ void Settings::CreateOptions() {
mOptions[RSK_LINKS_POCKET_REWARD].Unhide();
} else {
mOptions[RSK_LINKS_POCKET_REWARD].Hide();
}
}
}
});
OPT_U8(RSK_LINKS_POCKET, "Link's Pocket", {"Dungeon Reward", "Advancement", "Anything", "Nothing"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocket"), mOptionDescriptions[RSK_LINKS_POCKET], WIDGET_CVAR_COMBOBOX, RO_LINKS_POCKET_DUNGEON_REWARD);
OPT_U8(RSK_LINKS_POCKET, {"Dungeon Reward", "Advancement", "Anything", "Nothing"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocket"), WIDGET_CVAR_COMBOBOX, RO_LINKS_POCKET_DUNGEON_REWARD);
OPT_CALLBACK(RSK_LINKS_POCKET, {
// Only show the dungeon reward type if Link's Pocket is set to Dungeon Reward and Dungeon Rewards are not Vanilla, OR Dungeon Rewards are end of dungeon
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_DUNGEON_REWARD) == RO_LINKS_POCKET_DUNGEON_REWARD ||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_DUNGEON_REWARD) == RO_LINKS_POCKET_DUNGEON_REWARD ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) == RO_DUNGEON_REWARDS_END_OF_DUNGEON) {
mOptions[RSK_LINKS_POCKET_REWARD].Unhide();
} else {
mOptions[RSK_LINKS_POCKET_REWARD].Hide();
}
});
OPT_U8(RSK_LINKS_POCKET_REWARD, "Link's Pocket Reward Type", {"Any Reward", "Any Stone", "Any Medallion", "Light Medallion"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocketReward"), mOptionDescriptions[RSK_LINKS_POCKET_REWARD], WIDGET_CVAR_COMBOBOX, RO_LINKS_POCKET_ANY_REWARD);
OPT_U8(RSK_SHUFFLE_SONGS, "Shuffle Songs", {"Off", "Song Locations", "Dungeon Rewards", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSongs"), mOptionDescriptions[RSK_SHUFFLE_SONGS], WIDGET_CVAR_COMBOBOX, RO_SONG_SHUFFLE_SONG_LOCATIONS);
OPT_U8(RSK_SHOPSANITY, "Shop Shuffle", {"Off", "Specific Count", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), mOptionDescriptions[RSK_SHOPSANITY], WIDGET_CVAR_COMBOBOX, RO_SHOPSANITY_OFF);
OPT_U8(RSK_LINKS_POCKET_REWARD, {"Any Reward", "Any Stone", "Any Medallion", "Light Medallion"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocketReward"), WIDGET_CVAR_COMBOBOX, RO_LINKS_POCKET_ANY_REWARD);
OPT_U8(RSK_SHUFFLE_SONGS, {"Off", "Song Locations", "Dungeon Rewards", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSongs"), WIDGET_CVAR_COMBOBOX, RO_SONG_SHUFFLE_SONG_LOCATIONS);
OPT_U8(RSK_SHOPSANITY, {"Off", "Specific Count", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), WIDGET_CVAR_COMBOBOX, RO_SHOPSANITY_OFF);
OPT_CALLBACK(RSK_SHOPSANITY, {
// Hide shopsanity prices if shopsanity is off or zero
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_OFF)) {
@@ -626,23 +625,23 @@ void Settings::CreateOptions() {
break;
}
});
OPT_U8(RSK_SHOPSANITY_COUNT, "Shops Item Count", {NumOpts(0, 8)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityCount"), mOptionDescriptions[RSK_SHOPSANITY_COUNT], WIDGET_CVAR_SLIDER_INT, 0, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES, "Shops Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), mOptionDescriptions[RSK_SHOPSANITY_PRICES], WIDGET_CVAR_COMBOBOX, RO_PRICE_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_COUNT, {NumOpts(0, 8)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityCount"), WIDGET_CVAR_SLIDER_INT, 0, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES, {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), WIDGET_CVAR_COMBOBOX, RO_PRICE_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_CALLBACK(RSK_SHOPSANITY_PRICES, {
HandleShopsanityPriceUI();
});
OPT_U8(RSK_SHOPSANITY_PRICES_FIXED_PRICE, "Shops Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE], WIDGET_CVAR_SLIDER_INT, 10, true);
OPT_U8(RSK_SHOPSANITY_PRICES_RANGE_1, "Shops Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_1], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_RANGE_2, "Shops Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_2], WIDGET_CVAR_SLIDER_INT, 100, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT, "Shops No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT, "Shops Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT, "Shops Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT, "Shops Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT, "Shops Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_SHOPSANITY_PRICES_AFFORDABLE, "Shops Affordable Prices", CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE]);
OPT_BOOL(RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL, "Gate Shop Shields & Tunics", CVAR_RANDOMIZER_SETTING("ShopShieldsTunicsGate"), mOptionDescriptions[RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL]);
OPT_U8(RSK_SHUFFLE_TOKENS, "Token Shuffle", {"Off", "Dungeons", "Overworld", "All Tokens"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleTokens"), mOptionDescriptions[RSK_SHUFFLE_TOKENS], WIDGET_CVAR_COMBOBOX, RO_TOKENSANITY_OFF);
OPT_U8(RSK_SHUFFLE_SCRUBS, "Scrubs Shuffle", {"Off", "One-Time Only", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), mOptionDescriptions[RSK_SHUFFLE_SCRUBS], WIDGET_CVAR_COMBOBOX, RO_SCRUBS_OFF);
OPT_U8(RSK_SHOPSANITY_PRICES_FIXED_PRICE, {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"), WIDGET_CVAR_SLIDER_INT, 10, true);
OPT_U8(RSK_SHOPSANITY_PRICES_RANGE_1, {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_RANGE_2, {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"), WIDGET_CVAR_SLIDER_INT, 100, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_SHOPSANITY_PRICES_AFFORDABLE, CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"));
OPT_BOOL(RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL, CVAR_RANDOMIZER_SETTING("ShopShieldsTunicsGate"));
OPT_U8(RSK_SHUFFLE_TOKENS, {"Off", "Dungeons", "Overworld", "All Tokens"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleTokens"), WIDGET_CVAR_COMBOBOX, RO_TOKENSANITY_OFF);
OPT_U8(RSK_SHUFFLE_SCRUBS, {"Off", "One-Time Only", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), WIDGET_CVAR_COMBOBOX, RO_SCRUBS_OFF);
OPT_CALLBACK(RSK_SHUFFLE_SCRUBS, {
bool isTycoon = CVarGetInteger(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), RO_GENERIC_OFF);
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_OFF)) {
@@ -725,7 +724,7 @@ void Settings::CreateOptions() {
break;
}
});
OPT_U8(RSK_SCRUBS_PRICES, "Scrubs Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPrices"), mOptionDescriptions[RSK_SCRUBS_PRICES], WIDGET_CVAR_COMBOBOX, RO_PRICE_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES, {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPrices"), WIDGET_CVAR_COMBOBOX, RO_PRICE_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_CALLBACK(RSK_SCRUBS_PRICES, {
bool isTycoon = CVarGetInteger(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), RO_GENERIC_OFF);
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ScrubsPrices"), RO_PRICE_VANILLA)) {
@@ -791,16 +790,16 @@ void Settings::CreateOptions() {
break;
}
});
OPT_U8(RSK_SCRUBS_PRICES_FIXED_PRICE, "Scrubs Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), mOptionDescriptions[RSK_SCRUBS_PRICES_FIXED_PRICE], WIDGET_CVAR_SLIDER_INT, 10, true);
OPT_U8(RSK_SCRUBS_PRICES_RANGE_1, "Scrubs Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_1], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_RANGE_2, "Scrubs Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_2], WIDGET_CVAR_SLIDER_INT, 100, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT, "Scrubs No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT, "Scrubs Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT, "Scrubs Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT, "Scrubs Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsGiantWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT, "Scrubs Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_SCRUBS_PRICES_AFFORDABLE, "Scrubs Affordable Prices", CVAR_RANDOMIZER_SETTING("ScrubsPricesAffordable"), mOptionDescriptions[RSK_SCRUBS_PRICES_AFFORDABLE]);
OPT_BOOL(RSK_SHUFFLE_BEEHIVES, "Shuffle Beehives", CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), mOptionDescriptions[RSK_SHUFFLE_BEEHIVES]);
OPT_U8(RSK_SCRUBS_PRICES_FIXED_PRICE, {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), WIDGET_CVAR_SLIDER_INT, 10, true);
OPT_U8(RSK_SCRUBS_PRICES_RANGE_1, {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_RANGE_2, {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"), WIDGET_CVAR_SLIDER_INT, 100, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsGiantWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_SCRUBS_PRICES_AFFORDABLE, CVAR_RANDOMIZER_SETTING("ScrubsPricesAffordable"));
OPT_BOOL(RSK_SHUFFLE_BEEHIVES, CVAR_RANDOMIZER_SETTING("ShuffleBeehives"));
OPT_CALLBACK(RSK_SHUFFLE_BEEHIVES, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_OFF)) {
mOptions[RSK_SLINGBOW_BREAK_BEEHIVES].Enable();
@@ -809,7 +808,7 @@ void Settings::CreateOptions() {
"This option is disabled because Shuffle Beehives is not enabled.");
}
});
OPT_BOOL(RSK_SHUFFLE_COWS, "Shuffle Cows", CVAR_RANDOMIZER_SETTING("ShuffleCows"), mOptionDescriptions[RSK_SHUFFLE_COWS]);
OPT_BOOL(RSK_SHUFFLE_COWS, CVAR_RANDOMIZER_SETTING("ShuffleCows"));
OPT_CALLBACK(RSK_SHUFFLE_COWS, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCows"), RO_GENERIC_OFF)) {
mOptions[RSK_MALON_HINT].Enable();
@@ -817,10 +816,10 @@ void Settings::CreateOptions() {
mOptions[RSK_MALON_HINT].Disable("Malon's hint points to a cow, so requires cows to be shuffled.");
}
});
OPT_BOOL(RSK_SHUFFLE_KOKIRI_SWORD, "Shuffle Kokiri Sword", CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), mOptionDescriptions[RSK_SHUFFLE_KOKIRI_SWORD]);
OPT_BOOL(RSK_SHUFFLE_MASTER_SWORD, "Shuffle Master Sword", CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), mOptionDescriptions[RSK_SHUFFLE_MASTER_SWORD]);
OPT_BOOL(RSK_SWORDLESS_EPONA_ITEMS, "Swordless Epona Items", CVAR_RANDOMIZER_SETTING("SwordlessEponaItems"), mOptionDescriptions[RSK_SWORDLESS_EPONA_ITEMS]);
OPT_BOOL(RSK_SHUFFLE_CHILD_WALLET, "Shuffle Child's Wallet", CVAR_RANDOMIZER_SETTING("ShuffleChildWallet"), mOptionDescriptions[RSK_SHUFFLE_CHILD_WALLET], IMFLAG_NONE);
OPT_BOOL(RSK_SHUFFLE_KOKIRI_SWORD, CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"));
OPT_BOOL(RSK_SHUFFLE_MASTER_SWORD, CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"));
OPT_BOOL(RSK_SWORDLESS_EPONA_ITEMS, CVAR_RANDOMIZER_SETTING("SwordlessEponaItems"));
OPT_BOOL(RSK_SHUFFLE_CHILD_WALLET, CVAR_RANDOMIZER_SETTING("ShuffleChildWallet"), IMFLAG_NONE);
OPT_CALLBACK(RSK_SHUFFLE_CHILD_WALLET, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleChildWallet"), 0)) {
CVarSetInteger(CVAR_RANDOMIZER_SETTING("StartingWallet"), 0);
@@ -829,13 +828,13 @@ void Settings::CreateOptions() {
mOptions[RSK_STARTING_WALLET].Enable();
}
});
OPT_BOOL(RSK_INCLUDE_TYCOON_WALLET, "Include Tycoon Wallet", CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), mOptionDescriptions[RSK_INCLUDE_TYCOON_WALLET]);
OPT_BOOL(RSK_SHUFFLE_OCARINA, "Shuffle Ocarinas", CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), mOptionDescriptions[RSK_SHUFFLE_OCARINA]);
OPT_BOOL(RSK_INCLUDE_TYCOON_WALLET, CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"));
OPT_BOOL(RSK_SHUFFLE_OCARINA, CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"));
OPT_CALLBACK(RSK_SHUFFLE_OCARINA, {
HandleStartingAgeUI();
});
OPT_BOOL(RSK_SHUFFLE_OCARINA_BUTTONS, "Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]);
OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]);
OPT_BOOL(RSK_SHUFFLE_OCARINA_BUTTONS, CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"));
OPT_BOOL(RSK_SHUFFLE_SWIM, CVAR_RANDOMIZER_SETTING("ShuffleSwim"));
OPT_CALLBACK(RSK_SHUFFLE_SWIM, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleSwim"), 0)) {
CVarSetInteger(CVAR_RANDOMIZER_SETTING("StartingScale"), 0);
@@ -844,9 +843,9 @@ void Settings::CreateOptions() {
mOptions[RSK_STARTING_SCALE].Enable();
}
});
OPT_BOOL(RSK_SHUFFLE_CLIMB, "Shuffle Climb", CVAR_RANDOMIZER_SETTING("ShuffleClimb"), mOptionDescriptions[RSK_SHUFFLE_CLIMB]);
OPT_BOOL(RSK_SHUFFLE_CRAWL, "Shuffle Crawl", CVAR_RANDOMIZER_SETTING("ShuffleCrawl"), mOptionDescriptions[RSK_SHUFFLE_CRAWL]);
OPT_BOOL(RSK_SHUFFLE_GRAB, "Shuffle Grab", CVAR_RANDOMIZER_SETTING("ShuffleGrab"), mOptionDescriptions[RSK_SHUFFLE_GRAB]);
OPT_BOOL(RSK_SHUFFLE_CLIMB, CVAR_RANDOMIZER_SETTING("ShuffleClimb"));
OPT_BOOL(RSK_SHUFFLE_CRAWL, CVAR_RANDOMIZER_SETTING("ShuffleCrawl"));
OPT_BOOL(RSK_SHUFFLE_GRAB, CVAR_RANDOMIZER_SETTING("ShuffleGrab"));
OPT_CALLBACK(RSK_SHUFFLE_GRAB, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGrab"), 0)) {
CVarSetInteger(CVAR_RANDOMIZER_SETTING("StartingStrength"), 0);
@@ -855,22 +854,22 @@ void Settings::CreateOptions() {
mOptions[RSK_STARTING_STRENGTH].Enable();
}
});
OPT_BOOL(RSK_SHUFFLE_SPEAK, "Shuffle Jabber Nuts", CVAR_RANDOMIZER_SETTING("ShuffleSpeak"), mOptionDescriptions[RSK_SHUFFLE_SPEAK]);
OPT_U8(RSK_SHUFFLE_OPEN_CHEST, "Shuffle Open Chest", {"Off", "On", "Progressive"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleOpenChest"), mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST], WIDGET_CVAR_COMBOBOX, RO_OPEN_CHEST_OFF);
OPT_U8(RSK_SHUFFLE_WEIRD_EGG, "Shuffle Weird Egg", {"Vanilla", "Shuffled", "Skip Waking Talon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG], WIDGET_CVAR_COMBOBOX, RO_WEIRD_EGG_VANILLA);
OPT_BOOL(RSK_SHUFFLE_ZELDAS_LETTER, "Shuffle Zelda's Letter", CVAR_RANDOMIZER_SETTING("ShuffleZeldasLetter"), mOptionDescriptions[RSK_SHUFFLE_ZELDAS_LETTER]);
OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, "Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]);
OPT_U8(RSK_SHUFFLE_POTS, "Shuffle Pots", {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), mOptionDescriptions[RSK_SHUFFLE_POTS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_POTS_OFF);
OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_GRASS_OFF);
OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_CRATES_OFF);
OPT_BOOL(RSK_SHUFFLE_ROCKS, "Shuffle Rocks", CVAR_RANDOMIZER_SETTING("ShuffleRocks"), mOptionDescriptions[RSK_SHUFFLE_ROCKS]);
OPT_U8(RSK_SHUFFLE_BOULDERS, "Shuffle Boulders", {"Off", "Dungeons", "Overworld", "All Boulders"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBoulders"), mOptionDescriptions[RSK_SHUFFLE_BOULDERS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_BOULDERS_OFF);
OPT_BOOL(RSK_SHUFFLE_TREES, "Shuffle Trees", CVAR_RANDOMIZER_SETTING("ShuffleTrees"), mOptionDescriptions[RSK_SHUFFLE_TREES]);
OPT_BOOL(RSK_SHUFFLE_BUSHES, "Shuffle Bushes", CVAR_RANDOMIZER_SETTING("ShuffleBushes"), mOptionDescriptions[RSK_SHUFFLE_BUSHES]);
OPT_BOOL(RSK_SHUFFLE_ICICLES, "Shuffle Icicles", CVAR_RANDOMIZER_SETTING("ShuffleIcicles"), mOptionDescriptions[RSK_SHUFFLE_ICICLES]);
OPT_BOOL(RSK_SHUFFLE_RED_ICE, "Shuffle Red Ice", CVAR_RANDOMIZER_SETTING("ShuffleRedIce"), mOptionDescriptions[RSK_SHUFFLE_RED_ICE]);
OPT_U8(RSK_SHUFFLE_SIGNS, "Shuffle Signs", {"Off", "Dungeons", "Overworld", "All Signs"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSigns"), mOptionDescriptions[RSK_SHUFFLE_SIGNS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_SIGNS_OFF);
OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, "Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]);
OPT_BOOL(RSK_SHUFFLE_SPEAK, CVAR_RANDOMIZER_SETTING("ShuffleSpeak"));
OPT_U8(RSK_SHUFFLE_OPEN_CHEST, {"Off", "On", "Progressive"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleOpenChest"), WIDGET_CVAR_COMBOBOX, RO_OPEN_CHEST_OFF);
OPT_U8(RSK_SHUFFLE_WEIRD_EGG, {"Vanilla", "Shuffled", "Skip Waking Talon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), WIDGET_CVAR_COMBOBOX, RO_WEIRD_EGG_VANILLA);
OPT_BOOL(RSK_SHUFFLE_ZELDAS_LETTER, CVAR_RANDOMIZER_SETTING("ShuffleZeldasLetter"));
OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"));
OPT_U8(RSK_SHUFFLE_POTS, {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_POTS_OFF);
OPT_U8(RSK_SHUFFLE_GRASS, {"Off", "Dungeons", "Overworld", "All Grass"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_GRASS_OFF);
OPT_U8(RSK_SHUFFLE_CRATES, {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_CRATES_OFF);
OPT_BOOL(RSK_SHUFFLE_ROCKS, CVAR_RANDOMIZER_SETTING("ShuffleRocks"));
OPT_U8(RSK_SHUFFLE_BOULDERS, {"Off", "Dungeons", "Overworld", "All Boulders"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBoulders"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_BOULDERS_OFF);
OPT_BOOL(RSK_SHUFFLE_TREES, CVAR_RANDOMIZER_SETTING("ShuffleTrees"));
OPT_BOOL(RSK_SHUFFLE_BUSHES, CVAR_RANDOMIZER_SETTING("ShuffleBushes"));
OPT_BOOL(RSK_SHUFFLE_ICICLES, CVAR_RANDOMIZER_SETTING("ShuffleIcicles"));
OPT_BOOL(RSK_SHUFFLE_RED_ICE, CVAR_RANDOMIZER_SETTING("ShuffleRedIce"));
OPT_U8(RSK_SHUFFLE_SIGNS, {"Off", "Dungeons", "Overworld", "All Signs"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSigns"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_SIGNS_OFF);
OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"));
OPT_CALLBACK(RSK_SHUFFLE_FISHING_POLE, {
// Disable fishing pole hint if the fishing pole is not shuffled
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), RO_GENERIC_OFF)) {
@@ -879,7 +878,7 @@ void Settings::CreateOptions() {
mOptions[RSK_FISHING_POLE_HINT].Disable("This option is disabled since the fishing pole is not shuffled.");
}
});
OPT_U8(RSK_SHUFFLE_MERCHANTS, "Shuffle Merchants", {"Off", "Bean Merchant Only", "All But Beans", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), mOptionDescriptions[RSK_SHUFFLE_MERCHANTS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_MERCHANTS_OFF, IMFLAG_NONE);
OPT_U8(RSK_SHUFFLE_MERCHANTS, {"Off", "Bean Merchant Only", "All But Beans", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_MERCHANTS_OFF, IMFLAG_NONE);
OPT_CALLBACK(RSK_SHUFFLE_MERCHANTS, {
bool isTycoon = CVarGetInteger(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), RO_GENERIC_OFF);
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_OFF)) {
@@ -962,7 +961,7 @@ void Settings::CreateOptions() {
break;
}
});
OPT_U8(RSK_MERCHANT_PRICES, "Merchant Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPrices"), mOptionDescriptions[RSK_MERCHANT_PRICES], WIDGET_CVAR_COMBOBOX, RO_PRICE_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES, {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPrices"), WIDGET_CVAR_COMBOBOX, RO_PRICE_VANILLA, false, nullptr, IMFLAG_NONE);
OPT_CALLBACK(RSK_MERCHANT_PRICES, {
bool isTycoon = CVarGetInteger(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), RO_GENERIC_OFF);
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MerchantPrices"), RO_PRICE_VANILLA)) {
@@ -1028,18 +1027,18 @@ void Settings::CreateOptions() {
break;
}
});
OPT_U8(RSK_MERCHANT_PRICES_FIXED_PRICE, "Merchant Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"), mOptionDescriptions[RSK_MERCHANT_PRICES_FIXED_PRICE], WIDGET_CVAR_SLIDER_INT, 10, true);
OPT_U8(RSK_MERCHANT_PRICES_RANGE_1, "Merchant Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_1], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_RANGE_2, "Merchant Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_2], WIDGET_CVAR_SLIDER_INT, 100, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT, "Merchant No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT, "Merchant Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT, "Merchant Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT, "Merchant Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT, "Merchant Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_MERCHANT_PRICES_AFFORDABLE, "Merchant Affordable Prices", CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"), mOptionDescriptions[RSK_MERCHANT_PRICES_AFFORDABLE]);
OPT_BOOL(RSK_SHUFFLE_BEGGAR, "Shuffle Beggar", CVAR_RANDOMIZER_SETTING("ShuffleBeggar"), mOptionDescriptions[RSK_SHUFFLE_BEGGAR]);
OPT_BOOL(RSK_SHUFFLE_FROG_SONG_RUPEES, "Shuffle Frog Song Rupees", CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES]);
OPT_BOOL(RSK_SHUFFLE_ADULT_TRADE, "Shuffle Adult Trade", CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]);
OPT_U8(RSK_MERCHANT_PRICES_FIXED_PRICE, {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"), WIDGET_CVAR_SLIDER_INT, 10, true);
OPT_U8(RSK_MERCHANT_PRICES_RANGE_1, {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_RANGE_2, {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"), WIDGET_CVAR_SLIDER_INT, 100, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_MERCHANT_PRICES_AFFORDABLE, CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"));
OPT_BOOL(RSK_SHUFFLE_BEGGAR, CVAR_RANDOMIZER_SETTING("ShuffleBeggar"));
OPT_BOOL(RSK_SHUFFLE_FROG_SONG_RUPEES, CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"));
OPT_BOOL(RSK_SHUFFLE_ADULT_TRADE, CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"));
OPT_CALLBACK(RSK_SHUFFLE_ADULT_TRADE, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), RO_GENERIC_OFF)) {
mOptions[RSK_EARLY_GRANNYS_SHOP].Disable("This has no effect when Shuffle Adult Trade is on.");
@@ -1047,11 +1046,11 @@ void Settings::CreateOptions() {
mOptions[RSK_EARLY_GRANNYS_SHOP].Enable();
}
});
OPT_BOOL(RSK_SHUFFLE_CHEST_MINIGAME, "Shuffle Chest Minigame", CVAR_RANDOMIZER_SETTING("ShuffleChestMinigame"), mOptionDescriptions[RSK_SHUFFLE_CHEST_MINIGAME]);
OPT_BOOL(RSK_SHUFFLE_CHEST_MINIGAME, CVAR_RANDOMIZER_SETTING("ShuffleChestMinigame"));
OPT_CALLBACK(RSK_SHUFFLE_CHEST_MINIGAME, {
HandleKeyringUI();
});
OPT_BOOL(RSK_SHUFFLE_100_GS_REWARD, "Shuffle 100 GS Reward", CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), mOptionDescriptions[RSK_SHUFFLE_100_GS_REWARD], IMFLAG_SEPARATOR_BOTTOM, WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_SHUFFLE_100_GS_REWARD, CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), IMFLAG_SEPARATOR_BOTTOM, WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_CALLBACK(RSK_SHUFFLE_100_GS_REWARD, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), RO_GENERIC_OFF)) {
mOptions[RSK_KAK_100_SKULLS_HINT].Enable();
@@ -1059,9 +1058,9 @@ void Settings::CreateOptions() {
mOptions[RSK_KAK_100_SKULLS_HINT].Disable("There is no point to hinting 100 skulls if it is not shuffled.");
}
});
OPT_BOOL(RSK_SHUFFLE_BEAN_SOULS, "Shuffle Bean Souls", CVAR_RANDOMIZER_SETTING("ShuffleBeanSouls"), mOptionDescriptions[RSK_SHUFFLE_BEAN_SOULS], IMFLAG_SEPARATOR_BOTTOM, WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_U8(RSK_SHUFFLE_BOSS_SOULS, "Shuffle Boss Souls", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WIDGET_CVAR_COMBOBOX);
OPT_BOOL(RSK_SHUFFLE_DEKU_STICK_BAG, "Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_SHUFFLE_BEAN_SOULS, CVAR_RANDOMIZER_SETTING("ShuffleBeanSouls"), IMFLAG_SEPARATOR_BOTTOM, WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_U8(RSK_SHUFFLE_BOSS_SOULS, {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), WIDGET_CVAR_COMBOBOX);
OPT_BOOL(RSK_SHUFFLE_DEKU_STICK_BAG, CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), IMFLAG_SEPARATOR_BOTTOM, WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_CALLBACK(RSK_SHUFFLE_DEKU_STICK_BAG, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), 0)) {
mOptions[RSK_STARTING_STICKS].Disable("Disabled because Shuffle Deku Stick Bag is on.");
@@ -1069,7 +1068,7 @@ void Settings::CreateOptions() {
mOptions[RSK_STARTING_STICKS].Enable();
}
});
OPT_BOOL(RSK_SHUFFLE_DEKU_NUT_BAG, "Shuffle Deku Nut Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG], IMFLAG_SEPARATOR_BOTTOM, WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_SHUFFLE_DEKU_NUT_BAG, CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), IMFLAG_SEPARATOR_BOTTOM, WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_CALLBACK(RSK_SHUFFLE_DEKU_NUT_BAG, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), 0)) {
mOptions[RSK_STARTING_NUTS].Disable("Disabled because Shuffle Deku Nut Bag is on.");
@@ -1077,10 +1076,10 @@ void Settings::CreateOptions() {
mOptions[RSK_STARTING_NUTS].Enable();
}
});
OPT_U8(RSK_SHUFFLE_FREESTANDING, "Shuffle Freestanding Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), mOptionDescriptions[RSK_SHUFFLE_FREESTANDING], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_FREESTANDING_OFF);
OPT_U8(RSK_SHUFFLE_WONDER_ITEMS, "Shuffle Wonder Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleWonderItems"), mOptionDescriptions[RSK_SHUFFLE_WONDER_ITEMS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_WONDER_ITEMS_OFF);
OPT_U8(RSK_SHUFFLE_SILVER, "Shuffle Silver Rupees", {"Off", "On", "Wallet", "Start With"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSilver"), mOptionDescriptions[RSK_SHUFFLE_SILVER], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_SILVER_OFF);
OPT_U8(RSK_FISHSANITY, "Fishsanity", {"Off", "Shuffle only Hyrule Loach", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WIDGET_CVAR_COMBOBOX, RO_FISHSANITY_OFF);
OPT_U8(RSK_SHUFFLE_FREESTANDING, {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_FREESTANDING_OFF);
OPT_U8(RSK_SHUFFLE_WONDER_ITEMS, {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleWonderItems"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_WONDER_ITEMS_OFF);
OPT_U8(RSK_SHUFFLE_SILVER, {"Off", "On", "Wallet", "Start With"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSilver"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_SILVER_OFF);
OPT_U8(RSK_FISHSANITY, {"Off", "Shuffle only Hyrule Loach", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), WIDGET_CVAR_COMBOBOX, RO_FISHSANITY_OFF);
OPT_CALLBACK(RSK_FISHSANITY, {
// Hide fishing pond settings if we aren't shuffling the fishing pond
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_FISHSANITY_OFF)) {
@@ -1101,21 +1100,21 @@ void Settings::CreateOptions() {
"setting where you present the loach to the fishing pond owner.");
}
});
OPT_U8(RSK_FISHSANITY_POND_COUNT, "Pond Fish Count", {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), mOptionDescriptions[RSK_FISHSANITY_POND_COUNT], WIDGET_CVAR_SLIDER_INT, 0, true, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_FISHSANITY_AGE_SPLIT, "Pond Age Split", CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT]);
OPT_BOOL(RSK_SHUFFLE_FOUNTAIN_FAIRIES, "Shuffle Fairies in Fountains", CVAR_RANDOMIZER_SETTING("ShuffleFountainFairies"), mOptionDescriptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES]);
OPT_BOOL(RSK_SHUFFLE_STONE_FAIRIES, "Shuffle Gossip Stone Fairies", CVAR_RANDOMIZER_SETTING("ShuffleStoneFairies"), mOptionDescriptions[RSK_SHUFFLE_STONE_FAIRIES]);
OPT_BOOL(RSK_SHUFFLE_BEAN_FAIRIES, "Shuffle Bean Fairies", CVAR_RANDOMIZER_SETTING("ShuffleBeanFairies"), mOptionDescriptions[RSK_SHUFFLE_BEAN_FAIRIES]);
OPT_BOOL(RSK_SHUFFLE_SONG_FAIRIES, "Shuffle Fairy Spots", CVAR_RANDOMIZER_SETTING("ShuffleFairySpots"), mOptionDescriptions[RSK_SHUFFLE_SONG_FAIRIES]);
OPT_BOOL(RSK_SHUFFLE_BUTTERFLY_FAIRIES, "Shuffle Butterfly Fairies", CVAR_RANDOMIZER_SETTING("ShuffleButterflyFairies"), mOptionDescriptions[RSK_SHUFFLE_BUTTERFLY_FAIRIES]);
OPT_U8(RSK_SHUFFLE_MAPANDCOMPASS, "Maps/Compasses", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), mOptionDescriptions[RSK_SHUFFLE_MAPANDCOMPASS], WIDGET_CVAR_COMBOBOX, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON);
OPT_U8(RSK_KEYSANITY, "Small Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Keysanity"), mOptionDescriptions[RSK_KEYSANITY], WIDGET_CVAR_COMBOBOX, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON);
OPT_U8(RSK_GERUDO_KEYS, "Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoKeys"), mOptionDescriptions[RSK_GERUDO_KEYS], WIDGET_CVAR_COMBOBOX, RO_GERUDO_KEYS_VANILLA);
OPT_U8(RSK_FISHSANITY_POND_COUNT, {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), WIDGET_CVAR_SLIDER_INT, 0, true, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_FISHSANITY_AGE_SPLIT, CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"));
OPT_BOOL(RSK_SHUFFLE_FOUNTAIN_FAIRIES, CVAR_RANDOMIZER_SETTING("ShuffleFountainFairies"));
OPT_BOOL(RSK_SHUFFLE_STONE_FAIRIES, CVAR_RANDOMIZER_SETTING("ShuffleStoneFairies"));
OPT_BOOL(RSK_SHUFFLE_BEAN_FAIRIES, CVAR_RANDOMIZER_SETTING("ShuffleBeanFairies"));
OPT_BOOL(RSK_SHUFFLE_SONG_FAIRIES, CVAR_RANDOMIZER_SETTING("ShuffleFairySpots"));
OPT_BOOL(RSK_SHUFFLE_BUTTERFLY_FAIRIES, CVAR_RANDOMIZER_SETTING("ShuffleButterflyFairies"));
OPT_U8(RSK_SHUFFLE_MAPANDCOMPASS, {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), WIDGET_CVAR_COMBOBOX, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON);
OPT_U8(RSK_KEYSANITY, {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Keysanity"), WIDGET_CVAR_COMBOBOX, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON);
OPT_U8(RSK_GERUDO_KEYS, {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoKeys"), WIDGET_CVAR_COMBOBOX, RO_GERUDO_KEYS_VANILLA);
OPT_CALLBACK(RSK_GERUDO_KEYS, {
HandleKeyringUI();
});
OPT_U8(RSK_BOSS_KEYSANITY, "Boss Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BossKeysanity"), mOptionDescriptions[RSK_BOSS_KEYSANITY], WIDGET_CVAR_COMBOBOX, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON);
OPT_U8(RSK_GANONS_BOSS_KEY, "Ganon's Boss Key", {"Vanilla", "Own Dungeon", "Start With", "Any Dungeon", "Overworld", "Anywhere", "Trigger-Stones", "Trigger-Medallions", "Trigger-Rewards", "Trigger-Dungeons", "Trigger-Tokens", "Trigger-Triforce Pieces"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), mOptionDescriptions[RSK_GANONS_BOSS_KEY], WIDGET_CVAR_COMBOBOX, RO_GANON_BOSS_KEY_VANILLA);
OPT_U8(RSK_BOSS_KEYSANITY, {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BossKeysanity"), WIDGET_CVAR_COMBOBOX, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON);
OPT_U8(RSK_GANONS_BOSS_KEY, {"Vanilla", "Own Dungeon", "Start With", "Any Dungeon", "Overworld", "Anywhere", "Trigger-Stones", "Trigger-Medallions", "Trigger-Rewards", "Trigger-Dungeons", "Trigger-Tokens", "Trigger-Triforce Pieces"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), WIDGET_CVAR_COMBOBOX, RO_GANON_BOSS_KEY_VANILLA);
OPT_CALLBACK(RSK_GANONS_BOSS_KEY, {
mOptions[RSK_GBK_OPTIONS].Hide();
mOptions[RSK_GBK_STONE_COUNT].Hide();
@@ -1149,13 +1148,13 @@ void Settings::CreateOptions() {
break;
}
});
OPT_U8(RSK_GBK_STONE_COUNT, "GBK Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkStoneCount"), "", WIDGET_CVAR_SLIDER_INT, 3, true);
OPT_U8(RSK_GBK_MEDALLION_COUNT, "GBK Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkMedallionCount"), "", WIDGET_CVAR_SLIDER_INT, 6, true);
OPT_U8(RSK_GBK_REWARD_COUNT, "GBK Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkRewardCount"), "", WIDGET_CVAR_SLIDER_INT, 9, true);
OPT_U8(RSK_GBK_DUNGEON_COUNT, "GBK Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkDungeonCount"), "", WIDGET_CVAR_SLIDER_INT, 8, true);
OPT_U8(RSK_GBK_TOKEN_COUNT, "GBK Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkTokenCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_GBK_TRIFORCE_COUNT, "GBK Triforce Piece Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkTriforceCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_GBK_OPTIONS, "GBK Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkRewardOptions"), mOptionDescriptions[RSK_GBK_OPTIONS], WIDGET_CVAR_COMBOBOX, RO_CHECK_TRIGGER_STANDARD_REWARD);
OPT_U8(RSK_GBK_STONE_COUNT, {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkStoneCount"), WIDGET_CVAR_SLIDER_INT, 3, true);
OPT_U8(RSK_GBK_MEDALLION_COUNT, {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkMedallionCount"), WIDGET_CVAR_SLIDER_INT, 6, true);
OPT_U8(RSK_GBK_REWARD_COUNT, {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkRewardCount"), WIDGET_CVAR_SLIDER_INT, 9, true);
OPT_U8(RSK_GBK_DUNGEON_COUNT, {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkDungeonCount"), WIDGET_CVAR_SLIDER_INT, 8, true);
OPT_U8(RSK_GBK_TOKEN_COUNT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkTokenCount"), WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_GBK_TRIFORCE_COUNT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkTriforceCount"), WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_GBK_OPTIONS, {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GbkRewardOptions"), WIDGET_CVAR_COMBOBOX, RO_CHECK_TRIGGER_STANDARD_REWARD);
OPT_CALLBACK(RSK_GBK_OPTIONS, {
const uint8_t gbkOpts = CVarGetInteger(CVAR_RANDOMIZER_SETTING("GbkRewardOptions"), RO_CHECK_TRIGGER_STANDARD_REWARD);
if (gbkOpts == RO_CHECK_TRIGGER_GREG_REWARD) {
@@ -1170,7 +1169,7 @@ void Settings::CreateOptions() {
mOptions[RSK_GBK_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8));
}
});
OPT_U8(RSK_GANONS_SOUL, "Ganon's Soul", {"Start With", "Any Dungeon", "Overworld", "Anywhere", "Trigger-Stones", "Trigger-Medallions", "Trigger-Rewards", "Trigger-Dungeons", "Trigger-Tokens", "Trigger-Triforce Pieces"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonsSoul"), mOptionDescriptions[RSK_GANONS_SOUL], WIDGET_CVAR_COMBOBOX, RO_GANONS_SOUL_STARTWITH);
OPT_U8(RSK_GANONS_SOUL, {"Start With", "Any Dungeon", "Overworld", "Anywhere", "Trigger-Stones", "Trigger-Medallions", "Trigger-Rewards", "Trigger-Dungeons", "Trigger-Tokens", "Trigger-Triforce Pieces"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonsSoul"), WIDGET_CVAR_COMBOBOX, RO_GANONS_SOUL_STARTWITH);
OPT_CALLBACK(RSK_GANONS_SOUL, {
mOptions[RSK_GANONS_SOUL_OPTIONS].Hide();
mOptions[RSK_GANONS_SOUL_STONE_COUNT].Hide();
@@ -1204,13 +1203,13 @@ void Settings::CreateOptions() {
break;
}
});
OPT_U8(RSK_GANONS_SOUL_STONE_COUNT, "Ganon's Soul Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulStoneCount"), "", WIDGET_CVAR_SLIDER_INT, 3, true);
OPT_U8(RSK_GANONS_SOUL_MEDALLION_COUNT, "Ganon's Soul Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulMedallionCount"), "", WIDGET_CVAR_SLIDER_INT, 6, true);
OPT_U8(RSK_GANONS_SOUL_REWARD_COUNT, "Ganon's Soul Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulRewardCount"), "", WIDGET_CVAR_SLIDER_INT, 9, true);
OPT_U8(RSK_GANONS_SOUL_DUNGEON_COUNT, "Ganon's Soul Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulDungeonCount"), "", WIDGET_CVAR_SLIDER_INT, 8, true);
OPT_U8(RSK_GANONS_SOUL_TOKEN_COUNT, "Ganon's Soul Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulTokenCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_GANONS_SOUL_TRIFORCE_COUNT, "Ganon's Soul Triforce Piece Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulTriforceCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_GANONS_SOUL_OPTIONS, "Ganon's Soul Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulRewardOptions"), mOptionDescriptions[RSK_GANONS_SOUL_OPTIONS], WIDGET_CVAR_COMBOBOX, RO_CHECK_TRIGGER_STANDARD_REWARD);
OPT_U8(RSK_GANONS_SOUL_STONE_COUNT, {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulStoneCount"), WIDGET_CVAR_SLIDER_INT, 3, true);
OPT_U8(RSK_GANONS_SOUL_MEDALLION_COUNT, {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulMedallionCount"), WIDGET_CVAR_SLIDER_INT, 6, true);
OPT_U8(RSK_GANONS_SOUL_REWARD_COUNT, {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulRewardCount"), WIDGET_CVAR_SLIDER_INT, 9, true);
OPT_U8(RSK_GANONS_SOUL_DUNGEON_COUNT, {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulDungeonCount"), WIDGET_CVAR_SLIDER_INT, 8, true);
OPT_U8(RSK_GANONS_SOUL_TOKEN_COUNT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulTokenCount"), WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_GANONS_SOUL_TRIFORCE_COUNT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulTriforceCount"), WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_GANONS_SOUL_OPTIONS, {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonsSoulRewardOptions"), WIDGET_CVAR_COMBOBOX, RO_CHECK_TRIGGER_STANDARD_REWARD);
OPT_CALLBACK(RSK_GANONS_SOUL_OPTIONS, {
const uint8_t soulOpts = CVarGetInteger(CVAR_RANDOMIZER_SETTING("GanonsSoulRewardOptions"), RO_CHECK_TRIGGER_STANDARD_REWARD);
if (soulOpts == RO_CHECK_TRIGGER_GREG_REWARD) {
@@ -1225,7 +1224,7 @@ void Settings::CreateOptions() {
mOptions[RSK_GANONS_SOUL_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8));
}
});
OPT_U8(RSK_WINCON, "Win Condition", {"Defeat Ganon", "Anywhere", "Trigger-Stones", "Trigger-Medallions", "Trigger-Rewards", "Trigger-Dungeons", "Trigger-Tokens", "Trigger-Triforce Pieces"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleWincon"), mOptionDescriptions[RSK_WINCON], WIDGET_CVAR_COMBOBOX, RO_WINCON_DEFEAT_GANON);
OPT_U8(RSK_WINCON, {"Defeat Ganon", "Anywhere", "Trigger-Stones", "Trigger-Medallions", "Trigger-Rewards", "Trigger-Dungeons", "Trigger-Tokens", "Trigger-Triforce Pieces"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleWincon"), WIDGET_CVAR_COMBOBOX, RO_WINCON_DEFEAT_GANON);
OPT_CALLBACK(RSK_WINCON, {
mOptions[RSK_WINCON_OPTIONS].Hide();
mOptions[RSK_WINCON_STONE_COUNT].Hide();
@@ -1259,13 +1258,13 @@ void Settings::CreateOptions() {
break;
}
});
OPT_U8(RSK_WINCON_STONE_COUNT, "Win Condition Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconStoneCount"), "", WIDGET_CVAR_SLIDER_INT, 3, true);
OPT_U8(RSK_WINCON_MEDALLION_COUNT, "Win Condition Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconMedallionCount"), "", WIDGET_CVAR_SLIDER_INT, 6, true);
OPT_U8(RSK_WINCON_REWARD_COUNT, "Win Condition Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconRewardCount"), "", WIDGET_CVAR_SLIDER_INT, 9, true);
OPT_U8(RSK_WINCON_DUNGEON_COUNT, "Win Condition Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconDungeonCount"), "", WIDGET_CVAR_SLIDER_INT, 8, true);
OPT_U8(RSK_WINCON_TOKEN_COUNT, "Win Condition Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconTokenCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_WINCON_TRIFORCE_COUNT, "Win Condition Triforce Piece Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconTriforceCount"), "", WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_WINCON_OPTIONS, "Win Condition Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconRewardOptions"), mOptionDescriptions[RSK_WINCON_OPTIONS], WIDGET_CVAR_COMBOBOX, RO_CHECK_TRIGGER_STANDARD_REWARD);
OPT_U8(RSK_WINCON_STONE_COUNT, {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconStoneCount"), WIDGET_CVAR_SLIDER_INT, 3, true);
OPT_U8(RSK_WINCON_MEDALLION_COUNT, {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconMedallionCount"), WIDGET_CVAR_SLIDER_INT, 6, true);
OPT_U8(RSK_WINCON_REWARD_COUNT, {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconRewardCount"), WIDGET_CVAR_SLIDER_INT, 9, true);
OPT_U8(RSK_WINCON_DUNGEON_COUNT, {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconDungeonCount"), WIDGET_CVAR_SLIDER_INT, 8, true);
OPT_U8(RSK_WINCON_TOKEN_COUNT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconTokenCount"), WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_WINCON_TRIFORCE_COUNT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconTriforceCount"), WIDGET_CVAR_SLIDER_INT, 100, true);
OPT_U8(RSK_WINCON_OPTIONS, {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("WinconRewardOptions"), WIDGET_CVAR_COMBOBOX, RO_CHECK_TRIGGER_STANDARD_REWARD);
OPT_CALLBACK(RSK_WINCON_OPTIONS, {
const uint8_t winconOpts = CVarGetInteger(CVAR_RANDOMIZER_SETTING("WinconRewardOptions"), RO_CHECK_TRIGGER_STANDARD_REWARD);
if (winconOpts == RO_CHECK_TRIGGER_GREG_REWARD) {
@@ -1280,7 +1279,7 @@ void Settings::CreateOptions() {
mOptions[RSK_WINCON_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8));
}
});
OPT_U8(RSK_KEYRINGS, "Keyrings", {"Off", "Random", "Count", "Selection"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), mOptionDescriptions[RSK_KEYRINGS], WIDGET_CVAR_COMBOBOX, RO_KEYRINGS_OFF);
OPT_U8(RSK_KEYRINGS, {"Off", "Random", "Count", "Selection"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), WIDGET_CVAR_COMBOBOX, RO_KEYRINGS_OFF);
OPT_CALLBACK(RSK_KEYRINGS, {
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_OFF)) {
case RO_KEYRINGS_COUNT:
@@ -1326,25 +1325,25 @@ void Settings::CreateOptions() {
break;
}
});
OPT_U8(RSK_KEYRINGS_RANDOM_COUNT, "Keyring Dungeon Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), "", WIDGET_CVAR_SLIDER_INT, 8);
OPT_U8(RSK_KEYRINGS_GERUDO_FORTRESS, "Gerudo Fortress Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_FOREST_TEMPLE, "Forest Temple Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsForestTemple"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_FIRE_TEMPLE, "Fire Temple Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsFireTemple"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_WATER_TEMPLE, "Water Temple Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsWaterTemple"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_SPIRIT_TEMPLE, "Spirit Temple Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsSpiritTemple"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_SHADOW_TEMPLE, "Shadow Temple Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsShadowTemple"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_BOTTOM_OF_THE_WELL, "Bottom of the Well Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsBottomOfTheWell"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_GTG, "Gerudo Training Ground Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGTG"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_GANONS_CASTLE, "Ganon's Castle Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGanonsCastle"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_CHEST_GAME, "Chest Minigame Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsChestGame"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_RANDOM_COUNT, {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), WIDGET_CVAR_SLIDER_INT, 8);
OPT_U8(RSK_KEYRINGS_GERUDO_FORTRESS, {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_FOREST_TEMPLE, {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsForestTemple"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_FIRE_TEMPLE, {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsFireTemple"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_WATER_TEMPLE, {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsWaterTemple"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_SPIRIT_TEMPLE, {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsSpiritTemple"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_SHADOW_TEMPLE, {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsShadowTemple"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_BOTTOM_OF_THE_WELL, {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsBottomOfTheWell"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_GTG, {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGTG"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_GANONS_CASTLE, {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGanonsCastle"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_KEYRINGS_CHEST_GAME, {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsChestGame"), WIDGET_CVAR_COMBOBOX, 0);
//Dummied out due to redundancy with TimeSavers.SkipChildStealth until such a time that logic needs to consider child stealth e.g. because it's freestanding checks are added to freestanding shuffle.
//To undo this dummying, readd this setting to an OptionGroup so it appears in the UI, then edit the timesaver check hooks to look at this, and the timesaver setting to lock itself as needed.
OPT_BOOL(RSK_SKIP_CHILD_STEALTH, "Skip Child Stealth", {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipChildStealth"), mOptionDescriptions[RSK_SKIP_CHILD_STEALTH], WIDGET_CVAR_CHECKBOX, RO_GENERIC_DONT_SKIP);
OPT_BOOL(RSK_EARLY_GRANNYS_SHOP, "Early Granny's Potion Shop", CVAR_RANDOMIZER_SETTING("EarlyGrannysShop"), mOptionDescriptions[RSK_EARLY_GRANNYS_SHOP]);
OPT_BOOL(RSK_SKIP_EPONA_RACE, "Skip Epona Race", {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipEponaRace"), mOptionDescriptions[RSK_SKIP_EPONA_RACE], WIDGET_CVAR_CHECKBOX, RO_GENERIC_DONT_SKIP);
OPT_BOOL(RSK_SKIP_SCARECROWS_SONG, "Skip Scarecrow's Song", CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG]);
OPT_BOOL(RSK_SKIP_PLANTING_BEANS, "Skip Planting Beans", CVAR_RANDOMIZER_SETTING("SkipPlantingBeans"), mOptionDescriptions[RSK_SKIP_PLANTING_BEANS]);
OPT_U8(RSK_BIG_POE_COUNT, "Big Poe Target Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), mOptionDescriptions[RSK_BIG_POE_COUNT], WIDGET_CVAR_SLIDER_INT, 10);
OPT_BOOL(RSK_SKIP_CHILD_STEALTH, {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipChildStealth"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_DONT_SKIP);
OPT_BOOL(RSK_EARLY_GRANNYS_SHOP, CVAR_RANDOMIZER_SETTING("EarlyGrannysShop"));
OPT_BOOL(RSK_SKIP_EPONA_RACE, {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipEponaRace"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_DONT_SKIP);
OPT_BOOL(RSK_SKIP_SCARECROWS_SONG, CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"));
OPT_BOOL(RSK_SKIP_PLANTING_BEANS, CVAR_RANDOMIZER_SETTING("SkipPlantingBeans"));
OPT_U8(RSK_BIG_POE_COUNT, {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), WIDGET_CVAR_SLIDER_INT, 10);
OPT_CALLBACK(RSK_BIG_POE_COUNT, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 10) == 0) {
mOptions[RSK_BIG_POES_HINT].Disable("Poe Collector will just give you the item instead with 0 big poes.");
@@ -1352,8 +1351,8 @@ void Settings::CreateOptions() {
mOptions[RSK_BIG_POES_HINT].Enable();
}
});
OPT_BOOL(RSK_SHUFFLE_MASKS, "Shuffle Masks", CVAR_RANDOMIZER_SETTING("ShuffleMasks"), mOptionDescriptions[RSK_SHUFFLE_MASKS]);
OPT_U8(RSK_GOSSIP_STONE_HINTS, "Gossip Stone Hints", {"No Hints", "Need Nothing", "Mask of Truth", "Stone of Agony"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GossipStoneHints"), mOptionDescriptions[RSK_GOSSIP_STONE_HINTS], WIDGET_CVAR_COMBOBOX, RO_GOSSIP_STONES_NEED_NOTHING, false, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_SHUFFLE_MASKS, CVAR_RANDOMIZER_SETTING("ShuffleMasks"));
OPT_U8(RSK_GOSSIP_STONE_HINTS, {"No Hints", "Need Nothing", "Mask of Truth", "Stone of Agony"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GossipStoneHints"), WIDGET_CVAR_COMBOBOX, RO_GOSSIP_STONES_NEED_NOTHING, false, nullptr, IMFLAG_NONE);
OPT_CALLBACK(RSK_GOSSIP_STONE_HINTS, {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GossipStoneHints"), RO_GOSSIP_STONES_NEED_NOTHING) ==
RO_GOSSIP_STONES_NONE) {
@@ -1364,113 +1363,114 @@ void Settings::CreateOptions() {
mOptions[RSK_HINT_DISTRIBUTION].Unhide();
}
});
OPT_U8(RSK_HINT_CLARITY, "Hint Clarity", {"Obscure", "Ambiguous", "Clear"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("HintClarity"), mOptionDescriptions[RSK_HINT_CLARITY], WIDGET_CVAR_COMBOBOX, RO_HINT_CLARITY_CLEAR, true, nullptr, IMFLAG_INDENT);
OPT_U8(RSK_HINT_DISTRIBUTION, "Hint Distribution", {"Useless", "Balanced", "Strong", "Very Strong"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("HintDistribution"), mOptionDescriptions[RSK_HINT_DISTRIBUTION], WIDGET_CVAR_COMBOBOX, RO_HINT_DIST_BALANCED, true, nullptr, IMFLAG_UNINDENT);
OPT_BOOL(RSK_TOT_ALTAR_HINT, "ToT Altar Hint", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("AltarHint"), mOptionDescriptions[RSK_TOT_ALTAR_HINT], WIDGET_CVAR_CHECKBOX, RO_GENERIC_ON, false, nullptr, IMFLAG_INDENT);
OPT_BOOL(RSK_GANONDORF_HINT, "Ganondorf Hint", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanondorfHint"), mOptionDescriptions[RSK_GANONDORF_HINT], WIDGET_CVAR_CHECKBOX, RO_GENERIC_ON, false, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_SHEIK_LA_HINT, "Sheik Light Arrow Hint", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SheikLAHint"), mOptionDescriptions[RSK_SHEIK_LA_HINT], WIDGET_CVAR_CHECKBOX, RO_GENERIC_ON, false, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_BOSS_KEY_HINT, "Boss Door Hints", CVAR_RANDOMIZER_SETTING("BossKeyHint"), mOptionDescriptions[RSK_BOSS_KEY_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_DAMPES_DIARY_HINT, "Dampe's Diary Hint", CVAR_RANDOMIZER_SETTING("DampeHint"), mOptionDescriptions[RSK_DAMPES_DIARY_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_GREG_HINT, "Greg the Green Rupee Hint", CVAR_RANDOMIZER_SETTING("GregHint"), mOptionDescriptions[RSK_GREG_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_LOACH_HINT, "Hyrule Loach Hint", CVAR_RANDOMIZER_SETTING("LoachHint"), mOptionDescriptions[RSK_LOACH_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_SARIA_HINT, "Saria's Hint", CVAR_RANDOMIZER_SETTING("SariaHint"), mOptionDescriptions[RSK_SARIA_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_MIDO_HINT, "Mido's Hint", CVAR_RANDOMIZER_SETTING("MidoHint"), mOptionDescriptions[RSK_MIDO_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_FISHING_POLE_HINT, "Fishing Pole Hint", CVAR_RANDOMIZER_SETTING("FishingPoleHint"), mOptionDescriptions[RSK_FISHING_POLE_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_FROGS_HINT, "Frog Ocarina Game Hint", CVAR_RANDOMIZER_SETTING("FrogsHint"), mOptionDescriptions[RSK_FROGS_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_OOT_HINT, "Ocarina of Time Hint", CVAR_RANDOMIZER_SETTING("OoTHint"), mOptionDescriptions[RSK_OOT_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_BIGGORON_HINT, "Biggoron's Hint", CVAR_RANDOMIZER_SETTING("BiggoronHint"), mOptionDescriptions[RSK_BIGGORON_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_BIG_POES_HINT, "Big Poes Hint", CVAR_RANDOMIZER_SETTING("BigPoesHint"), mOptionDescriptions[RSK_BIG_POES_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_CHICKENS_HINT, "Chickens Hint", CVAR_RANDOMIZER_SETTING("ChickensHint"), mOptionDescriptions[RSK_CHICKENS_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_MALON_HINT, "Malon Hint", CVAR_RANDOMIZER_SETTING("MalonHint"), mOptionDescriptions[RSK_MALON_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_HBA_HINT, "Horseback Archery Hint", CVAR_RANDOMIZER_SETTING("HBAHint"), mOptionDescriptions[RSK_HBA_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_WARP_SONG_HINTS, "Warp Song Hints", CVAR_RANDOMIZER_SETTING("WarpSongText"), mOptionDescriptions[RSK_WARP_SONG_HINTS], IMFLAG_NONE, WIDGET_CVAR_CHECKBOX, RO_GENERIC_ON);
OPT_BOOL(RSK_SCRUB_TEXT_HINT, "Scrub Hint Text", CVAR_RANDOMIZER_SETTING("ScrubText"), mOptionDescriptions[RSK_SCRUB_TEXT_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_MERCHANT_TEXT_HINT, "Merchant Hint Text", CVAR_RANDOMIZER_SETTING("MerchantText"), mOptionDescriptions[RSK_MERCHANT_TEXT_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_KAK_10_SKULLS_HINT, "10 GS Hint", CVAR_RANDOMIZER_SETTING("10GSHint"), mOptionDescriptions[RSK_KAK_10_SKULLS_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_KAK_20_SKULLS_HINT, "20 GS Hint", CVAR_RANDOMIZER_SETTING("20GSHint"), mOptionDescriptions[RSK_KAK_20_SKULLS_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_KAK_30_SKULLS_HINT, "30 GS Hint", CVAR_RANDOMIZER_SETTING("30GSHint"), mOptionDescriptions[RSK_KAK_30_SKULLS_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_KAK_40_SKULLS_HINT, "40 GS Hint", CVAR_RANDOMIZER_SETTING("40GSHint"), mOptionDescriptions[RSK_KAK_40_SKULLS_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_KAK_50_SKULLS_HINT, "50 GS Hint", CVAR_RANDOMIZER_SETTING("50GSHint"), mOptionDescriptions[RSK_KAK_50_SKULLS_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_KAK_100_SKULLS_HINT, "100 GS Hint", CVAR_RANDOMIZER_SETTING("100GSHint"), mOptionDescriptions[RSK_KAK_100_SKULLS_HINT], IMFLAG_NONE);
OPT_BOOL(RSK_MASK_SHOP_HINT, "Mask Shop Hint", CVAR_RANDOMIZER_SETTING("MaskShopHint"), mOptionDescriptions[RSK_MASK_SHOP_HINT]);
OPT_U8(RSK_HINT_CLARITY, {"Obscure", "Ambiguous", "Clear"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("HintClarity"), WIDGET_CVAR_COMBOBOX, RO_HINT_CLARITY_CLEAR, true, nullptr, IMFLAG_INDENT);
OPT_U8(RSK_HINT_DISTRIBUTION, {"Useless", "Balanced", "Strong", "Very Strong"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("HintDistribution"), WIDGET_CVAR_COMBOBOX, RO_HINT_DIST_BALANCED, true, nullptr, IMFLAG_UNINDENT);
OPT_BOOL(RSK_TOT_ALTAR_HINT, {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("AltarHint"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_ON, false, nullptr, IMFLAG_INDENT);
// RANDOTODO make this hint text about no dupe hints a global hint for static hints. Add to navi?
OPT_BOOL(RSK_GANONDORF_HINT, {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanondorfHint"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_ON, false, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_SHEIK_LA_HINT, {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SheikLAHint"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_ON, false, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_BOSS_KEY_HINT, CVAR_RANDOMIZER_SETTING("BossKeyHint"), IMFLAG_NONE);
OPT_BOOL(RSK_DAMPES_DIARY_HINT, CVAR_RANDOMIZER_SETTING("DampeHint"), IMFLAG_NONE);
OPT_BOOL(RSK_GREG_HINT, CVAR_RANDOMIZER_SETTING("GregHint"), IMFLAG_NONE);
OPT_BOOL(RSK_LOACH_HINT, CVAR_RANDOMIZER_SETTING("LoachHint"), IMFLAG_NONE);
OPT_BOOL(RSK_SARIA_HINT, CVAR_RANDOMIZER_SETTING("SariaHint"), IMFLAG_NONE);
OPT_BOOL(RSK_MIDO_HINT, CVAR_RANDOMIZER_SETTING("MidoHint"), IMFLAG_NONE);
OPT_BOOL(RSK_FISHING_POLE_HINT, CVAR_RANDOMIZER_SETTING("FishingPoleHint"), IMFLAG_NONE);
OPT_BOOL(RSK_FROGS_HINT, CVAR_RANDOMIZER_SETTING("FrogsHint"), IMFLAG_NONE);
OPT_BOOL(RSK_OOT_HINT, CVAR_RANDOMIZER_SETTING("OoTHint"), IMFLAG_NONE);
OPT_BOOL(RSK_BIGGORON_HINT, CVAR_RANDOMIZER_SETTING("BiggoronHint"), IMFLAG_NONE);
OPT_BOOL(RSK_BIG_POES_HINT, CVAR_RANDOMIZER_SETTING("BigPoesHint"), IMFLAG_NONE);
OPT_BOOL(RSK_CHICKENS_HINT, CVAR_RANDOMIZER_SETTING("ChickensHint"), IMFLAG_NONE);
OPT_BOOL(RSK_MALON_HINT, CVAR_RANDOMIZER_SETTING("MalonHint"), IMFLAG_NONE);
OPT_BOOL(RSK_HBA_HINT, CVAR_RANDOMIZER_SETTING("HBAHint"), IMFLAG_NONE);
OPT_BOOL(RSK_WARP_SONG_HINTS, CVAR_RANDOMIZER_SETTING("WarpSongText"), IMFLAG_NONE, WIDGET_CVAR_CHECKBOX, RO_GENERIC_ON);
OPT_BOOL(RSK_SCRUB_TEXT_HINT, CVAR_RANDOMIZER_SETTING("ScrubText"), IMFLAG_NONE);
OPT_BOOL(RSK_MERCHANT_TEXT_HINT, CVAR_RANDOMIZER_SETTING("MerchantText"), IMFLAG_NONE);
OPT_BOOL(RSK_KAK_10_SKULLS_HINT, CVAR_RANDOMIZER_SETTING("10GSHint"), IMFLAG_NONE);
OPT_BOOL(RSK_KAK_20_SKULLS_HINT, CVAR_RANDOMIZER_SETTING("20GSHint"), IMFLAG_NONE);
OPT_BOOL(RSK_KAK_30_SKULLS_HINT, CVAR_RANDOMIZER_SETTING("30GSHint"), IMFLAG_NONE);
OPT_BOOL(RSK_KAK_40_SKULLS_HINT, CVAR_RANDOMIZER_SETTING("40GSHint"), IMFLAG_NONE);
OPT_BOOL(RSK_KAK_50_SKULLS_HINT, CVAR_RANDOMIZER_SETTING("50GSHint"), IMFLAG_NONE);
OPT_BOOL(RSK_KAK_100_SKULLS_HINT, CVAR_RANDOMIZER_SETTING("100GSHint"), IMFLAG_NONE);
OPT_BOOL(RSK_MASK_SHOP_HINT, CVAR_RANDOMIZER_SETTING("MaskShopHint"));
// TODO: Compasses show rewards/woth, maps show dungeon mode
OPT_BOOL(RSK_BLUE_FIRE_ARROWS, "Blue Fire Arrows", CVAR_RANDOMIZER_SETTING("BlueFireArrows"), mOptionDescriptions[RSK_BLUE_FIRE_ARROWS]);
OPT_BOOL(RSK_SUNLIGHT_ARROWS, "Sunlight Arrows", CVAR_RANDOMIZER_SETTING("SunlightArrows"), mOptionDescriptions[RSK_SUNLIGHT_ARROWS]);
OPT_BOOL(RSK_ROCS_FEATHER, "Roc's Feather", CVAR_RANDOMIZER_SETTING("RocsFeather"), mOptionDescriptions[RSK_ROCS_FEATHER]);
OPT_U8(RSK_INFINITE_UPGRADES, "Infinite Upgrades", {"Off", "Progressive", "Condensed Progressive"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("InfiniteUpgrades"), mOptionDescriptions[RSK_INFINITE_UPGRADES]);
OPT_BOOL(RSK_SKELETON_KEY, "Skeleton Key", CVAR_RANDOMIZER_SETTING("SkeletonKey"), mOptionDescriptions[RSK_SKELETON_KEY]);
OPT_BOOL(RSK_SLINGBOW_BREAK_BEEHIVES, "Slingshot/Bow Can Break Beehives", CVAR_RANDOMIZER_SETTING("SlingBowBeehives"), mOptionDescriptions[RSK_SLINGBOW_BREAK_BEEHIVES]);
OPT_U8(RSK_ITEM_POOL, "Item Pool", {"Plentiful", "Balanced", "Scarce", "Minimal"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ItemPool"), mOptionDescriptions[RSK_ITEM_POOL], WIDGET_CVAR_COMBOBOX, RO_ITEM_POOL_BALANCED);
OPT_BOOL(RSK_BASE_ICE_TRAPS, "Base Ice Traps", CVAR_RANDOMIZER_SETTING("BaseIceTraps"), mOptionDescriptions[RSK_BASE_ICE_TRAPS], IMFLAG_NONE, WIDGET_CVAR_COMBOBOX, RO_GENERIC_ON);
OPT_U8(RSK_ADDITIONAL_ICE_TRAPS, "Additional Ice Traps", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("AdditionalIceTraps"), mOptionDescriptions[RSK_ADDITIONAL_ICE_TRAPS], WIDGET_CVAR_SLIDER_INT, 0);
OPT_U8(RSK_ICE_TRAP_PERCENT, "Ice Trap Percent", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("IceTrapPercent"), mOptionDescriptions[RSK_ICE_TRAP_PERCENT], WIDGET_CVAR_SLIDER_INT, 0);
OPT_BOOL(RSK_BLUE_FIRE_ARROWS, CVAR_RANDOMIZER_SETTING("BlueFireArrows"));
OPT_BOOL(RSK_SUNLIGHT_ARROWS, CVAR_RANDOMIZER_SETTING("SunlightArrows"));
OPT_BOOL(RSK_ROCS_FEATHER, CVAR_RANDOMIZER_SETTING("RocsFeather"));
OPT_U8(RSK_INFINITE_UPGRADES, {"Off", "Progressive", "Condensed Progressive"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("InfiniteUpgrades"));
OPT_BOOL(RSK_SKELETON_KEY, CVAR_RANDOMIZER_SETTING("SkeletonKey"));
OPT_BOOL(RSK_SLINGBOW_BREAK_BEEHIVES, CVAR_RANDOMIZER_SETTING("SlingBowBeehives"));
OPT_U8(RSK_ITEM_POOL, {"Plentiful", "Balanced", "Scarce", "Minimal"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ItemPool"), WIDGET_CVAR_COMBOBOX, RO_ITEM_POOL_BALANCED);
OPT_BOOL(RSK_BASE_ICE_TRAPS, CVAR_RANDOMIZER_SETTING("BaseIceTraps"), IMFLAG_NONE, WIDGET_CVAR_COMBOBOX, RO_GENERIC_ON);
OPT_U8(RSK_ADDITIONAL_ICE_TRAPS, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("AdditionalIceTraps"), WIDGET_CVAR_SLIDER_INT, 0);
OPT_U8(RSK_ICE_TRAP_PERCENT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("IceTrapPercent"), WIDGET_CVAR_SLIDER_INT, 0);
// TODO: Remove Double Defense
OPT_U8(RSK_STARTING_OCARINA, "Start with Ocarina", {"Off", "Fairy Ocarina", "Ocarina of Time"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingOcarina"), "", WIDGET_CVAR_COMBOBOX, RO_STARTING_OCARINA_OFF);
OPT_BOOL(RSK_STARTING_DEKU_SHIELD, "Start with Deku Shield", CVAR_RANDOMIZER_SETTING("StartingDekuShield"));
OPT_BOOL(RSK_STARTING_KOKIRI_SWORD, "Start with Kokiri Sword", CVAR_RANDOMIZER_SETTING("StartingKokiriSword"));
OPT_BOOL(RSK_STARTING_MASTER_SWORD, "Start with Master Sword", CVAR_RANDOMIZER_SETTING("StartingMasterSword"));
OPT_BOOL(RSK_STARTING_STICKS, "Start with Stick Ammo", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSticks"), "", WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_NUTS, "Start with Nut Ammo", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingNuts"), "", WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_BEANS, "Start with Magic Beans", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBeans"), "", WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_MEGATON_HAMMER, "Start with Megaton Hammer", CVAR_RANDOMIZER_SETTING("StartingMegatonHammer"));
OPT_BOOL(RSK_STARTING_BOOMERANG, "Start with Boomerang", CVAR_RANDOMIZER_SETTING("StartingBoomerang"));
OPT_BOOL(RSK_STARTING_LENS_OF_TRUTH, "Start with Lens of Truth", CVAR_RANDOMIZER_SETTING("StartingLensOfTruth"));
OPT_BOOL(RSK_STARTING_DINS_FIRE, "Start with Din's Fire", CVAR_RANDOMIZER_SETTING("StartingDinsFire"));
OPT_BOOL(RSK_STARTING_FARORES_WIND, "Start with Farore's Wind", CVAR_RANDOMIZER_SETTING("StartingFaroresWind"));
OPT_BOOL(RSK_STARTING_NAYRUS_LOVE, "Start with Nayru's Love", CVAR_RANDOMIZER_SETTING("StartingNayrusLove"));
OPT_BOOL(RSK_STARTING_FIRE_ARROWS, "Start with Fire Arrows", CVAR_RANDOMIZER_SETTING("StartingFireArrows"));
OPT_BOOL(RSK_STARTING_ICE_ARROWS, "Start with Ice Arrows", CVAR_RANDOMIZER_SETTING("StartingIceArrows"));
OPT_BOOL(RSK_STARTING_LIGHT_ARROWS, "Start with Light Arrows", CVAR_RANDOMIZER_SETTING("StartingLightArrows"));
OPT_BOOL(RSK_STARTING_IRON_BOOTS, "Start with Iron Boots", CVAR_RANDOMIZER_SETTING("StartingIronBoots"));
OPT_BOOL(RSK_STARTING_HOVER_BOOTS, "Start with Hover Boots", CVAR_RANDOMIZER_SETTING("StartingHoverBoots"));
OPT_BOOL(RSK_STARTING_HYLIAN_SHIELD, "Start with Hylian Shield", CVAR_RANDOMIZER_SETTING("StartingHylianShield"));
OPT_BOOL(RSK_STARTING_MIRROR_SHIELD, "Start with Mirror Shield", CVAR_RANDOMIZER_SETTING("StartingMirrorShield"));
OPT_BOOL(RSK_STARTING_GORON_TUNIC, "Start with Goron Tunic", CVAR_RANDOMIZER_SETTING("StartingGoronTunic"));
OPT_BOOL(RSK_STARTING_ZORA_TUNIC, "Start with Zora Tunic", CVAR_RANDOMIZER_SETTING("StartingZoraTunic"));
OPT_BOOL(RSK_STARTING_STONE_OF_AGONY, "Start with Stone of Agony", CVAR_RANDOMIZER_SETTING("StartingStoneOfAgony"));
OPT_U8(RSK_STARTING_HOOKSHOT, "Start with Hookshot", {"Off", "Hookshot", "Longshot"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingHookshot"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOW, "Start with Bow", {"Off", "Bow (Quiver 30)", "Bow (Quiver 40)", "Bow (Quiver 50)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBow"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_SLINGSHOT, "Start with Slingshot", {"Off", "Slingshot (30)", "Slingshot (40)", "Slingshot (50)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSlingshot"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOMB_BAG, "Start with Bomb Bag", {"Off", "Bomb Bag (20)", "Bomb Bag (30)", "Bomb Bag (40)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBombBag"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_STRENGTH, "Start with Strength Upgrade", {"Off", "Goron's Bracelet", "Silver Gauntlets", "Golden Gauntlets"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingStrength"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_SCALE, "Start with Diving Scale", {"Off", "Silver Scale", "Golden Scale"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingScale"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_WALLET, "Start with Wallet Upgrade", {"Off", "Adult's Wallet", "Giant's Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingWallet"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_MAGIC_METER, "Start with Magic Meter", {"Off", "Single Magic", "Double Magic"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMagicMeter"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOMBCHU_BAG, "Start with Bombchu Bag", {"Off", "Bombchu Bag (20)", "Bombchu Bag (30)", "Bombchu Bag (50)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBombchuBag"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOTTLE_1, "Starting Bottle 1", {"Off", "Empty Bottle", "Bottle with Big Poe", "Ruto's Letter"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle1"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOTTLE_2, "Starting Bottle 2", {"Off", "Empty Bottle", "Bottle with Big Poe"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle2"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOTTLE_3, "Starting Bottle 3", {"Off", "Empty Bottle", "Bottle with Big Poe"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle3"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOTTLE_4, "Starting Bottle 4", {"Off", "Empty Bottle", "Bottle with Big Poe"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle4"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_BOOL(RSK_STARTING_WEIRD_EGG, "Start with Weird Egg", CVAR_RANDOMIZER_SETTING("StartingWeirdEgg"));
OPT_BOOL(RSK_STARTING_ZELDAS_LETTER, "Start with Zelda's Letter", CVAR_RANDOMIZER_SETTING("StartingZeldasLetter"));
OPT_BOOL(RSK_STARTING_CLAIM_CHECK, "Start with Claim Check", CVAR_RANDOMIZER_SETTING("StartingClaimCheck"));
OPT_BOOL(RSK_STARTING_GERUDO_CARD, "Start with Gerudo Card", CVAR_RANDOMIZER_SETTING("StartingGerudoCard"));
OPT_BOOL(RSK_STARTING_KEATON_MASK, "Start with Keaton Mask", CVAR_RANDOMIZER_SETTING("StartingKeatonMask"));
OPT_BOOL(RSK_STARTING_SKULL_MASK, "Start with Skull Mask", CVAR_RANDOMIZER_SETTING("StartingSkullMask"));
OPT_BOOL(RSK_STARTING_SPOOKY_MASK, "Start with Spooky Mask", CVAR_RANDOMIZER_SETTING("StartingSpookyMask"));
OPT_BOOL(RSK_STARTING_BUNNY_HOOD, "Start with Bunny Hood", CVAR_RANDOMIZER_SETTING("StartingBunnyHood"));
OPT_BOOL(RSK_STARTING_GORON_MASK, "Start with Goron Mask", CVAR_RANDOMIZER_SETTING("StartingGoronMask"));
OPT_BOOL(RSK_STARTING_ZORA_MASK, "Start with Zora Mask", CVAR_RANDOMIZER_SETTING("StartingZoraMask"));
OPT_BOOL(RSK_STARTING_GERUDO_MASK, "Start with Gerudo Mask", CVAR_RANDOMIZER_SETTING("StartingGerudoMask"));
OPT_BOOL(RSK_STARTING_MASK_OF_TRUTH, "Start with Mask of Truth", CVAR_RANDOMIZER_SETTING("StartingMaskOfTruth"));
OPT_U8(RSK_STARTING_BIGGORON_SWORD, "Start with Biggoron's Sword", {"Off", "Giant's Knife", "Biggoron's Sword"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBiggoronSword"), "", WIDGET_CVAR_COMBOBOX, 0);
OPT_BOOL(RSK_FULL_WALLETS, "Full Wallets", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FullWallets"), mOptionDescriptions[RSK_FULL_WALLETS], WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_ZELDAS_LULLABY, "Start with Zelda's Lullaby", CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_EPONAS_SONG, "Start with Epona's Song", CVAR_RANDOMIZER_SETTING("StartingEponasSong"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_SARIAS_SONG, "Start with Saria's Song", CVAR_RANDOMIZER_SETTING("StartingSariasSong"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_SUNS_SONG, "Start with Sun's Song", CVAR_RANDOMIZER_SETTING("StartingSunsSong"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_SONG_OF_TIME, "Start with Song of Time", CVAR_RANDOMIZER_SETTING("StartingSongOfTime"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_SONG_OF_STORMS, "Start with Song of Storms", CVAR_RANDOMIZER_SETTING("StartingSongOfStorms"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_MINUET_OF_FOREST, "Start with Minuet of Forest", CVAR_RANDOMIZER_SETTING("StartingMinuetOfForest"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_BOLERO_OF_FIRE, "Start with Bolero of Fire", CVAR_RANDOMIZER_SETTING("StartingBoleroOfFire"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_SERENADE_OF_WATER, "Start with Serenade of Water", CVAR_RANDOMIZER_SETTING("StartingSerenadeOfWater"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_REQUIEM_OF_SPIRIT, "Start with Requiem of Spirit", CVAR_RANDOMIZER_SETTING("StartingRequiemOfSpirit"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_NOCTURNE_OF_SHADOW, "Start with Nocturne of Shadow", CVAR_RANDOMIZER_SETTING("StartingNocturneOfShadow"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_PRELUDE_OF_LIGHT, "Start with Prelude of Light", CVAR_RANDOMIZER_SETTING("StartingPreludeOfLight"));
OPT_U8(RSK_STARTING_SKULLTULA_TOKEN, "Gold Skulltula Tokens", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSkulltulaToken"), "", WIDGET_CVAR_SLIDER_INT);
OPT_U8(RSK_STARTING_HEARTS, "Starting Hearts", {NumOpts(1, 20)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingHearts"), "", WIDGET_CVAR_SLIDER_INT, 2);
OPT_U8(RSK_STARTING_OCARINA, {"Off", "Fairy Ocarina", "Ocarina of Time"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingOcarina"), WIDGET_CVAR_COMBOBOX, RO_STARTING_OCARINA_OFF);
OPT_BOOL(RSK_STARTING_DEKU_SHIELD, CVAR_RANDOMIZER_SETTING("StartingDekuShield"));
OPT_BOOL(RSK_STARTING_KOKIRI_SWORD, CVAR_RANDOMIZER_SETTING("StartingKokiriSword"));
OPT_BOOL(RSK_STARTING_MASTER_SWORD, CVAR_RANDOMIZER_SETTING("StartingMasterSword"));
OPT_BOOL(RSK_STARTING_STICKS, {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSticks"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_NUTS, {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingNuts"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_BEANS, {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBeans"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_MEGATON_HAMMER, CVAR_RANDOMIZER_SETTING("StartingMegatonHammer"));
OPT_BOOL(RSK_STARTING_BOOMERANG, CVAR_RANDOMIZER_SETTING("StartingBoomerang"));
OPT_BOOL(RSK_STARTING_LENS_OF_TRUTH, CVAR_RANDOMIZER_SETTING("StartingLensOfTruth"));
OPT_BOOL(RSK_STARTING_DINS_FIRE, CVAR_RANDOMIZER_SETTING("StartingDinsFire"));
OPT_BOOL(RSK_STARTING_FARORES_WIND, CVAR_RANDOMIZER_SETTING("StartingFaroresWind"));
OPT_BOOL(RSK_STARTING_NAYRUS_LOVE, CVAR_RANDOMIZER_SETTING("StartingNayrusLove"));
OPT_BOOL(RSK_STARTING_FIRE_ARROWS, CVAR_RANDOMIZER_SETTING("StartingFireArrows"));
OPT_BOOL(RSK_STARTING_ICE_ARROWS, CVAR_RANDOMIZER_SETTING("StartingIceArrows"));
OPT_BOOL(RSK_STARTING_LIGHT_ARROWS, CVAR_RANDOMIZER_SETTING("StartingLightArrows"));
OPT_BOOL(RSK_STARTING_IRON_BOOTS, CVAR_RANDOMIZER_SETTING("StartingIronBoots"));
OPT_BOOL(RSK_STARTING_HOVER_BOOTS, CVAR_RANDOMIZER_SETTING("StartingHoverBoots"));
OPT_BOOL(RSK_STARTING_HYLIAN_SHIELD, CVAR_RANDOMIZER_SETTING("StartingHylianShield"));
OPT_BOOL(RSK_STARTING_MIRROR_SHIELD, CVAR_RANDOMIZER_SETTING("StartingMirrorShield"));
OPT_BOOL(RSK_STARTING_GORON_TUNIC, CVAR_RANDOMIZER_SETTING("StartingGoronTunic"));
OPT_BOOL(RSK_STARTING_ZORA_TUNIC, CVAR_RANDOMIZER_SETTING("StartingZoraTunic"));
OPT_BOOL(RSK_STARTING_STONE_OF_AGONY, CVAR_RANDOMIZER_SETTING("StartingStoneOfAgony"));
OPT_U8(RSK_STARTING_HOOKSHOT, {"Off", "Hookshot", "Longshot"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingHookshot"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOW, {"Off", "Bow (Quiver 30)", "Bow (Quiver 40)", "Bow (Quiver 50)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBow"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_SLINGSHOT, {"Off", "Slingshot (30)", "Slingshot (40)", "Slingshot (50)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSlingshot"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOMB_BAG, {"Off", "Bomb Bag (20)", "Bomb Bag (30)", "Bomb Bag (40)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBombBag"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_STRENGTH, {"Off", "Goron's Bracelet", "Silver Gauntlets", "Golden Gauntlets"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingStrength"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_SCALE, {"Off", "Silver Scale", "Golden Scale"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingScale"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_WALLET, {"Off", "Adult's Wallet", "Giant's Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingWallet"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_MAGIC_METER, {"Off", "Single Magic", "Double Magic"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMagicMeter"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOMBCHU_BAG, {"Off", "Bombchu Bag (20)", "Bombchu Bag (30)", "Bombchu Bag (50)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBombchuBag"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOTTLE_1, {"Off", "Empty Bottle", "Bottle with Big Poe", "Ruto's Letter"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle1"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOTTLE_2, {"Off", "Empty Bottle", "Bottle with Big Poe"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle2"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOTTLE_3, {"Off", "Empty Bottle", "Bottle with Big Poe"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle3"), WIDGET_CVAR_COMBOBOX, 0);
OPT_U8(RSK_STARTING_BOTTLE_4, {"Off", "Empty Bottle", "Bottle with Big Poe"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle4"), WIDGET_CVAR_COMBOBOX, 0);
OPT_BOOL(RSK_STARTING_WEIRD_EGG, CVAR_RANDOMIZER_SETTING("StartingWeirdEgg"));
OPT_BOOL(RSK_STARTING_ZELDAS_LETTER, CVAR_RANDOMIZER_SETTING("StartingZeldasLetter"));
OPT_BOOL(RSK_STARTING_CLAIM_CHECK, CVAR_RANDOMIZER_SETTING("StartingClaimCheck"));
OPT_BOOL(RSK_STARTING_GERUDO_CARD, CVAR_RANDOMIZER_SETTING("StartingGerudoCard"));
OPT_BOOL(RSK_STARTING_KEATON_MASK, CVAR_RANDOMIZER_SETTING("StartingKeatonMask"));
OPT_BOOL(RSK_STARTING_SKULL_MASK, CVAR_RANDOMIZER_SETTING("StartingSkullMask"));
OPT_BOOL(RSK_STARTING_SPOOKY_MASK, CVAR_RANDOMIZER_SETTING("StartingSpookyMask"));
OPT_BOOL(RSK_STARTING_BUNNY_HOOD, CVAR_RANDOMIZER_SETTING("StartingBunnyHood"));
OPT_BOOL(RSK_STARTING_GORON_MASK, CVAR_RANDOMIZER_SETTING("StartingGoronMask"));
OPT_BOOL(RSK_STARTING_ZORA_MASK, CVAR_RANDOMIZER_SETTING("StartingZoraMask"));
OPT_BOOL(RSK_STARTING_GERUDO_MASK, CVAR_RANDOMIZER_SETTING("StartingGerudoMask"));
OPT_BOOL(RSK_STARTING_MASK_OF_TRUTH, CVAR_RANDOMIZER_SETTING("StartingMaskOfTruth"));
OPT_U8(RSK_STARTING_BIGGORON_SWORD, {"Off", "Giant's Knife", "Biggoron's Sword"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBiggoronSword"), WIDGET_CVAR_COMBOBOX, 0);
OPT_BOOL(RSK_FULL_WALLETS, {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FullWallets"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_ZELDAS_LULLABY, CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"), IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_EPONAS_SONG, CVAR_RANDOMIZER_SETTING("StartingEponasSong"), IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_SARIAS_SONG, CVAR_RANDOMIZER_SETTING("StartingSariasSong"), IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_SUNS_SONG, CVAR_RANDOMIZER_SETTING("StartingSunsSong"), IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_SONG_OF_TIME, CVAR_RANDOMIZER_SETTING("StartingSongOfTime"), IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_SONG_OF_STORMS, CVAR_RANDOMIZER_SETTING("StartingSongOfStorms"), IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_MINUET_OF_FOREST, CVAR_RANDOMIZER_SETTING("StartingMinuetOfForest"), IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_BOLERO_OF_FIRE, CVAR_RANDOMIZER_SETTING("StartingBoleroOfFire"), IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_SERENADE_OF_WATER, CVAR_RANDOMIZER_SETTING("StartingSerenadeOfWater"), IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_REQUIEM_OF_SPIRIT, CVAR_RANDOMIZER_SETTING("StartingRequiemOfSpirit"), IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_NOCTURNE_OF_SHADOW, CVAR_RANDOMIZER_SETTING("StartingNocturneOfShadow"), IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_PRELUDE_OF_LIGHT, CVAR_RANDOMIZER_SETTING("StartingPreludeOfLight"));
OPT_U8(RSK_STARTING_SKULLTULA_TOKEN, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSkulltulaToken"), WIDGET_CVAR_SLIDER_INT);
OPT_U8(RSK_STARTING_HEARTS, {NumOpts(1, 20)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingHearts"), WIDGET_CVAR_SLIDER_INT, 2);
// TODO: Remainder of Starting Items
OPT_U8(RSK_LOGIC_RULES, "Logic", {"Glitchless", "No Logic"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LogicRules"), mOptionDescriptions[RSK_LOGIC_RULES], WIDGET_CVAR_COMBOBOX, RO_LOGIC_GLITCHLESS, false, nullptr, IMFLAG_LABEL_INLINE);
OPT_U8(RSK_LOGIC_RULES, {"Glitchless", "No Logic"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LogicRules"), WIDGET_CVAR_COMBOBOX, RO_LOGIC_GLITCHLESS, false, nullptr, IMFLAG_LABEL_INLINE);
OPT_CALLBACK(RSK_LOGIC_RULES, {
HandleStartingAgeUI();
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != RO_LOGIC_NO_LOGIC &&
@@ -1478,9 +1478,9 @@ void Settings::CreateOptions() {
CVarSetInteger(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), 7);
}
});
OPT_BOOL(RSK_ALL_LOCATIONS_REACHABLE, "All Locations Reachable", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), mOptionDescriptions[RSK_ALL_LOCATIONS_REACHABLE], WIDGET_CVAR_CHECKBOX, RO_GENERIC_ON, false, nullptr, IMFLAG_SAME_LINE);
OPT_BOOL(RSK_SKULLS_SUNS_SONG, "Night Skulltula's Expect Sun's Song", CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), mOptionDescriptions[RSK_SKULLS_SUNS_SONG]);
OPT_U8(RSK_DAMAGE_MULTIPLIER, "Damage Multiplier", {"x1/2", "x1", "x2", "x4", "x8", "x16", "OHKO"}, OptionCategory::Setting, "", "", WIDGET_CVAR_SLIDER_INT, RO_DAMAGE_MULTIPLIER_DEFAULT);
OPT_BOOL(RSK_ALL_LOCATIONS_REACHABLE, {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_ON, false, nullptr, IMFLAG_SAME_LINE);
OPT_BOOL(RSK_SKULLS_SUNS_SONG, CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"));
OPT_U8(RSK_DAMAGE_MULTIPLIER, {"x1/2", "x1", "x2", "x4", "x8", "x16", "OHKO"}, OptionCategory::Setting, "", WIDGET_CVAR_SLIDER_INT, RO_DAMAGE_MULTIPLIER_DEFAULT);
// Don't show any MQ options if both quests aren't available
if (!(OTRGlobals::Instance->HasMasterQuest() && OTRGlobals::Instance->HasOriginal())) {
mOptions[RSK_MQ_DUNGEON_RANDOM].Disable("This option has been disabled because only one type of O2R has been loaded");
@@ -144,14 +144,9 @@ class Settings {
static std::shared_ptr<Settings> GetInstance();
private:
/**
* @brief Create the list of description strings for `Option`s.
*/
void CreateOptionDescriptions();
static std::shared_ptr<Settings> mInstance;
std::shared_ptr<Context> mContext = nullptr;
std::array<Option, RSK_MAX> mOptions = {};
std::array<std::string, RSK_MAX> mOptionDescriptions = {};
std::array<OptionGroup, RSG_MAX> mOptionGroups = {};
std::array<TrickSetting, RT_MAX> mTrickSettings = {};
std::array<std::vector<Option*>, RCAREA_INVALID> mExcludeLocationsOptionsAreas = {};
+2 -2
View File
@@ -564,7 +564,7 @@ void DrawTricksMenu(WidgetInfo& info) {
Rando::Tricks::DrawTagChips(option.GetTags(), option.GetName());
ImGui::SameLine();
ImGui::Text("%s", option.GetName().c_str());
UIWidgets::Tooltip(option.GetDescription().c_str());
UIWidgets::Tooltip(option.GetDescription());
}
}
areaTreeDisabled.insert(area);
@@ -638,7 +638,7 @@ void DrawTricksMenu(WidgetInfo& info) {
Rando::Tricks::DrawTagChips(option.GetTags(), option.GetName());
ImGui::SameLine();
ImGui::Text("%s", option.GetName().c_str());
UIWidgets::Tooltip(option.GetDescription().c_str());
UIWidgets::Tooltip(option.GetDescription());
}
}
areaTreeEnabled.insert(area);