Skip to content
Merged
76 changes: 60 additions & 16 deletions soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ void func_80AA106C(EnMa1* this, GlobalContext* globalCtx);
void func_80AA10EC(EnMa1* this, GlobalContext* globalCtx);
void func_80AA1150(EnMa1* this, GlobalContext* globalCtx);
void EnMa1_DoNothing(EnMa1* this, GlobalContext* globalCtx);
void EnMa1_WaitForSongGive(EnMa1* this, GlobalContext* globalCtx);

const ActorInit En_Ma1_InitVars = {
ACTOR_EN_MA1,
Expand Down Expand Up @@ -356,16 +357,20 @@ void func_80AA0EFC(EnMa1* this, GlobalContext* globalCtx) {

void GivePlayerRandoRewardMalon(EnMa1* malon, GlobalContext* globalCtx, RandomizerCheck check) {
GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_EPONAS_SONG);

// Prevents flag from getting set if we weren't able to get the item (i.e. Player is holding shield
// when closing the textbox).
if (malon->actor.parent != NULL && malon->actor.parent->id == GET_PLAYER(globalCtx)->actor.id &&
!Flags_GetTreasure(globalCtx, 0x1F)) {
Flags_SetTreasure(globalCtx, 0x1F);
} else if (!Flags_GetTreasure(globalCtx, 0x1F) &&
(INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_NONE || INV_CONTENT(ITEM_OCARINA_TIME) != ITEM_NONE) &&
Actor_TextboxIsClosing(&malon->actor, globalCtx) &&
(globalCtx->msgCtx.textId == 0x2049 || globalCtx->msgCtx.textId == 0x204A)) {
// puts malon in the action that vanilla has her in after learning the song
// (confirmed via breakpoints in a vanilla save).
malon->actionFunc = func_80AA0D88;
} else if (!Flags_GetTreasure(globalCtx, 0x1F)) {
func_8002F434(&malon->actor, globalCtx, getItemId, 10000.0f, 100.0f);
}
// make malon sing again after giving the item.
malon->unk_1E8.unk_00 = 0;
malon->unk_1E0 = 1;
}

void func_80AA0F44(EnMa1* this, GlobalContext* globalCtx) {
Expand All @@ -381,23 +386,28 @@ void func_80AA0F44(EnMa1* this, GlobalContext* globalCtx) {
}
}

if (gSaveContext.n64ddFlag) {
GivePlayerRandoRewardMalon(this, globalCtx, RC_SONG_FROM_MALON);
return;
}

if (gSaveContext.eventChkInf[1] & 0x40) {
// When the player pulls out the Ocarina while close to Malon
if (player->stateFlags2 & 0x1000000) {
player->stateFlags2 |= 0x2000000;
player->unk_6A8 = &this->actor;
this->actor.textId = 0x2061;
Message_StartTextbox(globalCtx, this->actor.textId, NULL);
this->unk_1E8.unk_00 = 1;
this->actor.flags |= ACTOR_FLAG_16;
this->actionFunc = func_80AA106C;
// when rando'ed, skip to the Item Giving. Otherwise go to the song teaching code.
this->actionFunc = gSaveContext.n64ddFlag ? func_80AA1150 : func_80AA106C;
} else if (this->actor.xzDistToPlayer < 30.0f + (f32)this->collider.dim.radius) {
// somehow flags that the player is close to malon so that pulling out the Ocarina
// triggers the code above this.
player->stateFlags2 |= 0x800000;
}
// If rando'ed, a textbox is closing, it's malon's 'my mom wrote this song' text, AND we do have an ocarina
// in our inventory. This allows us to grant the check when talking to malon with the ocarina in our inventory.
if (gSaveContext.n64ddFlag && (Actor_TextboxIsClosing(&this->actor, globalCtx) && globalCtx->msgCtx.textId == 0x2049) &&
(INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_NONE || INV_CONTENT(ITEM_OCARINA_TIME) != ITEM_NONE)) {
this->actionFunc = EnMa1_WaitForSongGive;
}
}
}

Expand All @@ -419,14 +429,48 @@ void func_80AA10EC(EnMa1* this, GlobalContext* globalCtx) {
}
}

void EnMa1_WaitForSongGive(EnMa1* this, GlobalContext* globalCtx) {
// Actually give the song check.
GivePlayerRandoRewardMalon(this, globalCtx, RC_SONG_FROM_MALON);
}

// Sets an Ocarina State necessary to not softlock in rando.
// This function should only be called in rando.
void EnMa1_EndTeachSong(EnMa1* this, GlobalContext* globalCtx) {
if (globalCtx->csCtx.state == CS_STATE_IDLE) {
this->actionFunc = func_80AA0F44;
globalCtx->msgCtx.ocarinaMode = OCARINA_MODE_04;
}

if (gSaveContext.n64ddFlag) {
// Transition to the giving the song check on the next update run.
this->actionFunc = EnMa1_WaitForSongGive;
}
}

void func_80AA1150(EnMa1* this, GlobalContext* globalCtx) {
GET_PLAYER(globalCtx)->stateFlags2 |= 0x800000;

// When rando'ed, trigger the "song learned" Ocarina mode.
if (gSaveContext.n64ddFlag && (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING)) {
globalCtx->msgCtx.ocarinaMode = OCARINA_MODE_03;
}

if (globalCtx->msgCtx.ocarinaMode == OCARINA_MODE_03) {
globalCtx->nextEntranceIndex = 0x157;
gSaveContext.nextCutsceneIndex = 0xFFF1;
globalCtx->fadeTransition = 42;
globalCtx->sceneLoadFlag = 0x14;
this->actionFunc = EnMa1_DoNothing;
if (!gSaveContext.n64ddFlag) {
globalCtx->nextEntranceIndex = 0x157;
gSaveContext.nextCutsceneIndex = 0xFFF1;
globalCtx->fadeTransition = 42;
globalCtx->sceneLoadFlag = 0x14;
this->actionFunc = EnMa1_DoNothing;
} else {
// When rando'ed, skip the cutscene, play the chime, reset some flags,
// and give the song on next update.
func_80078884(NA_SE_SY_CORRECT_CHIME);
this->actionFunc = EnMa1_EndTeachSong;
this->actor.flags &= ~ACTOR_FLAG_16;
globalCtx->msgCtx.ocarinaMode = OCARINA_MODE_00;
}
}
}

Expand Down