From 37e89c0c7c9f8cf060ff2499ba5ec324aa73a2b2 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 20 Feb 2024 21:49:07 -0600 Subject: [PATCH] Migrate song of storms check --- .../Enhancements/randomizer/location_list.cpp | 2 +- .../Enhancements/timesaver_hook_handlers.cpp | 41 +++++++++++++++++++ soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c | 20 +-------- soh/src/overlays/actors/ovl_En_Fu/z_en_fu.h | 3 ++ 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 67b2b35ed..faebd65c9 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -1316,7 +1316,7 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_SONG_FROM_SARIA] = Location::Delayed(RC_SONG_FROM_SARIA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_SACRED_FOREST_MEADOW, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, 0x28, "Song from Saria", "Song from Saria", RHT_SONG_FROM_SARIA, RG_SARIAS_SONG, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x57), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); locationTable[RC_SONG_FROM_ROYAL_FAMILYS_TOMB] = Location::Delayed(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x29, "Song from Composers Grave", "Song from Composers Grave", RHT_SONG_FROM_ROYAL_FAMILYS_TOMB, RG_SUNS_SONG, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x00), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); locationTable[RC_SONG_FROM_OCARINA_OF_TIME] = Location::Delayed(RC_SONG_FROM_OCARINA_OF_TIME, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_FIELD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2A, "Song from Ocarina of Time", "Song from Ocarina of Time", RHT_SONG_FROM_OCARINA_OF_TIME, RG_SONG_OF_TIME, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0xA9), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); - locationTable[RC_SONG_FROM_WINDMILL] = Location::Delayed(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2B, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x5B), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_SONG_FROM_WINDMILL] = Location::Delayed(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2B, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); //Beehives locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x2C), 0x00, "Storms Grotto Beehive Left", "KF Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 1a349805f..58cdfb6fe 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -18,6 +18,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Sa/z_en_sa.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_Fu/z_en_fu.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; } @@ -51,6 +52,19 @@ void EnMa1_EndTeachSong(EnMa1* enMa1, PlayState* play) { } } +void EnFu_EndTeachSong(EnFu* enFu, PlayState* play) { + if (Message_GetState(&gPlayState->msgCtx) == TEXT_STATE_CLOSING) { + func_80078884(NA_SE_SY_CORRECT_CHIME); + enFu->actionFunc = EnFu_WaitAdult; + enFu->actor.flags &= ~ACTOR_FLAG_WILL_TALK; + + play->msgCtx.ocarinaMode = OCARINA_MODE_04; + Flags_SetEventChkInf(EVENTCHKINF_PLAYED_SONG_OF_STORMS_IN_WINDMILL); + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS); + return; + } +} + u16 EnZl4_GiveItemTextId(PlayState* play, Actor* actor) { return 0x207D; } @@ -518,6 +532,8 @@ static uint32_t itemOcarinaUpdateHook = 0; static uint32_t itemOcarinaframesSinceSpawn = 0; static uint32_t enMa1UpdateHook = 0; static uint32_t enMa1KillHook = 0; +static uint32_t enFuUpdateHook = 0; +static uint32_t enFuKillHook = 0; void TimeSaverOnActorInitHandler(void* actorRef) { Actor* actor = static_cast(actorRef); @@ -593,6 +609,28 @@ void TimeSaverOnActorInitHandler(void* actorRef) { }); } + if (actor->id == ACTOR_EN_FU) { + enMa1UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { + Actor* innerActor = static_cast(innerActorRef); + if (innerActor->id == ACTOR_EN_FU && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO)) { + EnFu* enFu = static_cast(innerActorRef); + if (enFu->actionFunc == EnFu_TeachSong) { + enFu->actionFunc = EnFu_EndTeachSong; + GameInteractor::Instance->UnregisterGameHook(enFuUpdateHook); + GameInteractor::Instance->UnregisterGameHook(enFuKillHook); + enFuUpdateHook = 0; + enFuKillHook = 0; + } + } + }); + enMa1KillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { + GameInteractor::Instance->UnregisterGameHook(enMa1UpdateHook); + GameInteractor::Instance->UnregisterGameHook(enMa1KillHook); + enMa1UpdateHook = 0; + enMa1KillHook = 0; + }); + } + if (actor->id == ACTOR_EN_ZL4 && CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { EnZl4* enZl4 = static_cast(actorRef); if (enZl4->actionFunc != EnZl4_Cutscene || enZl4->csState != 0) return; @@ -740,6 +778,9 @@ void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) { case EVENTCHKINF_LEARNED_SONG_OF_TIME: vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_TIME).GetGIEntry_Copy(); break; + case EVENTCHKINF_LEARNED_SONG_OF_STORMS: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_STORMS).GetGIEntry_Copy(); + break; } break; case FLAG_RANDOMIZER_INF: 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 278fb18e2..ad1d6f12a 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 @@ -161,20 +161,12 @@ void GivePlayerRandoRewardSongOfStorms(EnFu* windmillGuy, PlayState* play, Rando } } -void func_WaitForSongGive(EnFu* this, PlayState* play) { - GivePlayerRandoRewardSongOfStorms(this, play, RC_SONG_FROM_WINDMILL); -} - void func_80A1DB60(EnFu* this, PlayState* play) { if (play->csCtx.state == CS_STATE_IDLE) { this->actionFunc = EnFu_WaitAdult; Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS); play->msgCtx.ocarinaMode = OCARINA_MODE_04; } - - if (IS_RANDO) { - this->actionFunc = func_WaitForSongGive; - } } void func_80A1DBA0(EnFu* this, PlayState* play) { @@ -186,10 +178,6 @@ void func_80A1DBA0(EnFu* this, PlayState* play) { void func_80A1DBD4(EnFu* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (IS_RANDO && (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING)) { - play->msgCtx.ocarinaMode = OCARINA_MODE_03; - } - if (play->msgCtx.ocarinaMode >= OCARINA_MODE_04) { this->actionFunc = EnFu_WaitAdult; play->msgCtx.ocarinaMode = OCARINA_MODE_04; @@ -199,12 +187,6 @@ void func_80A1DBD4(EnFu* this, PlayState* play) { this->actionFunc = func_80A1DB60; this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; - if (!IS_RANDO) { - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gSongOfStormsCs); - gSaveContext.cutsceneTrigger = 1; - 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) { @@ -249,7 +231,7 @@ void EnFu_WaitAdult(EnFu* this, PlayState* play) { } else if (player->stateFlags2 & 0x1000000) { this->actor.textId = 0x5035; Message_StartTextbox(play, this->actor.textId, NULL); - this->actionFunc = IS_RANDO ? func_80A1DBD4 : EnFu_TeachSong; + this->actionFunc = EnFu_TeachSong; this->behaviorFlags |= FU_WAIT; } else if (Actor_ProcessTalkRequest(&this->actor, play)) { this->actionFunc = func_80A1DBA0; diff --git a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.h b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.h index 7fddd6543..fd371000d 100644 --- a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.h +++ b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.h @@ -41,4 +41,7 @@ typedef struct EnFu { /* 0x02AC */ EnFuActionFunc actionFunc; } EnFu; // size = 0x02B0 +void EnFu_TeachSong(EnFu* enFu, PlayState* play); +void EnFu_WaitAdult(EnFu* enFu, PlayState* play); + #endif