From 7bebe7a5738f355278b8e0d512958678aeeae442 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 21 Feb 2024 14:01:49 -0600 Subject: [PATCH] Migrate okarina_tag changes --- .../game-interactor/GameInteractor.h | 13 +++ .../Enhancements/randomizer/hook_handlers.cpp | 10 +++ .../Enhancements/randomizer/location_list.cpp | 2 +- .../Enhancements/timesaver_hook_handlers.cpp | 81 +++++++++++++++++-- .../z_bg_spot02_objects.c | 26 +----- .../z_bg_spot02_objects.h | 3 + .../ovl_En_Okarina_Tag/z_en_okarina_tag.c | 48 +++-------- 7 files changed, 117 insertions(+), 66 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index f27342c3e..940e49cae 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -206,6 +206,9 @@ typedef enum { // Opt: *EnSyatekiMan // Vanilla condition: (this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50) GI_VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD, + // Opt: *EnOkarinaTag + // Vanilla condition: !Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME) + GI_VB_BE_ELIGIBLE_TO_OPEN_DOT, /*** Play Cutscenes ***/ @@ -235,6 +238,16 @@ typedef enum { GI_VB_PLAY_BOLERO_OF_FIRE_CS, GI_VB_PLAY_SERENADE_OF_WATER_CS, GI_VB_PLAY_EYEDROPS_CS, + // Opt: *EnOkarinaTag + GI_VB_PLAY_DRAIN_WELL_CS, + // Opt: *EnOkarinaTag + // Vanilla condition: !CHECK_QUEST_ITEM(QUEST_SONG_SUN) + GI_VB_PLAY_SUNS_SONG_CS, + // Opt: *EnOkarinaTag + GI_VB_PLAY_ROYAL_FAMILY_TOMB_CS, + GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE, + // Opt: *EnOkarinaTag + GI_VB_PLAY_DOOR_OF_TIME_CS, /*** Give Items ***/ diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 511c0d7e6..c55331edf 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -796,6 +796,16 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void } break; } + case GI_VB_BE_ELIGIBLE_TO_OPEN_DOT: { + bool eligible = RAND_GET_OPTION(RSK_DOOR_OF_TIME) != RO_DOOROFTIME_CLOSED || ( + INV_CONTENT(ITEM_OCARINA_FAIRY) == ITEM_OCARINA_TIME && + CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && + CHECK_QUEST_ITEM(QUEST_GORON_RUBY) && + CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) + ); + *should = eligible; + break; + } case GI_VB_TRADE_CLAIM_CHECK: case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index faebd65c9..8deeab8c8 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -1314,7 +1314,7 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_SONG_FROM_IMPA] = Location::Delayed(RC_SONG_FROM_IMPA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x26, "Song from Impa", "Song from Impa", RHT_SONG_FROM_IMPA, RG_ZELDAS_LULLABY, { Category::cSong, Category::cSongDungeonReward }, SpoilerCollectionCheck::EventChkInf(0x59), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_SONG_FROM_MALON] = Location::Delayed(RC_SONG_FROM_MALON, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_LON_LON_RANCH, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x27, "Song from Malon", "Song from Malon", RHT_SONG_FROM_MALON, RG_EPONAS_SONG, { Category::cSong }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LEARNED_EPONA_SONG), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, true); 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_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(EVENTCHKINF_LEARNED_SUNS_SONG), 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(EVENTCHKINF_LEARNED_SONG_OF_STORMS), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 58cdfb6fe..44102f944 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -19,6 +19,7 @@ extern "C" { #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" +#include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; } @@ -471,6 +472,44 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; } + case GI_VB_PLAY_DRAIN_WELL_CS: { + if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", 0)) { + *should = false; + Flags_SetSwitch(gPlayState, 0x2); + Flags_SetEventChkInf(EVENTCHKINF_PLAYED_SONG_OF_STORMS_IN_WINDMILL); + Flags_SetEventChkInf(EVENTCHKINF_DRAINED_WELL_IN_KAKARIKO); + } + break; + } + case GI_VB_PLAY_SUNS_SONG_CS: + if (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO) { + *should = false; + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SUNS_SONG); + // SoH [Randomizer] TODO: Increment time X amount (find out X) + // When time is 0, it's changed to 0x46A7 + // When it's 0x8000, it's changed to 0xC090 + } + break; + case GI_VB_PLAY_ROYAL_FAMILY_TOMB_CS: { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0)) { + *should = false; + } + break; + } + case GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE: { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0)) { + *should = Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB); + } + break; + } + case GI_VB_PLAY_DOOR_OF_TIME_CS: { + if (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0)) { + *should = false; + Flags_SetEnv(gPlayState, 2); + func_80078884(NA_SE_SY_CORRECT_CHIME); + } + break; + } case GI_VB_GIVE_ITEM_MINUET_OF_FOREST: case GI_VB_GIVE_ITEM_BOLERO_OF_FIRE: case GI_VB_GIVE_ITEM_SERENADE_OF_WATER: @@ -534,6 +573,8 @@ static uint32_t enMa1UpdateHook = 0; static uint32_t enMa1KillHook = 0; static uint32_t enFuUpdateHook = 0; static uint32_t enFuKillHook = 0; +static uint32_t bgSpot02UpdateHook = 0; +static uint32_t bgSpot02KillHook = 0; void TimeSaverOnActorInitHandler(void* actorRef) { Actor* actor = static_cast(actorRef); @@ -610,7 +651,7 @@ void TimeSaverOnActorInitHandler(void* actorRef) { } if (actor->id == ACTOR_EN_FU) { - enMa1UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { + enFuUpdateHook = 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); @@ -623,11 +664,36 @@ void TimeSaverOnActorInitHandler(void* actorRef) { } } }); - enMa1KillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { - GameInteractor::Instance->UnregisterGameHook(enMa1UpdateHook); - GameInteractor::Instance->UnregisterGameHook(enMa1KillHook); - enMa1UpdateHook = 0; - enMa1KillHook = 0; + enFuKillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { + GameInteractor::Instance->UnregisterGameHook(enFuUpdateHook); + GameInteractor::Instance->UnregisterGameHook(enFuKillHook); + enFuUpdateHook = 0; + enFuKillHook = 0; + }); + } + + if (actor->id == ACTOR_BG_SPOT02_OBJECTS && actor->params == 2) { + SPDLOG_INFO("Registering BG_SPOT02 hook"); + bgSpot02UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { + Actor* innerActor = static_cast(innerActorRef); + if (innerActor->id == ACTOR_BG_SPOT02_OBJECTS && innerActor->params == 2 && (CVarGetInteger("gTimeSavers.SkipMiscInteractions", 0))) { + SPDLOG_INFO("on update BG_SPOT02 hook"); + BgSpot02Objects* bgSpot02 = static_cast(innerActorRef); + if (bgSpot02->actionFunc == func_808ACC34) { + SPDLOG_INFO("BGspot02 OVERRIDDEN"); + bgSpot02->actionFunc = func_808AC908; + GameInteractor::Instance->UnregisterGameHook(bgSpot02UpdateHook); + GameInteractor::Instance->UnregisterGameHook(bgSpot02KillHook); + bgSpot02UpdateHook = 0; + bgSpot02KillHook = 0; + } + } + }); + bgSpot02KillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { + GameInteractor::Instance->UnregisterGameHook(bgSpot02UpdateHook); + GameInteractor::Instance->UnregisterGameHook(bgSpot02KillHook); + bgSpot02UpdateHook = 0; + bgSpot02KillHook = 0; }); } @@ -781,6 +847,9 @@ void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) { case EVENTCHKINF_LEARNED_SONG_OF_STORMS: vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_STORMS).GetGIEntry_Copy(); break; + case EVENTCHKINF_LEARNED_SUNS_SONG: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SUNS_SONG).GetGIEntry_Copy(); + break; } break; case FLAG_RANDOMIZER_INF: diff --git a/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c b/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c index 2eb3faeda..cc7d4c854 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c @@ -6,6 +6,7 @@ #include "z_bg_spot02_objects.h" #include "objects/object_spot02_objects/object_spot02_objects.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -129,20 +130,7 @@ void func_808AC908(BgSpot02Objects* this, PlayState* play) { static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; Vec3f pos; - // We want to do most of the same things in rando, but we're not in a cutscene and the flag for - // destroying the royal tombstone is already set. - if (IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB)) { - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_GRAVE_EXPLOSION); - this->timer = 25; - pos.x = (Math_SinS(this->dyna.actor.shape.rot.y) * 50.0f) + this->dyna.actor.world.pos.x; - pos.y = this->dyna.actor.world.pos.y + 30.0f; - pos.z = (Math_CosS(this->dyna.actor.shape.rot.y) * 50.0f) + this->dyna.actor.world.pos.z; - EffectSsBomb2_SpawnLayered(play, &pos, &zeroVec, &zeroVec, 70, 30); - this->actionFunc = func_808ACA08; - } - - if (play->csCtx.state != 0) { - if (play->csCtx.npcActions[3] != NULL && play->csCtx.npcActions[3]->action == 2) { + if (GameInteractor_Should(GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE, play->csCtx.state != 0 && play->csCtx.npcActions[3] != NULL && play->csCtx.npcActions[3]->action == 2, this)) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_GRAVE_EXPLOSION); Flags_SetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB); this->timer = 25; @@ -151,7 +139,6 @@ void func_808AC908(BgSpot02Objects* this, PlayState* play) { pos.z = (Math_CosS(this->dyna.actor.shape.rot.y) * 50.0f) + this->dyna.actor.world.pos.z; EffectSsBomb2_SpawnLayered(play, &pos, &zeroVec, &zeroVec, 70, 30); this->actionFunc = func_808ACA08; - } } } @@ -174,7 +161,7 @@ void func_808ACA08(BgSpot02Objects* this, PlayState* play) { // This shouldn't execute in rando even without the check since we never // enter the cutscene context. - if (play->csCtx.frames == 402 && !(IS_RANDO)) { + if (play->csCtx.frames == 402) { if (!LINK_IS_ADULT) { Player_PlaySfx(&player->actor, NA_SE_VO_LI_DEMO_DAMAGE_KID); } else { @@ -217,13 +204,6 @@ void BgSpot02Objects_Draw(Actor* thisx, PlayState* play) { } void func_808ACC34(BgSpot02Objects* this, PlayState* play) { - // This is the actionFunc that the game settles on when you load the Graveyard - // When we're in rando and the flag for the gravestone being destroyed gets set, - // set the actionFunc to the function where the gravestone explodes. - if (IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB)) { - this->actionFunc = func_808AC908; - } - if (play->csCtx.state != 0 && play->csCtx.npcActions[0] != NULL && play->csCtx.npcActions[0]->action == 2) { this->unk_16A++; diff --git a/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h b/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h index 0b54fa617..cf5152a7e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h +++ b/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h @@ -19,4 +19,7 @@ typedef struct BgSpot02Objects { /* 0x0172 */ u16 unk_172; } BgSpot02Objects; // size = 0x0174 +void func_808ACC34(BgSpot02Objects* bgSpot02Objects, PlayState* play); +void func_808AC908(BgSpot02Objects* bgSpot02Objects, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c index 74afaacff..34c094320 100644 --- a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c +++ b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c @@ -8,6 +8,7 @@ #include "scenes/misc/hakaana_ouke/hakaana_ouke_scene.h" #include "scenes/overworld/spot02/spot02_scene.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -192,7 +193,7 @@ void func_80ABF28C(EnOkarinaTag* this, PlayState* play) { if ((this->ocarinaSong != 6) || (gSaveContext.scarecrowSpawnSongSet)) { if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; - } else if (((this->type != 4) || !Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME)) && + } else if (((this->type != 4) || GameInteractor_Should(GI_VB_BE_ELIGIBLE_TO_OPEN_DOT, !Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME), this)) && ((this->type != 6) || !Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB)) && (this->actor.xzDistToPlayer < (90.0f + this->interactRange)) && (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 80.0f)) { @@ -234,47 +235,30 @@ void func_80ABF4C8(EnOkarinaTag* this, PlayState* play) { if (play->msgCtx.ocarinaMode == OCARINA_MODE_04) { this->actionFunc = func_80ABF28C; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { - if (!IS_RANDO || (IS_RANDO && Randomizer_GetSettingValue(RSK_DOOR_OF_TIME) != RO_DOOROFTIME_CLOSED)) { - func_80078884(NA_SE_SY_CORRECT_CHIME); - } + func_80078884(NA_SE_SY_CORRECT_CHIME); if (this->switchFlag >= 0) { Flags_SetSwitch(play, this->switchFlag); } switch (this->type) { - case 1: + case 1: // Zora's River Waterfall Flags_SetSwitch(play, this->switchFlag); Flags_SetEventChkInf(EVENTCHKINF_OPENED_ZORAS_DOMAIN); break; - case 2: - if (!IS_RANDO) { + case 2: // Kakariko Windmill + if (GameInteractor_Should(GI_VB_PLAY_DRAIN_WELL_CS, true, this)) { play->csCtx.segment = D_80ABF9D0; gSaveContext.cutsceneTrigger = 1; - } else { - Flags_SetEventChkInf(EVENTCHKINF_DRAINED_WELL_IN_KAKARIKO); - Flags_SetEventChkInf(EVENTCHKINF_PLAYED_SONG_OF_STORMS_IN_WINDMILL); } func_800F574C(1.18921f, 0x5A); break; - case 4: - if (IS_RANDO) { - if (Randomizer_GetSettingValue(RSK_DOOR_OF_TIME) == RO_DOOROFTIME_CLOSED && - (INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_OCARINA_TIME || - !CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) || !CHECK_QUEST_ITEM(QUEST_GORON_RUBY) || - !CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE))) { - func_80078884(NA_SE_SY_OCARINA_ERROR); - break; - } else { - Flags_SetEnv(play, 2); - func_80078884(NA_SE_SY_CORRECT_CHIME); - } - } else { + case 4: // Door of Time + if (GameInteractor_Should(GI_VB_PLAY_DOOR_OF_TIME_CS, true, this)) { play->csCtx.segment = D_80ABFB40; gSaveContext.cutsceneTrigger = 1; } break; - case 6: - // Don't start the cutscene in a rando save. - if (!(IS_RANDO)) { + case 6: // Royal Family Tomb + if (GameInteractor_Should(GI_VB_PLAY_ROYAL_FAMILY_TOMB_CS, true, this)) { play->csCtx.segment = LINK_IS_ADULT ? SEGMENTED_TO_VIRTUAL(&spot02_scene_Cs_003C80) : SEGMENTED_TO_VIRTUAL(&spot02_scene_Cs_005020); gSaveContext.cutsceneTrigger = 1; @@ -311,7 +295,7 @@ void func_80ABF708(EnOkarinaTag* this, PlayState* play) { yawDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y; this->unk_15A++; if (!(this->actor.xzDistToPlayer > 120.0f)) { - if (CHECK_QUEST_ITEM(QUEST_SONG_SUN) || IS_RANDO) { + if (CHECK_QUEST_ITEM(QUEST_SONG_SUN)) { this->actor.textId = 0x5021; } yawDiffNew = ABS(yawDiff); @@ -323,23 +307,15 @@ void func_80ABF708(EnOkarinaTag* this, PlayState* play) { } } -void GivePlayerRandoRewardSunSong(EnOkarinaTag* song, PlayState* play, RandomizerCheck check) { - Flags_SetTreasure(play, 0x1F); - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, GI_LETTER_ZELDA); - GiveItemEntryFromActor(&song->actor, play, getItemEntry, 10000.0f, 100.0f); -} - void func_80ABF7CC(EnOkarinaTag* this, PlayState* play) { // "Open sesame sesame!" osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 開けゴマゴマゴマ! ☆☆☆☆☆ %d\n" VT_RST, Message_GetState(&play->msgCtx)); if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); - if (!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_SONG_SUN)) { + if (GameInteractor_Should(GI_VB_PLAY_SUNS_SONG_CS, !CHECK_QUEST_ITEM(QUEST_SONG_SUN), this)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(&gSunSongGraveSunSongTeachCs); gSaveContext.cutsceneTrigger = 1; - } else if (IS_RANDO && !Flags_GetTreasure(play, 0x1F)) { - GivePlayerRandoRewardSunSong(this, play, RC_SONG_FROM_ROYAL_FAMILYS_TOMB); } this->actionFunc = func_80ABF708; }