Jabu fish cutscene skip: immediately transition (#7159)

This avoids awkward pause, also prevents recapturing fish

Also cleanup RSK_JABU_OPEN
This commit is contained in:
Philip Dubé
2026-09-08 13:38:20 +00:00
committed by GitHub
parent 371ef6f841
commit b4c41c9bf4
4 changed files with 43 additions and 54 deletions
@@ -3,6 +3,7 @@
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/Enhancements/enhancementTypes.h"
#include "soh/Enhancements/randomizer/SeedContext.h"
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
extern "C" {
#include "src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.h"
@@ -128,6 +129,20 @@ bool ForcedDialogIsDisabled(ForcedDialogMode type) {
type) != 0;
}
static void SkipJabuFeedingCutscene() {
Player_UpdateBottleHeld(gPlayState, GET_PLAYER(gPlayState), ITEM_BOTTLE, PLAYER_IA_BOTTLE);
Flags_SetEventChkInf(EVENTCHKINF_OFFERED_FISH_TO_JABU_JABU);
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) {
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_JABU_JABU_ENTRANCE);
} else {
gPlayState->nextEntranceIndex = ENTR_JABU_JABU_ENTRANCE;
}
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
gPlayState->transitionType = TRANS_TYPE_FADE_BLACK;
}
void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) {
va_list args;
va_copy(args, originalArgs);
@@ -581,10 +596,15 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
}
break;
}
case VB_JABU_JABU_EAT_FISH:
if (*should && CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) {
*should = false;
SkipJabuFeedingCutscene();
}
break;
case VB_PLAY_BEAN_PLANTING_CS:
case VB_PLAY_EYEDROP_CREATION_ANIM:
case VB_PLAY_EYEDROPS_CS:
case VB_PLAY_DROP_FISH_FOR_JABU_CS:
case VB_PLAY_DARUNIAS_JOY_CS:
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) {
*should = false;
@@ -940,8 +960,6 @@ static uint32_t enMa1UpdateHook = 0;
static uint32_t enMa1KillHook = 0;
static uint32_t enFuUpdateHook = 0;
static uint32_t enFuKillHook = 0;
static uint32_t enJjUpdateHook = 0;
static uint32_t enJjKillHook = 0;
static uint32_t bgSpot02UpdateHook = 0;
static uint32_t bgSpot02KillHook = 0;
static uint32_t bgSpot03UpdateHook = 0;
@@ -1010,36 +1028,12 @@ void TimeSaverOnActorInitHandler(void* actorRef) {
}
if (actor->id == ACTOR_EN_JJ) {
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).Get()
: 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;
});
EnJj* enJj = static_cast<EnJj*>(actorRef);
bool shouldOpen = IS_RANDO ? RAND_GET_OPTION(RSK_JABU_OPEN).Get()
: CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipJabuJabuFish"), 0);
if (shouldOpen && enJj->actionFunc == EnJj_WaitForFish) {
EnJj_SetupAction(enJj, EnJj_WaitToOpenMouth);
}
}
if (actor->id == ACTOR_EN_OWL && gPlayState->sceneNum == SCENE_ZORAS_RIVER &&
@@ -1584,6 +1584,14 @@ typedef enum {
// - `*EnItem00`
VB_ITEM00_TIMER_TICK,
// #### `result`
// ```c
// Math_Vec3f_DistXZ(&feedingSpot, &player->actor.world.pos) < 300.0f && play->isPlayerDroppingFish(play)
// ```
// #### `args`
// - `*EnJj`
VB_JABU_JABU_EAT_FISH,
// #### `result`
// ```c
// true
@@ -2036,14 +2044,6 @@ typedef enum {
// - `*EnOkarinaTag`
VB_PLAY_DRAIN_WELL_CS,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - None
VB_PLAY_DROP_FISH_FOR_JABU_CS,
// #### `result`
// ```c
// true
+3 -12
View File
@@ -497,18 +497,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
Player* player = GET_PLAYER(play);
s32 temp = 0;
bool shouldSkipCommand = false;
if (cmd->base == 8 && !GameInteractor_Should(VB_PLAY_PULL_MASTER_SWORD_CS, true)) {
shouldSkipCommand = true;
}
if (cmd->base == 24 && !GameInteractor_Should(VB_PLAY_DROP_FISH_FOR_JABU_CS, true)) {
shouldSkipCommand = true;
}
bool debugCsSkip = (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) &&
(gSaveContext.fileNum != 0xFEDC) && CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0));
bool shouldSkipCommand = cmd->base == 8 && !GameInteractor_Should(VB_PLAY_PULL_MASTER_SWORD_CS, true);
bool debugCsSkip = CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) &&
(gSaveContext.fileNum != 0xFEDC) && CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0);
if ((gSaveContext.gameMode != GAMEMODE_NORMAL) && (gSaveContext.gameMode != GAMEMODE_END_CREDITS) &&
(play->sceneNum != SCENE_HYRULE_FIELD) && (csCtx->frames > 20) &&
+5 -1
View File
@@ -7,6 +7,7 @@
#include "z_en_jj.h"
#include "objects/object_jj/object_jj.h"
#include "overlays/actors/ovl_Eff_Dust/z_eff_dust.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
@@ -197,7 +198,10 @@ void EnJj_WaitForFish(EnJj* this, PlayState* play) {
static Vec3f feedingSpot = { -1589.0f, 53.0f, -43.0f };
Player* player = GET_PLAYER(play);
if ((Math_Vec3f_DistXZ(&feedingSpot, &player->actor.world.pos) < 300.0f) && play->isPlayerDroppingFish(play)) {
if (GameInteractor_Should(VB_JABU_JABU_EAT_FISH,
(Math_Vec3f_DistXZ(&feedingSpot, &player->actor.world.pos) < 300.0f) &&
play->isPlayerDroppingFish(play),
this)) {
this->cutsceneCountdownTimer = 100;
EnJj_SetupAction(this, EnJj_BeginCutscene);
}