From b07c64ecf9e8f6e24173a75fe7e8ae04ee633248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Sat, 28 Feb 2026 23:51:13 +0000 Subject: [PATCH] Fix song of storms cutscene (#6310) --- .../vanilla-behavior/GIVanillaBehavior.h | 100 ++---------------- .../Enhancements/timesaver_hook_handlers.cpp | 18 +--- soh/src/code/z_demo.c | 4 +- soh/src/code/z_message_PAL.c | 18 +--- .../overlays/actors/ovl_Demo_Im/z_demo_im.c | 2 +- soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c | 9 +- soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c | 2 +- soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c | 8 +- 8 files changed, 31 insertions(+), 130 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 091eb9de6..06e3ab6fe 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -720,22 +720,6 @@ typedef enum { // - `*EnJs` VB_GIVE_BOMBCHUS_FROM_CARPET_SALESMAN, - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_GIVE_ITEM_BOLERO_OF_FIRE, - - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_GIVE_ITEM_EPONAS_SONG, - // #### `result` // ```c // true @@ -1003,22 +987,6 @@ typedef enum { // - None VB_GIVE_ITEM_MASTER_SWORD, - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_GIVE_ITEM_MINUET_OF_FOREST, - - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, - // #### `result` // ```c // true @@ -1027,38 +995,6 @@ typedef enum { // - None VB_GIVE_ITEM_OCARINA_OF_TIME, - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_GIVE_ITEM_PRELUDE_OF_LIGHT, - - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, - - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_GIVE_ITEM_SARIAS_SONG, - - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_GIVE_ITEM_SERENADE_OF_WATER, - // #### `result` // ```c // true @@ -1080,16 +1016,8 @@ typedef enum { // true // ``` // #### `args` - // - None - VB_GIVE_ITEM_SONG_OF_STORMS, - - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_GIVE_ITEM_SONG_OF_TIME, + // - `songItemId` + VB_GIVE_ITEM_SONG, // #### `result` // ```c @@ -1107,14 +1035,6 @@ typedef enum { // - None VB_GIVE_ITEM_STRENGTH_1, - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_GIVE_ITEM_SUNS_SONG, - // #### `result` // ```c // true @@ -1139,14 +1059,6 @@ typedef enum { // - None VB_GIVE_ITEM_ZELDAS_LETTER, - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_GIVE_ITEM_ZELDAS_LULLABY, - // #### `result` // ```c // false @@ -1861,6 +1773,14 @@ typedef enum { // - `*EnBox` VB_PLAY_SLOW_CHEST_CS, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnFu` + VB_PLAY_SONG_OF_STORMS_CS, + // #### `result` // ```c // !CHECK_QUEST_ITEM(QUEST_SONG_SUN) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 53fce0b75..6b3353778 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -153,7 +153,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); // Normally happens in the cutscene gSaveContext.dayTime = gSaveContext.skyboxTime = 0xAC60; - if (GameInteractor_Should(VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true)) { + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, ITEM_SONG_REQUIEM)) { Item_Give(gPlayState, ITEM_SONG_REQUIEM); } *should = false; @@ -169,7 +169,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); // Normally happens in the cutscene Flags_SetEventChkInf(EVENTCHKINF_LEARNED_NOCTURNE_OF_SHADOW); - if (GameInteractor_Should(VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true)) { + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, ITEM_SONG_NOCTURNE)) { Item_Give(gPlayState, ITEM_SONG_NOCTURNE); } *should = false; @@ -704,21 +704,11 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } break; } - case VB_GIVE_ITEM_MINUET_OF_FOREST: - case VB_GIVE_ITEM_BOLERO_OF_FIRE: - case VB_GIVE_ITEM_SERENADE_OF_WATER: - case VB_GIVE_ITEM_REQUIEM_OF_SPIRIT: - case VB_GIVE_ITEM_NOCTURNE_OF_SHADOW: - case VB_GIVE_ITEM_PRELUDE_OF_LIGHT: - case VB_GIVE_ITEM_ZELDAS_LULLABY: - case VB_GIVE_ITEM_EPONAS_SONG: - case VB_GIVE_ITEM_SARIAS_SONG: - case VB_GIVE_ITEM_SUNS_SONG: - case VB_GIVE_ITEM_SONG_OF_TIME: - case VB_GIVE_ITEM_SONG_OF_STORMS: + case VB_GIVE_ITEM_SONG: case VB_PLAY_MINUET_OF_FOREST_CS: case VB_PLAY_BOLERO_OF_FIRE_CS: case VB_PLAY_SERENADE_OF_WATER_CS: + case VB_PLAY_SONG_OF_STORMS_CS: case VB_PLAY_PRELUDE_OF_LIGHT_CS: if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), IS_RANDO) || IS_RANDO) { *should = false; diff --git a/soh/src/code/z_demo.c b/soh/src/code/z_demo.c index b6ccedc7c..fda3cd061 100644 --- a/soh/src/code/z_demo.c +++ b/soh/src/code/z_demo.c @@ -728,7 +728,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 22: - if (GameInteractor_Should(VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true)) { + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, ITEM_SONG_REQUIEM)) { Item_Give(play, ITEM_SONG_REQUIEM); } play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_EAST_EXIT; @@ -868,7 +868,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; break; case 47: - if (GameInteractor_Should(VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true)) { + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, ITEM_SONG_NOCTURNE)) { Item_Give(play, ITEM_SONG_NOCTURNE); } Flags_SetEventChkInf(EVENTCHKINF_LEARNED_NOCTURNE_OF_SHADOW); diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index e682c3fd8..df7928eb5 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -3859,23 +3859,7 @@ void Message_DrawMain(PlayState* play, Gfx** p) { u8 songItemId = ITEM_SONG_MINUET + gOcarinaSongItemMap[msgCtx->ocarinaStaff->state]; - if ((songItemId == ITEM_SONG_MINUET && - GameInteractor_Should(VB_GIVE_ITEM_MINUET_OF_FOREST, true)) || - (songItemId == ITEM_SONG_BOLERO && GameInteractor_Should(VB_GIVE_ITEM_BOLERO_OF_FIRE, true)) || - (songItemId == ITEM_SONG_SERENADE && - GameInteractor_Should(VB_GIVE_ITEM_SERENADE_OF_WATER, true)) || - (songItemId == ITEM_SONG_REQUIEM && - GameInteractor_Should(VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true)) || - (songItemId == ITEM_SONG_NOCTURNE && - GameInteractor_Should(VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true)) || - (songItemId == ITEM_SONG_PRELUDE && - GameInteractor_Should(VB_GIVE_ITEM_PRELUDE_OF_LIGHT, true)) || - (songItemId == ITEM_SONG_LULLABY && GameInteractor_Should(VB_GIVE_ITEM_ZELDAS_LULLABY, true)) || - (songItemId == ITEM_SONG_EPONA && GameInteractor_Should(VB_GIVE_ITEM_EPONAS_SONG, true)) || - (songItemId == ITEM_SONG_SARIA && GameInteractor_Should(VB_GIVE_ITEM_SARIAS_SONG, true)) || - (songItemId == ITEM_SONG_SUN && GameInteractor_Should(VB_GIVE_ITEM_SUNS_SONG, true)) || - (songItemId == ITEM_SONG_TIME && GameInteractor_Should(VB_GIVE_ITEM_SONG_OF_TIME, true)) || - (songItemId == ITEM_SONG_STORMS && GameInteractor_Should(VB_GIVE_ITEM_SONG_OF_STORMS, true))) { + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, songItemId)) { Item_Give(play, songItemId); } diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c index 0d156ec7c..18bf9155d 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c @@ -917,7 +917,7 @@ void func_80986C30(DemoIm* this, PlayState* play) { func_80985F54(this); } Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); - if (GameInteractor_Should(VB_GIVE_ITEM_ZELDAS_LULLABY, true)) { + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, ITEM_SONG_LULLABY)) { Item_Give(play, ITEM_SONG_LULLABY); } } diff --git a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c index cf578134d..7ccea3d70 100644 --- a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c +++ b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c @@ -8,6 +8,7 @@ #include "objects/object_fu/object_fu.h" #include "scenes/indoors/hakasitarelay/hakasitarelay_scene.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS \ (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \ @@ -178,7 +179,13 @@ void func_80A1DBD4(EnFu* this, PlayState* play) { Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); this->actionFunc = func_80A1DB60; this->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; - + if (GameInteractor_Should(VB_PLAY_SONG_OF_STORMS_CS, true, this)) { + play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gSongOfStormsCs); + gSaveContext.cutsceneTrigger = 1; + } + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, ITEM_SONG_STORMS)) { + Item_Give(play, ITEM_SONG_STORMS); + } play->msgCtx.ocarinaMode = OCARINA_MODE_00; Flags_SetEventChkInf(EVENTCHKINF_PLAYED_SONG_OF_STORMS_IN_WINDMILL); } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_02) { diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c index 66e888fcb..5857102ec 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c @@ -715,7 +715,7 @@ void func_80AF68E4(EnSa* this, PlayState* play) { void func_80AF6B20(EnSa* this, PlayState* play) { if (play->sceneNum == SCENE_SACRED_FOREST_MEADOW) { - if (GameInteractor_Should(VB_GIVE_ITEM_SARIAS_SONG, true)) { + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, ITEM_SONG_SARIA)) { Item_Give(play, ITEM_SONG_SARIA); } EnSa_ChangeAnim(this, ENSA_ANIM1_6); diff --git a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c index af2df2cec..967ccc70c 100644 --- a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c +++ b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c @@ -302,7 +302,7 @@ s32 EnXc_MinuetCS(EnXc* this, PlayState* play) { gSaveContext.cutsceneTrigger = 1; } Flags_SetEventChkInf(EVENTCHKINF_LEARNED_MINUET_OF_FOREST); - if (GameInteractor_Should(VB_GIVE_ITEM_MINUET_OF_FOREST, true)) { + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, ITEM_SONG_MINUET)) { Item_Give(play, ITEM_SONG_MINUET); } if (GameInteractor_Should(VB_PLAY_MINUET_OF_FOREST_CS, true)) { @@ -339,7 +339,7 @@ s32 EnXc_BoleroCS(EnXc* this, PlayState* play) { gSaveContext.cutsceneTrigger = 1; } Flags_SetEventChkInf(EVENTCHKINF_LEARNED_BOLERO_OF_FIRE); - if (GameInteractor_Should(VB_GIVE_ITEM_BOLERO_OF_FIRE, true)) { + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, ITEM_SONG_BOLERO)) { Item_Give(play, ITEM_SONG_BOLERO); } if (GameInteractor_Should(VB_PLAY_BOLERO_OF_FIRE_CS, true)) { @@ -378,7 +378,7 @@ s32 EnXc_SerenadeCS(EnXc* this, PlayState* play) { gSaveContext.cutsceneTrigger = 1; } Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER); // Learned Serenade of Water Flag - if (GameInteractor_Should(VB_GIVE_ITEM_SERENADE_OF_WATER, true)) { + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, ITEM_SONG_SERENADE)) { Item_Give(play, ITEM_SONG_SERENADE); } osSyncPrintf("ブーツを取った!!!!!!!!!!!!!!!!!!\n"); @@ -2195,7 +2195,7 @@ void EnXc_InitTempleOfTime(EnXc* this, PlayState* play) { !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP))) { Flags_SetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT); - if (GameInteractor_Should(VB_GIVE_ITEM_PRELUDE_OF_LIGHT, true)) { + if (GameInteractor_Should(VB_GIVE_ITEM_SONG, true, ITEM_SONG_PRELUDE)) { Item_Give(play, ITEM_SONG_PRELUDE); } if (GameInteractor_Should(VB_PLAY_PRELUDE_OF_LIGHT_CS, true)) {