diff --git a/soh/soh/Enhancements/AlwaysOnFixes.cpp b/soh/soh/Enhancements/AlwaysOnFixes.cpp index d56b2020be..7303bedef4 100644 --- a/soh/soh/Enhancements/AlwaysOnFixes.cpp +++ b/soh/soh/Enhancements/AlwaysOnFixes.cpp @@ -7,6 +7,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Go2/z_en_go2.h" #include "include/z64camera.h" #include "src/overlays/actors/ovl_En_Test/z_en_test.h" +#include "src/overlays/actors/ovl_En_Horse/z_en_horse.h" extern void Player_UseItem(PlayState*, Player*, s32); extern PlayState* gPlayState; } @@ -72,6 +73,21 @@ void RegisterAlwaysOnFixes() { } }); + COND_VB_SHOULD(VB_PREVENT_HBA_FANFARE_SOFTLOCK_TIMER, true, { + EnHorse* enHorse = va_arg(args, EnHorse*); + if (enHorse->hbaFlags & 1) { + *should = true; // hbaFlags 1 = end of tour + } + }); + + COND_VB_SHOULD(VB_PREVENT_HBA_FANFARE_SOFTLOCK_BUTTONS, true, { + EnHorse* enHorse = va_arg(args, EnHorse*); + if (enHorse->hbaTimer >= 80 && + CHECK_BTN_ANY(gPlayState->state.input[0].press.button, BTN_A | BTN_B | BTN_START)) { + *should = true; + } + }); + COND_ID_HOOK(OnActorDestroy, ACTOR_EN_TEST, true, [](void* refActor) { Actor* actor = reinterpret_cast(refActor); if (actor->params != STALFOS_TYPE_2 && !EnTest_HasLivingNearby(actor)) { diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 8ef4948ff4..eec16c7ffd 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -3293,6 +3293,26 @@ typedef enum { // - `*EnGo2` (Goron Link) VB_PREVENT_GORON_LINK_SOFTLOCK, + // #### `result` + // ```c + // play->interfaceCtx.hbaAmmo == 0 + // ``` + // Prevent custom fanfares set to loop from softlocking Horseback Archery by + // letting players escape the cutscene with A/B/start after a normal number of playframes. + // #### `args` + // - none + VB_PREVENT_HBA_FANFARE_SOFTLOCK_TIMER, + + // #### `result` + // ```c + // (isFanfarePlaying != 1 && gSaveContext.minigameState != 3) + // ``` + // Prevent custom fanfares set to loop from softlocking Horseback Archery by + // letting players escape the cutscene with A/B/start after a normal number of playframes. + // #### `args` + // - `EnHorse*` + VB_PREVENT_HBA_FANFARE_SOFTLOCK_BUTTONS, + // #### `result` // ```c // sets `camMode` to new mode if applicable diff --git a/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c b/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c index ac329cf836..e62c3a45ab 100644 --- a/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c +++ b/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c @@ -2519,14 +2519,17 @@ void EnHorse_UpdateHorsebackArchery(EnHorse* this, PlayState* play) { if (this->animationIdx == ENHORSE_ANIM_WALK) { EnHorse_PlayWalkingSfx(this); } - if (play->interfaceCtx.hbaAmmo == 0) { + + if (GameInteractor_Should(VB_PREVENT_HBA_FANFARE_SOFTLOCK_TIMER, play->interfaceCtx.hbaAmmo == 0, this)) { this->hbaTimer++; } isFanfarePlaying = Audio_IsSequencePlaying(NA_BGM_HORSE_GOAL); + EnHorse_UpdateHbaRaceInfo(this, play, &sHbaInfo); if (this->hbaFlags & 1 || this->hbaTimer >= 46) { - if (isFanfarePlaying != 1 && gSaveContext.minigameState != 3) { + if (GameInteractor_Should(VB_PREVENT_HBA_FANFARE_SOFTLOCK_BUTTONS, + (isFanfarePlaying != 1 && gSaveContext.minigameState != 3), this)) { gSaveContext.cutsceneIndex = 0; play->nextEntranceIndex = ENTR_GERUDOS_FORTRESS_16; play->transitionTrigger = TRANS_TRIGGER_START;