From c7e4e8cceec33fb14c3dcc69c26be643db68d2d0 Mon Sep 17 00:00:00 2001 From: Jordan Longstaff Date: Thu, 15 Jan 2026 16:02:27 -0500 Subject: [PATCH] Owl Travel cutscenes skipped as One Point cutscenes (#6141) --- .../TimeSavers/SkipCutscene/SkipOwlTravel.cpp | 54 +++++++++++++++++++ .../vanilla-behavior/GIVanillaBehavior.h | 8 +++ soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c | 51 ++++++------------ 3 files changed, 78 insertions(+), 35 deletions(-) create mode 100644 soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipOwlTravel.cpp diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipOwlTravel.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipOwlTravel.cpp new file mode 100644 index 000000000..e11890eb5 --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipOwlTravel.cpp @@ -0,0 +1,54 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/randomizer/randomizer_entrance.h" +#include "soh/ShipInit.hpp" +#include + +extern "C" { +#include "z64save.h" +extern PlayState* gPlayState; +extern SaveContext gSaveContext; + +u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); +} + +#define CVAR_NAME CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint") +#define CVAR_VALUE CVarGetInteger(CVAR_NAME, 0) + +static s16 GetEntranceIndex(s32 owlType) { + s16 entranceIndex; + + switch (owlType) { + case 7: + entranceIndex = ENTR_HYRULE_FIELD_OWL_DROP; + break; + case 8: + case 9: + entranceIndex = ENTR_KAKARIKO_VILLAGE_OWL_DROP; + break; + default: + assert(0); + return ENTR_MAX; + } + + if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_OWL_DROPS)) { + entranceIndex = Entrance_OverrideNextIndex(entranceIndex); + } + + return entranceIndex; +} + +static void SkipOwlTravel(s32 owlType) { + gPlayState->nextEntranceIndex = GetEntranceIndex(owlType); + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_FADE_BLACK; +} + +static void RegisterSkipOwlTravel() { + COND_VB_SHOULD(VB_PLAY_OWL_TRAVEL_CS, CVAR_VALUE || IS_RANDO, { + s32 owlType = va_arg(args, s32); + SkipOwlTravel(owlType); + *should = false; + }); +} + +static RegisterShipInitFunc initFunc(RegisterSkipOwlTravel, { CVAR_NAME, "IS_RANDO" }); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 03b256172..311779e2c 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -1703,6 +1703,14 @@ typedef enum { // - `*int16_t` (cutscene id) VB_PLAY_ONEPOINT_CS, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `int32_t` (owl type) + VB_PLAY_OWL_TRAVEL_CS, + // #### `result` // ```c // true diff --git a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c index 0d848e01f..de842a9ff 100644 --- a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c +++ b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c @@ -10,7 +10,6 @@ #include "scenes/overworld/spot16/spot16_scene.h" #include "vt.h" #include -#include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -941,42 +940,24 @@ void func_80ACC00C(EnOwl* this, PlayState* play) { osSyncPrintf(VT_FGCOL(CYAN)); osSyncPrintf("%dのフクロウ\n", owlType); // "%d owl" osSyncPrintf(VT_RST); - switch (owlType) { - case 7: - osSyncPrintf(VT_FGCOL(CYAN)); - osSyncPrintf("SPOT 06 の デモがはしった\n"); // "Demo of SPOT 06 has been completed" - osSyncPrintf(VT_RST); - if (IS_RANDO) { - if (Randomizer_GetSettingValue(RSK_SHUFFLE_OWL_DROPS)) { - play->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_HYRULE_FIELD_OWL_DROP); - } else { - play->nextEntranceIndex = ENTR_HYRULE_FIELD_OWL_DROP; - } - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_BLACK; + if (GameInteractor_Should(VB_PLAY_OWL_TRAVEL_CS, true, owlType)) { + switch (owlType) { + case 7: + osSyncPrintf(VT_FGCOL(CYAN)); + osSyncPrintf("SPOT 06 の デモがはしった\n"); // "Demo of SPOT 06 has been completed" + osSyncPrintf(VT_RST); + play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gLakeHyliaOwlCs); + this->actor.draw = NULL; break; - } - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gLakeHyliaOwlCs); - this->actor.draw = NULL; - break; - case 8: - case 9: - if (IS_RANDO) { - if (Randomizer_GetSettingValue(RSK_SHUFFLE_OWL_DROPS)) { - play->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_KAKARIKO_VILLAGE_OWL_DROP); - } else { - play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_OWL_DROP; - } - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_BLACK; + case 8: + case 9: + play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gDMTOwlCs); + this->actor.draw = NULL; break; - } - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gDMTOwlCs); - this->actor.draw = NULL; - break; - default: - assert(0); - break; + default: + assert(0); + break; + } } Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR);