Migrate okarina_tag changes

This commit is contained in:
Garrett Cox 2024-02-21 14:01:49 -06:00
parent 37e89c0c7c
commit 7bebe7a573
7 changed files with 117 additions and 66 deletions

View File

@ -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 ***/

View File

@ -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:

View File

@ -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);

View File

@ -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<Actor*>(actorRef);
@ -610,7 +651,7 @@ void TimeSaverOnActorInitHandler(void* actorRef) {
}
if (actor->id == ACTOR_EN_FU) {
enMa1UpdateHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorUpdate>([](void* innerActorRef) mutable {
enFuUpdateHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorUpdate>([](void* innerActorRef) mutable {
Actor* innerActor = static_cast<Actor*>(innerActorRef);
if (innerActor->id == ACTOR_EN_FU && (CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", 0) || IS_RANDO)) {
EnFu* enFu = static_cast<EnFu*>(innerActorRef);
@ -623,11 +664,36 @@ void TimeSaverOnActorInitHandler(void* actorRef) {
}
}
});
enMa1KillHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) mutable {
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(enMa1UpdateHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(enMa1KillHook);
enMa1UpdateHook = 0;
enMa1KillHook = 0;
enFuKillHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) mutable {
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(enFuUpdateHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(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<GameInteractor::OnActorUpdate>([](void* innerActorRef) mutable {
Actor* innerActor = static_cast<Actor*>(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<BgSpot02Objects*>(innerActorRef);
if (bgSpot02->actionFunc == func_808ACC34) {
SPDLOG_INFO("BGspot02 OVERRIDDEN");
bgSpot02->actionFunc = func_808AC908;
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(bgSpot02UpdateHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(bgSpot02KillHook);
bgSpot02UpdateHook = 0;
bgSpot02KillHook = 0;
}
}
});
bgSpot02KillHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) mutable {
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(bgSpot02UpdateHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(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:

View File

@ -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++;

View File

@ -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

View File

@ -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;
}