mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 13:23:45 -07:00
New options that affect feeding Jabu-Jabu (#5397)
* New options that affect feeding Jabu-Jabu
* Add hints for what Jabu-Jabu wants
* Roll back "key" settings to just closed/open, finish rando logic
* Revert "Add hints for what Jabu-Jabu wants"
This reverts commit 2a1974a669
.
* Fix vanilla enhancement disabler
This commit is contained in:
parent
eefe7729ab
commit
b600836e4f
7 changed files with 64 additions and 1 deletions
|
@ -82,6 +82,7 @@ const std::vector<PresetEntry> enhancedPresetEntries = {
|
||||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableCritWiggle"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterOwl"), 1),
|
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableCritWiggle"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterOwl"), 1),
|
||||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1),
|
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1),
|
||||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 1),
|
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 1),
|
||||||
|
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipJabuJabuFish"), 1),
|
||||||
|
|
||||||
// Skips & Speed-ups
|
// Skips & Speed-ups
|
||||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipText"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TextSpeed"), 5),
|
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipText"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TextSpeed"), 5),
|
||||||
|
@ -176,6 +177,7 @@ const std::vector<PresetEntry> randomizerPresetEntries = {
|
||||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 1),
|
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 1),
|
||||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1),
|
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1),
|
||||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 1),
|
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 1),
|
||||||
|
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipJabuJabuFish"), 1),
|
||||||
|
|
||||||
// Skips & Speed-ups
|
// Skips & Speed-ups
|
||||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), 1),
|
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), 1),
|
||||||
|
|
|
@ -31,7 +31,7 @@ void RegionTable_Init_ZorasFountain() {
|
||||||
//child can break the brown rock without lifting the silver rock and it stays gone for adult, but it's not intuitive and there's no reasonable case where it matters.
|
//child can break the brown rock without lifting the silver rock and it stays gone for adult, but it's not intuitive and there's no reasonable case where it matters.
|
||||||
Entrance(RR_ZF_HIDDEN_CAVE, []{return logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash();}),
|
Entrance(RR_ZF_HIDDEN_CAVE, []{return logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash();}),
|
||||||
Entrance(RR_ZF_ROCK, []{return logic->IsAdult && logic->CanUse(RG_SCARECROW);}),
|
Entrance(RR_ZF_ROCK, []{return logic->IsAdult && logic->CanUse(RG_SCARECROW);}),
|
||||||
Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, []{return (logic->IsChild && logic->CanUse(RG_BOTTLE_WITH_FISH));}),
|
Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, []{return logic->IsChild && (ctx->GetOption(RSK_JABU_OPEN).Is(RO_JABU_OPEN) || logic->CanUse(RG_BOTTLE_WITH_FISH));}),
|
||||||
Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, []{return logic->HasExplosives() || (ctx->GetTrickOption(RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SILVER_GAUNTLETS));}),
|
Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, []{return logic->HasExplosives() || (ctx->GetTrickOption(RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SILVER_GAUNTLETS));}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@ void Settings::CreateOptionDescriptions() {
|
||||||
"\n"
|
"\n"
|
||||||
"Open - Sleeping Waterfall is always open. "
|
"Open - Sleeping Waterfall is always open. "
|
||||||
"Link may always enter Zora's Domain.";
|
"Link may always enter Zora's Domain.";
|
||||||
|
mOptionDescriptions[RSK_JABU_OPEN] = "Closed - A fish is required to open Jabu-Jabu's mouth.\n\n"
|
||||||
|
"Open - Jabu-Jabu's mouth opens without the need for a fish.";
|
||||||
mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS] =
|
mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS] =
|
||||||
"Add locks to all wooden overworld doors, requiring specific small keys to open them";
|
"Add locks to all wooden overworld doors, requiring specific small keys to open them";
|
||||||
mOptionDescriptions[RSK_STARTING_AGE] =
|
mOptionDescriptions[RSK_STARTING_AGE] =
|
||||||
|
|
|
@ -5688,6 +5688,7 @@ typedef enum {
|
||||||
RSK_DOOR_OF_TIME,
|
RSK_DOOR_OF_TIME,
|
||||||
RSK_ZORAS_FOUNTAIN,
|
RSK_ZORAS_FOUNTAIN,
|
||||||
RSK_SLEEPING_WATERFALL,
|
RSK_SLEEPING_WATERFALL,
|
||||||
|
RSK_JABU_OPEN,
|
||||||
RSK_STARTING_AGE,
|
RSK_STARTING_AGE,
|
||||||
RSK_SELECTED_STARTING_AGE,
|
RSK_SELECTED_STARTING_AGE,
|
||||||
RSK_GERUDO_FORTRESS,
|
RSK_GERUDO_FORTRESS,
|
||||||
|
@ -5938,6 +5939,12 @@ typedef enum {
|
||||||
RO_WATERFALL_OPEN,
|
RO_WATERFALL_OPEN,
|
||||||
} RandoOptionSleepingWaterfall;
|
} RandoOptionSleepingWaterfall;
|
||||||
|
|
||||||
|
// Jabu-Jabu settings (closed, open)
|
||||||
|
typedef enum {
|
||||||
|
RO_JABU_CLOSED,
|
||||||
|
RO_JABU_OPEN,
|
||||||
|
} RandoOptionJabu;
|
||||||
|
|
||||||
// Starting Age settings (child, adult, random)
|
// Starting Age settings (child, adult, random)
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RO_AGE_CHILD,
|
RO_AGE_CHILD,
|
||||||
|
|
|
@ -120,6 +120,7 @@ void Settings::CreateOptions() {
|
||||||
OPT_U8(RSK_DOOR_OF_TIME, "Door of Time", {"Closed", "Song only", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DoorOfTime"), mOptionDescriptions[RSK_DOOR_OF_TIME], WidgetType::Combobox);
|
OPT_U8(RSK_DOOR_OF_TIME, "Door of Time", {"Closed", "Song only", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DoorOfTime"), mOptionDescriptions[RSK_DOOR_OF_TIME], WidgetType::Combobox);
|
||||||
OPT_U8(RSK_ZORAS_FOUNTAIN, "Zora's Fountain", {"Closed", "Closed as child", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ZorasFountain"), mOptionDescriptions[RSK_ZORAS_FOUNTAIN]);
|
OPT_U8(RSK_ZORAS_FOUNTAIN, "Zora's Fountain", {"Closed", "Closed as child", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ZorasFountain"), mOptionDescriptions[RSK_ZORAS_FOUNTAIN]);
|
||||||
OPT_U8(RSK_SLEEPING_WATERFALL, "Sleeping Waterfall", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), mOptionDescriptions[RSK_SLEEPING_WATERFALL]);
|
OPT_U8(RSK_SLEEPING_WATERFALL, "Sleeping Waterfall", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), mOptionDescriptions[RSK_SLEEPING_WATERFALL]);
|
||||||
|
OPT_U8(RSK_JABU_OPEN, "Jabu-Jabu", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("JabuJabu"), mOptionDescriptions[RSK_JABU_OPEN]);
|
||||||
OPT_BOOL(RSK_LOCK_OVERWORLD_DOORS, "Lock Overworld Doors", CVAR_RANDOMIZER_SETTING("LockOverworldDoors"), mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS]);
|
OPT_BOOL(RSK_LOCK_OVERWORLD_DOORS, "Lock Overworld Doors", CVAR_RANDOMIZER_SETTING("LockOverworldDoors"), mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS]);
|
||||||
OPT_U8(RSK_GERUDO_FORTRESS, "Fortress Carpenters", {"Normal", "Fast", "Free"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FortressCarpenters"), mOptionDescriptions[RSK_GERUDO_FORTRESS]);
|
OPT_U8(RSK_GERUDO_FORTRESS, "Fortress Carpenters", {"Normal", "Fast", "Free"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FortressCarpenters"), mOptionDescriptions[RSK_GERUDO_FORTRESS]);
|
||||||
OPT_U8(RSK_RAINBOW_BRIDGE, "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);
|
OPT_U8(RSK_RAINBOW_BRIDGE, "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);
|
||||||
|
@ -1151,6 +1152,7 @@ void Settings::CreateOptions() {
|
||||||
&mOptions[RSK_DOOR_OF_TIME],
|
&mOptions[RSK_DOOR_OF_TIME],
|
||||||
&mOptions[RSK_ZORAS_FOUNTAIN],
|
&mOptions[RSK_ZORAS_FOUNTAIN],
|
||||||
&mOptions[RSK_SLEEPING_WATERFALL],
|
&mOptions[RSK_SLEEPING_WATERFALL],
|
||||||
|
&mOptions[RSK_JABU_OPEN],
|
||||||
&mOptions[RSK_LOCK_OVERWORLD_DOORS],
|
&mOptions[RSK_LOCK_OVERWORLD_DOORS],
|
||||||
},
|
},
|
||||||
WidgetContainerType::COLUMN);
|
WidgetContainerType::COLUMN);
|
||||||
|
@ -1405,6 +1407,7 @@ void Settings::CreateOptions() {
|
||||||
&mOptions[RSK_DOOR_OF_TIME],
|
&mOptions[RSK_DOOR_OF_TIME],
|
||||||
&mOptions[RSK_ZORAS_FOUNTAIN],
|
&mOptions[RSK_ZORAS_FOUNTAIN],
|
||||||
&mOptions[RSK_SLEEPING_WATERFALL],
|
&mOptions[RSK_SLEEPING_WATERFALL],
|
||||||
|
&mOptions[RSK_JABU_OPEN],
|
||||||
&mOptions[RSK_LOCK_OVERWORLD_DOORS],
|
&mOptions[RSK_LOCK_OVERWORLD_DOORS],
|
||||||
&mOptions[RSK_GERUDO_FORTRESS],
|
&mOptions[RSK_GERUDO_FORTRESS],
|
||||||
&mOptions[RSK_RAINBOW_BRIDGE],
|
&mOptions[RSK_RAINBOW_BRIDGE],
|
||||||
|
|
|
@ -25,6 +25,7 @@ extern "C" {
|
||||||
#include "src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.h"
|
#include "src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.h"
|
||||||
#include "src/overlays/actors/ovl_En_Tk/z_en_tk.h"
|
#include "src/overlays/actors/ovl_En_Tk/z_en_tk.h"
|
||||||
#include "src/overlays/actors/ovl_En_Fu/z_en_fu.h"
|
#include "src/overlays/actors/ovl_En_Fu/z_en_fu.h"
|
||||||
|
#include "src/overlays/actors/ovl_En_Jj/z_en_jj.h"
|
||||||
#include "src/overlays/actors/ovl_En_Daiku/z_en_daiku.h"
|
#include "src/overlays/actors/ovl_En_Daiku/z_en_daiku.h"
|
||||||
#include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h"
|
#include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h"
|
||||||
#include "src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h"
|
#include "src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h"
|
||||||
|
@ -47,6 +48,10 @@ extern void EnGo2_CurledUp(EnGo2* enGo2, PlayState* play);
|
||||||
extern void EnRu2_SetEncounterSwitchFlag(EnRu2* enRu2, PlayState* play);
|
extern void EnRu2_SetEncounterSwitchFlag(EnRu2* enRu2, PlayState* play);
|
||||||
|
|
||||||
extern void EnDaiku_EscapeSuccess(EnDaiku* enDaiku, PlayState* play);
|
extern void EnDaiku_EscapeSuccess(EnDaiku* enDaiku, PlayState* play);
|
||||||
|
|
||||||
|
extern void EnJj_WaitToOpenMouth(EnJj* enJj, PlayState* play);
|
||||||
|
extern void EnJj_WaitForFish(EnJj* enJj, PlayState* play);
|
||||||
|
extern void EnJj_SetupAction(EnJj* enJj, EnJjActionFunc actionFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
||||||
|
@ -869,6 +874,8 @@ static uint32_t enMa1UpdateHook = 0;
|
||||||
static uint32_t enMa1KillHook = 0;
|
static uint32_t enMa1KillHook = 0;
|
||||||
static uint32_t enFuUpdateHook = 0;
|
static uint32_t enFuUpdateHook = 0;
|
||||||
static uint32_t enFuKillHook = 0;
|
static uint32_t enFuKillHook = 0;
|
||||||
|
static uint32_t enJjUpdateHook = 0;
|
||||||
|
static uint32_t enJjKillHook = 0;
|
||||||
static uint32_t bgSpot02UpdateHook = 0;
|
static uint32_t bgSpot02UpdateHook = 0;
|
||||||
static uint32_t bgSpot02KillHook = 0;
|
static uint32_t bgSpot02KillHook = 0;
|
||||||
static uint32_t bgSpot03UpdateHook = 0;
|
static uint32_t bgSpot03UpdateHook = 0;
|
||||||
|
@ -934,6 +941,39 @@ void TimeSaverOnActorInitHandler(void* actorRef) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actor->id == ACTOR_EN_JJ && !IS_RANDO) {
|
||||||
|
enJjUpdateHook =
|
||||||
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorUpdate>([](void* innerActorRef) mutable {
|
||||||
|
Actor* innerActor = static_cast<Actor*>(innerActorRef);
|
||||||
|
|
||||||
|
if (innerActor->id != ACTOR_EN_JJ || Flags_GetEventChkInf(EVENTCHKINF_OFFERED_FISH_TO_JABU_JABU)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shouldOpen = IS_RANDO ? RAND_GET_OPTION(RSK_JABU_OPEN)
|
||||||
|
: CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipJabuJabuFish"), 0);
|
||||||
|
if (!shouldOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnJj* enJj = static_cast<EnJj*>(innerActorRef);
|
||||||
|
if (enJj->actionFunc == EnJj_WaitForFish) {
|
||||||
|
EnJj_SetupAction(enJj, EnJj_WaitToOpenMouth);
|
||||||
|
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(enJjUpdateHook);
|
||||||
|
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(enJjKillHook);
|
||||||
|
enJjUpdateHook = 0;
|
||||||
|
enJjKillHook = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
enJjKillHook =
|
||||||
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) mutable {
|
||||||
|
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(enJjUpdateHook);
|
||||||
|
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(enJjKillHook);
|
||||||
|
enJjUpdateHook = 0;
|
||||||
|
enJjKillHook = 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (actor->id == ACTOR_EN_OWL && gPlayState->sceneNum == SCENE_ZORAS_RIVER &&
|
if (actor->id == ACTOR_EN_OWL && gPlayState->sceneNum == SCENE_ZORAS_RIVER &&
|
||||||
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 0) == 2) {
|
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 0) == 2) {
|
||||||
Actor_Kill(actor);
|
Actor_Kill(actor);
|
||||||
|
|
|
@ -262,6 +262,15 @@ void SohMenu::AddMenuEnhancements() {
|
||||||
"open permanently.\n"
|
"open permanently.\n"
|
||||||
"Never: Link never needs to play Zelda's Lullaby to open the waterfall. He only needs to have "
|
"Never: Link never needs to play Zelda's Lullaby to open the waterfall. He only needs to have "
|
||||||
"learned it and have an Ocarina."));
|
"learned it and have an Ocarina."));
|
||||||
|
AddWidget(path, "Skip Feeding Jabu-Jabu", WIDGET_CVAR_CHECKBOX)
|
||||||
|
.CVar(CVAR_ENHANCEMENT("TimeSavers.SkipJabuJabuFish"))
|
||||||
|
.PreFunc([](WidgetInfo& info) {
|
||||||
|
info.options->disabled =
|
||||||
|
IS_RANDO && OTRGlobals::Instance->gRandoContext->GetOption(RSK_JABU_OPEN).Is(RO_JABU_OPEN);
|
||||||
|
info.options->disabledTooltip =
|
||||||
|
"This setting is disabled because a randomizer savefile with \"Jabu-Jaby: Open\" is loaded.";
|
||||||
|
})
|
||||||
|
.Options(CheckboxOptions().Tooltip("Allow Link to enter Jabu-Jabu without feeding him a fish."));
|
||||||
|
|
||||||
// Skips & Speed-ups
|
// Skips & Speed-ups
|
||||||
path.sidebarName = "Skips & Speed-ups";
|
path.sidebarName = "Skips & Speed-ups";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue