Race Lockout (#5364)

* Implement race lockout on the new menu, with option for opt-out.

* Cal's requests.
This commit is contained in:
Malkierian 2025-04-13 16:29:29 -07:00 committed by GitHub
parent 46b40b0220
commit 5e399fe7a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 251 additions and 89 deletions

View file

@ -2376,10 +2376,12 @@ void CosmeticsEditorWindow::DrawElement() {
.Step(0.01f) .Step(0.01f)
.Size(ImVec2(300.0f, 0.0f)) .Size(ImVec2(300.0f, 0.0f))
.Color(THEME_COLOR)); .Color(THEME_COLOR));
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
UIWidgets::CVarCheckbox("Randomize All on New Scene", CVAR_COSMETIC("RandomizeAllOnNewScene"), UIWidgets::CVarCheckbox("Randomize All on New Scene", CVAR_COSMETIC("RandomizeAllOnNewScene"),
UIWidgets::CheckboxOptions() UIWidgets::CheckboxOptions()
.Color(THEME_COLOR) .Color(THEME_COLOR)
.Tooltip("Enables randomizing all unlocked cosmetics when you enter a new scene.")); .Tooltip("Enables randomizing all unlocked cosmetics when you enter a new scene."));
ImGui::EndDisabled();
UIWidgets::CVarCheckbox( UIWidgets::CVarCheckbox(
"Advanced Mode", CVAR_COSMETIC("AdvancedMode"), "Advanced Mode", CVAR_COSMETIC("AdvancedMode"),
UIWidgets::CheckboxOptions() UIWidgets::CheckboxOptions()
@ -2408,9 +2410,12 @@ void CosmeticsEditorWindow::DrawElement() {
} }
} }
} }
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
if (UIWidgets::Button("Randomize All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { if (UIWidgets::Button("Randomize All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) {
CosmeticsEditor_RandomizeAll(); CosmeticsEditor_RandomizeAll();
} }
ImGui::EndDisabled();
ImGui::SameLine(); ImGui::SameLine();
if (UIWidgets::Button("Reset All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { if (UIWidgets::Button("Reset All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) {
CosmeticsEditor_ResetAll(); CosmeticsEditor_ResetAll();
@ -2431,6 +2436,7 @@ void CosmeticsEditorWindow::DrawElement() {
} }
} }
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
if (UIWidgets::Button("Rainbow All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { if (UIWidgets::Button("Rainbow All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) {
for (auto& [id, cosmeticOption] : cosmeticOptions) { for (auto& [id, cosmeticOption] : cosmeticOptions) {
if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) &&
@ -2440,6 +2446,8 @@ void CosmeticsEditorWindow::DrawElement() {
} }
} }
} }
ImGui::EndDisabled();
ImGui::SameLine(); ImGui::SameLine();
if (UIWidgets::Button("Un-Rainbow All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { if (UIWidgets::Button("Un-Rainbow All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) {
for (auto& [id, cosmeticOption] : cosmeticOptions) { for (auto& [id, cosmeticOption] : cosmeticOptions) {
@ -2469,6 +2477,7 @@ void CosmeticsEditorWindow::DrawElement() {
if (ImGui::BeginTabItem("Keys")) { if (ImGui::BeginTabItem("Keys")) {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
UIWidgets::Separator(true, true, 2.0f, 2.0f); UIWidgets::Separator(true, true, 2.0f, 2.0f);
if (UIWidgets::Button("Give all keys dungeon-specific colors", if (UIWidgets::Button("Give all keys dungeon-specific colors",
@ -2482,6 +2491,7 @@ void CosmeticsEditorWindow::DrawElement() {
DrawCosmeticGroup(COSMETICS_GROUP_SMALL_KEYS); DrawCosmeticGroup(COSMETICS_GROUP_SMALL_KEYS);
DrawCosmeticGroup(COSMETICS_GROUP_BOSS_KEYS); DrawCosmeticGroup(COSMETICS_GROUP_BOSS_KEYS);
ImGui::EndDisabled();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }

View file

@ -27,6 +27,7 @@ void MessageViewer::InitElement() {
} }
void MessageViewer::DrawElement() { void MessageViewer::DrawElement() {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
ImGui::Text("Table ID"); ImGui::Text("Table ID");
ImGui::SameLine(); ImGui::SameLine();
PushStyleInput(THEME_COLOR); PushStyleInput(THEME_COLOR);
@ -78,6 +79,7 @@ void MessageViewer::DrawElement() {
mDisplayCustomMessageClicked = true; mDisplayCustomMessageClicked = true;
} }
PopStyleButton(); PopStyleButton();
ImGui::EndDisabled();
} }
void MessageViewer::UpdateElement() { void MessageViewer::UpdateElement() {

View file

@ -12,6 +12,7 @@ void SohConsoleWindow::UpdateElement() {
} }
void SohConsoleWindow::DrawElement() { void SohConsoleWindow::DrawElement() {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
UIWidgets::PushStyleInput(THEME_COLOR); UIWidgets::PushStyleInput(THEME_COLOR);
// Small font (13) to match hardcoded width values in the LUS window.. set large font after below TODO addressed // Small font (13) to match hardcoded width values in the LUS window.. set large font after below TODO addressed
ImGui::PushFont(OTRGlobals::Instance->fontMonoSmall); ImGui::PushFont(OTRGlobals::Instance->fontMonoSmall);
@ -27,4 +28,5 @@ void SohConsoleWindow::DrawElement() {
ImGui::PopFont(); ImGui::PopFont();
UIWidgets::PopStyleInput(); UIWidgets::PopStyleInput();
ImGui::EndDisabled();
} }

View file

@ -10,7 +10,9 @@ void SohGfxDebuggerWindow::UpdateElement() {
} }
void SohGfxDebuggerWindow::DrawElement() { void SohGfxDebuggerWindow::DrawElement() {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger); ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger);
GfxDebuggerWindow::DrawElement(); GfxDebuggerWindow::DrawElement();
ImGui::PopFont(); ImGui::PopFont();
ImGui::EndDisabled();
} }

View file

@ -849,6 +849,7 @@ void ActorViewer_AddTagForAllActors() {
} }
void ActorViewerWindow::DrawElement() { void ActorViewerWindow::DrawElement() {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
static Actor* display; static Actor* display;
static Actor empty{}; static Actor empty{};
static Actor* fetch = NULL; static Actor* fetch = NULL;
@ -1186,6 +1187,7 @@ void ActorViewerWindow::DrawElement() {
actors.clear(); actors.clear();
} }
} }
ImGui::EndDisabled();
} }
void ActorViewerWindow::InitElement() { void ActorViewerWindow::InitElement() {

View file

@ -58,6 +58,7 @@ using namespace UIWidgets;
// Draws the ImGui window for the collision viewer // Draws the ImGui window for the collision viewer
void ColViewerWindow::DrawElement() { void ColViewerWindow::DrawElement() {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
CheckboxOptions checkOpt = CheckboxOptions().Color(THEME_COLOR); CheckboxOptions checkOpt = CheckboxOptions().Color(THEME_COLOR);
ComboboxOptions comboOpt = ComboboxOptions().Color(THEME_COLOR); ComboboxOptions comboOpt = ComboboxOptions().Color(THEME_COLOR);
CVarCheckbox("Enabled", CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), checkOpt); CVarCheckbox("Enabled", CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), checkOpt);
@ -139,6 +140,7 @@ void ColViewerWindow::DrawElement() {
UIWidgets::Tooltip(colorHelpText.c_str()); UIWidgets::Tooltip(colorHelpText.c_str());
} }
PopStyleHeader(); PopStyleHeader();
ImGui::EndDisabled();
} }
// Calculates the normal for a triangle at the 3 specified points // Calculates the normal for a triangle at the 3 specified points

View file

@ -1665,6 +1665,7 @@ void ResetBaseOptions() {
void SaveEditorWindow::DrawElement() { void SaveEditorWindow::DrawElement() {
PushStyleTabs(THEME_COLOR); PushStyleTabs(THEME_COLOR);
ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger); ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger);
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
if (ImGui::BeginTabBar("SaveContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) { if (ImGui::BeginTabBar("SaveContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) {
ResetBaseOptions(); ResetBaseOptions();
@ -1706,6 +1707,7 @@ void SaveEditorWindow::DrawElement() {
ImGui::EndTabBar(); ImGui::EndTabBar();
} }
ImGui::EndDisabled();
ImGui::PopFont(); ImGui::PopFont();
PopStyleTabs(); PopStyleTabs();
} }

View file

@ -89,6 +89,7 @@ void PerformDisplayListSearch() {
} }
void DLViewerWindow::DrawElement() { void DLViewerWindow::DrawElement() {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
// Debounce the search field as listing otr files is expensive // Debounce the search field as listing otr files is expensive
UIWidgets::PushStyleInput(THEME_COLOR); UIWidgets::PushStyleInput(THEME_COLOR);
ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger); ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger);
@ -122,6 +123,7 @@ void DLViewerWindow::DrawElement() {
if (activeDisplayList == "") { if (activeDisplayList == "") {
ImGui::PopFont(); ImGui::PopFont();
ImGui::EndDisabled();
return; return;
} }
@ -131,6 +133,8 @@ void DLViewerWindow::DrawElement() {
if (res->GetInitData()->Type != static_cast<uint32_t>(Fast::ResourceType::DisplayList)) { if (res->GetInitData()->Type != static_cast<uint32_t>(Fast::ResourceType::DisplayList)) {
ImGui::Text("Resource type is not a Display List. Please choose another."); ImGui::Text("Resource type is not a Display List. Please choose another.");
ImGui::PopFont();
ImGui::EndDisabled();
return; return;
} }
@ -325,13 +329,10 @@ void DLViewerWindow::DrawElement() {
} }
ImGui::EndGroup(); ImGui::EndGroup();
} }
} catch (const std::exception& e) { } catch (const std::exception& e) { ImGui::Text("Error displaying DL instructions."); }
ImGui::Text("Error displaying DL instructions.");
ImGui::PopFont();
return;
}
ImGui::PopFont(); ImGui::PopFont();
ImGui::EndDisabled();
} }
void DLViewerWindow::InitElement() { void DLViewerWindow::InitElement() {

View file

@ -77,6 +77,7 @@ void DrawHookRegisteringInfos(const char* hookName) {
} }
void HookDebuggerWindow::DrawElement() { void HookDebuggerWindow::DrawElement() {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
#ifndef __cpp_lib_source_location #ifndef __cpp_lib_source_location
ImGui::TextColored(yellow, "Some features of the Hook Debugger are unavailable because SoH was compiled " ImGui::TextColored(yellow, "Some features of the Hook Debugger are unavailable because SoH was compiled "
"without \"<source_location>\" support " "without \"<source_location>\" support "
@ -93,6 +94,7 @@ void HookDebuggerWindow::DrawElement() {
} }
ImGui::PopFont(); ImGui::PopFont();
ImGui::EndDisabled();
} }
void HookDebuggerWindow::InitElement() { void HookDebuggerWindow::InitElement() {

View file

@ -154,6 +154,7 @@ void RegisterValueViewerHooks() {
RegisterShipInitFunc initFunc(RegisterValueViewerHooks, { CVAR_NAME }); RegisterShipInitFunc initFunc(RegisterValueViewerHooks, { CVAR_NAME });
void ValueViewerWindow::DrawElement() { void ValueViewerWindow::DrawElement() {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
UIWidgets::CVarCheckbox("Enable Printing", CVAR_NAME, UIWidgets::CheckboxOptions().Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Enable Printing", CVAR_NAME, UIWidgets::CheckboxOptions().Color(THEME_COLOR));
ImGui::BeginGroup(); ImGui::BeginGroup();
@ -275,6 +276,7 @@ void ValueViewerWindow::DrawElement() {
} }
ImGui::EndGroup(); ImGui::EndGroup();
} }
ImGui::EndDisabled();
} }
void ValueViewerWindow::InitElement() { void ValueViewerWindow::InitElement() {

View file

@ -368,7 +368,9 @@ void OptionGroup::Disable() {
bool OptionGroup::RenderImGui() const { // NOLINT(*-no-recursion) bool OptionGroup::RenderImGui() const { // NOLINT(*-no-recursion)
ImGuiWindow* window = ImGui::GetCurrentWindow(); ImGuiWindow* window = ImGui::GetCurrentWindow();
bool changed = false; bool changed = false;
ImGui::BeginDisabled(mDisabled); ImGui::BeginDisabled(mDisabled || CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) ||
CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0) ||
CVarGetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0));
if (mContainerType == WidgetContainerType::TABLE) { if (mContainerType == WidgetContainerType::TABLE) {
if (ImGui::BeginTable(mName.c_str(), static_cast<int>(mSubGroups.size()), if (ImGui::BeginTable(mName.c_str(), static_cast<int>(mSubGroups.size()),
ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {

View file

@ -3690,6 +3690,7 @@ void RandomizerSettingsWindow::DrawElement() {
locationsTabOpen = false; locationsTabOpen = false;
tricksTabOpen = false; tricksTabOpen = false;
} }
ImGui::EndDisabled();
UIWidgets::Spacer(0); UIWidgets::Spacer(0);
UIWidgets::CVarCheckbox("Manual seed entry", CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), UIWidgets::CVarCheckbox("Manual seed entry", CVAR_RANDOMIZER_SETTING("ManualSeedEntry"),
@ -3725,9 +3726,7 @@ void RandomizerSettingsWindow::DrawElement() {
} }
UIWidgets::Spacer(0); UIWidgets::Spacer(0);
ImGui::BeginDisabled((CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0) && ImGui::BeginDisabled((gSaveContext.gameMode != GAMEMODE_FILE_SELECT) || GameInteractor::IsSaveLoaded());
gSaveContext.gameMode != GAMEMODE_FILE_SELECT) ||
GameInteractor::IsSaveLoaded());
if (UIWidgets::Button("Generate Randomizer", if (UIWidgets::Button("Generate Randomizer",
UIWidgets::ButtonOptions().Size(ImVec2(250.f, 0.f)).Color(THEME_COLOR))) { UIWidgets::ButtonOptions().Size(ImVec2(250.f, 0.f)).Color(THEME_COLOR))) {
ctx->SetSpoilerLoaded(false); ctx->SetSpoilerLoaded(false);
@ -3746,7 +3745,6 @@ void RandomizerSettingsWindow::DrawElement() {
// ImGui::Text("Settings File: %s", presetfilepath.c_str()); // ImGui::Text("Settings File: %s", presetfilepath.c_str());
UIWidgets::Separator(true, true, 0.f, 0.f); UIWidgets::Separator(true, true, 0.f, 0.f);
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
ImGuiWindow* window = ImGui::GetCurrentWindow(); ImGuiWindow* window = ImGui::GetCurrentWindow();
static ImVec2 cellPadding(8.0f, 8.0f); static ImVec2 cellPadding(8.0f, 8.0f);
@ -3762,8 +3760,6 @@ void RandomizerSettingsWindow::DrawElement() {
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) ==
RO_LOGIC_VANILLA);
if (ImGui::BeginTabItem("Items")) { if (ImGui::BeginTabItem("Items")) {
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) ==
@ -3775,23 +3771,23 @@ void RandomizerSettingsWindow::DrawElement() {
ImGui::PopStyleVar(1); ImGui::PopStyleVar(1);
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
ImGui::EndDisabled();
if (ImGui::BeginTabItem("Gameplay")) {
ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) ==
RO_LOGIC_VANILLA); RO_LOGIC_VANILLA);
if (ImGui::BeginTabItem("Gameplay")) {
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
if (mSettings->GetOptionGroup(RSG_GAMEPLAY_IMGUI_TABLE).RenderImGui()) { if (mSettings->GetOptionGroup(RSG_GAMEPLAY_IMGUI_TABLE).RenderImGui()) {
mNeedsUpdate = true; mNeedsUpdate = true;
} }
ImGui::EndDisabled();
ImGui::PopStyleVar(1); ImGui::PopStyleVar(1);
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
ImGui::EndDisabled();
ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) ==
RO_LOGIC_VANILLA);
if (ImGui::BeginTabItem("Locations")) { if (ImGui::BeginTabItem("Locations")) {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) ==
RO_LOGIC_VANILLA);
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
if (!locationsTabOpen) { if (!locationsTabOpen) {
locationsTabOpen = true; locationsTabOpen = true;
@ -3924,10 +3920,10 @@ void RandomizerSettingsWindow::DrawElement() {
} }
ImGui::PopStyleVar(1); ImGui::PopStyleVar(1);
ImGui::EndTabItem(); ImGui::EndTabItem();
ImGui::EndDisabled();
} else { } else {
locationsTabOpen = false; locationsTabOpen = false;
} }
ImGui::EndDisabled();
if (ImGui::BeginTabItem("Tricks/Glitches")) { if (ImGui::BeginTabItem("Tricks/Glitches")) {
if (!tricksTabOpen) { if (!tricksTabOpen) {
@ -3975,7 +3971,8 @@ void RandomizerSettingsWindow::DrawElement() {
ImGui::EndTable(); ImGui::EndTable();
} }
ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) ==
RO_LOGIC_VANILLA); RO_LOGIC_VANILLA);
// Tricks // Tricks
@ -4354,9 +4351,6 @@ void RandomizerSettingsWindow::DrawElement() {
ImGui::EndTabBar(); ImGui::EndTabBar();
} }
UIWidgets::PopStyleTabs(); UIWidgets::PopStyleTabs();
ImGui::EndDisabled();
ImGui::EndDisabled();
} }
void RandomizerSettingsWindow::UpdateElement() { void RandomizerSettingsWindow::UpdateElement() {

View file

@ -2080,11 +2080,13 @@ void CheckTrackerSettingsWindow::DrawElement() {
.DefaultIndex(TRACKER_COMBO_BUTTON_L)); .DefaultIndex(TRACKER_COMBO_BUTTON_L));
} }
} }
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
UIWidgets::CVarCheckbox("Vanilla/MQ Dungeon Spoilers", CVAR_TRACKER_CHECK("MQSpoilers"), UIWidgets::CVarCheckbox("Vanilla/MQ Dungeon Spoilers", CVAR_TRACKER_CHECK("MQSpoilers"),
UIWidgets::CheckboxOptions() UIWidgets::CheckboxOptions()
.Tooltip("If enabled, Vanilla/MQ dungeons will show on the tracker immediately. " .Tooltip("If enabled, Vanilla/MQ dungeons will show on the tracker immediately. "
"Otherwise, Vanilla/MQ dungeon locations must be unlocked.") "Otherwise, Vanilla/MQ dungeon locations must be unlocked.")
.Color(THEME_COLOR)); .Color(THEME_COLOR));
ImGui::EndDisabled();
if (UIWidgets::CVarCheckbox( if (UIWidgets::CVarCheckbox(
"Hide unshuffled shop item checks", CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"), "Hide unshuffled shop item checks", CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"),
UIWidgets::CheckboxOptions() UIWidgets::CheckboxOptions()
@ -2105,6 +2107,7 @@ void CheckTrackerSettingsWindow::DrawElement() {
UIWidgets::CheckboxOptions() UIWidgets::CheckboxOptions()
.Tooltip("If enabled, will show a check's logic when hovering over it.") .Tooltip("If enabled, will show a check's logic when hovering over it.")
.Color(THEME_COLOR)); .Color(THEME_COLOR));
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
if (UIWidgets::CVarCheckbox("Enable Available Checks", CVAR_TRACKER_CHECK("EnableAvailableChecks"), if (UIWidgets::CVarCheckbox("Enable Available Checks", CVAR_TRACKER_CHECK("EnableAvailableChecks"),
UIWidgets::CheckboxOptions() UIWidgets::CheckboxOptions()
.Tooltip("If enabled, will show the checks that are available to be collected " .Tooltip("If enabled, will show the checks that are available to be collected "
@ -2113,6 +2116,7 @@ void CheckTrackerSettingsWindow::DrawElement() {
enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0); enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0);
RecalculateAvailableChecks(); RecalculateAvailableChecks();
} }
ImGui::EndDisabled();
// Filtering settings // Filtering settings
UIWidgets::PaddedSeparator(); UIWidgets::PaddedSeparator();

View file

@ -690,6 +690,7 @@ void EntranceTrackerSettingsWindow::DrawElement() {
UIWidgets::CheckboxOptions() UIWidgets::CheckboxOptions()
.Tooltip("Automatically scroll to the first available entrance in the current scene") .Tooltip("Automatically scroll to the first available entrance in the current scene")
.Color(THEME_COLOR)); .Color(THEME_COLOR));
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
UIWidgets::CVarCheckbox("Highlight previous", CVAR_TRACKER_ENTRANCE("HighlightPrevious"), UIWidgets::CVarCheckbox("Highlight previous", CVAR_TRACKER_ENTRANCE("HighlightPrevious"),
UIWidgets::CheckboxOptions() UIWidgets::CheckboxOptions()
.Tooltip("Highlight the previous entrance that Link came from") .Tooltip("Highlight the previous entrance that Link came from")
@ -698,6 +699,7 @@ void EntranceTrackerSettingsWindow::DrawElement() {
UIWidgets::CheckboxOptions() UIWidgets::CheckboxOptions()
.Tooltip("Highlight available entrances in the current scene") .Tooltip("Highlight available entrances in the current scene")
.Color(THEME_COLOR)); .Color(THEME_COLOR));
ImGui::EndDisabled();
UIWidgets::CVarCheckbox("Hide undiscovered", CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), UIWidgets::CVarCheckbox("Hide undiscovered", CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"),
UIWidgets::CheckboxOptions() UIWidgets::CheckboxOptions()
.Tooltip("Collapse undiscovered entrances towards the bottom of each group") .Tooltip("Collapse undiscovered entrances towards the bottom of each group")
@ -724,6 +726,7 @@ void EntranceTrackerSettingsWindow::DrawElement() {
UIWidgets::RadioButtonsOptions().Color(THEME_COLOR).Tooltip("Group entrances by their entrance type")); UIWidgets::RadioButtonsOptions().Color(THEME_COLOR).Tooltip("Group entrances by their entrance type"));
ImGui::Text("Spoiler Reveal"); ImGui::Text("Spoiler Reveal");
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
UIWidgets::CVarCheckbox( UIWidgets::CVarCheckbox(
"Show Source", CVAR_TRACKER_ENTRANCE("ShowFrom"), "Show Source", CVAR_TRACKER_ENTRANCE("ShowFrom"),
UIWidgets::CheckboxOptions().Tooltip("Reveal the sourcefor undiscovered entrances").Color(THEME_COLOR)); UIWidgets::CheckboxOptions().Tooltip("Reveal the sourcefor undiscovered entrances").Color(THEME_COLOR));
@ -731,7 +734,7 @@ void EntranceTrackerSettingsWindow::DrawElement() {
UIWidgets::CheckboxOptions() UIWidgets::CheckboxOptions()
.Tooltip("Reveal the destination for undiscovered entrances") .Tooltip("Reveal the destination for undiscovered entrances")
.Color(THEME_COLOR)); .Color(THEME_COLOR));
ImGui::EndDisabled();
ImGui::EndTable(); ImGui::EndTable();
} }

View file

@ -65,6 +65,8 @@ uint32_t GetVectorIndexOf(std::vector<std::string>& vector, std::string value) {
return std::distance(vector.begin(), std::find(vector.begin(), vector.end(), value)); return std::distance(vector.begin(), std::find(vector.begin(), vector.end(), value));
} }
static bool raceDisableActive = false;
void Menu::InsertSidebarSearch() { void Menu::InsertSidebarSearch() {
menuEntries["Settings"].sidebars.emplace("Search", searchSidebarEntry); menuEntries["Settings"].sidebars.emplace("Search", searchSidebarEntry);
uint32_t curIndex = 0; uint32_t curIndex = 0;
@ -228,7 +230,7 @@ std::unordered_map<uint32_t, disabledInfo>& Menu::GetDisabledMap() {
} }
void Menu::MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors menuThemeIndex) { void Menu::MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors menuThemeIndex) {
disabledTempTooltip = "This setting is disabled because: \n\n"; disabledTempTooltip = "This setting is disabled because: \n";
disabledValue = false; disabledValue = false;
disabledTooltip = " "; disabledTooltip = " ";
@ -241,11 +243,16 @@ void Menu::MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors me
if (!widget.activeDisables.empty()) { if (!widget.activeDisables.empty()) {
widget.options->disabled = true; widget.options->disabled = true;
for (auto option : widget.activeDisables) { for (auto option : widget.activeDisables) {
disabledTempTooltip += std::string("- ") + disabledMap.at(option).reason + std::string("\n"); disabledTempTooltip += std::string("\n- ") + disabledMap.at(option).reason;
} }
widget.options->disabledTooltip = disabledTempTooltip.c_str(); widget.options->disabledTooltip = disabledTempTooltip.c_str();
} }
} }
if (widget.raceDisable && raceDisableActive) {
widget.options->disabled = true;
disabledTempTooltip += std::string("\n- Race Lockout Active");
widget.options->disabledTooltip = disabledTempTooltip.c_str();
}
if (widget.sameLine) { if (widget.sameLine) {
ImGui::SameLine(); ImGui::SameLine();
@ -492,6 +499,8 @@ void Menu::DrawElement() {
info.active = info.evaluation(info); info.active = info.evaluation(info);
} }
raceDisableActive = CVarGetInteger(CVAR_SETTING("DisableChanges"), 0);
windowHeight = ImGui::GetMainViewport()->WorkSize.y; windowHeight = ImGui::GetMainViewport()->WorkSize.y;
windowWidth = ImGui::GetMainViewport()->WorkSize.x; windowWidth = ImGui::GetMainViewport()->WorkSize.x;
auto windowFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings; auto windowFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings;

View file

@ -109,6 +109,7 @@ struct WidgetInfo {
const char* windowName = ""; const char* windowName = "";
bool isHidden = false; bool isHidden = false;
bool sameLine = false; bool sameLine = false;
bool raceDisable = true;
WidgetInfo& CVar(const char* cVar_) { WidgetInfo& CVar(const char* cVar_) {
cVar = cVar_; cVar = cVar_;
@ -191,6 +192,10 @@ struct WidgetInfo {
customFunction = customFunction_; customFunction = customFunction_;
return *this; return *this;
} }
WidgetInfo& RaceDisable(bool disable) {
raceDisable = disable;
return *this;
}
}; };
struct WidgetPath { struct WidgetPath {

View file

@ -371,29 +371,37 @@ void RegisterResolutionWidgets() {
WidgetPath path = { "Settings", "Graphics", SECTION_COLUMN_2 }; WidgetPath path = { "Settings", "Graphics", SECTION_COLUMN_2 };
// Resolution visualiser // Resolution visualiser
mSohMenu->AddWidget(path, "Viewport dimensions: {} x {}", WIDGET_TEXT).PreFunc([](WidgetInfo& info) { mSohMenu->AddWidget(path, "Viewport dimensions: {} x {}", WIDGET_TEXT)
.RaceDisable(false)
.PreFunc([](WidgetInfo& info) {
info.name = fmt::format("Viewport dimensions: {} x {}", gfx_current_game_window_viewport.width, info.name = fmt::format("Viewport dimensions: {} x {}", gfx_current_game_window_viewport.width,
gfx_current_game_window_viewport.height); gfx_current_game_window_viewport.height);
}); });
mSohMenu->AddWidget(path, "Internal resolution: {} x {}", WIDGET_TEXT).PreFunc([](WidgetInfo& info) { mSohMenu->AddWidget(path, "Internal resolution: {} x {}", WIDGET_TEXT)
info.name = .RaceDisable(false)
fmt::format("Internal resolution: {} x {}", gfx_current_dimensions.width, gfx_current_dimensions.height); .PreFunc([](WidgetInfo& info) {
info.name = fmt::format("Internal resolution: {} x {}", gfx_current_dimensions.width,
gfx_current_dimensions.height);
}); });
// Activator // Activator
mSohMenu->AddWidget(path, "Enable advanced settings.", WIDGET_CVAR_CHECKBOX) mSohMenu->AddWidget(path, "Enable advanced settings.", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled"); .CVar(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled")
.RaceDisable(false);
// Error/Warning display // Error/Warning display
mSohMenu mSohMenu
->AddWidget(path, ICON_FA_EXCLAMATION_TRIANGLE " Significant frame rate (FPS) drops may be occuring.", ->AddWidget(path, ICON_FA_EXCLAMATION_TRIANGLE " Significant frame rate (FPS) drops may be occuring.",
WIDGET_TEXT) WIDGET_TEXT)
.RaceDisable(false)
.PreFunc( .PreFunc(
[](WidgetInfo& info) { info.isHidden = !(!CVarGetInteger(CVAR_LOW_RES_MODE, 0) && IsDroppingFrames()); }) [](WidgetInfo& info) { info.isHidden = !(!CVarGetInteger(CVAR_LOW_RES_MODE, 0) && IsDroppingFrames()); })
.Options(TextOptions().Color(Colors::Orange)); .Options(TextOptions().Color(Colors::Orange));
mSohMenu->AddWidget(path, ICON_FA_QUESTION_CIRCLE " \"N64 Mode\" is overriding these settings.", WIDGET_TEXT) mSohMenu->AddWidget(path, ICON_FA_QUESTION_CIRCLE " \"N64 Mode\" is overriding these settings.", WIDGET_TEXT)
.RaceDisable(false)
.PreFunc([](WidgetInfo& info) { info.isHidden = !CVarGetInteger(CVAR_LOW_RES_MODE, 0); }) .PreFunc([](WidgetInfo& info) { info.isHidden = !CVarGetInteger(CVAR_LOW_RES_MODE, 0); })
.Options(TextOptions().Color(Colors::LightBlue)); .Options(TextOptions().Color(Colors::LightBlue));
mSohMenu->AddWidget(path, "Click to disable N64 mode", WIDGET_BUTTON) mSohMenu->AddWidget(path, "Click to disable N64 mode", WIDGET_BUTTON)
.RaceDisable(false)
.PreFunc([](WidgetInfo& info) { info.isHidden = !CVarGetInteger(CVAR_LOW_RES_MODE, 0); }) .PreFunc([](WidgetInfo& info) { info.isHidden = !CVarGetInteger(CVAR_LOW_RES_MODE, 0); })
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
CVarSetInteger(CVAR_LOW_RES_MODE, 0); CVarSetInteger(CVAR_LOW_RES_MODE, 0);
@ -401,17 +409,18 @@ void RegisterResolutionWidgets() {
}); });
// Aspect Ratio // Aspect Ratio
mSohMenu->AddWidget(path, "AspectSep", WIDGET_SEPARATOR).PreFunc([](WidgetInfo& info) { mSohMenu->AddWidget(path, "AspectSep", WIDGET_SEPARATOR).RaceDisable(false).PreFunc([](WidgetInfo& info) {
if (mSohMenu->GetDisabledMap().at(DISABLE_FOR_ADVANCED_RESOLUTION_OFF).active) { if (mSohMenu->GetDisabledMap().at(DISABLE_FOR_ADVANCED_RESOLUTION_OFF).active) {
info.activeDisables.push_back(DISABLE_FOR_ADVANCED_RESOLUTION_OFF); info.activeDisables.push_back(DISABLE_FOR_ADVANCED_RESOLUTION_OFF);
} }
}); });
mSohMenu->AddWidget(path, "Force aspect ratio:", WIDGET_TEXT).PreFunc([](WidgetInfo& info) { mSohMenu->AddWidget(path, "Force aspect ratio:", WIDGET_TEXT).RaceDisable(false).PreFunc([](WidgetInfo& info) {
if (mSohMenu->GetDisabledMap().at(DISABLE_FOR_ADVANCED_RESOLUTION_OFF).active) { if (mSohMenu->GetDisabledMap().at(DISABLE_FOR_ADVANCED_RESOLUTION_OFF).active) {
info.activeDisables.push_back(DISABLE_FOR_ADVANCED_RESOLUTION_OFF); info.activeDisables.push_back(DISABLE_FOR_ADVANCED_RESOLUTION_OFF);
} }
}); });
mSohMenu->AddWidget(path, "(Select \"Off\" to disable.)", WIDGET_TEXT) mSohMenu->AddWidget(path, "(Select \"Off\" to disable.)", WIDGET_TEXT)
.RaceDisable(false)
.PreFunc([](WidgetInfo& info) { .PreFunc([](WidgetInfo& info) {
if (mSohMenu->GetDisabledMap().at(DISABLE_FOR_ADVANCED_RESOLUTION_OFF).active) { if (mSohMenu->GetDisabledMap().at(DISABLE_FOR_ADVANCED_RESOLUTION_OFF).active) {
info.activeDisables.push_back(DISABLE_FOR_ADVANCED_RESOLUTION_OFF); info.activeDisables.push_back(DISABLE_FOR_ADVANCED_RESOLUTION_OFF);
@ -422,6 +431,7 @@ void RegisterResolutionWidgets() {
// Presets // Presets
mSohMenu->AddWidget(path, "Aspect Ratio", WIDGET_COMBOBOX) mSohMenu->AddWidget(path, "Aspect Ratio", WIDGET_COMBOBOX)
.ValuePointer(&item_aspectRatio) .ValuePointer(&item_aspectRatio)
.RaceDisable(false)
.PreFunc([](WidgetInfo& info) { .PreFunc([](WidgetInfo& info) {
if (mSohMenu->GetDisabledMap().at(DISABLE_FOR_ADVANCED_RESOLUTION_OFF).active) { if (mSohMenu->GetDisabledMap().at(DISABLE_FOR_ADVANCED_RESOLUTION_OFF).active) {
info.activeDisables.push_back(DISABLE_FOR_ADVANCED_RESOLUTION_OFF); info.activeDisables.push_back(DISABLE_FOR_ADVANCED_RESOLUTION_OFF);
@ -443,7 +453,9 @@ void RegisterResolutionWidgets() {
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
}) })
.Options(ComboboxOptions().ComboMap(aspectRatioPresetLabels)); .Options(ComboboxOptions().ComboMap(aspectRatioPresetLabels));
mSohMenu->AddWidget(path, "AspectRatioCustom", WIDGET_CUSTOM).CustomFunction([](WidgetInfo& info) { mSohMenu->AddWidget(path, "AspectRatioCustom", WIDGET_CUSTOM)
.RaceDisable(false)
.CustomFunction([](WidgetInfo& info) {
// Hide aspect ratio input fields if using one of the presets. // Hide aspect ratio input fields if using one of the presets.
if (item_aspectRatio == default_aspectRatio && !showHorizontalResField) { if (item_aspectRatio == default_aspectRatio && !showHorizontalResField) {
// Declare input interaction bools outside of IF statement to prevent Y field from disappearing. // Declare input interaction bools outside of IF statement to prevent Y field from disappearing.
@ -475,12 +487,15 @@ void RegisterResolutionWidgets() {
} else if (showHorizontalResField) { // Show calculated aspect ratio } else if (showHorizontalResField) { // Show calculated aspect ratio
if (item_aspectRatio) { if (item_aspectRatio) {
ImGui::Dummy({ 0, 2 }); ImGui::Dummy({ 0, 2 });
const float resolvedAspectRatio = (float)gfx_current_dimensions.width / gfx_current_dimensions.height; const float resolvedAspectRatio =
(float)gfx_current_dimensions.width / gfx_current_dimensions.height;
ImGui::Text("Aspect ratio: %.2f:1", resolvedAspectRatio); ImGui::Text("Aspect ratio: %.2f:1", resolvedAspectRatio);
} }
} }
}); });
mSohMenu->AddWidget(path, "MoreResolutionSettings", WIDGET_CUSTOM).CustomFunction(ResolutionCustomWidget); mSohMenu->AddWidget(path, "MoreResolutionSettings", WIDGET_CUSTOM)
.CustomFunction(ResolutionCustomWidget)
.RaceDisable(false);
} }
void UpdateResolutionVars() { void UpdateResolutionVars() {

View file

@ -93,6 +93,7 @@ void SohMenu::AddMenuDevTools() {
AddSidebarEntry("Dev Tools", path.sidebarName, 1); AddSidebarEntry("Dev Tools", path.sidebarName, 1);
AddWidget(path, "Popout Stats Window", WIDGET_WINDOW_BUTTON) AddWidget(path, "Popout Stats Window", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("SohStats")) .CVar(CVAR_WINDOW("SohStats"))
.RaceDisable(false)
.WindowName("Stats##Soh") .WindowName("Stats##Soh")
.Options(WindowButtonOptions().Tooltip("Enables the separate Stats Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Stats Window."));

View file

@ -85,6 +85,7 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Saving", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Saving", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Autosave", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Autosave", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("Autosave")) .CVar(CVAR_ENHANCEMENT("Autosave"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Save the game automatically on a 3 minute interval and when soft-resetting the game. The interval " "Save the game automatically on a 3 minute interval and when soft-resetting the game. The interval "
"autosave will wait if the game is paused in any way (dialogue, pause screen up, cutscenes, " "autosave will wait if the game is paused in any way (dialogue, pause screen up, cutscenes, "
@ -168,9 +169,11 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Controls", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Controls", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Answer Navi Prompt with L Button", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Answer Navi Prompt with L Button", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("NaviOnL")) .CVar(CVAR_ENHANCEMENT("NaviOnL"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Speak to Navi with L but enter First-Person Camera with C-Up.")); .Options(CheckboxOptions().Tooltip("Speak to Navi with L but enter First-Person Camera with C-Up."));
AddWidget(path, "Don't Require Input for Credits Sequence", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Don't Require Input for Credits Sequence", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("NoInputForCredits")) .CVar(CVAR_ENHANCEMENT("NoInputForCredits"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Removes the Input Requirement on Text boxes after defeating Ganon, allowing the Credits " "Removes the Input Requirement on Text boxes after defeating Ganon, allowing the Credits "
"Sequence to continue to progress.")); "Sequence to continue to progress."));
@ -202,14 +205,20 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Item Count Messages", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Item Count Messages", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Gold Skulltula Tokens", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Gold Skulltula Tokens", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("InjectItemCounts.GoldSkulltula")); .CVar(CVAR_ENHANCEMENT("InjectItemCounts.GoldSkulltula"))
AddWidget(path, "Pieces of Heart", WIDGET_CVAR_CHECKBOX).CVar(CVAR_ENHANCEMENT("InjectItemCounts.HeartPiece")); .RaceDisable(false);
AddWidget(path, "Heart Containers", WIDGET_CVAR_CHECKBOX).CVar(CVAR_ENHANCEMENT("InjectItemCounts.HeartContainer")); AddWidget(path, "Pieces of Heart", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("InjectItemCounts.HeartPiece"))
.RaceDisable(false);
AddWidget(path, "Heart Containers", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("InjectItemCounts.HeartContainer"))
.RaceDisable(false);
path.column = SECTION_COLUMN_3; path.column = SECTION_COLUMN_3;
AddWidget(path, "Misc", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Misc", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Disable Crit Wiggle", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Disable Crit Wiggle", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("DisableCritWiggle")) .CVar(CVAR_ENHANCEMENT("DisableCritWiggle"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Disable Random Camera Wiggle at Low Health.")); .Options(CheckboxOptions().Tooltip("Disable Random Camera Wiggle at Low Health."));
AddWidget(path, "Better Owl", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Better Owl", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("BetterOwl")) .CVar(CVAR_ENHANCEMENT("BetterOwl"))
@ -430,27 +439,32 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Mods", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Mods", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Use Alternate Assets", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Use Alternate Assets", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SETTING("AltAssets")) .CVar(CVAR_SETTING("AltAssets"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Toggle between standard assets and alternate assets. Usually mods will indicate if " "Toggle between standard assets and alternate assets. Usually mods will indicate if "
"this setting has to be used or not.")); "this setting has to be used or not."));
AddWidget(path, "Disable Bomb Billboarding", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Disable Bomb Billboarding", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("DisableBombBillboarding")) .CVar(CVAR_ENHANCEMENT("DisableBombBillboarding"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Disables bombs always rotating to face the camera. To be used in conjunction with mods that want to " "Disables bombs always rotating to face the camera. To be used in conjunction with mods that want to "
"replace bombs with 3D objects.")); "replace bombs with 3D objects."));
AddWidget(path, "Disable Grotto Fixed Rotation", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Disable Grotto Fixed Rotation", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("DisableGrottoRotation")) .CVar(CVAR_ENHANCEMENT("DisableGrottoRotation"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Disables Grottos rotating with the Camera. To be used in conjuction with mods that want to " "Disables Grottos rotating with the Camera. To be used in conjuction with mods that want to "
"replace grottos with 3D objects.")); "replace grottos with 3D objects."));
AddWidget(path, "Ingame Text Spacing: %d", WIDGET_CVAR_SLIDER_INT) AddWidget(path, "Ingame Text Spacing: %d", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_ENHANCEMENT("TextSpacing")) .CVar(CVAR_ENHANCEMENT("TextSpacing"))
.RaceDisable(false)
.Options(IntSliderOptions().Min(4).Max(6).DefaultValue(6).Tooltip( .Options(IntSliderOptions().Min(4).Max(6).DefaultValue(6).Tooltip(
"Space between text characters (useful for HD font textures).")); "Space between text characters (useful for HD font textures)."));
AddWidget(path, "Models & Textures", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Models & Textures", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Disable LOD", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Disable LOD", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("DisableLOD")) .CVar(CVAR_ENHANCEMENT("DisableLOD"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Turns off the Level of Detail setting, making models use their Higher-Poly variants at any distance.")); "Turns off the Level of Detail setting, making models use their Higher-Poly variants at any distance."));
AddWidget(path, "Enemy Health Bars", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Enemy Health Bars", WIDGET_CVAR_CHECKBOX)
@ -458,18 +472,22 @@ void SohMenu::AddMenuEnhancements() {
.Options(CheckboxOptions().Tooltip("Renders a health bar for Enemies when Z-Targeted.")); .Options(CheckboxOptions().Tooltip("Renders a health bar for Enemies when Z-Targeted."));
AddWidget(path, "Enable 3D Dropped Items/Projectiles", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Enable 3D Dropped Items/Projectiles", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("NewDrops")) .CVar(CVAR_ENHANCEMENT("NewDrops"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Replaces most 2D items and projectiles on the overworld with their equivalent 3D models.")); "Replaces most 2D items and projectiles on the overworld with their equivalent 3D models."));
AddWidget(path, "Animated Link in Pause Menu", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Animated Link in Pause Menu", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("PauseMenuAnimatedLink")) .CVar(CVAR_ENHANCEMENT("PauseMenuAnimatedLink"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Turns the Static Image of Link in the Pause Menu's Equipment Subscreen " .Options(CheckboxOptions().Tooltip("Turns the Static Image of Link in the Pause Menu's Equipment Subscreen "
"into a model cycling through his idle animations.")); "into a model cycling through his idle animations."));
AddWidget(path, "Show Age-Dependent Equipment", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Show Age-Dependent Equipment", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("EquipmentAlwaysVisible")) .CVar(CVAR_ENHANCEMENT("EquipmentAlwaysVisible"))
.RaceDisable(false)
.Callback([](WidgetInfo& info) { UpdatePatchHand(); }) .Callback([](WidgetInfo& info) { UpdatePatchHand(); })
.Options(CheckboxOptions().Tooltip("Makes all equipment visible, regardless of age.")); .Options(CheckboxOptions().Tooltip("Makes all equipment visible, regardless of age."));
AddWidget(path, "Scale Adult Equipment as Child", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Scale Adult Equipment as Child", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("ScaleAdultEquipmentAsChild")) .CVar(CVAR_ENHANCEMENT("ScaleAdultEquipmentAsChild"))
.RaceDisable(false)
.PreFunc([](WidgetInfo& info) { .PreFunc([](WidgetInfo& info) {
info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("EquipmentAlwaysVisible"), 0) == 0; info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("EquipmentAlwaysVisible"), 0) == 0;
}) })
@ -478,11 +496,14 @@ void SohMenu::AddMenuEnhancements() {
"not work properly with some mods.")); "not work properly with some mods."));
AddWidget(path, "Show Gauntlets in First Person", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Show Gauntlets in First Person", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FirstPersonGauntlets")) .CVar(CVAR_ENHANCEMENT("FirstPersonGauntlets"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Renders Gauntlets when using the Bow and Hookshot like in OoT3D.")); .Options(CheckboxOptions().Tooltip("Renders Gauntlets when using the Bow and Hookshot like in OoT3D."));
AddWidget(path, "Show Chains on Both Sides of Locked Doors", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Show Chains on Both Sides of Locked Doors", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("ShowDoorLocksOnBothSides")); .CVar(CVAR_ENHANCEMENT("ShowDoorLocksOnBothSides"))
.RaceDisable(false);
AddWidget(path, "Color Temple of Time's Medallions", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Color Temple of Time's Medallions", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("ToTMedallionsColors")) .CVar(CVAR_ENHANCEMENT("ToTMedallionsColors"))
.RaceDisable(false)
.Callback([](WidgetInfo& info) { PatchToTMedallions(); }) .Callback([](WidgetInfo& info) { PatchToTMedallions(); })
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"When Medallions are collected, the Medallion imprints around the Master Sword Pedestal in the Temple " "When Medallions are collected, the Medallion imprints around the Master Sword Pedestal in the Temple "
@ -500,15 +521,18 @@ void SohMenu::AddMenuEnhancements() {
"in Hot/Underwater conditions.")); "in Hot/Underwater conditions."));
AddWidget(path, "Remember Minimap State Between Areas", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Remember Minimap State Between Areas", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("RememberMapToggleState")) .CVar(CVAR_ENHANCEMENT("RememberMapToggleState"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Preverse the minimap visibility state when going between areas rather than default it to \"on\" " "Preserve the minimap visibility state when going between areas rather than default it to \"on\" "
"when going through loading zones.")); "when going through loading zones."));
AddWidget(path, "Visual Stone of Agony", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Visual Stone of Agony", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("VisualAgony")) .CVar(CVAR_ENHANCEMENT("VisualAgony"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Displays an icon and plays a sound when Stone of Agony should be activated, for those without rumble.")); "Displays an icon and plays a sound when Stone of Agony should be activated, for those without rumble."));
AddWidget(path, "Disable HUD Heart Animations", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Disable HUD Heart Animations", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("NoHUDHeartAnimation")) .CVar(CVAR_ENHANCEMENT("NoHUDHeartAnimation"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Disables the Beating Animation of the Hearts on the HUD.")); .Options(CheckboxOptions().Tooltip("Disables the Beating Animation of the Hearts on the HUD."));
AddWidget(path, "Glitch Line-up Tick", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Glitch Line-up Tick", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("DrawLineupTick")) .CVar(CVAR_ENHANCEMENT("DrawLineupTick"))
@ -517,26 +541,32 @@ void SohMenu::AddMenuEnhancements() {
"UI based line-ups do not work outside of 4:3")); "UI based line-ups do not work outside of 4:3"));
AddWidget(path, "Disable Black Bar Letterboxes", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Disable Black Bar Letterboxes", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("DisableBlackBars")) .CVar(CVAR_ENHANCEMENT("DisableBlackBars"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Disables Black Bar Letterboxes during cutscenes and Z-Targeting. NOTE: There may be minor visual " "Disables Black Bar Letterboxes during cutscenes and Z-Targeting. NOTE: There may be minor visual "
"glitches that were covered up by the black bars. Please disable this setting before reporting a bug.")); "glitches that were covered up by the black bars. Please disable this setting before reporting a bug."));
AddWidget(path, "Dynamic Wallet Icon", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Dynamic Wallet Icon", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("DynamicWalletIcon")) .CVar(CVAR_ENHANCEMENT("DynamicWalletIcon"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Changes the Rupee in the Wallet icon to match the wallet size you currently have.")); "Changes the Rupee in the Wallet icon to match the wallet size you currently have."));
AddWidget(path, "Always Show Dungeon Entrances", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Always Show Dungeon Entrances", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon")) .CVar(CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Always shows dungeon entrance icons on the Minimap.")); .Options(CheckboxOptions().Tooltip("Always shows dungeon entrance icons on the Minimap."));
AddWidget(path, "More Info in File Select", WIDGET_CVAR_CHECKBOX) AddWidget(path, "More Info in File Select", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FileSelectMoreInfo")) .CVar(CVAR_ENHANCEMENT("FileSelectMoreInfo"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Shows what items you have collected in the File Select screen, like in N64 Randomizer.")); "Shows what items you have collected in the File Select screen, like in N64 Randomizer."));
AddWidget(path, "Better Ammo Rendering in Pause Menu", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Better Ammo Rendering in Pause Menu", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("BetterAmmoRendering")) .CVar(CVAR_ENHANCEMENT("BetterAmmoRendering"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Ammo counts in the pause menu will work correctly regardless of the position of items in the Inventory.")); "Ammo counts in the pause menu will work correctly regardless of the position of items in the Inventory."));
AddWidget(path, "Enable Passage of Time on File Select", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Enable Passage of Time on File Select", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("TimeFlowFileSelect")) .CVar(CVAR_ENHANCEMENT("TimeFlowFileSelect"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("The skybox in the background of the File Select screen will go through the " .Options(CheckboxOptions().Tooltip("The skybox in the background of the File Select screen will go through the "
"day and night cycle over time.")); "day and night cycle over time."));
@ -544,14 +574,17 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Misc.", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Misc.", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "N64 Mode", WIDGET_CVAR_CHECKBOX) AddWidget(path, "N64 Mode", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_LOW_RES_MODE) .CVar(CVAR_LOW_RES_MODE)
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Sets the aspect ratio to 4:3 and lowers resolution to 240p, the N64's native resolution.")); "Sets the aspect ratio to 4:3 and lowers resolution to 240p, the N64's native resolution."));
AddWidget(path, "Remove Spin Attack Darkness", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Remove Spin Attack Darkness", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("RemoveSpinAttackDarkness")) .CVar(CVAR_ENHANCEMENT("RemoveSpinAttackDarkness"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Remove the Darkness that appears when charging a Spin Attack.")); .Options(CheckboxOptions().Tooltip("Remove the Darkness that appears when charging a Spin Attack."));
AddWidget(path, "Draw Distance", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Draw Distance", WIDGET_SEPARATOR_TEXT).RaceDisable(false);
AddWidget(path, "Increase Actor Draw Distance: %dx", WIDGET_CVAR_SLIDER_INT) AddWidget(path, "Increase Actor Draw Distance: %dx", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_ENHANCEMENT("DisableDrawDistance")) .CVar(CVAR_ENHANCEMENT("DisableDrawDistance"))
.RaceDisable(false)
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1) <= 1) { if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1) <= 1) {
CVarSetInteger(CVAR_ENHANCEMENT("DisableKokiriDrawDistance"), 0); CVarSetInteger(CVAR_ENHANCEMENT("DisableKokiriDrawDistance"), 0);
@ -561,6 +594,7 @@ void SohMenu::AddMenuEnhancements() {
"Increases the range in which Actors/Objects are drawn.")); "Increases the range in which Actors/Objects are drawn."));
AddWidget(path, "Kokiri Draw Distance", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Kokiri Draw Distance", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("DisableKokiriDrawDistance")) .CVar(CVAR_ENHANCEMENT("DisableKokiriDrawDistance"))
.RaceDisable(false)
.PreFunc( .PreFunc(
[](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1) <= 1; }) [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1) <= 1; })
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
@ -896,22 +930,27 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Graphical Fixes", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Graphical Fixes", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Fix L&R Pause Menu", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Fix L&R Pause Menu", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FixMenuLR")) .CVar(CVAR_ENHANCEMENT("FixMenuLR"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Makes the L and R buttons in the pause menu the same color.")); .Options(CheckboxOptions().Tooltip("Makes the L and R buttons in the pause menu the same color."));
AddWidget(path, "Fix Dungeon Entrances", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Fix Dungeon Entrances", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FixDungeonMinimapIcon")) .CVar(CVAR_ENHANCEMENT("FixDungeonMinimapIcon"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Removes the Dungeon Entrance icon on the top-left corner of the screen when no dungeon is present on the " "Removes the Dungeon Entrance icon on the top-left corner of the screen when no dungeon is present on the "
"current map.")); "current map."));
AddWidget(path, "Fix Two-Handed Idle Animations", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Fix Two-Handed Idle Animations", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("TwoHandedIdle")) .CVar(CVAR_ENHANCEMENT("TwoHandedIdle"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Re-Enables the two-handed idle animation, a seemingly finished animation that was disabled on accident " "Re-Enables the two-handed idle animation, a seemingly finished animation that was disabled on accident "
"in the original game.")); "in the original game."));
AddWidget(path, "Fix Navi Text HUD Position", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Fix Navi Text HUD Position", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("NaviTextFix")) .CVar(CVAR_ENHANCEMENT("NaviTextFix"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Correctly centers the Navi text prompt on the HUD's C-Up button.")); .Options(CheckboxOptions().Tooltip("Correctly centers the Navi text prompt on the HUD's C-Up button."));
AddWidget(path, "Fix Gerudo Warrior's Clothing Colors", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Fix Gerudo Warrior's Clothing Colors", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("GerudoWarriorClothingFix")) .CVar(CVAR_ENHANCEMENT("GerudoWarriorClothingFix"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Prevent the Gerudo Warrior's clothes changing color when changing Link's tunic or " "Prevent the Gerudo Warrior's clothes changing color when changing Link's tunic or "
"using bombs in front of her.")); "using bombs in front of her."));
@ -922,15 +961,18 @@ void SohMenu::AddMenuEnhancements() {
"Fixes authentic out of bounds texture reads, instead loading textures with the correct size.")); "Fixes authentic out of bounds texture reads, instead loading textures with the correct size."));
AddWidget(path, "Fix Link's Eyes Open while Sleeping", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Fix Link's Eyes Open while Sleeping", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FixEyesOpenWhileSleeping")) .CVar(CVAR_ENHANCEMENT("FixEyesOpenWhileSleeping"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Fixes Link's eyes being open in the opening cutscene when he is supposed to be sleeping.")); "Fixes Link's eyes being open in the opening cutscene when he is supposed to be sleeping."));
AddWidget(path, "Fix Hand Holding Hammer", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Fix Hand Holding Hammer", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FixHammerHand")) .CVar(CVAR_ENHANCEMENT("FixHammerHand"))
.RaceDisable(false)
.Callback([](WidgetInfo& info) { UpdatePatchHand(); }) .Callback([](WidgetInfo& info) { UpdatePatchHand(); })
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Fixes Adult Link having a backwards Left hand when holding the Megaton Hammer.")); "Fixes Adult Link having a backwards Left hand when holding the Megaton Hammer."));
AddWidget(path, "Fix Vanishing Paths", WIDGET_CVAR_COMBOBOX) AddWidget(path, "Fix Vanishing Paths", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_ENHANCEMENT("SceneSpecificDirtPathFix")) .CVar(CVAR_ENHANCEMENT("SceneSpecificDirtPathFix"))
.RaceDisable(false)
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
if (gPlayState != NULL) { if (gPlayState != NULL) {
UpdateDirtPathFixState(gPlayState->sceneNum); UpdateDirtPathFixState(gPlayState->sceneNum);
@ -948,6 +990,7 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Audio Fixes", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Audio Fixes", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Fix Missing Jingle after 5 Silver Rupees", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Fix Missing Jingle after 5 Silver Rupees", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("SilverRupeeJingleExtend")) .CVar(CVAR_ENHANCEMENT("SilverRupeeJingleExtend"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Adds 5 higher pitches for the Silver Rupee Jingle for the rooms with more than 5 Silver Rupees. " "Adds 5 higher pitches for the Silver Rupee Jingle for the rooms with more than 5 Silver Rupees. "
"Only relevant for playthroughs involving Master Quest Dungeons.")); "Only relevant for playthroughs involving Master Quest Dungeons."));
@ -955,10 +998,12 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Desync Fixes", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Desync Fixes", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Fix Darunia Dancing too Fast", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Fix Darunia Dancing too Fast", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FixDaruniaDanceSpeed")) .CVar(CVAR_ENHANCEMENT("FixDaruniaDanceSpeed"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Fixes Darunia's dancing speed so he dances to the beat of Saria's Song, like in the Original Game.")); "Fixes Darunia's dancing speed so he dances to the beat of Saria's Song, like in the Original Game."));
AddWidget(path, "Fix Credits Timing (PAL)", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Fix Credits Timing (PAL)", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("CreditsFix")) .CVar(CVAR_ENHANCEMENT("CreditsFix"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Extend certain credits scenes so the music lines up properly with the visuals. (PAL only)")); "Extend certain credits scenes so the music lines up properly with the visuals. (PAL only)"));
@ -966,6 +1011,7 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Graphical Restorations", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Graphical Restorations", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Red Ganon Blood", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Red Ganon Blood", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("RedGanonBlood")) .CVar(CVAR_ENHANCEMENT("RedGanonBlood"))
.RaceDisable(false)
.Options( .Options(
CheckboxOptions().Tooltip("Restore the original red blood from NTSC 1.0/1.1. Disable for Green blood.")); CheckboxOptions().Tooltip("Restore the original red blood from NTSC 1.0/1.1. Disable for Green blood."));
AddWidget(path, "Restore Old Gold Skulltula Cutscene", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Restore Old Gold Skulltula Cutscene", WIDGET_CVAR_CHECKBOX)
@ -974,6 +1020,7 @@ void SohMenu::AddMenuEnhancements() {
"Restore pre-release behavior where defeating a Gold Skulltula will play a cutscene showing it die.")); "Restore pre-release behavior where defeating a Gold Skulltula will play a cutscene showing it die."));
AddWidget(path, "Pulsate Boss Icon", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Pulsate Boss Icon", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("PulsateBossIcon")) .CVar(CVAR_ENHANCEMENT("PulsateBossIcon"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Restores an unfinished feature to pulsate the boss room icon when you are in the boss room.")); "Restores an unfinished feature to pulsate the boss room icon when you are in the boss room."));
@ -1657,6 +1704,7 @@ void SohMenu::AddMenuEnhancements() {
path.column = SECTION_COLUMN_1; path.column = SECTION_COLUMN_1;
AddWidget(path, "Popout Cosmetics Editor Window", WIDGET_WINDOW_BUTTON) AddWidget(path, "Popout Cosmetics Editor Window", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("CosmeticsEditor")) .CVar(CVAR_WINDOW("CosmeticsEditor"))
.RaceDisable(false)
.WindowName("Cosmetics Editor") .WindowName("Cosmetics Editor")
.Options(WindowButtonOptions().Tooltip("Enables the separate Cosmetics Editor Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Cosmetics Editor Window."));
@ -1665,6 +1713,7 @@ void SohMenu::AddMenuEnhancements() {
AddSidebarEntry("Enhancements", path.sidebarName, 1); AddSidebarEntry("Enhancements", path.sidebarName, 1);
AddWidget(path, "Popout Audio Editor Window", WIDGET_WINDOW_BUTTON) AddWidget(path, "Popout Audio Editor Window", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("AudioEditor")) .CVar(CVAR_WINDOW("AudioEditor"))
.RaceDisable(false)
.WindowName("Audio Editor") .WindowName("Audio Editor")
.Options(WindowButtonOptions().Tooltip("Enables the separate Audio Editor Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Audio Editor Window."));
@ -1673,6 +1722,7 @@ void SohMenu::AddMenuEnhancements() {
AddSidebarEntry("Enhancements", path.sidebarName, 2); AddSidebarEntry("Enhancements", path.sidebarName, 2);
AddWidget(path, "Popout Gameplay Stats Window", WIDGET_WINDOW_BUTTON) AddWidget(path, "Popout Gameplay Stats Window", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("GameplayStats")) .CVar(CVAR_WINDOW("GameplayStats"))
.RaceDisable(false)
.WindowName("Gameplay Stats") .WindowName("Gameplay Stats")
.Options(WindowButtonOptions().Tooltip("Enables the separate Gameplay Stats Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Gameplay Stats Window."));
@ -1681,6 +1731,7 @@ void SohMenu::AddMenuEnhancements() {
AddSidebarEntry("Enhancements", path.sidebarName, 1); AddSidebarEntry("Enhancements", path.sidebarName, 1);
AddWidget(path, "Popout Time Splits Window", WIDGET_WINDOW_BUTTON) AddWidget(path, "Popout Time Splits Window", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("TimeSplits")) .CVar(CVAR_WINDOW("TimeSplits"))
.RaceDisable(false)
.WindowName("Time Splits") .WindowName("Time Splits")
.Options(WindowButtonOptions().Tooltip("Enables the separate Time Splits Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Time Splits Window."));
@ -1689,19 +1740,23 @@ void SohMenu::AddMenuEnhancements() {
AddSidebarEntry("Enhancements", path.sidebarName, 3); AddSidebarEntry("Enhancements", path.sidebarName, 3);
AddWidget(path, "Toggle Timers Window", WIDGET_WINDOW_BUTTON) AddWidget(path, "Toggle Timers Window", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("TimeDisplayEnabled")) .CVar(CVAR_WINDOW("TimeDisplayEnabled"))
.RaceDisable(false)
.WindowName("Additional Timers") .WindowName("Additional Timers")
.Options(WindowButtonOptions().Tooltip("Enables the separate Additional Timers Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Additional Timers Window."));
AddWidget(path, "Font Scale: %.2fx", WIDGET_CVAR_SLIDER_FLOAT) AddWidget(path, "Font Scale: %.2fx", WIDGET_CVAR_SLIDER_FLOAT)
.CVar(CVAR_TIME_DISPLAY("FontScale")) .CVar(CVAR_TIME_DISPLAY("FontScale"))
.RaceDisable(false)
.Callback([](WidgetInfo& info) { TimeDisplayInitSettings(); }) .Callback([](WidgetInfo& info) { TimeDisplayInitSettings(); })
.Options(FloatSliderOptions().Min(1.0f).Max(5.0f).DefaultValue(1.0f).Format("%.2fx")); .Options(FloatSliderOptions().Min(1.0f).Max(5.0f).DefaultValue(1.0f).Format("%.2fx"));
AddWidget(path, "Hide Background", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Hide Background", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_TIME_DISPLAY("ShowWindowBG")) .CVar(CVAR_TIME_DISPLAY("ShowWindowBG"))
.RaceDisable(false)
.Callback([](WidgetInfo& info) { TimeDisplayInitSettings(); }); .Callback([](WidgetInfo& info) { TimeDisplayInitSettings(); });
for (auto& timer : timeDisplayList) { for (auto& timer : timeDisplayList) {
AddWidget(path, timer.timeLabel, WIDGET_CVAR_CHECKBOX).CVar(timer.timeEnable).Callback([](WidgetInfo& info) { AddWidget(path, timer.timeLabel, WIDGET_CVAR_CHECKBOX)
TimeDisplayUpdateDisplayOptions(); .RaceDisable(false)
}); .CVar(timer.timeEnable)
.Callback([](WidgetInfo& info) { TimeDisplayUpdateDisplayOptions(); });
} }
} }

View file

@ -39,7 +39,7 @@ void SohMenu::AddMenuNetwork() {
}) })
.Options(ButtonOptions().Tooltip("https://github.com/HarbourMasters/sail")); .Options(ButtonOptions().Tooltip("https://github.com/HarbourMasters/sail"));
AddWidget(path, "Host & Port", WIDGET_CUSTOM).CustomFunction([](WidgetInfo& info) { AddWidget(path, "Host & Port", WIDGET_CUSTOM).CustomFunction([](WidgetInfo& info) {
ImGui::BeginDisabled(Sail::Instance->isEnabled); ImGui::BeginDisabled(Sail::Instance->isEnabled || CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
ImGui::Text("%s", info.name.c_str()); ImGui::Text("%s", info.name.c_str());
CVarInputString("##HostSail", CVAR_REMOTE_SAIL("Host"), CVarInputString("##HostSail", CVAR_REMOTE_SAIL("Host"),
InputOptions() InputOptions()
@ -111,7 +111,7 @@ void SohMenu::AddMenuNetwork() {
}) })
.Options(ButtonOptions().Tooltip("https://crowdcontrol.live")); .Options(ButtonOptions().Tooltip("https://crowdcontrol.live"));
AddWidget(path, "Host & Port", WIDGET_CUSTOM).CustomFunction([](WidgetInfo& info) { AddWidget(path, "Host & Port", WIDGET_CUSTOM).CustomFunction([](WidgetInfo& info) {
ImGui::BeginDisabled(CrowdControl::Instance->isEnabled); ImGui::BeginDisabled(CrowdControl::Instance->isEnabled || CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
ImGui::Text("%s", info.name.c_str()); ImGui::Text("%s", info.name.c_str());
CVarInputString("##HostCrowdControl", CVAR_REMOTE_CROWD_CONTROL("Host"), CVarInputString("##HostCrowdControl", CVAR_REMOTE_CROWD_CONTROL("Host"),
InputOptions() InputOptions()

View file

@ -29,6 +29,7 @@ void SohMenu::AddMenuRandomizer() {
.DefaultValue(true)); .DefaultValue(true));
AddWidget(path, "Random Rupee Names", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Random Rupee Names", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_RANDOMIZER_ENHANCEMENT("RandomizeRupeeNames")) .CVar(CVAR_RANDOMIZER_ENHANCEMENT("RandomizeRupeeNames"))
.RaceDisable(false)
.Options(CheckboxOptions() .Options(CheckboxOptions()
.Tooltip("When obtaining Rupees, randomize what the Rupee is called in the textbox.") .Tooltip("When obtaining Rupees, randomize what the Rupee is called in the textbox.")
.DefaultValue(true)); .DefaultValue(true));
@ -60,6 +61,7 @@ void SohMenu::AddMenuRandomizer() {
.DefaultValue(true)); .DefaultValue(true));
AddWidget(path, "Quest Item Fanfares", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Quest Item Fanfares", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_RANDOMIZER_ENHANCEMENT("QuestItemFanfares")) .CVar(CVAR_RANDOMIZER_ENHANCEMENT("QuestItemFanfares"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Play unique fanfares when obtaining quest items (medallions/stones/songs). Note that these " "Play unique fanfares when obtaining quest items (medallions/stones/songs). Note that these "
"fanfares can be longer than usual.")); "fanfares can be longer than usual."));
@ -71,6 +73,7 @@ void SohMenu::AddMenuRandomizer() {
"so you never know what you're getting.")); "so you never know what you're getting."));
AddWidget(path, "Simpler Boss Soul Models", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Simpler Boss Soul Models", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_RANDOMIZER_ENHANCEMENT("SimplerBossSoulModels")) .CVar(CVAR_RANDOMIZER_ENHANCEMENT("SimplerBossSoulModels"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"When shuffling boss souls, they'll appear as a simpler model instead of showing the boss' models." "When shuffling boss souls, they'll appear as a simpler model instead of showing the boss' models."
"This might make boss souls more distinguishable from a distance, and can help with performance.")); "This might make boss souls more distinguishable from a distance, and can help with performance."));
@ -93,6 +96,7 @@ void SohMenu::AddMenuRandomizer() {
AddSidebarEntry("Randomizer", path.sidebarName, 1); AddSidebarEntry("Randomizer", path.sidebarName, 1);
AddWidget(path, "Popout Plandomizer Window", WIDGET_WINDOW_BUTTON) AddWidget(path, "Popout Plandomizer Window", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("PlandomizerEditor")) .CVar(CVAR_WINDOW("PlandomizerEditor"))
.RaceDisable(false)
.WindowName("Plandomizer Editor") .WindowName("Plandomizer Editor")
.Options(WindowButtonOptions().Tooltip("Enables the separate Randomizer Settings Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Randomizer Settings Window."));
@ -103,12 +107,14 @@ void SohMenu::AddMenuRandomizer() {
AddWidget(path, "Item Tracker", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Item Tracker", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Toggle Item Tracker", WIDGET_WINDOW_BUTTON) AddWidget(path, "Toggle Item Tracker", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("ItemTracker")) .CVar(CVAR_WINDOW("ItemTracker"))
.RaceDisable(false)
.WindowName("Item Tracker") .WindowName("Item Tracker")
.Options(WindowButtonOptions().Tooltip("Toggles the Item Tracker.").EmbedWindow(false)); .Options(WindowButtonOptions().Tooltip("Toggles the Item Tracker.").EmbedWindow(false));
AddWidget(path, "Item Tracker Settings", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Item Tracker Settings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Popout Item Tracker Settings", WIDGET_WINDOW_BUTTON) AddWidget(path, "Popout Item Tracker Settings", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("ItemTrackerSettings")) .CVar(CVAR_WINDOW("ItemTrackerSettings"))
.RaceDisable(false)
.WindowName("Item Tracker Settings") .WindowName("Item Tracker Settings")
.Options(WindowButtonOptions().Tooltip("Enables the separate Item Tracker Settings Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Item Tracker Settings Window."));
@ -119,12 +125,14 @@ void SohMenu::AddMenuRandomizer() {
AddWidget(path, "Entrance Tracker", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Entrance Tracker", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Toggle Entrance Tracker", WIDGET_WINDOW_BUTTON) AddWidget(path, "Toggle Entrance Tracker", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("EntranceTracker")) .CVar(CVAR_WINDOW("EntranceTracker"))
.RaceDisable(false)
.WindowName("Entrance Tracker") .WindowName("Entrance Tracker")
.Options(WindowButtonOptions().Tooltip("Toggles the Entrance Tracker.").EmbedWindow(false)); .Options(WindowButtonOptions().Tooltip("Toggles the Entrance Tracker.").EmbedWindow(false));
AddWidget(path, "Entrance Tracker Settings", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Entrance Tracker Settings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Popout Entrance Tracker Settings", WIDGET_WINDOW_BUTTON) AddWidget(path, "Popout Entrance Tracker Settings", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("EntranceTrackerSettings")) .CVar(CVAR_WINDOW("EntranceTrackerSettings"))
.RaceDisable(false)
.WindowName("Entrance Tracker Settings") .WindowName("Entrance Tracker Settings")
.Options(WindowButtonOptions().Tooltip("Enables the separate Entrance Tracker Settings Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Entrance Tracker Settings Window."));
@ -135,12 +143,14 @@ void SohMenu::AddMenuRandomizer() {
AddWidget(path, "Check Tracker", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Check Tracker", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Toggle Check Tracker", WIDGET_WINDOW_BUTTON) AddWidget(path, "Toggle Check Tracker", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("CheckTracker")) .CVar(CVAR_WINDOW("CheckTracker"))
.RaceDisable(false)
.WindowName("Check Tracker") .WindowName("Check Tracker")
.Options(WindowButtonOptions().Tooltip("Toggles the Check Tracker.").EmbedWindow(false)); .Options(WindowButtonOptions().Tooltip("Toggles the Check Tracker.").EmbedWindow(false));
AddWidget(path, "Check Tracker Settings", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Check Tracker Settings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Popout Check Tracker Settings", WIDGET_WINDOW_BUTTON) AddWidget(path, "Popout Check Tracker Settings", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("CheckTrackerSettings")) .CVar(CVAR_WINDOW("CheckTrackerSettings"))
.RaceDisable(false)
.WindowName("Check Tracker Settings") .WindowName("Check Tracker Settings")
.Options(WindowButtonOptions().Tooltip("Enables the separate Check Tracker Settings Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Check Tracker Settings Window."));
} }

View file

@ -95,6 +95,7 @@ void SohMenu::AddMenuSettings() {
AddWidget(path, "Menu Settings", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Menu Settings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Menu Theme", WIDGET_CVAR_COMBOBOX) AddWidget(path, "Menu Theme", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_SETTING("Menu.Theme")) .CVar(CVAR_SETTING("Menu.Theme"))
.RaceDisable(false)
.Options(ComboboxOptions() .Options(ComboboxOptions()
.Tooltip("Changes the Theme of the Menu Widgets.") .Tooltip("Changes the Theme of the Menu Widgets.")
.ComboMap(menuThemeOptions) .ComboMap(menuThemeOptions)
@ -102,18 +103,21 @@ void SohMenu::AddMenuSettings() {
#if not defined(__SWITCH__) and not defined(__WIIU__) #if not defined(__SWITCH__) and not defined(__WIIU__)
AddWidget(path, "Menu Controller Navigation", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Menu Controller Navigation", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_IMGUI_CONTROLLER_NAV) .CVar(CVAR_IMGUI_CONTROLLER_NAV)
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Allows controller navigation of the port menu (Settings, Enhancements,...)\nCAUTION: " "Allows controller navigation of the port menu (Settings, Enhancements,...)\nCAUTION: "
"This will disable game inputs while the menu is visible.\n\nD-pad to move between " "This will disable game inputs while the menu is visible.\n\nD-pad to move between "
"items, A to select, B to move up in scope.")); "items, A to select, B to move up in scope."));
AddWidget(path, "Menu Background Opacity", WIDGET_CVAR_SLIDER_FLOAT) AddWidget(path, "Menu Background Opacity", WIDGET_CVAR_SLIDER_FLOAT)
.CVar(CVAR_SETTING("Menu.BackgroundOpacity")) .CVar(CVAR_SETTING("Menu.BackgroundOpacity"))
.RaceDisable(false)
.Options(FloatSliderOptions().DefaultValue(0.85f).IsPercentage().Tooltip( .Options(FloatSliderOptions().DefaultValue(0.85f).IsPercentage().Tooltip(
"Sets the opacity of the background of the port menu.")); "Sets the opacity of the background of the port menu."));
AddWidget(path, "General Settings", WIDGET_SEPARATOR_TEXT); AddWidget(path, "General Settings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Cursor Always Visible", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Cursor Always Visible", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SETTING("CursorVisibility")) .CVar(CVAR_SETTING("CursorVisibility"))
.RaceDisable(false)
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
Ship::Context::GetInstance()->GetWindow()->SetForceCursorVisibility( Ship::Context::GetInstance()->GetWindow()->SetForceCursorVisibility(
CVarGetInteger(CVAR_SETTING("CursorVisibility"), 0)); CVarGetInteger(CVAR_SETTING("CursorVisibility"), 0));
@ -122,6 +126,7 @@ void SohMenu::AddMenuSettings() {
#endif #endif
AddWidget(path, "Search In Sidebar", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Search In Sidebar", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SETTING("Menu.SidebarSearch")) .CVar(CVAR_SETTING("Menu.SidebarSearch"))
.RaceDisable(false)
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
if (CVarGetInteger(CVAR_SETTING("Menu.SidebarSearch"), 0)) { if (CVarGetInteger(CVAR_SETTING("Menu.SidebarSearch"), 0)) {
mSohMenu->InsertSidebarSearch(); mSohMenu->InsertSidebarSearch();
@ -133,13 +138,16 @@ void SohMenu::AddMenuSettings() {
"Displays the Search menu as a sidebar entry in Settings instead of in the header.")); "Displays the Search menu as a sidebar entry in Settings instead of in the header."));
AddWidget(path, "Search Input Autofocus", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Search Input Autofocus", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SETTING("Menu.SearchAutofocus")) .CVar(CVAR_SETTING("Menu.SearchAutofocus"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Search input box gets autofocus when visible. Does not affect using other widgets.")); "Search input box gets autofocus when visible. Does not affect using other widgets."));
AddWidget(path, "Alt Assets Tab hotkey", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Alt Assets Tab hotkey", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SETTING("Mods.AlternateAssetsHotkey")) .CVar(CVAR_SETTING("Mods.AlternateAssetsHotkey"))
.RaceDisable(false)
.Options( .Options(
CheckboxOptions().Tooltip("Allows pressing the Tab key to toggle alternate assets").DefaultValue(true)); CheckboxOptions().Tooltip("Allows pressing the Tab key to toggle alternate assets").DefaultValue(true));
AddWidget(path, "Open App Files Folder", WIDGET_BUTTON) AddWidget(path, "Open App Files Folder", WIDGET_BUTTON)
.RaceDisable(false)
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
std::string filesPath = Ship::Context::GetInstance()->GetAppDirectoryPath(); std::string filesPath = Ship::Context::GetInstance()->GetAppDirectoryPath();
SDL_OpenURL(std::string("file:///" + std::filesystem::absolute(filesPath).string()).c_str()); SDL_OpenURL(std::string("file:///" + std::filesystem::absolute(filesPath).string()).c_str());
@ -149,6 +157,7 @@ void SohMenu::AddMenuSettings() {
AddWidget(path, "Boot", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Boot", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Boot Sequence", WIDGET_CVAR_COMBOBOX) AddWidget(path, "Boot Sequence", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_SETTING("BootSequence")) .CVar(CVAR_SETTING("BootSequence"))
.RaceDisable(false)
.Options(ComboboxOptions() .Options(ComboboxOptions()
.DefaultIndex(BOOTSEQUENCE_DEFAULT) .DefaultIndex(BOOTSEQUENCE_DEFAULT)
.LabelPosition(LabelPositions::Far) .LabelPosition(LabelPositions::Far)
@ -160,9 +169,12 @@ void SohMenu::AddMenuSettings() {
"File Select: Skip to file select menu")); "File Select: Skip to file select menu"));
AddWidget(path, "Languages", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Languages", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Translate Title Screen", WIDGET_CVAR_CHECKBOX).CVar(CVAR_SETTING("TitleScreenTranslation")); AddWidget(path, "Translate Title Screen", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SETTING("TitleScreenTranslation"))
.RaceDisable(false);
AddWidget(path, "Language", WIDGET_CVAR_COMBOBOX) AddWidget(path, "Language", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_SETTING("Languages")) .CVar(CVAR_SETTING("Languages"))
.RaceDisable(false)
.PreFunc([](WidgetInfo& info) { .PreFunc([](WidgetInfo& info) {
auto options = std::static_pointer_cast<UIWidgets::ComboboxOptions>(info.options); auto options = std::static_pointer_cast<UIWidgets::ComboboxOptions>(info.options);
SohMenu::UpdateLanguageMap(options->comboMap); SohMenu::UpdateLanguageMap(options->comboMap);
@ -176,14 +188,17 @@ void SohMenu::AddMenuSettings() {
#if defined(_WIN32) || defined(__APPLE__) #if defined(_WIN32) || defined(__APPLE__)
AddWidget(path, "Text to Speech", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Text to Speech", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SETTING("A11yTTS")) .CVar(CVAR_SETTING("A11yTTS"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Enables text to speech for in game dialog")); .Options(CheckboxOptions().Tooltip("Enables text to speech for in game dialog"));
#endif #endif
AddWidget(path, "Disable Idle Camera Re-Centering", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Disable Idle Camera Re-Centering", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SETTING("A11yDisableIdleCam")) .CVar(CVAR_SETTING("A11yDisableIdleCam"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Disables the automatic re-centering of the camera when idle.")); .Options(CheckboxOptions().Tooltip("Disables the automatic re-centering of the camera when idle."));
AddWidget(path, "EXPERIMENTAL", WIDGET_SEPARATOR_TEXT).Options(TextOptions().Color(Colors::Orange)); AddWidget(path, "EXPERIMENTAL", WIDGET_SEPARATOR_TEXT).Options(TextOptions().Color(Colors::Orange));
AddWidget(path, "ImGui Menu Scaling", WIDGET_CVAR_COMBOBOX) AddWidget(path, "ImGui Menu Scaling", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_SETTING("ImGuiScale")) .CVar(CVAR_SETTING("ImGuiScale"))
.RaceDisable(false)
.Options(ComboboxOptions() .Options(ComboboxOptions()
.ComboMap(imguiScaleOptions) .ComboMap(imguiScaleOptions)
.Tooltip("Changes the scaling of the ImGui menu elements.") .Tooltip("Changes the scaling of the ImGui menu elements.")
@ -214,9 +229,11 @@ void SohMenu::AddMenuSettings() {
AddWidget(path, "Master Volume: %d %%", WIDGET_CVAR_SLIDER_INT) AddWidget(path, "Master Volume: %d %%", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_SETTING("Volume.Master")) .CVar(CVAR_SETTING("Volume.Master"))
.RaceDisable(false)
.Options(IntSliderOptions().Min(0).Max(100).DefaultValue(40).ShowButtons(true).Format("")); .Options(IntSliderOptions().Min(0).Max(100).DefaultValue(40).ShowButtons(true).Format(""));
AddWidget(path, "Main Music Volume: %d %%", WIDGET_CVAR_SLIDER_INT) AddWidget(path, "Main Music Volume: %d %%", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_SETTING("Volume.MainMusic")) .CVar(CVAR_SETTING("Volume.MainMusic"))
.RaceDisable(false)
.Options(IntSliderOptions().Min(0).Max(100).DefaultValue(100).ShowButtons(true).Format("")) .Options(IntSliderOptions().Min(0).Max(100).DefaultValue(100).ShowButtons(true).Format(""))
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
Audio_SetGameVolume(SEQ_PLAYER_BGM_MAIN, Audio_SetGameVolume(SEQ_PLAYER_BGM_MAIN,
@ -224,6 +241,7 @@ void SohMenu::AddMenuSettings() {
}); });
AddWidget(path, "Sub Music Volume: %d %%", WIDGET_CVAR_SLIDER_INT) AddWidget(path, "Sub Music Volume: %d %%", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_SETTING("Volume.SubMusic")) .CVar(CVAR_SETTING("Volume.SubMusic"))
.RaceDisable(false)
.Options(IntSliderOptions().Min(0).Max(100).DefaultValue(100).ShowButtons(true).Format("")) .Options(IntSliderOptions().Min(0).Max(100).DefaultValue(100).ShowButtons(true).Format(""))
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
Audio_SetGameVolume(SEQ_PLAYER_BGM_SUB, Audio_SetGameVolume(SEQ_PLAYER_BGM_SUB,
@ -231,6 +249,7 @@ void SohMenu::AddMenuSettings() {
}); });
AddWidget(path, "Fanfare Volume: %d %%", WIDGET_CVAR_SLIDER_INT) AddWidget(path, "Fanfare Volume: %d %%", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_SETTING("Volume.Fanfare")) .CVar(CVAR_SETTING("Volume.Fanfare"))
.RaceDisable(false)
.Options(IntSliderOptions().Min(0).Max(100).DefaultValue(100).ShowButtons(true).Format("")) .Options(IntSliderOptions().Min(0).Max(100).DefaultValue(100).ShowButtons(true).Format(""))
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
Audio_SetGameVolume(SEQ_PLAYER_FANFARE, Audio_SetGameVolume(SEQ_PLAYER_FANFARE,
@ -238,11 +257,12 @@ void SohMenu::AddMenuSettings() {
}); });
AddWidget(path, "Sound Effects Volume: %d %%", WIDGET_CVAR_SLIDER_INT) AddWidget(path, "Sound Effects Volume: %d %%", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_SETTING("Volume.SFX")) .CVar(CVAR_SETTING("Volume.SFX"))
.RaceDisable(false)
.Options(IntSliderOptions().Min(0).Max(100).DefaultValue(100).ShowButtons(true).Format("")) .Options(IntSliderOptions().Min(0).Max(100).DefaultValue(100).ShowButtons(true).Format(""))
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
Audio_SetGameVolume(SEQ_PLAYER_SFX, ((float)CVarGetInteger(CVAR_SETTING("Volume.SFX"), 100) / 100.0f)); Audio_SetGameVolume(SEQ_PLAYER_SFX, ((float)CVarGetInteger(CVAR_SETTING("Volume.SFX"), 100) / 100.0f));
}); });
AddWidget(path, "Audio API (Needs reload)", WIDGET_AUDIO_BACKEND); AddWidget(path, "Audio API (Needs reload)", WIDGET_AUDIO_BACKEND).RaceDisable(false);
// Graphics Settings // Graphics Settings
static int32_t maxFps = 360; static int32_t maxFps = 360;
@ -253,10 +273,12 @@ void SohMenu::AddMenuSettings() {
AddSidebarEntry("Settings", "Graphics", 3); AddSidebarEntry("Settings", "Graphics", 3);
AddWidget(path, "Graphics Options", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Graphics Options", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Toggle Fullscreen", WIDGET_BUTTON) AddWidget(path, "Toggle Fullscreen", WIDGET_BUTTON)
.RaceDisable(false)
.Callback([](WidgetInfo& info) { Ship::Context::GetInstance()->GetWindow()->ToggleFullscreen(); }) .Callback([](WidgetInfo& info) { Ship::Context::GetInstance()->GetWindow()->ToggleFullscreen(); })
.Options(ButtonOptions().Tooltip("Toggles Fullscreen On/Off.")); .Options(ButtonOptions().Tooltip("Toggles Fullscreen On/Off."));
AddWidget(path, "Internal Resolution", WIDGET_CVAR_SLIDER_FLOAT) AddWidget(path, "Internal Resolution", WIDGET_CVAR_SLIDER_FLOAT)
.CVar(CVAR_INTERNAL_RESOLUTION) .CVar(CVAR_INTERNAL_RESOLUTION)
.RaceDisable(false)
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
Ship::Context::GetInstance()->GetWindow()->SetResolutionMultiplier( Ship::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(
CVarGetFloat(CVAR_INTERNAL_RESOLUTION, 1)); CVarGetFloat(CVAR_INTERNAL_RESOLUTION, 1));
@ -281,6 +303,7 @@ void SohMenu::AddMenuSettings() {
#ifndef __WIIU__ #ifndef __WIIU__
AddWidget(path, "Anti-aliasing (MSAA)", WIDGET_CVAR_SLIDER_INT) AddWidget(path, "Anti-aliasing (MSAA)", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_MSAA_VALUE) .CVar(CVAR_MSAA_VALUE)
.RaceDisable(false)
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
Ship::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger(CVAR_MSAA_VALUE, 1)); Ship::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger(CVAR_MSAA_VALUE, 1));
}) })
@ -297,6 +320,7 @@ void SohMenu::AddMenuSettings() {
const char* fpsFormat = fps == 20 ? "Original (%d)" : "%d"; const char* fpsFormat = fps == 20 ? "Original (%d)" : "%d";
AddWidget(path, "Current FPS", WIDGET_CVAR_SLIDER_INT) AddWidget(path, "Current FPS", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_SETTING("InterpolationFPS")) .CVar(CVAR_SETTING("InterpolationFPS"))
.RaceDisable(false)
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
auto options = std::static_pointer_cast<IntSliderOptions>(info.options); auto options = std::static_pointer_cast<IntSliderOptions>(info.options);
int32_t defaultValue = options->defaultValue; int32_t defaultValue = options->defaultValue;
@ -313,28 +337,33 @@ void SohMenu::AddMenuSettings() {
.Options(IntSliderOptions().Tooltip(tooltip).Min(20).Max(maxFps).DefaultValue(20).Format(fpsFormat)); .Options(IntSliderOptions().Tooltip(tooltip).Min(20).Max(maxFps).DefaultValue(20).Format(fpsFormat));
AddWidget(path, "Match Refresh Rate", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Match Refresh Rate", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SETTING("MatchRefreshRate")) .CVar(CVAR_SETTING("MatchRefreshRate"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Matches interpolation value to the refresh rate of your display.")); .Options(CheckboxOptions().Tooltip("Matches interpolation value to the refresh rate of your display."));
AddWidget(path, "Renderer API (Needs reload)", WIDGET_VIDEO_BACKEND); AddWidget(path, "Renderer API (Needs reload)", WIDGET_VIDEO_BACKEND).RaceDisable(false);
AddWidget(path, "Enable Vsync", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Enable Vsync", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_VSYNC_ENABLED) .CVar(CVAR_VSYNC_ENABLED)
.RaceDisable(false)
.PreFunc([](WidgetInfo& info) { info.isHidden = mSohMenu->disabledMap.at(DISABLE_FOR_NO_VSYNC).active; }) .PreFunc([](WidgetInfo& info) { info.isHidden = mSohMenu->disabledMap.at(DISABLE_FOR_NO_VSYNC).active; })
.Options(CheckboxOptions() .Options(CheckboxOptions()
.Tooltip("Removes tearing, but clamps your max FPS to your displays refresh rate.") .Tooltip("Removes tearing, but clamps your max FPS to your displays refresh rate.")
.DefaultValue(true)); .DefaultValue(true));
AddWidget(path, "Windowed Fullscreen", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Windowed Fullscreen", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SDL_WINDOWED_FULLSCREEN) .CVar(CVAR_SDL_WINDOWED_FULLSCREEN)
.RaceDisable(false)
.PreFunc([](WidgetInfo& info) { .PreFunc([](WidgetInfo& info) {
info.isHidden = mSohMenu->disabledMap.at(DISABLE_FOR_NO_WINDOWED_FULLSCREEN).active; info.isHidden = mSohMenu->disabledMap.at(DISABLE_FOR_NO_WINDOWED_FULLSCREEN).active;
}) })
.Options(CheckboxOptions().Tooltip("Enables Windowed Fullscreen Mode.")); .Options(CheckboxOptions().Tooltip("Enables Windowed Fullscreen Mode."));
AddWidget(path, "Allow multi-windows", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Allow multi-windows", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENABLE_MULTI_VIEWPORTS) .CVar(CVAR_ENABLE_MULTI_VIEWPORTS)
.RaceDisable(false)
.PreFunc( .PreFunc(
[](WidgetInfo& info) { info.isHidden = mSohMenu->disabledMap.at(DISABLE_FOR_NO_MULTI_VIEWPORT).active; }) [](WidgetInfo& info) { info.isHidden = mSohMenu->disabledMap.at(DISABLE_FOR_NO_MULTI_VIEWPORT).active; })
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Allows multiple windows to be opened at once. Requires a reload to take effect.")); "Allows multiple windows to be opened at once. Requires a reload to take effect."));
AddWidget(path, "Texture Filter (Needs reload)", WIDGET_CVAR_COMBOBOX) AddWidget(path, "Texture Filter (Needs reload)", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_TEXTURE_FILTER) .CVar(CVAR_TEXTURE_FILTER)
.RaceDisable(false)
.Options(ComboboxOptions().Tooltip("Sets the applied Texture Filtering.").ComboMap(textureFilteringMap)); .Options(ComboboxOptions().Tooltip("Sets the applied Texture Filtering.").ComboMap(textureFilteringMap));
path.column = SECTION_COLUMN_2; path.column = SECTION_COLUMN_2;
@ -347,6 +376,7 @@ void SohMenu::AddMenuSettings() {
AddWidget(path, "Controller Bindings", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Controller Bindings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Popout Bindings Window", WIDGET_WINDOW_BUTTON) AddWidget(path, "Popout Bindings Window", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("ControllerConfiguration")) .CVar(CVAR_WINDOW("ControllerConfiguration"))
.RaceDisable(false)
.WindowName("Configure Controller") .WindowName("Configure Controller")
.Options(WindowButtonOptions().Tooltip("Enables the separate Bindings Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Bindings Window."));
@ -356,12 +386,14 @@ void SohMenu::AddMenuSettings() {
AddWidget(path, "Input Viewer", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Input Viewer", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Toggle Input Viewer", WIDGET_WINDOW_BUTTON) AddWidget(path, "Toggle Input Viewer", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("InputViewer")) .CVar(CVAR_WINDOW("InputViewer"))
.RaceDisable(false)
.WindowName("Input Viewer") .WindowName("Input Viewer")
.Options(WindowButtonOptions().Tooltip("Toggles the Input Viewer.").EmbedWindow(false)); .Options(WindowButtonOptions().Tooltip("Toggles the Input Viewer.").EmbedWindow(false));
AddWidget(path, "Input Viewer Settings", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Input Viewer Settings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Popout Input Viewer Settings", WIDGET_WINDOW_BUTTON) AddWidget(path, "Popout Input Viewer Settings", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("InputViewerSettings")) .CVar(CVAR_WINDOW("InputViewerSettings"))
.RaceDisable(false)
.WindowName("Input Viewer Settings") .WindowName("Input Viewer Settings")
.Options(WindowButtonOptions().Tooltip("Enables the separate Input Viewer Settings Window.")); .Options(WindowButtonOptions().Tooltip("Enables the separate Input Viewer Settings Window."));
@ -371,12 +403,14 @@ void SohMenu::AddMenuSettings() {
AddSidebarEntry("Settings", path.sidebarName, 3); AddSidebarEntry("Settings", path.sidebarName, 3);
AddWidget(path, "Position", WIDGET_CVAR_COMBOBOX) AddWidget(path, "Position", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_SETTING("Notifications.Position")) .CVar(CVAR_SETTING("Notifications.Position"))
.RaceDisable(false)
.Options(ComboboxOptions() .Options(ComboboxOptions()
.Tooltip("Which corner of the screen notifications appear in.") .Tooltip("Which corner of the screen notifications appear in.")
.ComboMap(notificationPosition) .ComboMap(notificationPosition)
.DefaultIndex(3)); .DefaultIndex(3));
AddWidget(path, "Duration (seconds):", WIDGET_CVAR_SLIDER_FLOAT) AddWidget(path, "Duration (seconds):", WIDGET_CVAR_SLIDER_FLOAT)
.CVar(CVAR_SETTING("Notifications.Duration")) .CVar(CVAR_SETTING("Notifications.Duration"))
.RaceDisable(false)
.Options(FloatSliderOptions() .Options(FloatSliderOptions()
.Tooltip("How long notifications are displayed for.") .Tooltip("How long notifications are displayed for.")
.Format("%.1f") .Format("%.1f")
@ -386,12 +420,14 @@ void SohMenu::AddMenuSettings() {
.DefaultValue(10.0f)); .DefaultValue(10.0f));
AddWidget(path, "Background Opacity", WIDGET_CVAR_SLIDER_FLOAT) AddWidget(path, "Background Opacity", WIDGET_CVAR_SLIDER_FLOAT)
.CVar(CVAR_SETTING("Notifications.BgOpacity")) .CVar(CVAR_SETTING("Notifications.BgOpacity"))
.RaceDisable(false)
.Options(FloatSliderOptions() .Options(FloatSliderOptions()
.Tooltip("How opaque the background of notifications is.") .Tooltip("How opaque the background of notifications is.")
.DefaultValue(0.5f) .DefaultValue(0.5f)
.IsPercentage()); .IsPercentage());
AddWidget(path, "Size:", WIDGET_CVAR_SLIDER_FLOAT) AddWidget(path, "Size:", WIDGET_CVAR_SLIDER_FLOAT)
.CVar(CVAR_SETTING("Notifications.Size")) .CVar(CVAR_SETTING("Notifications.Size"))
.RaceDisable(false)
.Options(FloatSliderOptions() .Options(FloatSliderOptions()
.Tooltip("How large notifications are.") .Tooltip("How large notifications are.")
.Format("%.1f") .Format("%.1f")
@ -400,6 +436,7 @@ void SohMenu::AddMenuSettings() {
.Max(5.0f) .Max(5.0f)
.DefaultValue(1.8f)); .DefaultValue(1.8f));
AddWidget(path, "Test Notification", WIDGET_BUTTON) AddWidget(path, "Test Notification", WIDGET_BUTTON)
.RaceDisable(false)
.Callback([](WidgetInfo& info) { .Callback([](WidgetInfo& info) {
Notification::Emit({ Notification::Emit({
.itemIcon = "__OTR__textures/icon_item_24_static/gQuestIconGoldSkulltulaTex", .itemIcon = "__OTR__textures/icon_item_24_static/gQuestIconGoldSkulltulaTex",