mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-12 11:12:20 -05:00
Zora's River waterfall always open, take two (#4459)
* Zora's River waterfall always open, take two * Remove improper, redundant checks in hook * Move all checks into update hook * Add Randomizer setting for keeping Sleeping Waterfall open * Change header exports to extern exports * Remove "closed as child" option for rando setting * Oops, missed a spot * A bit more cleanup: simplify a redundant condition * Unify hook handlers * Oopsie, fix build error * Add "play only once" option * Force Sleeping Waterfall enhancement in rando mode * Force enhancement only if waterfall is Open in rando * Restore forced-open waterfall in rando * Fix rando condition in hook * Fix? rando entrance logic for OI * Fix build errors
This commit is contained in:
parent
ee628059d8
commit
9b74a09955
@ -304,6 +304,7 @@ const std::vector<const char*> enhancementsCvars = {
|
||||
CVAR_ENHANCEMENT("TimeSavers.SkipChildStealth"),
|
||||
CVAR_ENHANCEMENT("TimeSavers.SkipTowerEscape"),
|
||||
CVAR_ENHANCEMENT("TimeSavers.SkipForcedDialog"),
|
||||
CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"),
|
||||
CVAR_ENHANCEMENT("SlowTextSpeed"),
|
||||
};
|
||||
|
||||
@ -549,6 +550,7 @@ const std::vector<const char*> randomizerCvars = {
|
||||
CVAR_RANDOMIZER_SETTING("SkipChildZelda"),
|
||||
CVAR_RANDOMIZER_SETTING("SkipEponaRace"),
|
||||
CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"),
|
||||
CVAR_RANDOMIZER_SETTING("SleepingWaterfall"),
|
||||
CVAR_RANDOMIZER_SETTING("StartingAge"),
|
||||
CVAR_RANDOMIZER_SETTING("StartingBoleroOfFire"),
|
||||
CVAR_RANDOMIZER_SETTING("StartingConsumables"),
|
||||
@ -1175,12 +1177,13 @@ const std::vector<PresetEntry> s6PresetEntries = {
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipTowerEscape"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), RO_WATERFALL_CLOSED),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingAge"), RO_AGE_RANDOM),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingConsumables"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingDekuShield"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_STARTWITH),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingOcarina"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), 0),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), RO_ZF_CLOSED),
|
||||
};
|
||||
|
||||
const std::vector<PresetEntry> hellModePresetEntries = {
|
||||
@ -1235,16 +1238,18 @@ const std::vector<PresetEntry> hellModePresetEntries = {
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipTowerEscape"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), RO_WATERFALL_OPEN),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingAge"), RO_AGE_RANDOM),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_ANYWHERE),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SunlightArrows"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), 2),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), RO_ZF_OPEN),
|
||||
};
|
||||
|
||||
const std::vector<PresetEntry> BenchmarkPresetEntries = {
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_CLOSED_DEKU),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), RO_KAK_GATE_OPEN),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_SONGONLY),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), RO_WATERFALL_CLOSED),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), RO_ZF_CLOSED),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL),
|
||||
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_DUNGEON_REWARDS),
|
||||
|
@ -43,7 +43,12 @@ void RegionTable_Init_ZorasDomain() {
|
||||
Entrance(RR_ZR_FAIRY_GROTTO, {[]{return Here(RR_ZORAS_RIVER, []{return logic->BlastOrSmash();});}}),
|
||||
Entrance(RR_THE_LOST_WOODS, {[]{return logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS);}}),
|
||||
Entrance(RR_ZR_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}),
|
||||
Entrance(RR_ZR_BEHIND_WATERFALL, {[]{return logic->CanUse(RG_ZELDAS_LULLABY) || (logic->IsChild && ctx->GetTrickOption(RT_ZR_CUCCO)) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_ZR_HOVERS));}}),
|
||||
Entrance(RR_ZR_BEHIND_WATERFALL, {[]{
|
||||
return ctx->GetOption(RSK_SLEEPING_WATERFALL).Is(RO_WATERFALL_OPEN) ||
|
||||
Here(RR_ZORAS_RIVER, []{return logic->CanUse(RG_ZELDAS_LULLABY);}) ||
|
||||
(logic->IsChild && ctx->GetTrickOption(RT_ZR_CUCCO)) ||
|
||||
(logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_ZR_HOVERS));
|
||||
}}),
|
||||
});
|
||||
|
||||
areaTable[RR_ZR_BEHIND_WATERFALL] = Region("ZR Behind Waterfall", "Zora River", {RA_ZORAS_RIVER}, DAY_NIGHT_CYCLE, {}, {}, {
|
||||
|
@ -33,6 +33,12 @@ void Settings::CreateOptionDescriptions() {
|
||||
"\n"
|
||||
"Open - King Zora has already mweeped out of the way in both "
|
||||
"time periods. Ruto's Letter is removed from the item pool.";
|
||||
mOptionDescriptions[RSK_SLEEPING_WATERFALL] = "Closed - Sleeping Waterfall obstructs the entrance to Zora's "
|
||||
"Domain. Zelda's Lullaby must be played in order to open it "
|
||||
"(but only once; then it stays open in both time periods).\n"
|
||||
"\n"
|
||||
"Open - Sleeping Waterfall is always open. "
|
||||
"Link may always enter Zora's Domain.";
|
||||
mOptionDescriptions[RSK_STARTING_AGE] =
|
||||
"Choose which age Link will start as.\n\n"
|
||||
"Starting as adult means you start with the Master Sword in your inventory.\n"
|
||||
|
@ -3947,6 +3947,7 @@ typedef enum {
|
||||
RSK_KAK_GATE,
|
||||
RSK_DOOR_OF_TIME,
|
||||
RSK_ZORAS_FOUNTAIN,
|
||||
RSK_SLEEPING_WATERFALL,
|
||||
RSK_STARTING_AGE,
|
||||
RSK_GERUDO_FORTRESS,
|
||||
RSK_RAINBOW_BRIDGE,
|
||||
@ -4184,6 +4185,12 @@ typedef enum {
|
||||
RO_ZF_OPEN,
|
||||
} RandoOptionZorasFountain;
|
||||
|
||||
//Sleeping Waterfall settings (closed, open)
|
||||
typedef enum {
|
||||
RO_WATERFALL_CLOSED,
|
||||
RO_WATERFALL_OPEN,
|
||||
} RandoOptionSleepingWaterfall;
|
||||
|
||||
//Starting Age settings (child, adult, random)
|
||||
typedef enum {
|
||||
RO_AGE_CHILD,
|
||||
|
@ -109,6 +109,7 @@ void Settings::CreateOptions() {
|
||||
mOptions[RSK_KAK_GATE] = Option::U8("Kakariko Gate", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("KakarikoGate"), mOptionDescriptions[RSK_KAK_GATE]);
|
||||
mOptions[RSK_DOOR_OF_TIME] = Option::U8("Door of Time", {"Closed", "Song only", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DoorOfTime"), mOptionDescriptions[RSK_DOOR_OF_TIME], WidgetType::Combobox);
|
||||
mOptions[RSK_ZORAS_FOUNTAIN] = Option::U8("Zora's Fountain", {"Closed", "Closed as child", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ZorasFountain"), mOptionDescriptions[RSK_ZORAS_FOUNTAIN]);
|
||||
mOptions[RSK_SLEEPING_WATERFALL] = Option::U8("Sleeping Waterfall", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), mOptionDescriptions[RSK_SLEEPING_WATERFALL]);
|
||||
mOptions[RSK_GERUDO_FORTRESS] = Option::U8("Gerudo Fortress", {"Normal", "Fast", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoFortress"), mOptionDescriptions[RSK_GERUDO_FORTRESS]);
|
||||
mOptions[RSK_RAINBOW_BRIDGE] = Option::U8("Rainbow Bridge", {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Greg"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RainbowBridge"), mOptionDescriptions[RSK_RAINBOW_BRIDGE], WidgetType::Combobox, RO_BRIDGE_VANILLA, false, IMFLAG_NONE);
|
||||
mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT] = Option::U8("Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StoneCount"), "", WidgetType::Slider, 3, true);
|
||||
@ -696,6 +697,7 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_KAK_GATE],
|
||||
&mOptions[RSK_DOOR_OF_TIME],
|
||||
&mOptions[RSK_ZORAS_FOUNTAIN],
|
||||
&mOptions[RSK_SLEEPING_WATERFALL],
|
||||
}, false, WidgetContainerType::COLUMN);
|
||||
mOptionGroups[RSG_WORLD_IMGUI] = OptionGroup::SubGroup("World Settings", {
|
||||
&mOptions[RSK_STARTING_AGE],
|
||||
@ -945,6 +947,7 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_KAK_GATE],
|
||||
&mOptions[RSK_DOOR_OF_TIME],
|
||||
&mOptions[RSK_ZORAS_FOUNTAIN],
|
||||
&mOptions[RSK_SLEEPING_WATERFALL],
|
||||
&mOptions[RSK_GERUDO_FORTRESS],
|
||||
&mOptions[RSK_RAINBOW_BRIDGE],
|
||||
&mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT],
|
||||
@ -1262,6 +1265,7 @@ void Settings::CreateOptions() {
|
||||
{ "Open Settings:Kakariko Gate", RSK_KAK_GATE },
|
||||
{ "Open Settings:Door of Time", RSK_DOOR_OF_TIME },
|
||||
{ "Open Settings:Zora's Fountain", RSK_ZORAS_FOUNTAIN },
|
||||
{ "Open Settings:Sleeping Waterfall", RSK_SLEEPING_WATERFALL },
|
||||
{ "World Settings:Starting Age", RSK_STARTING_AGE },
|
||||
{ "Open Settings:Gerudo Fortress", RSK_GERUDO_FORTRESS },
|
||||
{ "Open Settings:Rainbow Bridge", RSK_RAINBOW_BRIDGE },
|
||||
@ -2625,6 +2629,13 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) {
|
||||
mOptions[index].SetContextIndex(RO_ZF_OPEN);
|
||||
}
|
||||
break;
|
||||
case RSK_SLEEPING_WATERFALL:
|
||||
if (it.value() == "Closed") {
|
||||
mOptions[index].SetContextIndex(RO_WATERFALL_CLOSED);
|
||||
} else if (it.value() == "Open") {
|
||||
mOptions[index].SetContextIndex(RO_WATERFALL_OPEN);
|
||||
}
|
||||
break;
|
||||
case RSK_STARTING_AGE:
|
||||
if (it.value() == "Child") {
|
||||
mOptions[index].SetContextIndex(RO_AGE_CHILD);
|
||||
|
@ -35,6 +35,9 @@ extern SaveContext gSaveContext;
|
||||
extern PlayState* gPlayState;
|
||||
extern int32_t D_8011D3AC;
|
||||
|
||||
extern void func_808ADEF0(BgSpot03Taki* bgSpot03Taki, PlayState* play);
|
||||
extern void BgSpot03Taki_ApplyOpeningAlpha(BgSpot03Taki* bgSpot03Taki, s32 bufferIndex);
|
||||
|
||||
extern void func_80AF36EC(EnRu2* enRu2, PlayState* play);
|
||||
}
|
||||
|
||||
@ -96,6 +99,9 @@ void EnDntDemo_JudgeSkipToReward(EnDntDemo* enDntDemo, PlayState* play) {
|
||||
}
|
||||
}
|
||||
|
||||
void BgSpot03Taki_KeepOpen(BgSpot03Taki* bgSpot03Taki, PlayState* play) {
|
||||
}
|
||||
|
||||
static int successChimeCooldown = 0;
|
||||
void RateLimitedSuccessChime() {
|
||||
if (successChimeCooldown == 0) {
|
||||
@ -692,6 +698,8 @@ static uint32_t enFuUpdateHook = 0;
|
||||
static uint32_t enFuKillHook = 0;
|
||||
static uint32_t bgSpot02UpdateHook = 0;
|
||||
static uint32_t bgSpot02KillHook = 0;
|
||||
static uint32_t bgSpot03UpdateHook = 0;
|
||||
static uint32_t bgSpot03KillHook = 0;
|
||||
static uint32_t enPoSistersUpdateHook = 0;
|
||||
static uint32_t enPoSistersKillHook = 0;
|
||||
void TimeSaverOnActorInitHandler(void* actorRef) {
|
||||
@ -747,6 +755,10 @@ void TimeSaverOnActorInitHandler(void* actorRef) {
|
||||
});
|
||||
}
|
||||
|
||||
if (actor->id == ACTOR_EN_OWL && gPlayState->sceneNum == SCENE_ZORAS_RIVER && CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 0) == 2) {
|
||||
Actor_Kill(actor);
|
||||
}
|
||||
|
||||
if (actor->id == ACTOR_BG_SPOT02_OBJECTS && actor->params == 2) {
|
||||
bgSpot02UpdateHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorUpdate>([](void* innerActorRef) mutable {
|
||||
Actor* innerActor = static_cast<Actor*>(innerActorRef);
|
||||
@ -769,6 +781,61 @@ void TimeSaverOnActorInitHandler(void* actorRef) {
|
||||
});
|
||||
}
|
||||
|
||||
if (actor->id == ACTOR_BG_SPOT03_TAKI) {
|
||||
bgSpot03UpdateHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorUpdate>([](void* innerActorRef) mutable {
|
||||
Actor* innerActor = static_cast<Actor*>(innerActorRef);
|
||||
|
||||
if (innerActor->id != ACTOR_BG_SPOT03_TAKI) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool shouldKeepOpen;
|
||||
switch (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 0)) {
|
||||
case 1:
|
||||
shouldKeepOpen = Flags_GetEventChkInf(EVENTCHKINF_OPENED_ZORAS_DOMAIN);
|
||||
break;
|
||||
case 2:
|
||||
if (IS_RANDO && RAND_GET_OPTION(RSK_SLEEPING_WATERFALL) == RO_WATERFALL_OPEN) {
|
||||
shouldKeepOpen = true;
|
||||
} else {
|
||||
shouldKeepOpen = CHECK_QUEST_ITEM(QUEST_SONG_LULLABY) &&
|
||||
(INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME ||
|
||||
INV_CONTENT(ITEM_OCARINA_FAIRY) == ITEM_OCARINA_FAIRY);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
shouldKeepOpen = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!shouldKeepOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
BgSpot03Taki* bgSpot03 = static_cast<BgSpot03Taki*>(innerActorRef);
|
||||
if (bgSpot03->actionFunc == func_808ADEF0) {
|
||||
bgSpot03->actionFunc = BgSpot03Taki_KeepOpen;
|
||||
bgSpot03->state = WATERFALL_OPENED;
|
||||
bgSpot03->openingAlpha = 0.0f;
|
||||
Flags_SetSwitch(gPlayState, bgSpot03->switchFlag);
|
||||
func_8003EBF8(gPlayState, &gPlayState->colCtx.dyna, bgSpot03->dyna.bgId);
|
||||
BgSpot03Taki_ApplyOpeningAlpha(bgSpot03, 0);
|
||||
BgSpot03Taki_ApplyOpeningAlpha(bgSpot03, 1);
|
||||
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(bgSpot03UpdateHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(bgSpot03KillHook);
|
||||
bgSpot03UpdateHook = 0;
|
||||
bgSpot03KillHook = 0;
|
||||
}
|
||||
});
|
||||
bgSpot03KillHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) mutable {
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(bgSpot03UpdateHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(bgSpot03KillHook);
|
||||
bgSpot03UpdateHook = 0;
|
||||
bgSpot03KillHook = 0;
|
||||
});
|
||||
}
|
||||
|
||||
if (actor->id == ACTOR_EN_DNT_DEMO && (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO))) {
|
||||
EnDntDemo* enDntDemo = static_cast<EnDntDemo*>(actorRef);
|
||||
enDntDemo->actionFunc = EnDntDemo_JudgeSkipToReward;
|
||||
|
@ -83,6 +83,7 @@ static const char* imguiScaleOptions[4] = { "Small", "Normal", "Large", "X-Large
|
||||
static const char* chestStyleMatchesContentsOptions[4] = { "Disabled", "Both", "Texture Only", "Size Only" };
|
||||
static const char* skipGetItemAnimationOptions[3] = { "Disabled", "Junk Items", "All Items" };
|
||||
static const char* skipForcedDialogOptions[4] = { "None", "Navi Only", "NPCs Only", "All" };
|
||||
static const char* sleepingWaterfallOptions[3] = { "Always", "Once", "Never" };
|
||||
static const char* bunnyHoodOptions[3] = { "Disabled", "Faster Run & Longer Jump", "Faster Run" };
|
||||
static const char* mirroredWorldModes[9] = {
|
||||
"Disabled", "Always", "Random", "Random (Seeded)", "Dungeons",
|
||||
@ -123,7 +124,7 @@ static const char* imguiScaleOptions[4] = { "Small", "Normal", "Large", "X-Large
|
||||
CVAR_ENHANCEMENT("InjectItemCounts.HeartPiece"),
|
||||
CVAR_ENHANCEMENT("InjectItemCounts.HeartContainer"),
|
||||
};
|
||||
static const char* itemCountMessageOptions[sizeof(itemCountMessageCVars) / sizeof(const char*)] = {
|
||||
static const char* itemCountMessageOptions[ARRAY_COUNT(itemCountMessageCVars)] = {
|
||||
"Gold Skulltula Tokens",
|
||||
"Pieces of Heart",
|
||||
"Heart Containers",
|
||||
@ -796,7 +797,23 @@ void DrawEnhancementsMenu() {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Skip Scarecrow Song", CVAR_ENHANCEMENT("InstantScarecrow"), true, false,
|
||||
forceSkipScarecrow, forceSkipScarecrowText, UIWidgets::CheckboxGraphics::Checkmark);
|
||||
UIWidgets::Tooltip("Pierre appears when Ocarina is pulled out. Requires learning scarecrow song.");
|
||||
|
||||
bool forceSleepingWaterfallEnhancement =
|
||||
IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SLEEPING_WATERFALL) == RO_WATERFALL_OPEN;
|
||||
uint8_t forceSleepingWaterfallValue = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SLEEPING_WATERFALL) + 1;
|
||||
static const char* forceSleepingWaterfallText =
|
||||
"This setting is forcefully enabled because a randomizer savefile with \"Sleeping Waterfall: Open\" is loaded.";
|
||||
UIWidgets::PaddedText("Play Zelda's Lullaby to open Sleeping Waterfall", true, false);
|
||||
UIWidgets::EnhancementCombobox(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"),
|
||||
sleepingWaterfallOptions, 0, forceSleepingWaterfallEnhancement,
|
||||
forceSleepingWaterfallText, forceSleepingWaterfallValue);
|
||||
UIWidgets::Tooltip(
|
||||
"Always: Link must always play Zelda's Lullaby to open "
|
||||
"the waterfall entrance to Zora's Domain.\n"
|
||||
"Once: Link only needs to play Zelda's Lullaby once to "
|
||||
"open the waterfall; after that, it stays open permanently.\n"
|
||||
"Never: Link never needs to play Zelda's Lullaby to open the "
|
||||
"waterfall; he only needs to have learned it and have an ocarina."
|
||||
);
|
||||
|
||||
ImGui::EndTable();
|
||||
ImGui::EndMenu();
|
||||
@ -867,7 +884,7 @@ void DrawEnhancementsMenu() {
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
if (ImGui::BeginMenu("Item Count Messages")) {
|
||||
int numOptions = sizeof(itemCountMessageCVars) / sizeof(const char*);
|
||||
int numOptions = ARRAY_COUNT(itemCountMessageCVars);
|
||||
bool allItemCountsChecked = std::all_of(itemCountMessageCVars, itemCountMessageCVars + numOptions,
|
||||
[](const char* cvar) { return CVarGetInteger(cvar, 0); });
|
||||
bool someItemCountsChecked = std::any_of(itemCountMessageCVars, itemCountMessageCVars + numOptions,
|
||||
|
Loading…
Reference in New Issue
Block a user