diff options
| author | Garrett Cox <garrettjcox@gmail.com> | 2024-01-08 09:25:47 -0600 |
|---|---|---|
| committer | Garrett Cox <garrettjcox@gmail.com> | 2024-02-02 15:39:01 -0600 |
| commit | 596ea5ebbb3e5a5dfab72fb7bee6d4802d8b13d4 (patch) | |
| tree | 4161db9bf2f0ad30895e9195e3bbaa7db56785cc /soh/src | |
| parent | fe9dcf1fc3f82711f03f932e3f153dc4ba3cf7df (diff) | |
Vanilla Behavior Overhaul
Co-authored-by: jordanpg <jordanpg@users.noreply.github.com>
Diffstat (limited to 'soh/src')
73 files changed, 995 insertions, 1886 deletions
diff --git a/soh/src/code/z_demo.c b/soh/src/code/z_demo.c index 9c0dd9b05..94b04580f 100644 --- a/soh/src/code/z_demo.c +++ b/soh/src/code/z_demo.c @@ -32,6 +32,7 @@ #include "scenes/misc/hakaana_ouke/hakaana_ouke_scene.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" u16 D_8011E1C0 = 0; u16 D_8011E1C4 = 0; @@ -485,6 +486,7 @@ void func_80065134(PlayState* play, CutsceneContext* csCtx, CsCmdDayTime* cmd) { gSaveContext.dayTime = temp1 + temp2; gSaveContext.skyboxTime = temp1 + temp2; + LUSLOG_INFO("SET TIME %d", gSaveContext.dayTime); } } @@ -493,11 +495,16 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB Player* player = GET_PLAYER(play); s32 temp = 0; - // Automatically skip certain cutscenes when in rando - // cmd->base == 8: Traveling back/forward in time cutscene - // cmd->base == 24: Dropping a fish for Jabu Jabu - // cmd->base == 33: Zelda escaping with impa cutscene - bool randoCsSkip = (IS_RANDO && (cmd->base == 8 || cmd->base == 24 || cmd->base == 33)); + bool shouldSkipCommand = false; + + if (cmd->base == 8 && !GameInteractor_Should(GI_VB_PLAY_PULL_MASTER_SWORD_CS, true, NULL)) { + shouldSkipCommand = true; + } + + if (cmd->base == 24 && !GameInteractor_Should(GI_VB_PLAY_DROP_FISH_FOR_JABU_CS, true, NULL)) { + shouldSkipCommand = true; + } + bool debugCsSkip = (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) && (gSaveContext.fileNum != 0xFEDC) && CVarGetInteger("gDebugEnabled", 0)); @@ -558,7 +565,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB } } - if (playCutscene || (temp != 0) || ((csCtx->frames > 20) && (randoCsSkip || debugCsSkip))) { + if (playCutscene || (temp != 0) || ((csCtx->frames > 20) && (shouldSkipCommand || debugCsSkip))) { csCtx->state = CS_STATE_UNSKIPPABLE_EXEC; Audio_SetCutsceneFlag(0); @@ -624,7 +631,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB gSaveContext.fw.set = 0; gSaveContext.respawn[RESPAWN_MODE_TOP].data = 0; } - if (!Flags_GetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL)) { + if (GameInteractor_Should(GI_VB_PLAY_PULL_MASTER_SWORD_CS, !Flags_GetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL), NULL)) { Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL); play->nextEntranceIndex = ENTR_CUTSCENE_MAP_0; play->transitionTrigger = TRANS_TRIGGER_START; @@ -716,7 +723,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 22: - Item_Give(play, ITEM_SONG_REQUIEM); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true, NULL)) { + Item_Give(play, ITEM_SONG_REQUIEM); + } play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_0; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF0; @@ -768,7 +777,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; - Item_Give(play, ITEM_MEDALLION_FIRE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FIRE_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FIRE); + } gSaveContext.chamberCutsceneNum = 1; break; case 31: @@ -848,7 +859,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; break; case 47: - Item_Give(play, ITEM_SONG_NOCTURNE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true, NULL)) { + Item_Give(play, ITEM_SONG_NOCTURNE); + } Flags_SetEventChkInf(EVENTCHKINF_LEARNED_NOCTURNE_OF_SHADOW); play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; play->transitionTrigger = TRANS_TRIGGER_START; @@ -1292,7 +1305,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB break; } - if (randoCsSkip) { + if (shouldSkipCommand && IS_RANDO) { Entrance_OverrideCutsceneEntrance(cmd->base); } } @@ -1561,7 +1574,49 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText } else if ((cmd->type == 4) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) { Message_StartTextbox(play, cmd->textId1, NULL); } else { + GetItemEntry getItemEntry = GET_ITEM_NONE; + if (IS_RANDO) { + switch (cmd->base) { + case 0x80: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_QUEEN_GOHMA, RG_KOKIRI_EMERALD); + break; + case 0x81: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KING_DODONGO, RG_GORON_RUBY); + break; + case 0x82: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE); + break; + case 0x3E: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_PHANTOM_GANON, RG_FOREST_MEDALLION); + break; + case 0x3C: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_VOLVAGIA, RG_FIRE_MEDALLION); + break; + case 0x3D: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MORPHA, RG_WATER_MEDALLION); + break; + case 0x3F: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TWINROVA, RG_SPIRIT_MEDALLION); + break; + case 0x41: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BONGO_BONGO, RG_SHADOW_MEDALLION); + break; + case 0x40: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GIFT_FROM_SAGES, RG_LIGHT_MEDALLION); + break; + case 0x72: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS); + break; + } + if (getItemEntry.getItemId != GI_NONE) { + // cmd->base = getItemEntry.textId; + // GET_PLAYER(play)->getItemEntry = getItemEntry; + } + } Message_StartTextbox(play, cmd->base, NULL); + if (IS_RANDO && getItemEntry.getItemId != GI_NONE) { + // GET_PLAYER(play)->getItemEntry = (GetItemEntry)GET_ITEM_NONE; + } } return; } @@ -1584,12 +1639,14 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText if ((dialogState == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) { if (play->msgCtx.choiceIndex == 0) { if (cmd->textId1 != 0xFFFF) { + // LUSLOG_INFO("Cutscene_Command_Textbox D: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2); Message_ContinueTextbox(play, cmd->textId1); } else { csCtx->frames++; } } else { if (cmd->textId2 != 0xFFFF) { + // LUSLOG_INFO("Cutscene_Command_Textbox E: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2); Message_ContinueTextbox(play, cmd->textId2); } else { csCtx->frames++; @@ -1599,6 +1656,7 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText if (dialogState == TEXT_STATE_9) { if (cmd->textId1 != 0xFFFF) { + // LUSLOG_INFO("Cutscene_Command_Textbox F: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2); Message_ContinueTextbox(play, cmd->textId1); } else { csCtx->frames++; @@ -2113,34 +2171,23 @@ void Cutscene_HandleEntranceTriggers(PlayState* play) { u8 requiredAge; s16 i; - if (IS_RANDO && - // don't skip epona escape cutscenes - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_11 && - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_12 && - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_13 && - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_15 && - // don't skip nabooru iron knuckle cs - gSaveContext.entranceIndex != ENTR_SPIRIT_TEMPLE_BOSS_0) { - gSaveContext.showTitleCard = false; - return; - } - for (i = 0; i < ARRAY_COUNT(sEntranceCutsceneTable); i++) { entranceCutscene = &sEntranceCutsceneTable[i]; - requiredAge = entranceCutscene->ageRestriction; if (requiredAge == 2) { requiredAge = gSaveContext.linkAge; } if ((gSaveContext.entranceIndex == entranceCutscene->entrance) && - (!Flags_GetEventChkInf(entranceCutscene->flag) || (entranceCutscene->flag == 0x18)) && + (!Flags_GetEventChkInf(entranceCutscene->flag) || (entranceCutscene->flag == EVENTCHKINF_EPONA_OBTAINED)) && (gSaveContext.cutsceneIndex < 0xFFF0) && ((u8)gSaveContext.linkAge == requiredAge) && (gSaveContext.respawnFlag <= 0)) { Flags_SetEventChkInf(entranceCutscene->flag); - Cutscene_SetSegment(play, entranceCutscene->segAddr); - gSaveContext.cutsceneTrigger = 2; - gSaveContext.showTitleCard = false; + if (GameInteractor_Should(GI_VB_PLAY_ENTRANCE_CS, true, &entranceCutscene->flag)) { + Cutscene_SetSegment(play, entranceCutscene->segAddr); + gSaveContext.cutsceneTrigger = 2; + gSaveContext.showTitleCard = false; + } break; } } @@ -2148,48 +2195,48 @@ void Cutscene_HandleEntranceTriggers(PlayState* play) { void Cutscene_HandleConditionalTriggers(PlayState* play) { osSyncPrintf("\ngame_info.mode=[%d] restart_flag", ((void)0, gSaveContext.respawnFlag)); + LUSLOG_INFO("Cutscene_HandleConditionalTriggers - entranceIndex: %#x cutsceneIndex: %#x", gSaveContext.entranceIndex, gSaveContext.cutsceneIndex); + + if (!GameInteractor_Should(GI_VB_PLAY_TRANSITION_CS, true, NULL)) { + return; + } if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { - const bool bShouldTowerRandoSkip = - (IS_RANDO && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE)); if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); - gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_0; - gSaveContext.cutsceneIndex = 0xFFF0; - } - } else if ((gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0) && LINK_IS_ADULT && (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) && - (Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) && (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) && - !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); - gSaveContext.cutsceneIndex = 0xFFF0; - } + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); + gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_0; + gSaveContext.cutsceneIndex = 0xFFF0; + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW, ( + (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0) && + LINK_IS_ADULT && + Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) && + !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) + ), NULL)) { + Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); + gSaveContext.cutsceneIndex = 0xFFF0; } else if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FAIRY_OCARINA, true, NULL)) { Item_Give(play, ITEM_OCARINA_FAIRY); - gSaveContext.entranceIndex = ENTR_LOST_WOODS_0; - gSaveContext.cutsceneIndex = 0xFFF0; - } - } else if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && - LINK_IS_ADULT && !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && - (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); - gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_0; - gSaveContext.cutsceneIndex = 0xFFF8; } - } else if ((!Flags_GetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO) && - gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANON_BOSS) || - (bShouldTowerRandoSkip && - gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR)) { + gSaveContext.entranceIndex = ENTR_LOST_WOODS_0; + gSaveContext.cutsceneIndex = 0xFFF0; + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, ( + CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && + LINK_IS_ADULT && + !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && + (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) + ), NULL)) { + Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); + gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_0; + gSaveContext.cutsceneIndex = 0xFFF8; + } else if (!Flags_GetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO) && + (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANON_BOSS)) { Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO); gSaveContext.entranceIndex = ENTR_GANON_BOSS_0; - // In rando, skip the cutscene for the tower falling down after the escape. - if (IS_RANDO) { - return; - } gSaveContext.cutsceneIndex = 0xFFF0; } } diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 77f42aebd..da7454961 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -3,6 +3,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h" #include "textures/icon_item_static/icon_item_static.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -349,6 +350,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { s32 getItemId = GI_NONE; this->randoGiEntry = (GetItemEntry)GET_ITEM_NONE; this->randoCheck = (RandomizerCheck)RC_UNKNOWN_CHECK; + this->itemEntry = (GetItemEntry)GET_ITEM_NONE; s16 spawnParam8000 = this->actor.params & 0x8000; s32 pad1; @@ -358,7 +360,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->actor.params &= 0xFF; - if (Flags_GetCollectible(play, this->collectibleFlag)) { + if (GameInteractor_Should(GI_VB_ITEM00_DESPAWN, Flags_GetCollectible(play, this->collectibleFlag), this)) { Actor_Kill(&this->actor); return; } @@ -381,12 +383,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->unk_158 = 0; Actor_SetScale(&this->actor, 0.03f); this->scale = 0.03f; - // Offset keys in randomizer slightly higher for their GID replacement - if (!IS_RANDO) { - yOffset = 350.0f; - } else { - yOffset = 430.0f; - } + yOffset = 350.0f; break; case ITEM00_HEART_PIECE: this->unk_158 = 0; @@ -479,6 +476,14 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { Actor_SetScale(&this->actor, 0.03f); this->scale = 0.03f; break; + case ITEM00_SOH_GIVE_ITEM_ENTRY: + case ITEM00_SOH_GIVE_ITEM_ENTRY_GI: + case ITEM00_SOH_DUMMY: + this->unk_158 = 0; + Actor_SetScale(&this->actor, 0.03f); + this->scale = 0.03f; + yOffset = 430.0f; + break; } this->unk_156 = 0; @@ -507,6 +512,10 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->actor.velocity.y = 0.0f; this->actor.gravity = 0.0f; + if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ITEM_00, true, this)) { + return; + } + switch (this->actor.params) { case ITEM00_RUPEE_GREEN: Item_Give(play, ITEM_RUPEE_GREEN); @@ -576,16 +585,8 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { break; } - if (!Actor_HasParent(&this->actor, play)) { - if (getItemId != GI_NONE) { - if (!IS_RANDO || this->randoGiEntry.getItemId == GI_NONE) { - func_8002F554(&this->actor, play, getItemId); - } else { - if (GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry) && this->randoInf != RAND_INF_MAX) { - Flags_SetRandomizerInf(this->randoInf); - } - } - } + if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) { + func_8002F554(&this->actor, play, getItemId); } EnItem00_SetupAction(this, func_8001E5C8); @@ -603,8 +604,7 @@ void func_8001DFC8(EnItem00* this, PlayState* play) { (this->actor.params == ITEM00_HEART_PIECE)) { this->actor.shape.rot.y += 960; } else { - if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params != ITEM00_BOMBS_SPECIAL) && - (this->actor.params != ITEM00_BOMBCHU)) { + if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params < ITEM00_BOMBS_SPECIAL)) { if (this->unk_15A == -1) { if (Math_SmoothStepToS(&this->actor.shape.rot.x, this->actor.world.rot.x - 0x4000, 2, 3000, 1500) == 0) { @@ -697,8 +697,7 @@ void func_8001E304(EnItem00* this, PlayState* play) { if (this->actor.params <= ITEM00_RUPEE_RED) { this->actor.shape.rot.y += 960; - } else if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params != ITEM00_BOMBS_SPECIAL) && - (this->actor.params != ITEM00_BOMBCHU)) { + } else if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params < ITEM00_BOMBS_SPECIAL)) { this->actor.world.rot.x -= 700; this->actor.shape.rot.y += 400; this->actor.shape.rot.x = this->actor.world.rot.x - 0x4000; @@ -733,13 +732,7 @@ void func_8001E5C8(EnItem00* this, PlayState* play) { Player* player = GET_PLAYER(play); if (this->getItemId != GI_NONE) { if (!Actor_HasParent(&this->actor, play)) { - if (!IS_RANDO) { - func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f); - } else { - if (GiveItemEntryFromActor(&this->actor, play, this->randoGiEntry, 50.0f, 80.0f) && this->randoInf != RAND_INF_MAX) { - Flags_SetRandomizerInf(this->randoInf); - } - } + func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f); this->unk_15A++; } else { this->getItemId = GI_NONE; @@ -781,13 +774,15 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { s32 pad; // Rotate some drops when 3D drops are on, otherwise reset rotation back to 0 for billboard effect - if ((this->actor.params == ITEM00_HEART && this->unk_15A >= 0) || + if ( + (this->actor.params == ITEM00_HEART && this->unk_15A >= 0) || (this->actor.params >= ITEM00_ARROWS_SMALL && this->actor.params <= ITEM00_SMALL_KEY) || - this->actor.params == ITEM00_BOMBS_A || this->actor.params == ITEM00_ARROWS_SINGLE || - this->actor.params == ITEM00_BOMBS_SPECIAL || this->actor.params == ITEM00_BOMBCHU) { - if (CVarGetInteger("gNewDrops", 0) || - // Keys in randomizer need to always rotate for their GID replacement - (IS_RANDO && this->actor.params == ITEM00_SMALL_KEY)) { + this->actor.params == ITEM00_BOMBS_A || + this->actor.params == ITEM00_ARROWS_SINGLE || + this->actor.params == ITEM00_BOMBS_SPECIAL || + (this->actor.params >= ITEM00_BOMBCHU && this->actor.params <= ITEM00_SOH_GIVE_ITEM_ENTRY_GI) + ) { + if (CVarGetInteger("gNewDrops", 0) || (this->actor.params >= ITEM00_SOH_DUMMY && this->actor.params <= ITEM00_SOH_GIVE_ITEM_ENTRY_GI)) { this->actor.shape.rot.y += 960; } else { this->actor.shape.rot.y = 0; @@ -871,6 +866,10 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { return; } + if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ITEM_00, true, this)) { + return; + } + switch (this->actor.params) { case ITEM00_RUPEE_GREEN: Item_Give(play, ITEM_RUPEE_GREEN); @@ -955,14 +954,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { params = &this->actor.params; if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) { - if (!IS_RANDO || this->randoGiEntry.getItemId == GI_NONE) { - func_8002F554(&this->actor, play, getItemId); - } else { - getItemId = this->randoGiEntry.getItemId; - if (GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry) && this->randoInf != RAND_INF_MAX) { - Flags_SetRandomizerInf(this->randoInf); - } - } + func_8002F554(&this->actor, play, getItemId); } switch (*params) { @@ -1052,7 +1044,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) { } break; case ITEM00_HEART_PIECE: - if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) { + if (CVarGetInteger("gNewDrops", 0)) { mtxScale = 21.0f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); GetItem_Draw(play, GID_HEART_PIECE); @@ -1162,7 +1154,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) { break; } case ITEM00_SMALL_KEY: - if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) { + if (CVarGetInteger("gNewDrops", 0)) { mtxScale = 8.0f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); GetItem_Draw(play, GID_KEY_SMALL); @@ -1368,17 +1360,7 @@ static const Vtx customDropVtx[] = { * Draw Function used for most collectible types of En_Item00 (ammo, bombs, sticks, nuts, magic...). */ void EnItem00_DrawCollectible(EnItem00* this, PlayState* play) { - if (IS_RANDO && (this->getItemId != GI_NONE || this->actor.params == ITEM00_SMALL_KEY)) { - if (this->randoCheck != RC_UNKNOWN_CHECK) { - this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, GI_NONE); - this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; - } - - f32 mtxScale = 10.67f; - Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - EnItem00_CustomItemsParticles(&this->actor, play, this->randoGiEntry); - GetItemEntry_Draw(play, this->randoGiEntry); - } else if (this->actor.params == ITEM00_BOMBCHU) { + if (this->actor.params == ITEM00_BOMBCHU) { OPEN_DISPS(play->state.gfxCtx); Matrix_ReplaceRotation(&play->billboardMtxF); @@ -1458,29 +1440,17 @@ void EnItem00_DrawHeartContainer(EnItem00* this, PlayState* play) { * Draw Function used for the Piece of Heart type of En_Item00. */ void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play) { - if (IS_RANDO) { - if (this->randoCheck != RC_UNKNOWN_CHECK) { - this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, GI_NONE); - this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; - } - - f32 mtxScale = 16.0f; - Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - EnItem00_CustomItemsParticles(&this->actor, play, this->randoGiEntry); - GetItemEntry_Draw(play, this->randoGiEntry); - } else { - s32 pad; + s32 pad; - OPEN_DISPS(play->state.gfxCtx); + OPEN_DISPS(play->state.gfxCtx); - Gfx_SetupDL_25Xlu(play->state.gfxCtx); - func_8002ED80(&this->actor, play, 0); - gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), - G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_XLU_DISP++, gHeartPieceInteriorDL); + Gfx_SetupDL_25Xlu(play->state.gfxCtx); + func_8002ED80(&this->actor, play, 0); + gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), + G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_XLU_DISP++, gHeartPieceInteriorDL); - CLOSE_DISPS(play->state.gfxCtx); - } + CLOSE_DISPS(play->state.gfxCtx); } /** diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 4c661aad7..1d00f73bb 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -2603,8 +2603,23 @@ void Message_DrawMain(PlayState* play, Gfx** p) { msgCtx->lastPlayedSong = msgCtx->ocarinaStaff->state; msgCtx->msgMode = MSGMODE_SONG_PLAYBACK_SUCCESS; - if (!IS_RANDO) { - Item_Give(play, ITEM_SONG_MINUET + gOcarinaSongItemMap[msgCtx->ocarinaStaff->state]); + u8 songItemId = ITEM_SONG_MINUET + gOcarinaSongItemMap[msgCtx->ocarinaStaff->state]; + + if ( + (songItemId == ITEM_SONG_MINUET && GameInteractor_Should(GI_VB_GIVE_ITEM_MINUET_OF_FOREST, true, NULL)) || + (songItemId == ITEM_SONG_BOLERO && GameInteractor_Should(GI_VB_GIVE_ITEM_BOLERO_OF_FIRE, true, NULL)) || + (songItemId == ITEM_SONG_SERENADE && GameInteractor_Should(GI_VB_GIVE_ITEM_SERENADE_OF_WATER, true, NULL)) || + (songItemId == ITEM_SONG_REQUIEM && GameInteractor_Should(GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true, NULL)) || + (songItemId == ITEM_SONG_NOCTURNE && GameInteractor_Should(GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true, NULL)) || + (songItemId == ITEM_SONG_PRELUDE && GameInteractor_Should(GI_VB_GIVE_ITEM_PRELUDE_OF_LIGHT, true, NULL)) || + (songItemId == ITEM_SONG_LULLABY && GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LULLABY, true, NULL)) || + (songItemId == ITEM_SONG_EPONA && GameInteractor_Should(GI_VB_GIVE_ITEM_EPONAS_SONG, true, NULL)) || + (songItemId == ITEM_SONG_SARIA && GameInteractor_Should(GI_VB_GIVE_ITEM_SARIAS_SONG, true, NULL)) || + (songItemId == ITEM_SONG_SUN && GameInteractor_Should(GI_VB_GIVE_ITEM_SUNS_SONG, true, NULL)) || + (songItemId == ITEM_SONG_TIME && GameInteractor_Should(GI_VB_GIVE_ITEM_SONG_OF_TIME, true, NULL)) || + (songItemId == ITEM_SONG_STORMS && GameInteractor_Should(GI_VB_GIVE_ITEM_SONG_OF_STORMS, true, NULL)) + ) { + Item_Give(play, songItemId); } osSyncPrintf(VT_FGCOL(YELLOW)); diff --git a/soh/src/code/z_onepointdemo.c b/soh/src/code/z_onepointdemo.c index 9489eefcd..ad5df65bd 100644 --- a/soh/src/code/z_onepointdemo.c +++ b/soh/src/code/z_onepointdemo.c @@ -1,6 +1,7 @@ #include "global.h" #include "vt.h" #include "overlays/actors/ovl_En_Sw/z_en_sw.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" static s16 sDisableAttention = false; static s16 sUnused = -1; @@ -810,12 +811,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor break; case 4100: csInfo->keyFrames = D_801225D4; - // RANDO: Waterfall opening cutscene skips to the end of the cutscene data earlier by doing this - if (!(IS_RANDO)) { - csInfo->keyFrameCnt = 5; - } else { - csInfo->keyFrameCnt = 2; - } + csInfo->keyFrameCnt = ARRAY_COUNT(D_801225D4); player->actor.shape.rot.y = player->actor.world.rot.y = player->currentYaw = 0x3FFC; func_800C0808(play, camIdx, player, CAM_SET_CS_C); @@ -1176,6 +1172,16 @@ s16 OnePointCutscene_Init(PlayState* play, s16 csId, s16 timer, Actor* actor, s1 s16 csCamIdx; Camera* csCam; + if (actor != NULL && actor->id != ACTOR_PLAYER) { + if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, actor)) { + return; + } + } else { + if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_CS, true, &csId)) { + return; + } + } + if (parentCamIdx == SUBCAM_ACTIVE) { parentCamIdx = play->activeCamera; } diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 828e98368..bc253ef3a 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2128,7 +2128,9 @@ u8 Item_Give(PlayState* play, u8 item) { AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS); } } - item = ITEM_STICK; + // [SOH] This results in the same behavior as the original code, but also allows us to get an accurate ReceivedItemEntry hook + INV_CONTENT(ITEM_STICK) = ITEM_STICK; + return Return_Item(item, MOD_NONE, returnItem); } else if (item == ITEM_NUT) { if (gSaveContext.inventory.items[slot] == ITEM_NONE) { Inventory_ChangeUpgrade(UPG_NUTS, 1); @@ -2152,7 +2154,9 @@ u8 Item_Give(PlayState* play, u8 item) { AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS); } } - item = ITEM_NUT; + // [SOH] This results in the same behavior as the original code, but also allows us to get an accurate ReceivedItemEntry hook + INV_CONTENT(ITEM_NUT) = ITEM_NUT; + return Return_Item(item, MOD_NONE, returnItem); } else if (item == ITEM_BOMB) { // "Bomb Bomb Bomb Bomb Bomb Bomb Bomb" osSyncPrintf(" 爆弾 爆弾 爆弾 爆弾 爆弾 爆弾 爆弾 \n"); diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index f9b3e7cf4..3ce5eeefc 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -226,60 +226,6 @@ void Play_Destroy(GameState* thisx) { gPlayState = NULL; } -void GivePlayerRandoRewardSongOfTime(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_16 && player != NULL && !Player_InBlockingCsMode(play, player) && - !Flags_GetTreasure(play, 0x1F) && gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT && !gSaveContext.pendingIceTrapCount) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = 0x1F; - player->pendingFlag.flagType = FLAG_SCENE_TREASURE; - } -} - -void GivePlayerRandoRewardNocturne(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if ((gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 || - gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_1 || - gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_2) && LINK_IS_ADULT && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && - CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && player != NULL && - !Player_InBlockingCsMode(play, player) && !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_NOCTURNE_OF_SHADOW); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = 0xAA; - player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; - } -} - -void GivePlayerRandoRewardRequiem(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { - if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT) && player != NULL && - !Player_InBlockingCsMode(play, player)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = 0xAC; - player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; - } - } -} - -void GivePlayerRandoRewardMasterSword(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_2 && LINK_IS_ADULT && player != NULL && - !Player_InBlockingCsMode(play, player) && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && - !Flags_GetRandomizerInf(RAND_INF_TOT_MASTER_SWORD)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_MASTER_SWORD); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = RAND_INF_TOT_MASTER_SWORD; - player->pendingFlag.flagType = FLAG_RANDOMIZER_INF; - } -} - u8 CheckStoneCount() { u8 stoneCount = 0; @@ -402,69 +348,6 @@ u8 CheckLACSRewardCount() { return lacsRewardCount; } -void GivePlayerRandoRewardZeldaLightArrowsGift(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - u8 meetsRequirements = 0; - - switch (Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY)) { - case RO_GANON_BOSS_KEY_LACS_STONES: - if ((CheckStoneCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_STONE_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_MEDALLIONS: - if ((CheckMedallionCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_MEDALLION_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_REWARDS: - if ((CheckMedallionCount() + CheckStoneCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_REWARD_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_DUNGEONS: - if ((CheckDungeonCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_DUNGEON_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_TOKENS: - if (gSaveContext.inventory.gsTokens >= Randomizer_GetSettingValue(RSK_LACS_TOKEN_COUNT)) { - meetsRequirements = true; - } - break; - default: - if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW)) { - meetsRequirements = true; - } - break; - } - - if (meetsRequirements && LINK_IS_ADULT && - (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) && - !Flags_GetTreasure(play, 0x1E) && player != NULL && !Player_InBlockingCsMode(play, player) && - play->transitionTrigger == TRANS_TRIGGER_OFF) { - GetItemEntry getItem = Randomizer_GetItemFromKnownCheck(check, GI_ARROW_LIGHT); - if (GiveItemEntryWithoutActor(play, getItem)) { - player->pendingFlag.flagID = 0x1E; - player->pendingFlag.flagType = FLAG_SCENE_TREASURE; - } - } -} - -void GivePlayerRandoRewardSariaGift(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - if (gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_ZELDAS_LULLABY); - - if (!Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE) && player != NULL && !Player_InBlockingCsMode(play, player)) { - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; - player->pendingFlag.flagID = 0xC1; - } - } -} - void Play_Init(GameState* thisx) { PlayState* play = (PlayState*)thisx; GraphicsContext* gfxCtx = play->state.gfxCtx; @@ -1448,15 +1331,6 @@ skip: Environment_Update(play, &play->envCtx, &play->lightCtx, &play->pauseCtx, &play->msgCtx, &play->gameOverCtx, play->state.gfxCtx); - - if (IS_RANDO) { - GivePlayerRandoRewardSariaGift(play, RC_LW_GIFT_FROM_SARIA); - GivePlayerRandoRewardSongOfTime(play, RC_SONG_FROM_OCARINA_OF_TIME); - GivePlayerRandoRewardZeldaLightArrowsGift(play, RC_TOT_LIGHT_ARROWS_CUTSCENE); - GivePlayerRandoRewardNocturne(play, RC_SHEIK_IN_KAKARIKO); - GivePlayerRandoRewardRequiem(play, RC_SHEIK_AT_COLOSSUS); - GivePlayerRandoRewardMasterSword(play, RC_TOT_MASTER_SWORD); - } } void Play_DrawOverlayElements(PlayState* play) { diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index dfffa7729..1f136674b 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -564,8 +564,8 @@ uint8_t Player_IsCustomLinkModel() { } s32 Player_InBlockingCsMode(PlayState* play, Player* this) { - return (this->stateFlags1 & 0x20000080) || (this->csAction != 0) || (play->transitionTrigger == TRANS_TRIGGER_START) || - (this->stateFlags1 & 1) || (this->stateFlags3 & 0x80) || + return (this->stateFlags1 & (PLAYER_STATE1_DEAD | PLAYER_STATE1_IN_CUTSCENE)) || (this->csAction != 0) || (play->transitionTrigger == TRANS_TRIGGER_START) || + (this->stateFlags1 & PLAYER_STATE1_LOADING) || (this->stateFlags3 & PLAYER_STATE3_HOOKSHOT_TRAVELLING) || ((gSaveContext.magicState != MAGIC_STATE_IDLE) && (Player_ActionToMagicSpell(this, this->itemAction) >= 0)); } diff --git a/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c b/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c index 86d23c45b..e05c171f0 100644 --- a/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c +++ b/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c @@ -6,6 +6,7 @@ #include "z_bg_bdan_switch.h" #include "objects/object_bdan_objects/object_bdan_objects.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -224,10 +225,12 @@ void func_8086D4B4(BgBdanSwitch* this, PlayState* play) { if (!Flags_GetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F)) { type = this->dyna.actor.params & 0xFF; Flags_SetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F); - if (type == BLUE || type == YELLOW_TALL_2) { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); - } else { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_CORRECT_CHIME); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + if (type == BLUE || type == YELLOW_TALL_2) { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + } else { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_CORRECT_CHIME); + } } } } @@ -236,7 +239,9 @@ void func_8086D548(BgBdanSwitch* this, PlayState* play) { if (Flags_GetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F)) { Flags_UnsetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F); if ((this->dyna.actor.params & 0xFF) == YELLOW_TALL_2) { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + } } } } diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c index 58f11a7f3..d0fc8864f 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c @@ -8,6 +8,7 @@ #include "scenes/dungeons/ddan/ddan_scene.h" #include "objects/object_bwall/object_bwall.h" #include "objects/object_kingdodongo/object_kingdodongo.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -300,10 +301,13 @@ void BgBreakwall_Wait(BgBreakwall* this, PlayState* play) { if ((wallType == BWALL_DC_ENTRANCE) && (!Flags_GetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN))) { Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN); - Cutscene_SetSegment(play, gDcOpeningCs); - gSaveContext.cutsceneTrigger = 1; + s32 flag = EVENTCHKINF_ENTERED_DODONGOS_CAVERN; + if (GameInteractor_Should(GI_VB_PLAY_ENTRANCE_CS, true, &flag)) { + Cutscene_SetSegment(play, gDcOpeningCs); + gSaveContext.cutsceneTrigger = 1; + func_8002DF54(play, NULL, 0x31); + } Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - func_8002DF54(play, NULL, 0x31); } if (this->dyna.actor.params < 0) { diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c b/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c index eeecfabcb..51b7dc622 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c @@ -6,6 +6,7 @@ #include "z_bg_mori_bigst.h" #include "objects/object_mori_objects/object_mori_objects.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -149,7 +150,9 @@ void BgMoriBigst_StalfosFight(BgMoriBigst* this, PlayState* play) { if ((this->dyna.actor.home.rot.z == 0) && ((this->dyna.actor.home.pos.y - 5.0f) <= GET_PLAYER(play)->actor.world.pos.y)) { BgMoriBigst_SetupFall(this, play); - OnePointCutscene_Init(play, 3220, 72, &this->dyna.actor, MAIN_CAM); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_Init(play, 3220, 72, &this->dyna.actor, MAIN_CAM); + } } } @@ -163,8 +166,10 @@ void BgMoriBigst_Fall(BgMoriBigst* this, PlayState* play) { this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; BgMoriBigst_SetupLanding(this, play); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND); - OnePointCutscene_Init(play, 1020, 8, &this->dyna.actor, MAIN_CAM); - func_8002DF38(play, NULL, 0x3C); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_Init(play, 1020, 8, &this->dyna.actor, MAIN_CAM); + func_8002DF38(play, NULL, 0x3C); + } } } diff --git a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c index 26a02aa96..b6d5ed15a 100644 --- a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c +++ b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c @@ -6,6 +6,7 @@ #include "z_bg_toki_swd.h" #include "objects/object_toki_objects/object_toki_objects.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -115,14 +116,17 @@ void func_808BAF40(BgTokiSwd* this, PlayState* play) { if (((Flags_GetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER)) == 0) && (gSaveContext.sceneSetupIndex < 4) && Actor_IsFacingAndNearPlayer(&this->actor, 800.0f, 0x7530) && !Play_InCsMode(play)) { Flags_SetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER); - play->csCtx.segment = D_808BBD90; - gSaveContext.cutsceneTrigger = 1; + s32 flag = EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER; + if (GameInteractor_Should(GI_VB_PLAY_ENTRANCE_CS, true, &flag)) { + play->csCtx.segment = D_808BBD90; + gSaveContext.cutsceneTrigger = 1; + } } if (!LINK_IS_ADULT || (Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && !IS_RANDO) || IS_RANDO) { if (Actor_HasParent(&this->actor, play)) { if (!LINK_IS_ADULT) { - if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_MASTER_SWORD, true, NULL)) { Item_Give(play, ITEM_SWORD_MASTER); } play->csCtx.segment = D_808BB2F0; diff --git a/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c b/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c index 75e920b29..04d1d6c72 100644 --- a/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c +++ b/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c @@ -7,6 +7,7 @@ #include "z_bg_treemouth.h" #include "objects/object_spot04_objects/object_spot04_objects.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -73,11 +74,7 @@ void BgTreemouth_Init(Actor* thisx, PlayState* play) { if ((gSaveContext.sceneSetupIndex < 4) && !LINK_IS_ADULT) { BgTreemouth_SetupAction(this, func_808BC8B8); - // If dungeon entrance randomizer is on, keep the tree mouth open - // when Link is adult and sword & shield have been shown to Mido - } else if ((LINK_IS_ADULT && (!IS_RANDO || - Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) == RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) || - !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) || (gSaveContext.sceneSetupIndex == 7)) { + } else if (LINK_IS_ADULT || (gSaveContext.sceneSetupIndex == 7)) { this->unk_168 = 0.0f; BgTreemouth_SetupAction(this, BgTreemouth_DoNothing); } else { @@ -157,9 +154,11 @@ void func_808BC8B8(BgTreemouth* this, PlayState* play) { } } else if (Actor_IsFacingAndNearPlayer(&this->dyna.actor, 1658.0f, 0x4E20)) { Flags_SetEventChkInf(EVENTCHKINF_MET_DEKU_TREE); - play->csCtx.segment = D_808BCE20; - gSaveContext.cutsceneTrigger = 1; - BgTreemouth_SetupAction(this, func_808BC9EC); + if (GameInteractor_Should(GI_VB_PLAY_DEKU_TREE_INTRO_CS, true, this)) { + play->csCtx.segment = D_808BCE20; + gSaveContext.cutsceneTrigger = 1; + BgTreemouth_SetupAction(this, func_808BC9EC); + } } } } else { diff --git a/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h b/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h index 7fe96cfa1..daa33bfee 100644 --- a/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h +++ b/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h @@ -15,4 +15,7 @@ typedef struct BgTreemouth { /* 0x016C */ BgTreemouthActionFunc actionFunc; } BgTreemouth; // size = 0x0170 +void BgTreemouth_SetupAction(BgTreemouth* actor, BgTreemouthActionFunc actionFunc); +void func_808BC6F8(BgTreemouth* actor, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c b/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c index 1c2f4c16b..cffdbea38 100644 --- a/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c +++ b/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c @@ -3,6 +3,7 @@ #include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -184,7 +185,9 @@ void func_80969F38(DemoDu* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0, DEMO_EFFECT_MEDAL_FIRE); - Item_Give(play, ITEM_MEDALLION_FIRE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FIRE_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FIRE); + } } void func_80969FB4(DemoDu* this, PlayState* play) { @@ -201,7 +204,9 @@ void DemoDu_CsFireMedallion_AdvanceTo01(DemoDu* this, PlayState* play) { this->updateIndex = CS_FIREMEDALLION_SUBSCENE(1); play->csCtx.segment = D_8096C1A4; gSaveContext.cutsceneTrigger = 2; - Item_Give(play, ITEM_MEDALLION_FIRE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FIRE_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FIRE); + } player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000; } diff --git a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c index 9e4dd6119..4af2e9f87 100644 --- a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c +++ b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c @@ -142,7 +142,7 @@ f32 DemoEffect_InterpolateCsFrames(PlayState* play, s32 csActionId) { */ void DemoEffect_InitJewel(PlayState* play, DemoEffect* this) { this->initDrawFunc = DemoEffect_DrawJewel; - if (IS_RANDO && play->sceneNum == SCENE_JABU_JABU) { + if (IS_RANDO && (play->sceneNum != SCENE_TEMPLE_OF_TIME || this->actor.params == DEMO_EFFECT_LIGHTARROW)) { this->initDrawFunc = DemoEffect_DrawGetItem; } if (!LINK_IS_ADULT) { @@ -156,7 +156,7 @@ void DemoEffect_InitJewel(PlayState* play, DemoEffect* this) { Actor_SetScale(&this->actor, 0.10f); } this->csActionId = 1; - this->actor.shape.rot.x = (IS_RANDO && play->sceneNum == SCENE_JABU_JABU) ? 0 : 16384; + this->actor.shape.rot.x = (IS_RANDO && (play->sceneNum != SCENE_TEMPLE_OF_TIME || this->actor.params == DEMO_EFFECT_LIGHTARROW)) ? 0 : 16384; DemoEffect_InitJewelColor(this); this->jewel.alpha = 0; this->jewelCsRotation.x = this->jewelCsRotation.y = this->jewelCsRotation.z = 0; @@ -2087,13 +2087,48 @@ void DemoEffect_DrawGetItem(Actor* thisx, PlayState* play) { this->getItem.isLoaded = 1; return; } - if (IS_RANDO && play->sceneNum == SCENE_JABU_JABU) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE); - this->getItem.drawId = getItemEntry.gid; - func_8002EBCC(thisx, play, 0); - func_8002ED80(thisx, play, 0); - GetItemEntry_Draw(play, getItemEntry); - return; + if (IS_RANDO && (play->sceneNum != SCENE_TEMPLE_OF_TIME || this->actor.params == DEMO_EFFECT_LIGHTARROW)) { + GetItemEntry getItemEntry = GET_ITEM_NONE; + + switch (this->actor.params) { + case DEMO_EFFECT_JEWEL_KOKIRI: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_QUEEN_GOHMA, RG_KOKIRI_EMERALD); + break; + case DEMO_EFFECT_JEWEL_GORON: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KING_DODONGO, RG_GORON_RUBY); + break; + case DEMO_EFFECT_JEWEL_ZORA: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE); + break; + case DEMO_EFFECT_MEDAL_FOREST: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_PHANTOM_GANON, RG_FOREST_MEDALLION); + break; + case DEMO_EFFECT_MEDAL_FIRE: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_VOLVAGIA, RG_FIRE_MEDALLION); + break; + case DEMO_EFFECT_MEDAL_WATER: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MORPHA, RG_WATER_MEDALLION); + break; + case DEMO_EFFECT_MEDAL_SPIRIT: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TWINROVA, RG_SPIRIT_MEDALLION); + break; + case DEMO_EFFECT_MEDAL_SHADOW: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BONGO_BONGO, RG_SHADOW_MEDALLION); + break; + case DEMO_EFFECT_MEDAL_LIGHT: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GIFT_FROM_SAGES, RG_LIGHT_MEDALLION); + break; + case DEMO_EFFECT_LIGHTARROW: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS); + break; + } + if (getItemEntry.getItemId != GI_NONE) { + this->getItem.drawId = getItemEntry.gid; + func_8002EBCC(thisx, play, 0); + func_8002ED80(thisx, play, 0); + GetItemEntry_Draw(play, getItemEntry); + return; + } } func_8002EBCC(thisx, play, 0); func_8002ED80(thisx, play, 0); diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c index 4ddeec155..a06786b2d 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c @@ -10,6 +10,7 @@ #include "scenes/indoors/nakaniwa/nakaniwa_scene.h" #include "objects/object_im/object_im.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -318,7 +319,9 @@ void func_809853B4(DemoIm* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, playerX, playerY, playerZ, 0, 0, 0, 0xD); - Item_Give(play, ITEM_MEDALLION_SHADOW); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SHADOW_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_SHADOW); + } } void func_80985430(DemoIm* this, PlayState* play) { @@ -334,7 +337,9 @@ void func_8098544C(DemoIm* this, PlayState* play) { this->action = 1; play->csCtx.segment = D_8098786C; gSaveContext.cutsceneTrigger = 2; - Item_Give(play, ITEM_MEDALLION_SHADOW); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SHADOW_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_SHADOW); + } player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000; } } @@ -903,40 +908,17 @@ void func_80986BF8(DemoIm* this, PlayState* play) { } } -void GivePlayerRandoRewardImpa(Actor* impa, PlayState* play, RandomizerCheck check) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_ZELDAS_LULLABY); - - if (impa->parent != NULL && impa->parent->id == GET_PLAYER(play)->actor.id && - !Flags_GetTreasure(play, 0x1F)) { - Flags_SetTreasure(play, 0x1F); - } else if (!Flags_GetTreasure(play, 0x1F) && !Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) { - GiveItemEntryFromActor(impa, play, getItemEntry, 75.0f, 50.0f); - } else if (!Player_InBlockingCsMode(play, GET_PLAYER(play))) { - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_WHITE; - gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; - // In entrance rando have impa bring link back to the front of castle grounds - if (Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) { - play->nextEntranceIndex = ENTR_HYRULE_CASTLE_0; - } else { - play->nextEntranceIndex = ENTR_HYRULE_FIELD_17; - } - gSaveContext.nextCutsceneIndex = 0; - } -} - void func_80986C30(DemoIm* this, PlayState* play) { if (func_80986A5C(this, play)) { - if (IS_RANDO) { - GivePlayerRandoRewardImpa(this, play, RC_SONG_FROM_IMPA); - } else { + if (GameInteractor_Should(GI_VB_PLAY_ZELDAS_LULLABY_CS, true, this)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gZeldasCourtyardLullabyCs); gSaveContext.cutsceneTrigger = 1; - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); - Item_Give(play, ITEM_SONG_LULLABY); func_80985F54(this); } + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LULLABY, true, NULL)) { + Item_Give(play, ITEM_SONG_LULLABY); + } } } @@ -960,7 +942,7 @@ void func_80986D40(DemoIm* this, PlayState* play) { if (gSaveContext.sceneSetupIndex == 6) { this->action = 19; this->drawConfig = 1; - } else if ((Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) && !IS_RANDO) { + } else if ((Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) && !IS_RANDO) { // SoH [Randomizer] Not sure why we're not killing impa here. Actor_Kill(&this->actor); } else if (!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY)) { this->action = 23; diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h index 3697733e1..06d6e5d7e 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h @@ -51,4 +51,6 @@ typedef struct DemoIm { /* 0x02D4 */ NpcInteractInfo interactInfo; } DemoIm; // size = 0x02FC +void func_80986794(DemoIm* demoIm); + #endif diff --git a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c index 6da87ab3c..85dcb4ebe 100644 --- a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c +++ b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c @@ -9,6 +9,7 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "objects/object_sa/object_sa.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "vt.h" @@ -241,7 +242,9 @@ void func_8098E8C8(DemoSa* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0, 0xB); - Item_Give(play, ITEM_MEDALLION_FOREST); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FOREST_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FOREST); + } } void func_8098E944(DemoSa* this, PlayState* play) { @@ -258,7 +261,9 @@ void func_8098E960(DemoSa* this, PlayState* play) { this->action = 1; play->csCtx.segment = D_8099010C; gSaveContext.cutsceneTrigger = 2; - Item_Give(play, ITEM_MEDALLION_FOREST); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FOREST_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FOREST); + } player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000; } else { this->action = 1; diff --git a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index 290e809f6..eeb0df2d2 100644 --- a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -23,6 +23,7 @@ #include "objects/object_menkuri_objects/object_menkuri_objects.h" #include "objects/object_demo_kekkai/object_demo_kekkai.h" #include "objects/object_ouke_haka/object_ouke_haka.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -354,9 +355,11 @@ void func_80996A54(DoorShutter* this, PlayState* play) { if (Flags_GetClear(play, this->dyna.actor.room) || Flags_GetTempClear(play, this->dyna.actor.room)) { Flags_SetClear(play, this->dyna.actor.room); DoorShutter_SetupAction(this, func_80997150); - OnePointCutscene_Attention(play, &this->dyna.actor); - OnePointCutscene_Attention(play, &GET_PLAYER(play)->actor); - this->unk_16F = -100; + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_Attention(play, &this->dyna.actor); + OnePointCutscene_Attention(play, &GET_PLAYER(play)->actor); + this->unk_16F = -100; + } } else if (func_809968D4(this, play) != 0) { Player* player = GET_PLAYER(play); @@ -470,8 +473,10 @@ void func_80996EE8(DoorShutter* this, PlayState* play) { if (func_80996E08(this, play, 1.0f)) { if (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { DoorShutter_SetupAction(this, func_80997150); - OnePointCutscene_Attention(play, &this->dyna.actor); - this->unk_16F = -100; + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_Attention(play, &this->dyna.actor); + this->unk_16F = -100; + } } else if (func_809968D4(this, play)) { Player* player = GET_PLAYER(play); // Jabu navi text for switch doors is different diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index 5ea64e232..bdb154a92 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -2,6 +2,7 @@ #include "objects/object_warp1/object_warp1.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -487,44 +488,6 @@ s32 DoorWarp1_PlayerInRange(DoorWarp1* this, PlayState* play) { return ret; } -void GivePlayerRandoReward(DoorWarp1* this, Player* player, PlayState* play, u8 ruto, u8 adult) { - GetItemEntry getItemEntry = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, 0x00, GI_NONE); - - if (this->actor.parent != NULL && this->actor.parent->id == GET_PLAYER(play)->actor.id && - !Flags_GetTreasure(play, 0x1F)) { - Flags_SetTreasure(play, 0x1F); - } else if (!Flags_GetTreasure(play, 0x1F)) { - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 100.0f); - } else if (!Player_InBlockingCsMode(play, GET_PLAYER(play))) { - if (adult) { - OnePointCutscene_Init(play, 0x25E8, 999, &this->actor, MAIN_CAM); - func_8002DF54(play, &this->actor, 10); - player->unk_450.x = this->actor.world.pos.x; - player->unk_450.z = this->actor.world.pos.z; - this->unk_1B2 = 20; - DoorWarp1_SetupAction(this, func_8099A508); - } else { - if (ruto) { - this->rutoWarpState = WARP_BLUE_RUTO_STATE_ENTERED; - func_8002DF54(play, &this->actor, 10); - this->unk_1B2 = 1; - DoorWarp1_SetupAction(this, func_80999EE0); - } else { - Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); - OnePointCutscene_Init(play, 0x25E7, 999, &this->actor, MAIN_CAM); - func_8002DF54(play, &this->actor, 10); - - player->unk_450.x = this->actor.world.pos.x; - player->unk_450.z = this->actor.world.pos.z; - this->unk_1B2 = 1; - - DoorWarp1_SetupAction(this, DoorWarp1_ChildWarpOut); - } - } - } -} - void DoorWarp1_ChildWarpIdle(DoorWarp1* this, PlayState* play) { Player* player; @@ -532,11 +495,6 @@ void DoorWarp1_ChildWarpIdle(DoorWarp1* this, PlayState* play) { if (DoorWarp1_PlayerInRange(this, play)) { player = GET_PLAYER(play); - - if (IS_RANDO) { - GivePlayerRandoReward(this, player, play, 0, 0); - return; - } Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); @@ -570,36 +528,26 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) { osSyncPrintf("\n\n\nじかんがきたからおーしまい fade_direction=[%d]", play->transitionTrigger, TRANS_TRIGGER_START); if (play->sceneNum == SCENE_DODONGOS_CAVERN_BOSS) { - if (!Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP), EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) { Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN); - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; - gSaveContext.nextCutsceneIndex = 0; - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_GORON_RUBY)) { Item_Give(play, ITEM_GORON_RUBY); - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; - gSaveContext.nextCutsceneIndex = 0xFFF1; } + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; + gSaveContext.nextCutsceneIndex = 0xFFF1; } else { play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_DEKU_TREE_BOSS) { - if (!Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD) || IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD), EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD)) { Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD); Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE); - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11; - gSaveContext.nextCutsceneIndex = 0; - // Skip Mido complaining about dead Deku tree - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH); - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_KOKIRI_EMERALD)) { Item_Give(play, ITEM_KOKIRI_EMERALD); - play->nextEntranceIndex = ENTR_KOKIRI_FOREST_0; - gSaveContext.nextCutsceneIndex = 0xFFF1; } + play->nextEntranceIndex = ENTR_KOKIRI_FOREST_0; + gSaveContext.nextCutsceneIndex = 0xFFF1; } else { play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11; gSaveContext.nextCutsceneIndex = 0; @@ -635,12 +583,6 @@ void DoorWarp1_RutoWarpIdle(DoorWarp1* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_WARP_HOLE - SFX_FLAG); if (this->rutoWarpState != WARP_BLUE_RUTO_STATE_INITIAL && DoorWarp1_PlayerInRange(this, play)) { - - if (IS_RANDO) { - GivePlayerRandoReward(this, GET_PLAYER(play), play, 1, 0); - return; - } - this->rutoWarpState = WARP_BLUE_RUTO_STATE_ENTERED; func_8002DF54(play, &this->actor, 10); this->unk_1B2 = 1; @@ -670,9 +612,8 @@ void func_80999EE0(DoorWarp1* this, PlayState* play) { Play_CameraSetAtEye(play, sRutoWarpSubCamId, &at, &eye); Play_CameraSetFov(play, sRutoWarpSubCamId, 90.0f); this->rutoWarpState = WARP_BLUE_RUTO_STATE_TALKING; - if (!IS_RANDO) { - Message_StartTextbox(play, 0x4022, NULL); - } + // TODO: Why was this disabled in rando? + Message_StartTextbox(play, 0x4022, NULL); DoorWarp1_SetupAction(this, func_80999FE4); } } @@ -704,17 +645,14 @@ void DoorWarp1_RutoWarpOut(DoorWarp1* this, PlayState* play) { this->warpTimer++; if (this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF) { - Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; - gSaveContext.nextCutsceneIndex = 0; - } else { - Item_Give(play, ITEM_ZORA_SAPPHIRE); - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, true, EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP)) { + Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_ZORA_SAPPHIRE)) { + Item_Give(play, ITEM_ZORA_SAPPHIRE); + } gSaveContext.nextCutsceneIndex = 0xFFF0; } + play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; if (IS_RANDO && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) { @@ -767,11 +705,6 @@ void DoorWarp1_AdultWarpIdle(DoorWarp1* this, PlayState* play) { player = GET_PLAYER(play); - if (IS_RANDO) { - GivePlayerRandoReward(this, player, play, 0, 1); - return; - } - OnePointCutscene_Init(play, 0x25E8, 999, &this->actor, MAIN_CAM); func_8002DF54(play, &this->actor, 10); player->unk_450.x = this->actor.world.pos.x; @@ -829,19 +762,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (IS_BOSS_RUSH) { BossRush_HandleBlueWarp(play, this->actor.world.pos.x, this->actor.world.pos.z); } else if (play->sceneNum == SCENE_FOREST_TEMPLE_BOSS) { - if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) { Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_3; - gSaveContext.nextCutsceneIndex = 0; - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FOREST)) { Item_Give(play, ITEM_MEDALLION_FOREST); - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_FOREST; } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_FOREST; } else { if (!LINK_IS_ADULT) { play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_2; @@ -851,20 +779,13 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_FIRE_TEMPLE_BOSS) { - if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5; - gSaveContext.nextCutsceneIndex = 0; - // Change Death Mountain cloud since we aren't warping to the cutscene - Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED); - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FIRE)) { Item_Give(play, ITEM_MEDALLION_FIRE); - play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; - gSaveContext.nextCutsceneIndex = 0xFFF3; } + play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; + gSaveContext.nextCutsceneIndex = 0xFFF3; } else { if (!LINK_IS_ADULT) { play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_4; @@ -874,21 +795,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_WATER_TEMPLE_BOSS) { - if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_LAKE_HYLIA_9; - gSaveContext.nextCutsceneIndex = 0; - // Fill Lake Hylia since we aren't warping to the cutscene - Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_WATER)) { Item_Give(play, ITEM_MEDALLION_WATER); - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_WATER; } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_WATER; } else { if (!LINK_IS_ADULT) { play->nextEntranceIndex = ENTR_LAKE_HYLIA_8; @@ -898,18 +812,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) { - if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) || IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT), RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE)) { Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_8; - gSaveContext.nextCutsceneIndex = 0; - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SPIRIT)) { Item_Give(play, ITEM_MEDALLION_SPIRIT); - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_SPIRIT; } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_SPIRIT; } else { if (!LINK_IS_ADULT) { play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_5; @@ -919,18 +829,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) { - if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) || IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW), RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE)) { Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE); - - if (IS_RANDO) { - play->nextEntranceIndex = ENTR_GRAVEYARD_8; - gSaveContext.nextCutsceneIndex = 0; - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SHADOW)) { Item_Give(play, ITEM_MEDALLION_SHADOW); - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_SHADOW; } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_SHADOW; } else { if (!LINK_IS_ADULT) { play->nextEntranceIndex = ENTR_GRAVEYARD_7; diff --git a/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c b/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c index 3fe7fc689..495ef96b8 100644 --- a/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c +++ b/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c @@ -7,6 +7,7 @@ #include "z_elf_msg.h" #include "vt.h" #include "overlays/actors/ovl_En_Elf/z_en_elf.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -110,7 +111,7 @@ void ElfMsg_Destroy(Actor* thisx, PlayState* play) { s32 ElfMsg_GetMessageId(ElfMsg* this) { // Negative message ID forces link to talk to Navi - if (this->actor.params & 0x8000 || CVarGetInteger("gNoForcedNavi", 0) != 0) { + if (this->actor.params & 0x8000) { return (this->actor.params & 0xFF) + 0x100; } else { return -((this->actor.params & 0xFF) + 0x100); @@ -125,8 +126,10 @@ void ElfMsg_CallNaviCuboid(ElfMsg* this, PlayState* play) { (this->actor.world.pos.y <= player->actor.world.pos.y) && ((player->actor.world.pos.y - this->actor.world.pos.y) < (100.0f * this->actor.scale.y)) && (fabsf(player->actor.world.pos.z - this->actor.world.pos.z) < (100.0f * this->actor.scale.z))) { - player->naviTextId = ElfMsg_GetMessageId(this); - navi->elfMsg = this; + if (GameInteractor_Should(GI_VB_NAVI_TALK, true, this)) { + player->naviTextId = ElfMsg_GetMessageId(this); + navi->elfMsg = this; + } } } @@ -145,8 +148,10 @@ void ElfMsg_CallNaviCylinder(ElfMsg* this, PlayState* play) { if (ElfMsg_WithinXZDistance(&player->actor.world.pos, &this->actor.world.pos, this->actor.scale.x * 100.0f) && (this->actor.world.pos.y <= player->actor.world.pos.y) && ((player->actor.world.pos.y - this->actor.world.pos.y) < (100.0f * this->actor.scale.y))) { - player->naviTextId = ElfMsg_GetMessageId(this); - navi->elfMsg = this; + if (GameInteractor_Should(GI_VB_NAVI_TALK, true, this)) { + player->naviTextId = ElfMsg_GetMessageId(this); + navi->elfMsg = this; + } } } diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c index a4d86ff61..e01573c9b 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -3,6 +3,7 @@ #include "soh_assets.h" #include "soh/Enhancements/enhancementTypes.h" #include <assert.h> +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -192,10 +193,12 @@ void EnBox_Init(Actor* thisx, PlayState* play2) { SkelAnime_Init(play, &this->skelanime, &gTreasureChestSkel, anim, this->jointTable, this->morphTable, 5); Animation_Change(&this->skelanime, anim, 1.5f, animFrameStart, endFrame, ANIMMODE_ONCE, 0.0f); + this->getItemEntry = ItemTable_RetrieveEntry(MOD_NONE, this->dyna.actor.params >> 5 & 0x7F); if (IS_RANDO) { - this->getItemEntry = Randomizer_GetItemFromActor(this->dyna.actor.id, play->sceneNum, this->dyna.actor.params, this->dyna.actor.params >> 5 & 0x7F); - } else { - this->getItemEntry = ItemTable_RetrieveEntry(MOD_NONE, this->dyna.actor.params >> 5 & 0x7F); + RandomizerCheck rc = Randomizer_GetCheckFromActor(this->dyna.actor.id, play->sceneNum, this->dyna.actor.params); + if (rc != RC_UNKNOWN_CHECK) { + this->getItemEntry = Randomizer_GetItemFromKnownCheck(rc, this->dyna.actor.params >> 5 & 0x7F); + } } EnBox_UpdateSizeAndTexture(this, play); @@ -275,7 +278,9 @@ void EnBox_Fall(EnBox* this, PlayState* play) { this->dyna.actor.shape.rot.z = 0; this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight; EnBox_SetupAction(this, EnBox_WaitOpen); - OnePointCutscene_EndCutscene(play, this->unk_1AC); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_EndCutscene(play, this->unk_1AC); + } } Audio_PlaySoundGeneral(NA_SE_EV_COFFIN_CAP_BOUND, &this->dyna.actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); @@ -445,74 +450,12 @@ void EnBox_WaitOpen(EnBox* this, PlayState* play) { } osSyncPrintf("Actor_Environment_Tbox_On() %d\n", this->dyna.actor.params & 0x1F); Flags_SetTreasure(play, this->dyna.actor.params & 0x1F); - - // treasure chest game rando - if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { - if (IS_RANDO && play->sceneNum == SCENE_TREASURE_BOX_SHOP && (this->dyna.actor.params & 0x60) != 0x20) { - if((this->dyna.actor.params & 0xF) < 2) { - Flags_SetCollectible(play, 0x1B); - } - if((this->dyna.actor.params & 0xF) >= 2 && (this->dyna.actor.params & 0xF) < 4) { - Flags_SetCollectible(play, 0x1C); - } - if((this->dyna.actor.params & 0xF) >= 4 && (this->dyna.actor.params & 0xF) < 6) { - Flags_SetCollectible(play, 0x1D); - } - if((this->dyna.actor.params & 0xF) >= 6 && (this->dyna.actor.params & 0xF) < 8) { - Flags_SetCollectible(play, 0x1E); - } - if((this->dyna.actor.params & 0xF) >= 8 && (this->dyna.actor.params & 0xF) < 10) { - Flags_SetCollectible(play, 0x1F); - } - } - } } else { player = GET_PLAYER(play); func_8002DBD0(&this->dyna.actor, &sp4C, &player->actor.world.pos); if (sp4C.z > -50.0f && sp4C.z < 0.0f && fabsf(sp4C.y) < 10.0f && fabsf(sp4C.x) < 20.0f && Player_IsFacingActor(&this->dyna.actor, 0x3000, play)) { - GetItemEntry sItem = Randomizer_GetItemFromActor(this->dyna.actor.id, play->sceneNum, this->dyna.actor.params, this->dyna.actor.params >> 5 & 0x7F); - GetItemEntry blueRupee = ItemTable_RetrieveEntry(MOD_NONE, GI_RUPEE_BLUE); - - // RANDOTODO treasure chest game rando - if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { - if (IS_RANDO && play->sceneNum == SCENE_TREASURE_BOX_SHOP && (this->dyna.actor.params & 0x60) != 0x20) { - if((this->dyna.actor.params & 0xF) < 2) { - if(Flags_GetCollectible(play, 0x1B)) { - sItem = blueRupee; - } - } - if((this->dyna.actor.params & 0xF) >= 2 && (this->dyna.actor.params & 0xF) < 4) { - if(Flags_GetCollectible(play, 0x1C)) { - sItem = blueRupee; - } - } - if((this->dyna.actor.params & 0xF) >= 4 && (this->dyna.actor.params & 0xF) < 6) { - if(Flags_GetCollectible(play, 0x1D)) { - sItem = blueRupee; - } - } - if((this->dyna.actor.params & 0xF) >= 6 && (this->dyna.actor.params & 0xF) < 8) { - if(Flags_GetCollectible(play, 0x1E)) { - sItem = blueRupee; - } - } - if((this->dyna.actor.params & 0xF) >= 8 && (this->dyna.actor.params & 0xF) < 10) { - if(Flags_GetCollectible(play, 0x1F)) { - sItem = blueRupee; - } - } - } - } - // Chests need to have a negative getItemId in order to not immediately give their item - // when approaching. - if (IS_RANDO) { - sItem.getItemId = 0 - sItem.getItemId; - sItem.getItemFrom = ITEM_FROM_CHEST; - GiveItemEntryFromActorWithFixedRange(&this->dyna.actor, play, sItem); - } else { func_8002F554(&this->dyna.actor, play, -(this->dyna.actor.params >> 5 & 0x7F)); - } } if (Flags_GetTreasure(play, this->dyna.actor.params & 0x1F)) { EnBox_SetupAction(this, EnBox_Open); @@ -626,12 +569,9 @@ void EnBox_Update(Actor* thisx, PlayState* play) { Actor_SetFocus(&this->dyna.actor, 40.0f); } - if (((!IS_RANDO && ((this->dyna.actor.params >> 5 & 0x7F) == 0x7C)) || - (IS_RANDO && this->getItemEntry.getItemId == RG_ICE_TRAP)) && - this->actionFunc == EnBox_Open && this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100) { - if (!CVarGetInteger("gAddTraps.enabled", 0)) { - EnBox_SpawnIceSmoke(this, play); - } + if ((this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open && + this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100) { + EnBox_SpawnIceSmoke(this, play); } } diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.h b/soh/src/overlays/actors/ovl_En_Box/z_en_box.h index 765779367..0168fc1a8 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.h +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.h @@ -4,6 +4,7 @@ #include <libultraship/libultra.h> #include "global.h" +#define ENBOX_PARAMS(type, itemId, treasureFlag) ((type) << 12 | (itemId) << 5 | (treasureFlag)) #define ENBOX_TREASURE_FLAG_UNK_MIN 20 #define ENBOX_TREASURE_FLAG_UNK_MAX 32 @@ -45,7 +46,7 @@ typedef struct EnBox { /* 0x01F9 */ u8 type; /* 0x01FA */ u8 iceSmokeTimer; /* 0x01FB */ u8 unk_1FB; - /* */ GetItemEntry getItemEntry; + /* */ GetItemEntry getItemEntry; // This is only to determine the Chest Style, randomzier item gives are handled elsewhere /* */ Gfx* boxLidDL; /* */ Gfx* boxBodyDL; } EnBox; // size = 0x01FC diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index 04123c7b3..b2bd6d65c 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -6,6 +6,7 @@ #include "z_en_cow.h" #include "objects/object_cow/object_cow.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -18,7 +19,6 @@ void func_809E0070(Actor* thisx, PlayState* play); void func_809DF494(EnCow* this, PlayState* play); void func_809DF6BC(EnCow* this, PlayState* play); -void EnCow_MoveForRandomizer(EnCow* this, PlayState* play); void func_809DF778(EnCow* this, PlayState* play); void func_809DF7D8(EnCow* this, PlayState* play); void func_809DF870(EnCow* this, PlayState* play); @@ -107,10 +107,6 @@ void EnCow_Init(Actor* thisx, PlayState* play) { EnCow* this = (EnCow*)thisx; s32 pad; - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_COWS)) { - EnCow_MoveForRandomizer(thisx, play); - } - ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 72.0f); switch (this->actor.params) { case 0: @@ -122,18 +118,15 @@ void EnCow_Init(Actor* thisx, PlayState* play) { Collider_SetCylinder(play, &this->colliders[1], &this->actor, &sCylinderInit); func_809DEE9C(this); this->actionFunc = func_809DF96C; - if (play->sceneNum == SCENE_LINKS_HOUSE) { - if (!LINK_IS_ADULT && !CVarGetInteger("gCowOfTime", 0)) { - Actor_Kill(&this->actor); - return; - } - if (!Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE)) { - Actor_Kill(&this->actor); - return; - } + if (GameInteractor_Should(GI_VB_DESPAWN_HORSE_RACE_COW, ( + play->sceneNum == SCENE_LINKS_HOUSE && (!LINK_IS_ADULT || !Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE)) + ), this)) { + Actor_Kill(&this->actor); + return; } + Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_COW, this->actor.world.pos.x, - this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 1); + this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 1); this->unk_278 = Rand_ZeroFloat(1000.0f) + 40.0f; this->unk_27A = 0; this->actor.targetMode = 6; @@ -216,30 +209,6 @@ void func_809DF730(EnCow* this, PlayState* play) { } } -void EnCow_MoveForRandomizer(EnCow* this, PlayState* play) { - // Only move the cow body (the tail will be moved with the body) - if (this->actor.params != 0) { - return; - } - - // Move left cow in lon lon tower - if (play->sceneNum == SCENE_LON_LON_BUILDINGS && this->actor.world.pos.x == -108 && this->actor.world.pos.z == -65) { - this->actor.world.pos.x = -229.0f; - this->actor.world.pos.z = 157.0f; - this->actor.shape.rot.y = 15783.0f; - // Move right cow in lon lon stable - } else if (play->sceneNum == SCENE_STABLE && this->actor.world.pos.x == -3 && this->actor.world.pos.z == -254) { - this->actor.world.pos.x += 119.0f; - } -} - -void EnCow_SetCowMilked(EnCow* this, PlayState* play) { - CowIdentity cowIdentity = Randomizer_IdentifyCow(play->sceneNum, this->actor.world.pos.x, this->actor.world.pos.z); - Player* player = GET_PLAYER(play); - player->pendingFlag.flagID = cowIdentity.randomizerInf; - player->pendingFlag.flagType = FLAG_RANDOMIZER_INF; -} - void func_809DF778(EnCow* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->actor.parent = NULL; @@ -281,23 +250,6 @@ void func_809DF8FC(EnCow* this, PlayState* play) { func_809DF494(this, play); } -bool EnCow_HasBeenMilked(EnCow* this, PlayState* play) { - CowIdentity cowIdentity = Randomizer_IdentifyCow(play->sceneNum, this->actor.world.pos.x, this->actor.world.pos.z); - return Flags_GetRandomizerInf(cowIdentity.randomizerInf); -} - -void EnCow_GivePlayerRandomizedItem(EnCow* this, PlayState* play) { - if (!EnCow_HasBeenMilked(this, play)) { - CowIdentity cowIdentity = Randomizer_IdentifyCow(play->sceneNum, this->actor.world.pos.x, this->actor.world.pos.z); - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(cowIdentity.randomizerCheck, GI_MILK); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 100.0f); - } else { - // once we've gotten the rando reward from the cow, - // return them to the their default action function - this->actionFunc = func_809DF96C; - } -} - void func_809DF96C(EnCow* this, PlayState* play) { if ((play->msgCtx.ocarinaMode == OCARINA_MODE_00) || (play->msgCtx.ocarinaMode == OCARINA_MODE_04)) { if (DREG(53) != 0) { @@ -308,23 +260,14 @@ void func_809DF96C(EnCow* this, PlayState* play) { if ((this->actor.xzDistToPlayer < 150.0f) && (ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 0x61A8)) { DREG(53) = 0; - // when randomized with cowsanity, if we haven't gotten the - // reward from this cow yet, give that, otherwise use the - // vanilla cow behavior - if (IS_RANDO && - Randomizer_GetSettingValue(RSK_SHUFFLE_COWS) && - !EnCow_HasBeenMilked(this, play)) { - EnCow_SetCowMilked(this, play); - // setting the ocarina mode here prevents intermittent issues - // with the item get not triggering until walking away - play->msgCtx.ocarinaMode = OCARINA_MODE_00; - this->actionFunc = EnCow_GivePlayerRandomizedItem; + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_COW, true, this)) { + this->actionFunc = func_809DF8FC; + this->actor.flags |= ACTOR_FLAG_WILL_TALK; + func_8002F2CC(&this->actor, play, 170.0f); + this->actor.textId = 0x2006; + } else { return; } - this->actionFunc = func_809DF8FC; - this->actor.flags |= ACTOR_FLAG_WILL_TALK; - func_8002F2CC(&this->actor, play, 170.0f); - this->actor.textId = 0x2006; } else { this->unk_276 |= 4; } diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h index 63dbbddd3..3cd244388 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.h @@ -21,4 +21,6 @@ typedef struct EnCow { /* 0x027C */ EnCowActionFunc actionFunc; } EnCow; // size = 0x0280 +void func_809DEE9C(EnCow* enCow); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c index 0dd33a8ac..09a5e6cd1 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -16,7 +16,6 @@ void EnDns_Destroy(Actor* thisx, PlayState* play); void EnDns_Update(Actor* thisx, PlayState* play); void EnDns_Draw(Actor* thisx, PlayState* play); -u32 EnDns_RandomizerPurchaseableCheck(EnDns* this); u32 func_809EF5A4(EnDns* this); u32 func_809EF658(EnDns* this); u32 func_809EF70C(EnDns* this); @@ -26,7 +25,6 @@ u32 func_809EF854(EnDns* this); u32 func_809EF8F4(EnDns* this); u32 func_809EF9A4(EnDns* this); -void EnDns_RandomizerPurchase(EnDns* this); void func_809EF9F8(EnDns* this); void func_809EFA28(EnDns* this); void func_809EFA58(EnDns* this); @@ -168,32 +166,6 @@ void EnDns_Init(Actor* thisx, PlayState* play) { this->actor.gravity = -1.0f; this->actor.textId = D_809F040C[this->actor.params]; this->dnsItemEntry = sItemEntries[this->actor.params]; - if (IS_RANDO) { - // Ugly, but the best way we can identify which grotto we are in, same method 3DRando uses, but we'll need to account for entrance rando - s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - this->scrubIdentity = Randomizer_IdentifyScrub(play->sceneNum, this->actor.params, respawnData); - - if ((Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_AFFORDABLE || - Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_RANDOM) && - this->scrubIdentity.itemPrice != -1) { - this->dnsItemEntry->itemPrice = this->scrubIdentity.itemPrice; - } - - if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_EXPENSIVE) { - // temporary workaround: always use 40 rupees as price instead of 70 - if (this->actor.params == 0x0006) { - this->dnsItemEntry->itemPrice = 40; - } - } - - if (this->scrubIdentity.isShuffled) { - this->dnsItemEntry->getItemId = this->scrubIdentity.getItemId; - this->dnsItemEntry->purchaseableCheck = EnDns_RandomizerPurchaseableCheck; - this->dnsItemEntry->setRupeesAndFlags = EnDns_RandomizerPurchase; - this->dnsItemEntry->itemAmount = 1; - this->actor.textId = 0x9000 + (this->scrubIdentity.randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT); - } - } this->actionFunc = EnDns_SetupWait; } @@ -216,13 +188,6 @@ void EnDns_ChangeAnim(EnDns* this, u8 index) { /* Item give checking functions */ -u32 EnDns_RandomizerPurchaseableCheck(EnDns* this) { - if (gSaveContext.rupees < this->dnsItemEntry->itemPrice || Flags_GetRandomizerInf(this->scrubIdentity.randomizerInf)) { - return 0; - } - return 4; -} - u32 func_809EF5A4(EnDns* this) { if ((CUR_CAPACITY(UPG_NUTS) != 0) && (AMMO(ITEM_NUT) >= CUR_CAPACITY(UPG_NUTS))) { return 1; @@ -319,10 +284,6 @@ u32 func_809EF9A4(EnDns* this) { } /* Paying and flagging functions */ -void EnDns_RandomizerPurchase(EnDns* this) { - Rupees_ChangeBy(-this->dnsItemEntry->itemPrice); - Flags_SetRandomizerInf(this->scrubIdentity.randomizerInf); -} void func_809EF9F8(EnDns* this) { Rupees_ChangeBy(-this->dnsItemEntry->itemPrice); @@ -412,44 +373,39 @@ void EnDns_Talk(EnDns* this, PlayState* play) { void func_809EFDD0(EnDns* this, PlayState* play) { u16 pendingGetItemId; - if (!IS_RANDO || !this->scrubIdentity.isShuffled) { - if (this->actor.params == 0x9) { - if (CUR_UPG_VALUE(UPG_STICKS) < 2) { - pendingGetItemId = GI_STICK_UPGRADE_20; - } else { - pendingGetItemId = GI_STICK_UPGRADE_30; - } - } else if (this->actor.params == 0xA) { - if (CUR_UPG_VALUE(UPG_NUTS) < 2) { - pendingGetItemId = GI_NUT_UPGRADE_30; - } else { - pendingGetItemId = GI_NUT_UPGRADE_40; - } + if (this->actor.params == 0x9) { + if (CUR_UPG_VALUE(UPG_STICKS) < 2) { + pendingGetItemId = GI_STICK_UPGRADE_20; } else { - pendingGetItemId = this->dnsItemEntry->getItemId; + pendingGetItemId = GI_STICK_UPGRADE_30; + } + } else if (this->actor.params == 0xA) { + if (CUR_UPG_VALUE(UPG_NUTS) < 2) { + pendingGetItemId = GI_NUT_UPGRADE_30; + } else { + pendingGetItemId = GI_NUT_UPGRADE_40; } - GetItemEntry itemEntry = ItemTable_Retrieve(pendingGetItemId); - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; - func_8002F434(&this->actor, play, pendingGetItemId, 130.0f, 100.0f); } else { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(this->scrubIdentity.randomizerCheck, this->scrubIdentity.getItemId); - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; - GiveItemEntryFromActor(&this->actor, play, itemEntry, 130.0f, 100.0f); + pendingGetItemId = this->dnsItemEntry->getItemId; } + GetItemEntry itemEntry = ItemTable_Retrieve(pendingGetItemId); + gSaveContext.pendingSale = itemEntry.itemId; + gSaveContext.pendingSaleMod = itemEntry.modIndex; + func_8002F434(&this->actor, play, pendingGetItemId, 130.0f, 100.0f); } void func_809EFEE8(EnDns* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { Message_CloseTextbox(play); - func_809EFDD0(this, play); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BUSINESS_SCRUB, true, this)) { + func_809EFDD0(this, play); + } this->actionFunc = func_809EFF50; } } void func_809EFF50(EnDns* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BUSINESS_SCRUB, true, this)) { this->actor.parent = NULL; this->actionFunc = func_809EFF98; } else { @@ -533,9 +489,6 @@ void EnDns_Update(Actor* thisx, PlayState* play) { this->dustTimer++; this->actor.textId = D_809F040C[this->actor.params]; - if (IS_RANDO && this->scrubIdentity.isShuffled) { - this->actor.textId = 0x9000 + (this->scrubIdentity.randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT); - } Actor_SetFocus(&this->actor, 60.0f); Actor_SetScale(&this->actor, 0.01f); SkelAnime_Update(&this->skelAnime); diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.h b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.h index bf0a3a167..0e3e50c9b 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.h +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.h @@ -32,7 +32,10 @@ typedef struct EnDns { /* 0x02BD */ u8 dropCollectible; /* 0x02C0 */ DnsItemEntry* dnsItemEntry; /* 0x02C4 */ f32 yInitPos; - /* */ ScrubIdentity scrubIdentity; + // #region SOH [Randomizer] + /* */ DnsItemEntry sohDnsItemEntry; + /* */ ScrubIdentity sohScrubIdentity; + // #endregion } EnDns; // size = 0x02C8 #endif diff --git a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c index 6da75b1e7..d3a0eadea 100644 --- a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c +++ b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c @@ -6,7 +6,7 @@ #include "z_en_ds.h" #include "objects/object_ds/object_ds.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -90,19 +90,12 @@ void EnDs_DisplayOddPotionText(EnDs* this, PlayState* play) { } void EnDs_GiveOddPotion(EnDs* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_TRADE_ODD_MUSHROOM, true, this)) { this->actor.parent = NULL; this->actionFunc = EnDs_DisplayOddPotionText; gSaveContext.timer2State = 0; } else { - u32 itemId = GI_ODD_POTION; - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - Randomizer_ConsumeAdultTradeItem(play, ITEM_ODD_MUSHROOM); - return; - } - func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f); + func_8002F434(&this->actor, play, GI_ODD_POTION, 10000.0f, 50.0f); } } @@ -111,13 +104,9 @@ void EnDs_TalkAfterBrewOddPotion(EnDs* this, PlayState* play) { Message_CloseTextbox(play); this->actionFunc = EnDs_GiveOddPotion; u32 itemId = GI_ODD_POTION; - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - Randomizer_ConsumeAdultTradeItem(play, ITEM_ODD_MUSHROOM); - return; + if (GameInteractor_Should(GI_VB_TRADE_ODD_MUSHROOM, true, this)) { + func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f); } - func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f); } } @@ -138,7 +127,7 @@ void EnDs_BrewOddPotion2(EnDs* this, PlayState* play) { this->brewTimer -= 1; } else { this->actionFunc = EnDs_BrewOddPotion3; - this->brewTimer = IS_RANDO ? 0 : 60; + this->brewTimer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 60 : 0; Flags_UnsetSwitch(play, 0x3F); } } @@ -148,7 +137,7 @@ void EnDs_BrewOddPotion1(EnDs* this, PlayState* play) { this->brewTimer -= 1; } else { this->actionFunc = EnDs_BrewOddPotion2; - this->brewTimer = IS_RANDO ? 0 : 20; + this->brewTimer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 20 : 0; } Math_StepToF(&this->unk_1E4, 1.0f, 0.01f); @@ -162,7 +151,7 @@ void EnDs_OfferOddPotion(EnDs* this, PlayState* play) { switch (play->msgCtx.choiceIndex) { case 0: // yes this->actionFunc = EnDs_BrewOddPotion1; - this->brewTimer = IS_RANDO ? 0 : 60; + this->brewTimer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 60 : 0; Flags_SetSwitch(play, 0x3F); play->msgCtx.msgMode = MSGMODE_PAUSED; player->exchangeItemId = EXCH_ITEM_NONE; @@ -174,22 +163,10 @@ void EnDs_OfferOddPotion(EnDs* this, PlayState* play) { } } -u8 EnDs_RandoCanGetGrannyItem() { - return IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP) && - // Traded odd mushroom when adult trade is on - ((Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) && Flags_GetItemGetInf(ITEMGETINF_30)) || - // Found claim check when adult trade is off - (!Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) && - INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)); -} - s32 EnDs_CheckRupeesAndBottle() { if (gSaveContext.rupees < 100) { return 0; - } else if (EnDs_RandoCanGetGrannyItem()) { // Allow buying the rando item regardless of having a bottle - return 2; - } else if (Inventory_HasEmptyBottle() == 0) { + } else if (GameInteractor_Should(GI_VB_NEED_BOTTLE_FOR_GRANNYS_ITEM, Inventory_HasEmptyBottle() == 0, NULL)) { return 1; } else { return 2; @@ -197,20 +174,11 @@ s32 EnDs_CheckRupeesAndBottle() { } void EnDs_GiveBluePotion(EnDs* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { - if (EnDs_RandoCanGetGrannyItem()) { - Flags_SetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP); - } - + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GRANNYS_SHOP, true, this)) { this->actor.parent = NULL; this->actionFunc = EnDs_Talk; } else { - if (EnDs_RandoCanGetGrannyItem()) { - GetItemEntry entry = Randomizer_GetItemFromKnownCheck(RC_KAK_GRANNYS_SHOP, GI_POTION_BLUE); - GiveItemEntryFromActor(&this->actor, play, entry, 10000.0f, 50.0f); - } else { - func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f); - } + func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f); } } @@ -229,18 +197,14 @@ void EnDs_OfferBluePotion(EnDs* this, PlayState* play) { case 2: // have 100 rupees and empty bottle Rupees_ChangeBy(-100); this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; - GetItemEntry itemEntry; - if (EnDs_RandoCanGetGrannyItem()) { - itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_GRANNYS_SHOP, GI_POTION_BLUE); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - } else { - itemEntry = ItemTable_Retrieve(GI_POTION_BLUE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GRANNYS_SHOP, true, this)) { + GetItemEntry itemEntry = ItemTable_Retrieve(GI_POTION_BLUE); func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f); + gSaveContext.pendingSale = itemEntry.itemId; + gSaveContext.pendingSaleMod = itemEntry.modIndex; } - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; this->actionFunc = EnDs_GiveBluePotion; return; } @@ -261,10 +225,7 @@ void EnDs_Wait(EnDs* this, PlayState* play) { Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); player->actor.textId = 0x504A; this->actionFunc = EnDs_OfferOddPotion; - } else if ( - // Always offer blue potion when adult trade is off - (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_OFF) || - Flags_GetItemGetInf(ITEMGETINF_30)) { // Traded odd mushroom + } else if (GameInteractor_Should(GI_VB_OFFER_BLUE_POTION, Flags_GetItemGetInf(ITEMGETINF_30), this)) { // Traded odd mushroom player->actor.textId = 0x500C; this->actionFunc = EnDs_OfferBluePotion; } else { diff --git a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c index db13ecc54..6f99f070f 100644 --- a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c +++ b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c @@ -1,6 +1,7 @@ #include "z_en_du.h" #include "objects/object_du/object_du.h" #include "scenes/overworld/spot18/spot18_scene.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -376,7 +377,7 @@ void func_809FE4A4(EnDu* this, PlayState* play) { play->msgCtx.ocarinaMode = OCARINA_MODE_00; EnDu_SetupAction(this, func_809FE3C0); } else if (play->msgCtx.ocarinaMode >= OCARINA_MODE_06) { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_DARUNIAS_JOY_CS, true, NULL)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gGoronCityDaruniaWrongCs); gSaveContext.cutsceneTrigger = 1; } @@ -385,7 +386,7 @@ void func_809FE4A4(EnDu* this, PlayState* play) { play->msgCtx.ocarinaMode = OCARINA_MODE_04; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_DARUNIAS_JOY_CS, true, NULL)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gGoronCityDaruniaCorrectCs); gSaveContext.cutsceneTrigger = 1; } @@ -474,10 +475,7 @@ void func_809FE890(EnDu* this, PlayState* play) { Vec3f velocity = { 0.0f, 0.0f, 0.0f }; CsCmdActorAction* csAction; - if (play->csCtx.state == CS_STATE_IDLE || IS_RANDO) { - if (IS_RANDO) { - play->csCtx.state = CS_STATE_IDLE; - } + if (play->csCtx.state == CS_STATE_IDLE) { func_8002DF54(play, &this->actor, 1); EnDu_SetupAction(this, func_809FEB08); return; @@ -556,11 +554,8 @@ void func_809FEB08(EnDu* this, PlayState* play) { EnDu_SetupAction(this, func_809FE3C0); return; } - if ((!IS_RANDO && CUR_UPG_VALUE(UPG_STRENGTH) <= 0) || - (IS_RANDO && !Flags_GetTreasure(play, 0x1E))) { - if (IS_RANDO) { - Flags_SetTreasure(play, 0x1E); - } + if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD, CUR_UPG_VALUE(UPG_STRENGTH) <= 0, NULL)) { + Flags_SetRandomizerInf(RAND_INF_DARUNIAS_JOY); this->actor.textId = 0x301C; EnDu_SetupAction(this, func_809FEC14); } else { @@ -581,17 +576,13 @@ void func_809FEC14(EnDu* this, PlayState* play) { } void func_809FEC70(EnDu* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_STRENGTH_1, true, NULL)) { this->actor.parent = NULL; EnDu_SetupAction(this, func_809FECE4); } else { f32 xzRange = this->actor.xzDistToPlayer + 1.0f; - if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_DARUNIAS_JOY, GI_BRACELET); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); - } + + func_8002F434(&this->actor, play, GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c index 11a7eb026..1c16a0eb0 100644 --- a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c +++ b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c @@ -45,7 +45,6 @@ void EnFr_OcarinaMistake(EnFr* this, PlayState* play); void EnFr_SetupReward(EnFr* this, PlayState* play, u8 unkCondition); void EnFr_PrintTextBox(EnFr* this, PlayState* play); void EnFr_TalkBeforeReward(EnFr* this, PlayState* play); -RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex); void EnFr_SetReward(EnFr* this, PlayState* play); // Deactivate @@ -618,7 +617,6 @@ void EnFr_Idle(EnFr* this, PlayState* play) { player->actor.world.pos.z = this->actor.world.pos.z; // z = -1220.0f player->currentYaw = player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y; this->reward = GI_NONE; - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->actionFunc = EnFr_Activate; } else if (EnFr_IsAboveAndWithin30DistXZ(player, this)) { player->unk_6A8 = &this->actor; @@ -854,7 +852,6 @@ s32 EnFr_IsFrogSongComplete(EnFr* this, PlayState* play) { void EnFr_OcarinaMistake(EnFr* this, PlayState* play) { Message_CloseTextbox(play); this->reward = GI_NONE; - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; func_80078884(NA_SE_SY_OCARINA_ERROR); Audio_OcaSetInstrument(0); sEnFrPointers.flags = 12; @@ -939,23 +936,6 @@ void EnFr_TalkBeforeReward(EnFr* this, PlayState* play) { } } -RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex) { - switch (songIndex) { - case FROG_ZL: - return RC_ZR_FROGS_ZELDAS_LULLABY; - case FROG_EPONA: - return RC_ZR_FROGS_EPONAS_SONG; - case FROG_SARIA: - return RC_ZR_FROGS_SARIAS_SONG; - case FROG_SUNS: - return RC_ZR_FROGS_SUNS_SONG; - case FROG_SOT: - return RC_ZR_FROGS_SONG_OF_TIME; - default: - return RC_UNKNOWN_CHECK; - } -} - void EnFr_SetReward(EnFr* this, PlayState* play) { u16 songIndex; @@ -963,16 +943,12 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { songIndex = this->songIndex; this->actionFunc = EnFr_Deactivate; this->reward = GI_NONE; - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; if ((songIndex >= FROG_ZL) && (songIndex <= FROG_SOT)) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) { this->reward = GI_RUPEE_PURPLE; - } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(EnFr_RandomizerCheckFromSongIndex(songIndex), GI_RUPEE_PURPLE); - this->reward = this->getItemEntry.getItemId; } } else { this->reward = GI_RUPEE_BLUE; @@ -981,11 +957,8 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) { this->reward = GI_HEART_PIECE; - } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZR_FROGS_IN_THE_RAIN, GI_HEART_PIECE); - this->reward = this->getItemEntry.getItemId; } } else { this->reward = GI_RUPEE_BLUE; @@ -994,11 +967,8 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) { this->reward = GI_HEART_PIECE; - } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZR_FROGS_OCARINA_GAME, GI_HEART_PIECE); - this->reward = this->getItemEntry.getItemId; } } else { this->reward = GI_RUPEE_PURPLE; @@ -1049,29 +1019,23 @@ void EnFr_Deactivate(EnFr* this, PlayState* play) { this->actionFunc = EnFr_Idle; } else { this->actionFunc = EnFr_GiveReward; - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) { func_8002F434(&this->actor, play, this->reward, 30.0f, 100.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 30.0f, 100.0f); } } } void EnFr_GiveReward(EnFr* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) { this->actor.parent = NULL; this->actionFunc = EnFr_SetIdle; } else { - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, this->reward, 30.0f, 100.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 30.0f, 100.0f); - } + func_8002F434(&this->actor, play, this->reward, 30.0f, 100.0f); } } void EnFr_SetIdle(EnFr* this, PlayState* play) { - if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play) || (IS_RANDO && this->reward == RG_ICE_TRAP)) { + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { this->actionFunc = EnFr_Idle; } } diff --git a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h index 19d612fdd..17b8b162e 100644 --- a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h +++ b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h @@ -73,7 +73,6 @@ typedef struct EnFr { /* 0x03AA */ s16 xyAngleButterfly; // Butterfly Travels along random angles in the x-y plane /* 0x03AC */ Vec3f posButterfly; // Position/Coordinates of the Butterfly /* 0x03B8 */ Vec3f posButterflyLight; // Used in Lights_PointNoGlowSetInfo() - /* */ GetItemEntry getItemEntry; } EnFr; // size = 0x03C4 typedef struct { @@ -81,4 +80,7 @@ typedef struct { EnFr* frogs[5]; } EnFrPointers; +void EnFr_Idle(EnFr* enFr, PlayState* play); +void EnFr_GiveReward(EnFr* enFr, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c index 4986f24f6..22754a87a 100644 --- a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c +++ b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c @@ -8,6 +8,7 @@ #include "objects/object_oF1d_map/object_oF1d_map.h" #include "objects/object_gm/object_gm.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include <assert.h> #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -96,10 +97,9 @@ void EnGm_Destroy(Actor* thisx, PlayState* play) { s32 func_80A3D7C8(void) { if (LINK_AGE_IN_YEARS == YEARS_CHILD) { return 0; - } else if ((IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF) && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { - return 1; - } else if (!CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON)) { // Don't have giant's knife + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE, ( + !CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON) // Don't have giant's knife + ), NULL)) { return 1; } else if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE)) { // Have broken giant's knife return 2; @@ -215,11 +215,6 @@ void func_80A3DC44(EnGm* this, PlayState* play) { return; case 1: Flags_SetInfTable(INFTABLE_B1); - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { - //Resets "Talked to Medigoron" flag in infTable to restore initial conversation state - Flags_UnsetInfTable(INFTABLE_B1); - } case 2: this->actionFunc = EnGm_ProcessChoiceIndex; default: @@ -254,20 +249,10 @@ void EnGm_ProcessChoiceIndex(EnGm* this, PlayState* play) { Message_ContinueTextbox(play, 0xC8); this->actionFunc = func_80A3DD7C; } else { - GetItemEntry itemEntry; - - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { - itemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_MEDIGORON, GI_SWORD_KNIFE); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 415.0f, 10.0f); - Flags_SetInfTable(INFTABLE_B1); - } else { - itemEntry = ItemTable_Retrieve(GI_SWORD_KNIFE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MEDIGORON, true, this)) { func_8002F434(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f); } - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; this->actionFunc = func_80A3DF00; } break; @@ -280,24 +265,12 @@ void EnGm_ProcessChoiceIndex(EnGm* this, PlayState* play) { } void func_80A3DF00(EnGm* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { - Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON); - } - + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MEDIGORON, true, this)) { + Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON); this->actor.parent = NULL; this->actionFunc = func_80A3DF60; } else { - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_MEDIGORON, GI_SWORD_KNIFE); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 415.0f, 10.0f); - Flags_SetInfTable(INFTABLE_B1); - } - else { - func_8002F434(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f); - } + func_8002F434(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c index 3094f2171..7dc67f427 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -3,7 +3,6 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_oF1d_map/object_oF1d_map.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -31,9 +30,11 @@ void func_80A40C78(EnGo* this, PlayState* play); void EnGo_Eyedrops(EnGo* this, PlayState* play); void func_80A40DCC(EnGo* this, PlayState* play); -void EnGo_AddDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, f32 scaleStep); -void EnGo_UpdateDust(EnGo* this); -void EnGo_DrawDust(EnGo* this, PlayState* play); + +void EnGo_SpawnEffectDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, + f32 scaleStep); +void EnGo_UpdateEffects(EnGo* this); +void EnGo_DrawEffects(EnGo* this, PlayState* play); const ActorInit En_Go_InitVars = { ACTOR_EN_GO, @@ -95,10 +96,10 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { switch (thisx->params & 0xF0) { case 0x90: - if (!IS_RANDO && gSaveContext.bgsFlag) { + if (gSaveContext.bgsFlag) { return 0x305E; } else if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_CLAIM_CHECK) { - if (Environment_GetBgsDayCount() >= CVarGetInteger("gForgeTime", 3)) { + if (Environment_GetBgsDayCount() >= 3) { return 0x305E; } else { return 0x305D; @@ -113,8 +114,7 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { return 0x3053; } case 0x00: - if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) { + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) { if (Flags_GetInfTable(INFTABLE_10F)) { return 0x3042; } else { @@ -199,7 +199,7 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { } s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { - s16 unkState = NPC_TALK_STATE_TALKING; + s16 talkState = NPC_TALK_STATE_TALKING; f32 xzRange; f32 yRange = fabsf(thisx->yDistToPlayer) + 1.0f; @@ -210,51 +210,51 @@ s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { switch (thisx->textId) { case 0x3008: Flags_SetInfTable(INFTABLE_E0); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x300B: Flags_SetInfTable(INFTABLE_EB); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3014: Flags_SetInfTable(INFTABLE_F0); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3016: Flags_SetInfTable(INFTABLE_F4); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3018: Flags_SetInfTable(INFTABLE_F8); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3036: func_8002F434(thisx, play, GI_TUNIC_GORON, xzRange, yRange); Flags_SetInfTable(INFTABLE_10D); // EnGo exclusive flag - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; break; case 0x3037: Flags_SetInfTable(INFTABLE_SPOKE_TO_GORON_LINK); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3041: Flags_SetInfTable(INFTABLE_10F); - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; case 0x3059: - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; break; case 0x3052: case 0x3054: case 0x3055: case 0x305A: - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; break; case 0x305E: - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; break; default: - unkState = NPC_TALK_STATE_IDLE; + talkState = NPC_TALK_STATE_IDLE; break; } break; @@ -272,7 +272,7 @@ s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { thisx->textId = 0x300D; } Message_ContinueTextbox(play, thisx->textId); - unkState = NPC_TALK_STATE_TALKING; + talkState = NPC_TALK_STATE_TALKING; break; case 0x3034: if (play->msgCtx.choiceIndex == 0) { @@ -287,16 +287,16 @@ s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { thisx->textId = 0x3033; } Message_ContinueTextbox(play, thisx->textId); - unkState = NPC_TALK_STATE_TALKING; + talkState = NPC_TALK_STATE_TALKING; break; case 0x3054: case 0x3055: if (play->msgCtx.choiceIndex == 0) { - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; } else { thisx->textId = 0x3056; Message_ContinueTextbox(play, thisx->textId); - unkState = NPC_TALK_STATE_TALKING; + talkState = NPC_TALK_STATE_TALKING; } Flags_SetInfTable(INFTABLE_B4); break; @@ -312,17 +312,17 @@ s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { case 0x3033: thisx->textId = 0x3034; Message_ContinueTextbox(play, thisx->textId); - unkState = NPC_TALK_STATE_TALKING; + talkState = NPC_TALK_STATE_TALKING; break; default: - unkState = NPC_TALK_STATE_ACTION; + talkState = NPC_TALK_STATE_ACTION; break; } } break; case TEXT_STATE_DONE: if (Message_ShouldAdvance(play)) { - unkState = NPC_TALK_STATE_ITEM_GIVEN; + talkState = NPC_TALK_STATE_ITEM_GIVEN; } break; case TEXT_STATE_NONE: @@ -332,21 +332,21 @@ s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { case TEXT_STATE_9: break; } - return unkState; + return talkState; } -s32 func_80A3ED24(PlayState* play, EnGo* this, NpcInteractInfo* interactInfo, f32 arg3, NpcGetTextIdFunc getTextId, +s32 EnGo_UpdateTalking(PlayState* play, Actor* thisx, s16* talkState, f32 interactRange, NpcGetTextIdFunc getTextId, NpcUpdateTalkStateFunc updateTalkState) { - if (interactInfo->talkState != NPC_TALK_STATE_IDLE) { - interactInfo->talkState = updateTalkState(play, &this->actor); + if (*talkState != NPC_TALK_STATE_IDLE) { + *talkState = updateTalkState(play, thisx); return false; - } else if (Actor_ProcessTalkRequest(&this->actor, play)) { - interactInfo->talkState = NPC_TALK_STATE_TALKING; + } else if (Actor_ProcessTalkRequest(thisx, play)) { + *talkState = NPC_TALK_STATE_TALKING; return true; - } else if (!func_8002F2CC(&this->actor, play, arg3)) { + } else if (!func_8002F2CC(thisx, play, interactRange)) { return false; } else { - this->actor.textId = getTextId(play, &this->actor); + thisx->textId = getTextId(play, thisx); return false; } } @@ -379,7 +379,7 @@ s32 EnGo_IsActorSpawned(EnGo* this, PlayState* play) { } } -f32 EnGo_GetGoronSize(EnGo* this) { +f32 EnGo_GetPlayerTrackingYOffset(EnGo* this) { switch (this->actor.params & 0xF0) { case 0x00: return 10.0f; @@ -398,16 +398,16 @@ f32 EnGo_GetGoronSize(EnGo* this) { void func_80A3F060(EnGo* this, PlayState* play) { Player* player = GET_PLAYER(play); - s16 npcTrackingMode; + s16 trackingMode; if (this->actionFunc != EnGo_BiggoronActionFunc && this->actionFunc != EnGo_FireGenericActionFunc && this->actionFunc != func_80A40B1C) { - npcTrackingMode = NPC_TRACKING_NONE; + trackingMode = NPC_TRACKING_NONE; } this->interactInfo.trackPos = player->actor.world.pos; - this->interactInfo.yOffset = EnGo_GetGoronSize(this); - Npc_TrackPoint(&this->actor, &this->interactInfo, 4, npcTrackingMode); + this->interactInfo.yOffset = EnGo_GetPlayerTrackingYOffset(this); + Npc_TrackPoint(&this->actor, &this->interactInfo, 4, trackingMode); } void func_80A3F0E4(EnGo* this) { @@ -421,23 +421,23 @@ void func_80A3F0E4(EnGo* this) { } s32 EnGo_IsCameraModified(EnGo* this, PlayState* play) { - f32 xyzDist; + f32 xyzDistSq; s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; - Camera* camera = play->cameraPtrs[MAIN_CAM]; + Camera* mainCam = play->cameraPtrs[MAIN_CAM]; if (fabsf(yawDiff) > 10920.0f) { return 0; } - xyzDist = (this->actor.scale.x / 0.01f) * 10000.0f; + xyzDistSq = (this->actor.scale.x / 0.01f) * SQ(100.0f); if ((this->actor.params & 0xF0) == 0x90) { - Camera_ChangeSetting(camera, CAM_SET_DIRECTED_YAW); - xyzDist *= 4.8f; + Camera_ChangeSetting(mainCam, CAM_SET_DIRECTED_YAW); + xyzDistSq *= 4.8f; } - if (fabsf(this->actor.xyzDistToPlayerSq) > xyzDist) { - if (camera->setting == CAM_SET_DIRECTED_YAW) { - Camera_ChangeSetting(camera, CAM_SET_NORMAL0); + if (fabsf(this->actor.xyzDistToPlayerSq) > xyzDistSq) { + if (mainCam->setting == CAM_SET_DIRECTED_YAW) { + Camera_ChangeSetting(mainCam, CAM_SET_NORMAL0); } return 0; } else { @@ -480,7 +480,7 @@ s32 EnGo_FollowPath(EnGo* this, PlayState* play) { pointPos += this->unk_218; xDist = pointPos->x - this->actor.world.pos.x; zDist = pointPos->z - this->actor.world.pos.z; - Math_SmoothStepToS(&this->actor.world.rot.y, (s16)(Math_FAtan2F(xDist, zDist) * ((f32)0x8000 / M_PI)), 10, 1000, 1); + Math_SmoothStepToS(&this->actor.world.rot.y, RADF_TO_BINANG(Math_FAtan2F(xDist, zDist)), 10, 1000, 1); if ((SQ(xDist) + SQ(zDist)) < 600.0f) { this->unk_218++; @@ -536,7 +536,7 @@ s32 EnGo_SpawnDust(EnGo* this, u8 initialTimer, f32 scale, f32 scaleStep, s32 nu accel.z = (Rand_ZeroOne() - 0.5f) * xzAccel; pos.x = (Math_SinS(angle) * radius) + this->actor.world.pos.x; pos.z = (Math_CosS(angle) * radius) + this->actor.world.pos.z; - EnGo_AddDust(this, &pos, &velocity, &accel, initialTimer, scale, scaleStep); + EnGo_SpawnEffectDust(this, &pos, &velocity, &accel, initialTimer, scale, scaleStep); angle += (s16)(0x10000 / numDustEffects); i--; } @@ -549,7 +549,7 @@ s32 EnGo_IsRollingOnGround(EnGo* this, s16 unkArg1, f32 unkArg2) { } else if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { return true; } else if (DECR(this->unk_21C)) { - if ((this->unk_21C & 1)) { + if (this->unk_21C & 1) { this->actor.world.pos.y += 1.5f; } else { this->actor.world.pos.y -= 1.5f; @@ -573,29 +573,29 @@ s32 EnGo_IsRollingOnGround(EnGo* this, s16 unkArg1, f32 unkArg2) { void func_80A3F908(EnGo* this, PlayState* play) { Player* player = GET_PLAYER(play); - f32 float1; - s32 isUnkCondition; + f32 interactRange; + s32 dialogStarted; if (this->actionFunc == EnGo_BiggoronActionFunc || this->actionFunc == EnGo_GoronLinkRolling || this->actionFunc == EnGo_FireGenericActionFunc || this->actionFunc == EnGo_Eyedrops || this->actionFunc == func_80A40DCC || this->actionFunc == EnGo_GetItem || this->actionFunc == func_80A40C78 || this->actionFunc == func_80A40B1C) { - float1 = (this->collider.dim.radius + 30.0f); - float1 *= (this->actor.scale.x / 0.01f); + interactRange = (this->collider.dim.radius + 30.0f); + interactRange *= (this->actor.scale.x / 0.01f); if ((this->actor.params & 0xF0) == 0x90) { - float1 *= 4.8f; + interactRange *= 4.8f; } if ((this->actor.params & 0xF0) == 0x90) { - isUnkCondition = - func_80A3ED24(play, this, &this->interactInfo, float1, EnGo_GetTextID, EnGo_UpdateTalkState); + dialogStarted = + EnGo_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, interactRange, EnGo_GetTextID, EnGo_UpdateTalkState); } else { - isUnkCondition = Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, float1, + dialogStarted = Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, interactRange, EnGo_GetTextID, EnGo_UpdateTalkState); } - if (((this->actor.params & 0xF0) == 0x90) && (isUnkCondition == true)) { + if (((this->actor.params & 0xF0) == 0x90) && (dialogStarted == true)) { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_SWORD_BROKEN) { if (func_8002F368(play) == EXCH_ITEM_SWORD_BROKEN) { if (Flags_GetInfTable(INFTABLE_B4)) { @@ -628,7 +628,7 @@ void EnGo_Init(Actor* thisx, PlayState* play) { Vec3f D_80A41BA8 = { 0.0f, 0.0f, 0.0f }; // unused ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); - SkelAnime_InitFlex(play, &this->skelAnime, &gGoronSkel, NULL, 0, 0, 0); + SkelAnime_InitFlex(play, &this->skelAnime, &gGoronSkel, NULL, NULL, NULL, 0); Collider_InitCylinder(play, &this->collider); Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); @@ -711,8 +711,8 @@ void EnGo_StopRolling(EnGo* this, PlayState* play) { EnBom* bomb; if (DECR(this->unk_20E) == 0) { - if (this->collider.base.ocFlags2 & 1) { - this->collider.base.ocFlags2 &= ~1; + if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) { + this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER; play->damagePlayer(play, -4); func_8002F71C(play, &this->actor, 4.0f, this->actor.yawTowardsPlayer, 6.0f); this->unk_20E = 0x10; @@ -859,7 +859,7 @@ void func_80A405CC(EnGo* this, PlayState* play) { void EnGo_BiggoronActionFunc(EnGo* this, PlayState* play) { if (((this->actor.params & 0xF0) == 0x90) && (this->interactInfo.talkState == NPC_TALK_STATE_ACTION)) { - if (!IS_RANDO && gSaveContext.bgsFlag) { + if (gSaveContext.bgsFlag) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } else { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_EYEDROPS) { @@ -958,45 +958,25 @@ void EnGo_GetItem(EnGo* this, PlayState* play) { this->unk_20C = 0; if ((this->actor.params & 0xF0) == 0x90) { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK) { - if (!IS_RANDO) { - getItemId = GI_SWORD_BGS; - } else { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS); - getItemId = getItemEntry.getItemId; - } + getItemId = GI_SWORD_BGS; this->unk_20C = 1; } if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_EYEDROPS) { - if (IS_RANDO) { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_EYEDROPS, GI_CLAIM_CHECK); - getItemId = getItemEntry.getItemId; - Randomizer_ConsumeAdultTradeItem(play, ITEM_EYEDROPS); - } else { - getItemId = GI_CLAIM_CHECK; - } + getItemId = GI_CLAIM_CHECK; } if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_SWORD_BROKEN) { - if (IS_RANDO) { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_BROKEN_SWORD, GI_PRESCRIPTION); - Randomizer_ConsumeAdultTradeItem(play, ITEM_SWORD_BROKEN); - getItemId = getItemEntry.getItemId; - } else { - getItemId = GI_PRESCRIPTION; - } + getItemId = GI_PRESCRIPTION; } } if ((this->actor.params & 0xF0) == 0) { getItemId = GI_TUNIC_GORON; + Flags_SetRandomizerInf(RAND_INF_ROLLING_GORON_AS_ADULT); } yDist = fabsf(this->actor.yDistToPlayer) + 1.0f; xzDist = this->actor.xzDistToPlayer + 1.0f; - if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, getItemId, xzDist, yDist); - } else { - GiveItemEntryFromActor(&this->actor, play, getItemEntry, xzDist, yDist); - } + func_8002F434(&this->actor, play, getItemId, xzDist, yDist); } } @@ -1105,32 +1085,30 @@ void EnGo_DrawRolling(EnGo* this, PlayState* play) { s32 EnGo_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { EnGo* this = (EnGo*)thisx; - Vec3s vec1; + Vec3s limbRot; f32 float1; if (limb == 17) { Matrix_Translate(2800.0f, 0.0f, 0.0f, MTXMODE_APPLY); - vec1 = this->interactInfo.headRot; - float1 = (vec1.y / (f32)0x8000) * M_PI; + limbRot = this->interactInfo.headRot; + float1 = (limbRot.y / (f32)0x8000) * M_PI; Matrix_RotateX(float1, MTXMODE_APPLY); - float1 = (vec1.x / (f32)0x8000) * M_PI; + float1 = (limbRot.x / (f32)0x8000) * M_PI; Matrix_RotateZ(float1, MTXMODE_APPLY); Matrix_Translate(-2800.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limb == 10) { - vec1 = this->interactInfo.torsoRot; - float1 = (vec1.y / (f32)0x8000) * M_PI; + limbRot = this->interactInfo.torsoRot; + float1 = (limbRot.y / (f32)0x8000) * M_PI; Matrix_RotateY(float1, MTXMODE_APPLY); - float1 = (vec1.x / (f32)0x8000) * M_PI; + float1 = (limbRot.x / (f32)0x8000) * M_PI; Matrix_RotateX(float1, MTXMODE_APPLY); } if ((limb == 10) || (limb == 11) || (limb == 14)) { - float1 = Math_SinS(this->jointTable[limb]); - rot->y += float1 * 200.0f; - float1 = Math_CosS(this->morphTable[limb]); - rot->z += float1 * 200.0f; + rot->y += Math_SinS(this->jointTable[limb]) * 200.0f; + rot->z += Math_CosS(this->morphTable[limb]) * 200.0f; } return 0; @@ -1150,9 +1128,9 @@ void EnGo_Draw(Actor* thisx, PlayState* play) { OPEN_DISPS(play->state.gfxCtx); - EnGo_UpdateDust(this); + EnGo_UpdateEffects(this); Matrix_Push(); - EnGo_DrawDust(this, play); + EnGo_DrawEffects(this, play); Matrix_Pop(); if (this->actionFunc == EnGo_CurledUp) { @@ -1167,39 +1145,36 @@ void EnGo_Draw(Actor* thisx, PlayState* play) { gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(gGoronCsMouthNeutralTex)); SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnGo_OverrideLimbDraw, EnGo_PostLimbDraw, &this->actor); - EnGo_DrawDust(this, play); + EnGo_DrawEffects(this, play); } CLOSE_DISPS(play->state.gfxCtx); } -void EnGo_AddDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, f32 scaleStep) { - EnGoEffect* dustEffect = this->dustEffects; +void EnGo_SpawnEffectDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, f32 scaleStep) { + EnGoEffect* dustEffect = this->effects; s16 i; - s16 timer; - for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) { + for (i = 0; i < EN_GO_EFFECT_COUNT; i++, dustEffect++) { if (dustEffect->type != 1) { dustEffect->epoch++; dustEffect->scale = scale; dustEffect->scaleStep = scaleStep; - timer = initialTimer; - dustEffect->timer = timer; + dustEffect->initialTimer = dustEffect->timer = initialTimer; dustEffect->type = 1; - dustEffect->initialTimer = initialTimer; dustEffect->pos = *pos; dustEffect->accel = *accel; dustEffect->velocity = *velocity; - return; + break; } } } -void EnGo_UpdateDust(EnGo* this) { - EnGoEffect* dustEffect = this->dustEffects; +void EnGo_UpdateEffects(EnGo* this) { + EnGoEffect* dustEffect = this->effects; f32 randomNumber; s16 i; - for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) { + for (i = 0; i < EN_GO_EFFECT_COUNT; i++, dustEffect++) { if (dustEffect->type) { dustEffect->timer--; if (dustEffect->timer == 0) { @@ -1220,24 +1195,24 @@ void EnGo_UpdateDust(EnGo* this) { } } -void EnGo_DrawDust(EnGo* this, PlayState* play) { +void EnGo_DrawEffects(EnGo* this, PlayState* play) { static void* dustTex[] = { gDust8Tex, gDust7Tex, gDust6Tex, gDust5Tex, gDust4Tex, gDust3Tex, gDust2Tex, gDust1Tex }; - EnGoEffect* dustEffect = this->dustEffects; + EnGoEffect* dustEffect = this->effects; s16 alpha; - s16 firstDone; + s16 materialFlag; s16 index; s16 i; OPEN_DISPS(play->state.gfxCtx); - firstDone = false; + materialFlag = false; Gfx_SetupDL_25Xlu(play->state.gfxCtx); - for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) { + for (i = 0; i < EN_GO_EFFECT_COUNT; i++, dustEffect++) { if (dustEffect->type) { - if (!firstDone) { + if (!materialFlag) { POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, 0); gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD40); gDPSetEnvColor(POLY_XLU_DISP++, 100, 60, 20, 0); - firstDone = true; + materialFlag = true; } FrameInterpolation_RecordOpenChild(dustEffect, dustEffect->epoch); diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.h b/soh/src/overlays/actors/ovl_En_Go/z_en_go.h index 7b3224aec..1b1320988 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.h +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.h @@ -16,12 +16,13 @@ typedef s16 (*callback2_80A3ED24)(PlayState*, struct EnGo*); // /* 0x20 */ GORON1_DMT_DC_ENTRANCE, // /* 0x30 */ GORON1_DMT_ROLLING_SMALL, // /* 0x40 */ GORON1_DMT_BOMB_FLOWER, -// /* 0x50 */ GORON1_CITY_ENTRANCE, +// /* 0x50 */ GORON1_CITY_ENTRANCE, // /* 0x60 */ GORON1_CITY_ISLAND, -// /* 0x70 */ GORON1_CITY_LOST_WOODS, +// /* 0x70 */ GORON1_CITY_LOST_WOODS, // /* 0x80 */ // Not Used // /* 0x90 */ GORON1_DMT_BIGGORON, +#define EN_GO_EFFECT_COUNT 20 typedef struct { /* 0x0000 */ u8 type; @@ -56,7 +57,7 @@ typedef struct EnGo { /* 0x021E */ s16 unk_21E; /* 0x0220 */ s16 jointTable[18]; /* 0x0244 */ s16 morphTable[18]; - /* 0x0268 */ EnGoEffect dustEffects[20]; + /* 0x0268 */ EnGoEffect effects[EN_GO_EFFECT_COUNT]; } EnGo; // size = 0x06C8 #endif diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index a4aede2e5..86d1b488a 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -3,7 +3,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_oF1d_map/object_oF1d_map.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -335,7 +335,8 @@ u16 EnGo2_GoronFireGenericGetTextId(EnGo2* this) { u16 EnGo2_GetTextIdGoronCityRollingBig(PlayState* play, EnGo2* this) { if (Flags_GetInfTable(INFTABLE_11E)) { return 0x3013; - } else if ((CUR_CAPACITY(UPG_BOMB_BAG) >= 20 || IS_RANDO) && this->waypoint > 7 && this->waypoint < 12) { + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD, CUR_CAPACITY(UPG_BOMB_BAG) >= 2, this) + && this->waypoint > 7 && this->waypoint < 12) { return 0x3012; } else { return 0x3011; @@ -350,13 +351,14 @@ s16 EnGo2_UpdateTalkStateGoronCityRollingBig(PlayState* play, EnGo2* this) { if (Message_ShouldAdvance(play)) { if (this->actor.textId == 0x3012) { this->actionFunc = EnGo2_SetupGetItem; - if(!IS_RANDO) { + if(GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_CHILD, true, this)) { EnGo2_GetItem(this, play, CUR_CAPACITY(UPG_BOMB_BAG) == 30 ? GI_BOMB_BAG_40 : GI_BOMB_BAG_30); } else { - EnGo2_GetItemEntry(this, play, Randomizer_GetItemFromKnownCheck(RC_GC_ROLLING_GORON_AS_CHILD, GI_BOMB_BAG_40)); + this->actionFunc = EnGo2_SetGetItem; } Message_CloseTextbox(play); Flags_SetInfTable(INFTABLE_11E); + Flags_SetRandomizerInf(RAND_INF_ROLLING_GORON_AS_CHILD); return NPC_TALK_STATE_ACTION; } else { return NPC_TALK_STATE_ACTION; @@ -416,11 +418,9 @@ s16 EnGo2_UpdateTalkStateGoronDmtRollingSmall(PlayState* play, EnGo2* this) { } u16 EnGo2_GetTextIdGoronDmtDcEntrance(PlayState* play, EnGo2* this) { - if (((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { return 0x3043; - } else if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN))) { + } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED, CHECK_QUEST_ITEM(QUEST_GORON_RUBY), NULL)) { return 0x3027; } else { return Flags_GetEventChkInf(EVENTCHKINF_BOMBED_DODONGOS_CAVERN_ENTRANCE) ? 0x3021 : Flags_GetInfTable(INFTABLE_E0) ? 0x302A : 0x3008; @@ -439,11 +439,9 @@ s16 EnGo2_UpdateTalkStateGoronDmtDcEntrance(PlayState* play, EnGo2* this) { } u16 EnGo2_GetTextIdGoronCityEntrance(PlayState* play, EnGo2* this) { - if (((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { return 0x3043; - } else if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN))) { + } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED, CHECK_QUEST_ITEM(QUEST_GORON_RUBY), NULL)) { return 0x3027; } else { return Flags_GetInfTable(INFTABLE_F0) ? 0x3015 : 0x3014; @@ -462,11 +460,9 @@ s16 EnGo2_UpdateTalkStateGoronCityEntrance(PlayState* play, EnGo2* this) { } u16 EnGo2_GetTextIdGoronCityIsland(PlayState* play, EnGo2* this) { - if (((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { return 0x3043; - } else if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN))) { + } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED, CHECK_QUEST_ITEM(QUEST_GORON_RUBY), NULL)) { return 0x3027; } else { return Flags_GetInfTable(INFTABLE_F4) ? 0x3017 : 0x3016; @@ -485,11 +481,9 @@ s16 EnGo2_UpdateTalkStateGoronCityIsland(PlayState* play, EnGo2* this) { } u16 EnGo2_GetTextIdGoronCityLowestFloor(PlayState* play, EnGo2* this) { - if (((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { return 0x3043; - } else if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN))) { + } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED, CHECK_QUEST_ITEM(QUEST_GORON_RUBY), NULL)) { return 0x3027; } else { return CUR_UPG_VALUE(UPG_STRENGTH) != 0 ? 0x302C @@ -511,18 +505,10 @@ s16 EnGo2_UpdateTalkStateGoronCityLowestFloor(PlayState* play, EnGo2* this) { } u16 EnGo2_GetTextIdGoronCityLink(PlayState* play, EnGo2* this) { - // For rando, prioritize opening the doors in GC when Link the goron has been stopped when - // the doors are not opened, otherwise let him talk about the DMC exit or that gorons are saved - if (IS_RANDO) { - if (!Flags_GetInfTable(INFTABLE_STOPPED_GORON_LINKS_ROLLING)) { - return 0x3030; - } else if (!Flags_GetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED)) { - return 0x3036; - } else if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE)) { - return 0x3041; - } else { - return Flags_GetInfTable(INFTABLE_SPOKE_TO_GORON_LINK) ? 0x3038 : 0x3037; - } + // In case a hook neglects to set the override, fall back to the first dialogue + u16 overrideTextId = 0x3030; + if (GameInteractor_Should(GI_VB_OVERRIDE_LINK_THE_GORON_DIALOGUE, false, &overrideTextId)) { + return overrideTextId; } if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) { @@ -543,20 +529,15 @@ s16 EnGo2_UpdateTalkStateGoronCityLink(PlayState* play, EnGo2* this) { case TEXT_STATE_CLOSING: switch (this->actor.textId) { case 0x3036: - if (!IS_RANDO) { + Flags_SetRandomizerInf(RAND_INF_ROLLING_GORON_AS_ADULT); + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ROLLING_GORON_AS_ADULT, true, this)) { EnGo2_GetItem(this, play, GI_TUNIC_GORON); this->actionFunc = EnGo2_SetupGetItem; return NPC_TALK_STATE_ACTION; } else { - if (Flags_GetTreasure(play, 0x1F)) { - return NPC_TALK_STATE_IDLE; - } - - Flags_SetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED); - EnGo2_GetItemEntry(this, play, Randomizer_GetItemFromKnownCheck(RC_GC_ROLLING_GORON_AS_ADULT, GI_TUNIC_GORON)); - this->actionFunc = EnGo2_SetupGetItem; - Flags_SetTreasure(play, 0x1F); - return NPC_TALK_STATE_ACTION; + this->actionFunc = EnGo2_SetGetItem; + return this->interactInfo.talkState; } case 0x3037: Flags_SetInfTable(INFTABLE_SPOKE_TO_GORON_LINK); @@ -605,7 +586,7 @@ s16 EnGo2_UpdateTalkStateGoronCityLink(PlayState* play, EnGo2* this) { u16 EnGo2_GetTextIdGoronDmtBiggoron(PlayState* play, EnGo2* this) { Player* player = GET_PLAYER(play); - if (!IS_RANDO && gSaveContext.bgsFlag) { + if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_TRADE_COMPLETE, gSaveContext.bgsFlag, NULL)) { player->exchangeItemId = EXCH_ITEM_CLAIM_CHECK; return 0x305E; } else if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_CLAIM_CHECK) { @@ -627,17 +608,17 @@ s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { switch (EnGo2_GetDialogState(this, play)) { case TEXT_STATE_DONE: if (this->actor.textId == 0x305E) { - if((!IS_RANDO && gSaveContext.bgsFlag) || (IS_RANDO && Flags_GetTreasure(play, 0x1F))) { + if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_SWORD_COLLECTED, gSaveContext.bgsFlag, NULL)) { return NPC_TALK_STATE_IDLE; } - - if(IS_RANDO) { - EnGo2_GetItemEntry(this, play, Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS)); - Flags_SetTreasure(play, 0x1F); - } else { + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK); + if (GameInteractor_Should(GI_VB_TRADE_CLAIM_CHECK, true, this)) { EnGo2_GetItem(this, play, GI_SWORD_BGS); + this->actionFunc = EnGo2_SetupGetItem; + } else { + this->actionFunc = EnGo2_SetGetItem; } - this->actionFunc = EnGo2_SetupGetItem; + return NPC_TALK_STATE_ACTION; } else { return NPC_TALK_STATE_IDLE; @@ -663,16 +644,13 @@ s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { if (Message_ShouldAdvance(play)) { if ((this->actor.textId == 0x3054) || (this->actor.textId == 0x3055)) { if (play->msgCtx.choiceIndex == 0) { - if (IS_RANDO) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_BROKEN_SWORD, GI_PRESCRIPTION); - Randomizer_ConsumeAdultTradeItem(play, ITEM_SWORD_BROKEN); - EnGo2_GetItemEntry(this, play, getItemEntry); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD); + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD); + if (GameInteractor_Should(GI_VB_TRADE_BROKEN_SWORD, true, this)) { + EnGo2_GetItem(this, play, GI_PRESCRIPTION); + this->actionFunc = EnGo2_SetupGetItem; } else { - u32 getItemId = GI_PRESCRIPTION; - EnGo2_GetItem(this, play, getItemId); + this->actionFunc = EnGo2_SetGetItem; } - this->actionFunc = EnGo2_SetupGetItem; return NPC_TALK_STATE_ACTION; } this->actor.textId = 0x3056; @@ -1070,7 +1048,7 @@ void EnGo2_BiggoronSetTextId(EnGo2* this, PlayState* play, Player* player) { u16 textId; if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) { - if ((!IS_RANDO && gSaveContext.bgsFlag)) { + if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_TRADE_COMPLETE, gSaveContext.bgsFlag, NULL)) { if (func_8002F368(play) == EXCH_ITEM_CLAIM_CHECK) { this->actor.textId = 0x3003; } else { @@ -1080,18 +1058,14 @@ void EnGo2_BiggoronSetTextId(EnGo2* this, PlayState* play, Player* player) { } else if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK) { if (func_8002F368(play) == EXCH_ITEM_CLAIM_CHECK) { - if (IS_RANDO && Flags_GetTreasure(play, 0x1F)) { - textId = 0x3003; - } else if (Environment_GetBgsDayCount() >= CVarGetInteger("gForgeTime", 3)) { + if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_SWORD_FORGED, Environment_GetBgsDayCount() >= 3, NULL)) { textId = 0x305E; } else { textId = 0x305D; } this->actor.textId = textId; } else { - if (IS_RANDO && Flags_GetTreasure(play, 0x1F)) { - textId = 0x305E; - } else if (Environment_GetBgsDayCount() >= CVarGetInteger("gForgeTime", 3)) { + if (GameInteractor_Should(GI_VB_BIGGORON_CONSIDER_SWORD_FORGED, Environment_GetBgsDayCount() >= 3, NULL)) { textId = 0x3002; } else { textId = 0x305D; @@ -1219,8 +1193,7 @@ s32 EnGo2_IsCameraModified(EnGo2* this, PlayState* play) { (this->actor.params & 0x1F) == GORON_CITY_STAIRWELL || (this->actor.params & 0x1F) == GORON_DMT_BIGGORON || (this->actor.params & 0x1F) == GORON_MARKET_BAZAAR) { return true; - } else if (((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && + } else if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { return true; } else { @@ -1278,8 +1251,7 @@ void EnGo2_SelectGoronWakingUp(EnGo2* this) { EnGo2_BiggoronWakingUp(this); break; case GORON_CITY_LINK: - if (((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { EnGo2_WakingUp(this); break; @@ -1624,8 +1596,7 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { case GORON_CITY_LOWEST_FLOOR: case GORON_CITY_STAIRWELL: case GORON_CITY_LOST_WOODS: - if (((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && LINK_IS_ADULT) { Actor_Kill(&this->actor); } this->actionFunc = EnGo2_CurledUp; @@ -1640,8 +1611,7 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { if ((Flags_GetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED))) { Path_CopyLastPoint(this->path, &this->actor.world.pos); this->actor.home.pos = this->actor.world.pos; - if (((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || - (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && + if (GameInteractor_Should(GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE), NULL) && CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { EnGo2_GetItemAnimation(this, play); } else { @@ -1862,11 +1832,7 @@ void EnGo2_SetupGetItem(EnGo2* this, PlayState* play) { this->actor.parent = NULL; this->actionFunc = EnGo2_SetGetItem; } else { - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, this->getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); - } + func_8002F434(&this->actor, play, this->getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } } @@ -1874,47 +1840,27 @@ void EnGo2_SetGetItem(EnGo2* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - // For randomizer, handle updating the states for the gorons after receiving the item based on - // the goron type rather then the item being received - if (IS_RANDO) { - switch (this->actor.params & 0x1F) { - case GORON_DMT_BIGGORON: - // Resolves #1301. unk_13EE is used to set the opacity of the HUD. The trade sequence discussion with Biggoron - // sets the HUD to transparent, and it is restored at z_message_PAL:3549, but by specifically watching for - // trade sequence items, this leaves it transparent for non-trade sequence items (in rando) so we fix that here - gSaveContext.unk_13EE = 0x32; + if (GameInteractor_Should(GI_VB_EN_GO2_RESET_AFTER_GET_ITEM, true, this)) { + switch (this->getItemId) { + case GI_CLAIM_CHECK: + Environment_ClearBgsDayCount(); + EnGo2_GetItemAnimation(this, play); return; - case GORON_CITY_LINK: + case GI_TUNIC_GORON: + Flags_SetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED); EnGo2_GetItemAnimation(this, play); return; - case GORON_CITY_ROLLING_BIG: + case GI_SWORD_BGS: + gSaveContext.bgsFlag = true; + break; + case GI_BOMB_BAG_30: + case GI_BOMB_BAG_40: EnGo2_RollingAnimation(this, play); this->actionFunc = EnGo2_GoronRollingBigContinueRolling; return; } this->actionFunc = func_80A46B40; - return; - } - - switch (this->getItemId) { - case GI_CLAIM_CHECK: - Environment_ClearBgsDayCount(); - EnGo2_GetItemAnimation(this, play); - return; - case GI_TUNIC_GORON: - Flags_SetInfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED); - EnGo2_GetItemAnimation(this, play); - return; - case GI_SWORD_BGS: - gSaveContext.bgsFlag = true; - break; - case GI_BOMB_BAG_30: - case GI_BOMB_BAG_40: - EnGo2_RollingAnimation(this, play); - this->actionFunc = EnGo2_GoronRollingBigContinueRolling; - return; } - this->actionFunc = func_80A46B40; } } @@ -1925,12 +1871,12 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, PlayState* play) { this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; this->actor.shape.rot.y += 0x5B0; this->trackingMode = NPC_TRACKING_NONE; - this->animTimer = IS_RANDO ? 0 : (this->skelAnime.endFrame + 60.0f + 60.0f); // eyeDrops animation timer + this->animTimer = !GameInteractor_Should(GI_VB_PLAY_EYEDROPS_CS, true, NULL) ? 0 : (this->skelAnime.endFrame + 60.0f + 60.0f); // eyeDrops animation timer this->eyeMouthTexState = 2; this->unk_20C = 0; this->goronState++; func_800F483C(0x28, 5); - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_EYEDROPS_CS, true, NULL)) { OnePointCutscene_Init(play, 4190, -99, &this->actor, MAIN_CAM); } break; @@ -1959,16 +1905,15 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, PlayState* play) { this->trackingMode = NPC_TRACKING_HEAD_AND_TORSO; this->skelAnime.playSpeed = 0.0f; this->skelAnime.curFrame = this->skelAnime.endFrame; - if (IS_RANDO) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_EYEDROPS, GI_CLAIM_CHECK); - Randomizer_ConsumeAdultTradeItem(play, ITEM_EYEDROPS); - EnGo2_GetItemEntry(this, play, getItemEntry); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS); - } else { + + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS); + if(GameInteractor_Should(GI_VB_TRADE_EYEDROPS, true, this)) { u32 getItemId = GI_CLAIM_CHECK; EnGo2_GetItem(this, play, getItemId); + this->actionFunc = EnGo2_SetupGetItem; + } else { + this->actionFunc = EnGo2_SetGetItem; } - this->actionFunc = EnGo2_SetupGetItem; this->goronState = 0; } break; diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h index 86ac0c32e..185a036f4 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h @@ -107,4 +107,9 @@ typedef struct EnGo2 { /* */ GetItemEntry getItemEntry; } EnGo2; // size = 0x05A0 +void EnGo2_GetItemAnimation(EnGo2* enGo2, PlayState* play); +void EnGo2_RollingAnimation(EnGo2* enGo2, PlayState* play); +void EnGo2_GoronRollingBigContinueRolling(EnGo2* enGo2, PlayState* play); +void func_80A46B40(EnGo2* enGo2, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c index 14b3703b8..c8d70fe1f 100644 --- a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c +++ b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c @@ -7,7 +7,7 @@ #include "z_en_hs.h" #include "vt.h" #include "objects/object_hs/object_hs.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -79,25 +79,7 @@ void EnHs_Init(Actor* thisx, PlayState* play) { // "chicken shop (adult era)" osSyncPrintf(VT_FGCOL(CYAN) " ヒヨコの店(大人の時) \n" VT_RST); func_80A6E3A0(this, func_80A6E9AC); - bool shouldSpawn; - bool tradedMushroom = Flags_GetItemGetInf(ITEMGETINF_30); - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) { - // To explain the logic because Fado and Grog are linked: - // - If you have Cojiro, then spawn Grog and not Fado. - // - If you don't have Cojiro but do have Odd Potion, spawn Fado and not Grog. - // - If you don't have either, spawn Grog if you haven't traded the Odd Mushroom. - // - If you don't have either but have traded the mushroom, don't spawn either. - if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) { - shouldSpawn = true; - } else if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION)) { - shouldSpawn = false; - } else { - shouldSpawn = !tradedMushroom; - } - } else { - shouldSpawn = !tradedMushroom; - } - if (!shouldSpawn) { + if (GameInteractor_Should(GI_VB_DESPAWN_GROG, Flags_GetItemGetInf(ITEMGETINF_30), this)) { // "chicken shop closed" osSyncPrintf(VT_FGCOL(CYAN) " ヒヨコ屋閉店 \n" VT_RST); Actor_Kill(&this->actor); @@ -148,11 +130,11 @@ void func_80A6E5EC(EnHs* this, PlayState* play) { void func_80A6E630(EnHs* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_TRADE_TIMER_ODD_MUSHROOM, true, NULL)) { func_80088AA0(180); + gSaveContext.eventInf[1] &= ~1; } func_80A6E3A0(this, func_80A6E6B0); - gSaveContext.eventInf[1] &= ~1; } this->unk_2A8 |= 1; @@ -175,19 +157,12 @@ void func_80A6E70C(EnHs* this, PlayState* play) { } void func_80A6E740(EnHs* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_TRADE_COJIRO, true, this)) { this->actor.parent = NULL; + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO); func_80A6E3A0(this, func_80A6E630); } else { - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TRADE_COJIRO, GI_ODD_MUSHROOM); - Randomizer_ConsumeAdultTradeItem(play, ITEM_COJIRO); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO); - } else { - s32 itemId = GI_ODD_MUSHROOM; - func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f); - } + func_8002F434(&this->actor, play, GI_ODD_MUSHROOM, 10000.0f, 50.0f); } this->unk_2A8 |= 1; @@ -198,14 +173,8 @@ void func_80A6E7BC(EnHs* this, PlayState* play) { switch (play->msgCtx.choiceIndex) { case 0: func_80A6E3A0(this, func_80A6E740); - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TRADE_COJIRO, GI_ODD_MUSHROOM); - Randomizer_ConsumeAdultTradeItem(play, ITEM_COJIRO); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO); - } else { - s32 itemId = GI_ODD_MUSHROOM; - func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f); + if (GameInteractor_Should(GI_VB_TRADE_COJIRO, true, this)) { + func_8002F434(&this->actor, play, GI_ODD_MUSHROOM, 10000.0f, 50.0f); } break; case 1: diff --git a/soh/src/overlays/actors/ovl_En_Js/z_en_js.c b/soh/src/overlays/actors/ovl_En_Js/z_en_js.c index 50be2e458..793017d3d 100644 --- a/soh/src/overlays/actors/ovl_En_Js/z_en_js.c +++ b/soh/src/overlays/actors/ovl_En_Js/z_en_js.c @@ -6,6 +6,7 @@ #include "z_en_js.h" #include "objects/object_js/object_js.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -127,23 +128,15 @@ void func_80A8910C(EnJs* this, PlayState* play) { } void func_80A89160(EnJs* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_CARPET_SALESMAN, true, this)) { this->actor.parent = NULL; En_Js_SetupAction(this, func_80A8910C); + Flags_SetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN); } else { - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN)) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_WASTELAND_BOMBCHU_SALESMAN, GI_BOMBCHUS_10); - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; - GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f); - Flags_SetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN); - } else { - GetItemEntry itemEntry = ItemTable_Retrieve(GI_BOMBCHUS_10); - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; - func_8002F434(&this->actor, play, GI_BOMBCHUS_10, 10000.0f, 50.0f); - } + GetItemEntry itemEntry = ItemTable_Retrieve(GI_BOMBCHUS_10); + gSaveContext.pendingSale = itemEntry.itemId; + gSaveContext.pendingSaleMod = itemEntry.modIndex; + func_8002F434(&this->actor, play, GI_BOMBCHUS_10, 10000.0f, 50.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c index 25299f5b0..c801356c9 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c @@ -10,7 +10,7 @@ #include "objects/object_km1/object_km1.h" #include "objects/object_kw1/object_kw1.h" #include "vt.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -1027,20 +1027,9 @@ s32 EnKo_CanSpawn(EnKo* this, PlayState* play) { } case SCENE_LOST_WOODS: - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) { - // To explain the logic because Fado and Grog are linked: - // - If you have Cojiro, then spawn Grog and not Fado. - // - If you don't have Cojiro but do have Odd Potion, spawn Fado and not Grog. - // - If you don't have either, spawn Grog if you haven't traded the Odd Mushroom. - // - If you don't have either but have traded the mushroom, don't spawn either. - if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) { - return false; - } else { - return PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION); - } - } else { - return (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_ODD_POTION) ? true : false; - } + return GameInteractor_Should(GI_VB_SPAWN_LW_FADO, ( + (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_ODD_POTION) ? true : false + ), this); default: return false; } @@ -1186,18 +1175,10 @@ void func_80A99048(EnKo* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_ELF, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 3); if (ENKO_TYPE == ENKO_TYPE_CHILD_3) { - if (!IS_RANDO) { - if (!CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) { - this->collider.dim.height += 200; - this->actionFunc = func_80A995CC; - return; - } - } else { - if (!Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD)) { - this->collider.dim.height += 200; - this->actionFunc = func_80A995CC; - return; - } + if (!GameInteractor_Should(GI_VB_OPEN_KOKIRI_FOREST, CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD), this)) { + this->collider.dim.height += 200; + this->actionFunc = func_80A995CC; + return; } Path_CopyLastPoint(this->path, &this->actor.world.pos); } @@ -1230,18 +1211,11 @@ void func_80A99438(EnKo* this, PlayState* play) { } void func_80A99504(EnKo* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_TRADE_ODD_POTION, true, this)) { this->actor.parent = NULL; this->actionFunc = func_80A99560; } else { - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TRADE_ODD_POTION, GI_SAW); - Randomizer_ConsumeAdultTradeItem(play, ITEM_ODD_POTION); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 120.0f, 10.0f); - } else { - s32 itemId = GI_SAW; - func_8002F434(&this->actor, play, itemId, 120.0f, 10.0f); - } + func_8002F434(&this->actor, play, GI_SAW, 120.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h index c247f53b9..5deeef465 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h @@ -57,4 +57,8 @@ typedef enum { ENKO_FQS_ADULT_SAVED } KokiriForestQuestState; +void func_80A995CC(EnKo* actor, PlayState* play); +void func_80A99384(EnKo* actor, PlayState* play); +void func_80A99560(EnKo* actor, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index ad3bd0ab5..3d5c2c354 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -6,7 +6,7 @@ #include "z_en_kz.h" #include "objects/object_kz/object_kz.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -73,12 +73,9 @@ static AnimationInfo sAnimationInfo[] = { u16 EnKz_GetTextNoMaskChild(PlayState* play, EnKz* this) { Player* player = GET_PLAYER(play); - if ((IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY)) || - (!IS_RANDO && CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE))) { - // Allow turning in Ruto's letter even if you have already rescued her - if (IS_RANDO && !Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { - player->exchangeItemId = EXCH_ITEM_LETTER_RUTO; - } + if (GameInteractor_Should(GI_VB_KING_ZORA_THANK_CHILD, ( + CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) + ), this)) { return 0x402B; } else if (Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { return 0x401C; @@ -94,8 +91,10 @@ u16 EnKz_GetTextNoMaskAdult(PlayState* play, EnKz* this) { // this works because both ITEM_NONE and later trade items are > ITEM_FROG if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_FROG) { if (!Flags_GetInfTable(INFTABLE_139)) { - if (!IS_RANDO) { - return CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) ? 0x401F : 0x4012; + if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, ( + !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) + ), this)) { + return 0x401F; } else { return 0x4012; } @@ -243,7 +242,9 @@ void func_80A9CB18(EnKz* this, PlayState* play) { Player* player = GET_PLAYER(play); if (func_80A9C95C(play, this, &this->interactInfo.talkState, 340.0f, EnKz_GetText, func_80A9C6C0)) { - if (((IS_RANDO && LINK_IS_CHILD) || this->actor.textId == 0x401A) && !Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { + if (GameInteractor_Should(GI_VB_BE_ABLE_TO_EXCHANGE_RUTOS_LETTER, (this->actor.textId == 0x401A), this) && + !Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) + { if (func_8002F368(play) == EXCH_ITEM_LETTER_RUTO) { this->actor.textId = 0x401B; this->sfxPlayed = false; @@ -257,7 +258,7 @@ void func_80A9CB18(EnKz* this, PlayState* play) { if (LINK_IS_ADULT) { if ((INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_PRESCRIPTION) && (func_8002F368(play) == EXCH_ITEM_PRESCRIPTION)) { - if (!IS_RANDO || !Flags_GetTreasure(play, 0x1F)) { + if (GameInteractor_Should(GI_VB_TRADE_PRESCRIPTION, true, this)) { this->actor.textId = 0x4014; this->sfxPlayed = false; player->actor.textId = this->actor.textId; @@ -271,11 +272,11 @@ void func_80A9CB18(EnKz* this, PlayState* play) { this->actor.textId = CHECK_QUEST_ITEM(QUEST_SONG_SERENADE) ? 0x4045 : 0x401A; player->actor.textId = this->actor.textId; } else { - if (!IS_RANDO) { - this->actor.textId = CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) ? 0x401F : 0x4012; - } else { - this->actor.textId = 0x4012; - } + this->actor.textId = + !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, + (!CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA)), this) + ? 0x401F + : 0x4012; player->actor.textId = this->actor.textId; } @@ -344,29 +345,10 @@ void EnKz_Init(Actor* thisx, PlayState* play) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; Animation_ChangeByInfo(&this->skelanime, sAnimationInfo, ENKZ_ANIM_0); - if (!IS_RANDO) { - if (Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { - EnKz_SetMovedPos(this, play); - } - } else { - int zorasFountain = Randomizer_GetSettingValue(RSK_ZORAS_FOUNTAIN); - switch (zorasFountain) { - case 0: - if (Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { - EnKz_SetMovedPos(this, play); - } - break; - case 1: - if (LINK_IS_ADULT) { - EnKz_SetMovedPos(this, play); - } else if (Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) { - EnKz_SetMovedPos(this, play); - } - break; - case 2: - EnKz_SetMovedPos(this, play); - break; - } + if (GameInteractor_Should(GI_VB_KING_ZORA_BE_MOVED, ( + Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED) + ), this)) { + EnKz_SetMovedPos(this, play); } if (LINK_IS_ADULT) { @@ -465,37 +447,29 @@ void EnKz_SetupGetItem(EnKz* this, PlayState* play) { f32 xzRange; f32 yRange; - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || ( + (this->isTrading && !GameInteractor_Should(GI_VB_TRADE_PRESCRIPTION, true, this)) || + (!this->isTrading && !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, true, this)) + )) { this->actor.parent = NULL; this->interactInfo.talkState = NPC_TALK_STATE_TALKING; this->actionFunc = EnKz_StartTimer; - } else { - if (IS_RANDO) { - if (this->isTrading) { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_TRADE_PRESCRIPTION, GI_FROG); - getItemId = getItemEntry.getItemId; - Randomizer_ConsumeAdultTradeItem(play, ITEM_PRESCRIPTION); - Flags_SetTreasure(play, 0x1F); - } else { - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_KING_ZORA_THAWED, GI_TUNIC_ZORA); - getItemId = getItemEntry.getItemId; - } + if (!this->isTrading) { + Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); } else { - getItemId = this->isTrading ? GI_FROG : GI_TUNIC_ZORA; + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); } + } else { + getItemId = this->isTrading ? GI_FROG : GI_TUNIC_ZORA; yRange = fabsf(this->actor.yDistToPlayer) + 1.0f; xzRange = this->actor.xzDistToPlayer + 1.0f; - if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) { - func_8002F434(&this->actor, play, getItemId, xzRange, yRange); - } else { - GiveItemEntryFromActor(&this->actor, play, getItemEntry, xzRange, yRange); - } + func_8002F434(&this->actor, play, getItemId, xzRange, yRange); } } void EnKz_StartTimer(EnKz* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { - if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_FROG && !IS_RANDO) { + if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_FROG && GameInteractor_Should(GI_VB_TRADE_TIMER_FROG, true, NULL)) { func_80088AA0(180); // start timer2 with 3 minutes gSaveContext.eventInf[1] &= ~1; } diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h index 37feb841a..c97732356 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h @@ -28,4 +28,6 @@ typedef struct EnKz { /* 0x02BE */ s16 unk_2BE[12]; } EnKz; // size = 0x02D8 +void EnKz_SetupGetItem(EnKz* enKz, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c index 8a11eb668..75db192cf 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c @@ -6,6 +6,7 @@ #include "z_en_ma1.h" #include "objects/object_ma1/object_ma1.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -25,7 +26,6 @@ void func_80AA106C(EnMa1* this, PlayState* play); void func_80AA10EC(EnMa1* this, PlayState* play); void func_80AA1150(EnMa1* this, PlayState* play); void EnMa1_DoNothing(EnMa1* this, PlayState* play); -void EnMa1_WaitForSongGive(EnMa1* this, PlayState* play); const ActorInit En_Ma1_InitVars = { ACTOR_EN_MA1, @@ -90,25 +90,16 @@ static void* sEyeTextures[] = { gMalonChildEyeClosedTex, }; -bool Randomizer_ObtainedMalonHCReward() { - return Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG); -} - u16 EnMa1_GetText(PlayState* play, Actor* thisx) { - // Special case for Malon Hyrule Castle Text. Placing it here at the beginning - // has the added benefit of circumventing mask text if wearing bunny hood. - if (IS_RANDO && play->sceneNum == SCENE_HYRULE_CASTLE) { - return Randomizer_ObtainedMalonHCReward() ? 0x2044 : 0x2043; - } + bool malonReturnedFromCastle = GameInteractor_Should(GI_VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE), NULL); + bool malonTaughtEponasSong = GameInteractor_Should(GI_VB_MALON_ALREADY_TAUGHT_EPONAS_SONG, CHECK_QUEST_ITEM(QUEST_SONG_EPONA), NULL); u16 faceReaction = Text_GetFaceReaction(play, 0x17); if (faceReaction != 0) { return faceReaction; } - if (!IS_RANDO) { - if (CHECK_QUEST_ITEM(QUEST_SONG_EPONA)) { - return 0x204A; - } + if (malonTaughtEponasSong) { + return 0x204A; } if (Flags_GetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON)) { return 0x2049; @@ -120,7 +111,7 @@ u16 EnMa1_GetText(PlayState* play, Actor* thisx) { return 0x2048; } } - if (Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE)) { + if (malonReturnedFromCastle) { return 0x2047; } if (Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG)) { @@ -194,6 +185,8 @@ s16 func_80AA0778(PlayState* play, Actor* thisx) { } s32 func_80AA08C4(EnMa1* this, PlayState* play) { + bool malonReturnedFromCastle = GameInteractor_Should(GI_VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE), NULL); + if ((this->actor.shape.rot.z == 3) && (gSaveContext.sceneSetupIndex == 5)) { return 1; } @@ -202,32 +195,24 @@ s32 func_80AA08C4(EnMa1* this, PlayState* play) { } // Causes Malon to appear in the market if you haven't met her yet. if (((play->sceneNum == SCENE_MARKET_NIGHT) || (play->sceneNum == SCENE_MARKET_DAY)) && - !Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE) && !Flags_GetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE)) { + !malonReturnedFromCastle && !Flags_GetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE)) { return 1; } - if ((play->sceneNum == SCENE_HYRULE_CASTLE) && // if we're at hyrule castle - (!Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE) || // and talon hasn't left - (IS_RANDO && - !Randomizer_ObtainedMalonHCReward()))) { // or we're rando'd and haven't gotten malon's HC check - if (Flags_GetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE)) { // if we've met malon - return 1; // make her appear at the castle - } else { // if we haven't met malon - Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE); // set the flag for meeting malon - return 0; // don't make her appear at the castle + if ((play->sceneNum == SCENE_HYRULE_CASTLE) && !malonReturnedFromCastle) { + if (Flags_GetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE)) { + return 1; + } else { + Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE); + return 0; } } - // Malon asleep in her bed if Talon has left Hyrule Castle and it is nighttime. - if ((play->sceneNum == SCENE_LON_LON_BUILDINGS) && IS_NIGHT && (Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE))) { + if ((play->sceneNum == SCENE_LON_LON_BUILDINGS) && IS_NIGHT && malonReturnedFromCastle) { return 1; } - // Don't spawn Malon if none of the above are true and we are not in Lon Lon Ranch. if (play->sceneNum != SCENE_LON_LON_RANCH) { return 0; } - // If we've gotten this far, we're in Lon Lon Ranch. Spawn Malon if it is daytime, Talon has left Hyrule Castle, and - // either we are not randomized, or we are and we have received Malon's item at Hyrule Castle. - if ((this->actor.shape.rot.z == 3) && IS_DAY && (Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE)) && - ((IS_RANDO && Randomizer_ObtainedMalonHCReward()) || !IS_RANDO)) { + if ((this->actor.shape.rot.z == 3) && IS_DAY && malonReturnedFromCastle) { return 1; } return 0; @@ -284,6 +269,8 @@ void func_80AA0B74(EnMa1* this) { void EnMa1_Init(Actor* thisx, PlayState* play) { EnMa1* this = (EnMa1*)thisx; + bool malonReturnedFromCastle = GameInteractor_Should(GI_VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE), NULL); + bool malonTaughtEponasSong = GameInteractor_Should(GI_VB_MALON_ALREADY_TAUGHT_EPONAS_SONG, CHECK_QUEST_ITEM(QUEST_SONG_EPONA), NULL); s32 pad; ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 18.0f); @@ -292,12 +279,6 @@ void EnMa1_Init(Actor* thisx, PlayState* play) { Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(22), &sColChkInfoInit); - if (IS_RANDO) { // Skip Malon's multiple textboxes before getting an item - Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE); - Flags_SetInfTable(INFTABLE_MET_CHILD_MALON_AT_CASTLE_OR_MARKET); - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_CASTLE_OR_MARKET); - } - if (!func_80AA08C4(this, play)) { Actor_Kill(&this->actor); return; @@ -308,21 +289,10 @@ void EnMa1_Init(Actor* thisx, PlayState* play) { this->actor.targetMode = 6; this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - // To avoid missing a check, we want Malon to have the actionFunc for singing, but not reacting to Ocarina, if any of - // the following are true. - // 1. Talon has not left Hyrule Castle. - // 2. We are Randomized and have not obtained Malon's Weird Egg Check. - // 3. We are not Randomized and have obtained Epona's Song - if (!Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE) || (IS_RANDO && !Randomizer_ObtainedMalonHCReward()) || (CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && !IS_RANDO) || - (IS_RANDO && Flags_GetTreasure(play, 0x1F))) { + if (!malonReturnedFromCastle || malonTaughtEponasSong) { this->actionFunc = func_80AA0D88; EnMa1_ChangeAnim(this, ENMA1_ANIM_2); - // If none of the above conditions were true, set Malon up to teach Epona's Song. } else { - if (IS_RANDO) { // Skip straight to "let's sing it together" textbox in the ranch - Flags_SetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON); - } - this->actionFunc = func_80AA0F44; EnMa1_ChangeAnim(this, ENMA1_ANIM_2); } @@ -336,6 +306,9 @@ void EnMa1_Destroy(Actor* thisx, PlayState* play) { } void func_80AA0D88(EnMa1* this, PlayState* play) { + bool malonReturnedFromCastle = GameInteractor_Should(GI_VB_MALON_RETURN_FROM_CASTLE, Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE), NULL); + bool malonTaughtEponasSong = GameInteractor_Should(GI_VB_MALON_ALREADY_TAUGHT_EPONAS_SONG, CHECK_QUEST_ITEM(QUEST_SONG_EPONA), NULL); + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { if (this->skelAnime.animation != &gMalonChildIdleAnim) { EnMa1_ChangeAnim(this, ENMA1_ANIM_1); @@ -346,16 +319,9 @@ void func_80AA0D88(EnMa1* this, PlayState* play) { } } - // We want to Kill Malon's Actor outside of randomizer when Talon is freed. In Randomizer we don't kill Malon's - // Actor here, otherwise if we wake up Talon first and then get her check she will spontaneously - // disappear. - if ((play->sceneNum == SCENE_HYRULE_CASTLE) && (!IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE))) { + if ((play->sceneNum == SCENE_HYRULE_CASTLE) && malonReturnedFromCastle) { Actor_Kill(&this->actor); - // We want Malon to give the Weird Egg Check (see function below) in the following situations: - // 1. Talon as not left Hyrule Castle (Vanilla) OR - // 2. We haven't obtained Malon's Weird Egg Check (Randomizer only) OR - // 3. We have Epona's Song? (Vanilla only, not sure why it's here but I didn't write that one) - } else if ((!Flags_GetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE) || (IS_RANDO && !Randomizer_ObtainedMalonHCReward())) || (CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && !IS_RANDO)) { + } else if (!malonReturnedFromCastle || malonTaughtEponasSong) { if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { this->actionFunc = func_80AA0EA0; play->msgCtx.stateTimer = 4; @@ -365,21 +331,16 @@ void func_80AA0D88(EnMa1* this, PlayState* play) { } void func_80AA0EA0(EnMa1* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_WEIRD_EGG, true, NULL)) { this->actor.parent = NULL; this->actionFunc = func_80AA0EFC; } else { - if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_WEIRD_EGG, 120.0f, 10.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HC_MALON_EGG, GI_WEIRD_EGG); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 120.0f, 10.0f); - } + func_8002F434(&this->actor, play, GI_WEIRD_EGG, 120.0f, 10.0f); } } void func_80AA0EFC(EnMa1* this, PlayState* play) { - if (this->interactInfo.talkState == NPC_TALK_STATE_ITEM_GIVEN) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ITEM_GIVEN || !GameInteractor_Should(GI_VB_GIVE_ITEM_WEIRD_EGG, true, NULL)) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actionFunc = func_80AA0D88; Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG); @@ -387,24 +348,6 @@ void func_80AA0EFC(EnMa1* this, PlayState* play) { } } -void GivePlayerRandoRewardMalon(EnMa1* malon, PlayState* play, RandomizerCheck check) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_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(play)->actor.id && - !Flags_GetTreasure(play, 0x1F)) { - Flags_SetTreasure(play, 0x1F); - // 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(play, 0x1F)) { - GiveItemEntryFromActor(&malon->actor, play, getItemEntry, 10000.0f, 100.0f); - } - // make malon sing again after giving the item. - malon->interactInfo.talkState = NPC_TALK_STATE_IDLE; - malon->unk_1E0 = 1; -} - void func_80AA0F44(EnMa1* this, PlayState* play) { Player* player = GET_PLAYER(play); @@ -419,7 +362,6 @@ void func_80AA0F44(EnMa1* this, PlayState* play) { } if (Flags_GetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON)) { - // When the player pulls out the Ocarina while close to Malon if (player->stateFlags2 & 0x1000000) { player->stateFlags2 |= 0x2000000; player->unk_6A8 = &this->actor; @@ -427,19 +369,10 @@ void func_80AA0F44(EnMa1* this, PlayState* play) { Message_StartTextbox(play, this->actor.textId, NULL); this->interactInfo.talkState = NPC_TALK_STATE_TALKING; this->actor.flags |= ACTOR_FLAG_WILL_TALK; - // when rando'ed, skip to the Item Giving. Otherwise go to the song teaching code. - this->actionFunc = IS_RANDO ? func_80AA1150 : func_80AA106C; + this->actionFunc = 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 (IS_RANDO && (Actor_TextboxIsClosing(&this->actor, play) && play->msgCtx.textId == 0x2049) && - (INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_NONE || INV_CONTENT(ITEM_OCARINA_TIME) != ITEM_NONE)) { - this->actionFunc = EnMa1_WaitForSongGive; - } } } @@ -461,48 +394,16 @@ void func_80AA10EC(EnMa1* this, PlayState* play) { } } -void EnMa1_WaitForSongGive(EnMa1* this, PlayState* play) { - // Actually give the song check. - GivePlayerRandoRewardMalon(this, play, 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, PlayState* play) { - if (play->csCtx.state == CS_STATE_IDLE) { - this->actionFunc = func_80AA0F44; - play->msgCtx.ocarinaMode = OCARINA_MODE_04; - } - - if (IS_RANDO) { - // Transition to the giving the song check on the next update run. - this->actionFunc = EnMa1_WaitForSongGive; - } -} - void func_80AA1150(EnMa1* this, PlayState* play) { GET_PLAYER(play)->stateFlags2 |= 0x800000; - // When rando'ed, trigger the "song learned" Ocarina mode. - if (IS_RANDO && (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING)) { - play->msgCtx.ocarinaMode = OCARINA_MODE_03; - } - if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { - if (!IS_RANDO) { - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; - gSaveContext.nextCutsceneIndex = 0xFFF1; - play->transitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST); - play->transitionTrigger = TRANS_TRIGGER_START; - 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_WILL_TALK; - play->msgCtx.ocarinaMode = OCARINA_MODE_00; - } + Flags_SetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG); + play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + gSaveContext.nextCutsceneIndex = 0xFFF1; + play->transitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST); + play->transitionTrigger = TRANS_TRIGGER_START; + this->actionFunc = EnMa1_DoNothing; } } diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h index 55b53bd72..f06f220c9 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h @@ -20,4 +20,7 @@ typedef struct EnMa1 { /* 0x01E8 */ NpcInteractInfo interactInfo; } EnMa1; // size = 0x0210 +void func_80AA106C(EnMa1* enMa1, PlayState* play); +void func_80AA0D88(EnMa1* enMa1, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c index 14d9cbb7b..6fb9119bf 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c @@ -7,6 +7,7 @@ #include "z_en_md.h" #include "objects/object_md/object_md.h" #include "overlays/actors/ovl_En_Elf/z_en_elf.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -372,11 +373,7 @@ u16 EnMd_GetTextKokiriForest(PlayState* play, EnMd* this) { this->unk_208 = 0; this->unk_209 = TEXT_STATE_NONE; - // In rando, skip talking about the tree being dead so we can have the prompt for sword and shield instead - if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) || - (IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) && - Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE) && - !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH))) { + if (GameInteractor_Should(GI_VB_MIDO_CONSIDER_DEKU_TREE_DEAD, CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD), this)) { return 0x1045; } @@ -486,25 +483,6 @@ s16 func_80AAAF04(PlayState* play, Actor* thisx) { } u8 EnMd_ShouldSpawn(EnMd* this, PlayState* play) { - // In rando, Mido's spawn logic is adjusted to support closed deku/forest options - // He will spawn in the forest if you haven't showed the sword and shield, and will remain - // in the forest until you've obtained Zelda's letter or Deku Tree dies - // This is to ensure Deku Tree can still be opened in dungeon entrance rando even if Ghoma is defeated - if (IS_RANDO) { - if (play->sceneNum == SCENE_LOST_WOODS) { - return 1; - } - - if (Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) && - Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && - (Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER) || - Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD))) { - return play->sceneNum == SCENE_MIDOS_HOUSE && !LINK_IS_ADULT; - } - - return play->sceneNum == SCENE_KOKIRI_FOREST; - } - if (play->sceneNum == SCENE_KOKIRI_FOREST) { if (!Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && !Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER)) { return 1; @@ -512,7 +490,7 @@ u8 EnMd_ShouldSpawn(EnMd* this, PlayState* play) { } if (play->sceneNum == SCENE_MIDOS_HOUSE) { - if (((Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH)) != 0) || ((Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER)) != 0)) { + if (Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) || Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER)) { if (!LINK_IS_ADULT) { return 1; } @@ -681,9 +659,8 @@ void EnMd_Init(Actor* thisx, PlayState* play) { this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, FAIRY_KOKIRI); if (((play->sceneNum == SCENE_KOKIRI_FOREST) && !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) || - ((play->sceneNum == SCENE_KOKIRI_FOREST) && (Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) && - ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) || - (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE)))) || + ((play->sceneNum == SCENE_KOKIRI_FOREST) && Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) && + CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) || ((play->sceneNum == SCENE_LOST_WOODS) && !Flags_GetEventChkInf(EVENTCHKINF_PLAYED_SARIAS_SONG_FOR_MIDO_AS_ADULT))) { this->actor.home.pos = this->actor.world.pos; this->actionFunc = func_80AAB948; @@ -745,10 +722,11 @@ void func_80AAB948(EnMd* this, PlayState* play) { this->skelAnime.playSpeed = CLAMP(temp, 1.0f, 3.0f); } - if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { - if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) || - IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE) && - Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && + if ( + (GameInteractor_Should(GI_VB_MOVE_MIDO_IN_KOKIRI_FOREST, this->interactInfo.talkState == NPC_TALK_STATE_ACTION, this) && play->sceneNum == SCENE_KOKIRI_FOREST) || + this->interactInfo.talkState == NPC_TALK_STATE_ACTION + ) { + if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && (play->sceneNum == SCENE_KOKIRI_FOREST)) { play->msgCtx.msgMode = MSGMODE_PAUSED; } @@ -815,9 +793,7 @@ void func_80AABD0C(EnMd* this, PlayState* play) { return; } - if ((!IS_RANDO && CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) || - IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE) && - Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && + if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH) && (play->sceneNum == SCENE_KOKIRI_FOREST)) { Message_CloseTextbox(play); Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH); diff --git a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c index e5501858c..54e48bfc2 100644 --- a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c +++ b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c @@ -6,7 +6,7 @@ #include "z_en_mk.h" #include "objects/object_mk/object_mk.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -93,37 +93,24 @@ void func_80AACA40(EnMk* this, PlayState* play) { } void func_80AACA94(EnMk* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play) != 0) { + if (Actor_HasParent(&this->actor, play) != 0 || !GameInteractor_Should(GI_VB_TRADE_FROG, true, this)) { this->actor.parent = NULL; this->actionFunc = func_80AACA40; - if (!IS_RANDO) { + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG); + if (GameInteractor_Should(GI_VB_TRADE_TIMER_EYEDROPS, true, NULL)) { func_80088AA0(240); gSaveContext.eventInf[1] &= ~1; } } else { - if (IS_RANDO) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_TRADE_FROG, GI_EYEDROPS); - Randomizer_ConsumeAdultTradeItem(play, ITEM_FROG); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG); - } else { - s32 getItemID = GI_EYEDROPS; - func_8002F434(&this->actor, play, getItemID, 10000.0f, 50.0f); - } + func_8002F434(&this->actor, play, GI_EYEDROPS, 10000.0f, 50.0f); } } void func_80AACB14(EnMk* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { this->actionFunc = func_80AACA94; - if (IS_RANDO) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_TRADE_FROG, GI_EYEDROPS); - Randomizer_ConsumeAdultTradeItem(play, ITEM_FROG); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG); - } else { - s32 getItemID = GI_EYEDROPS; - func_8002F434(&this->actor, play, getItemID, 10000.0f, 50.0f); + if (GameInteractor_Should(GI_VB_TRADE_FROG, true, this)) { + func_8002F434(&this->actor, play, GI_EYEDROPS, 10000.0f, 50.0f); } } } @@ -150,7 +137,7 @@ void func_80AACC04(EnMk* this, PlayState* play) { if (this->timer > 0) { this->timer--; } else { - this->timer = IS_RANDO ? 0 : 16; + this->timer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 16 : 0; this->actionFunc = func_80AACBAC; Animation_Change(&this->skelAnime, &object_mk_Anim_000D88, 1.0f, 0.0f, Animation_GetLastFrame(&object_mk_Anim_000D88), ANIMMODE_LOOP, -4.0f); @@ -163,7 +150,7 @@ void func_80AACCA0(EnMk* this, PlayState* play) { this->timer--; this->actor.shape.rot.y += 0x800; } else { - this->timer = IS_RANDO ? 0 : 120; + this->timer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 120 : 0; this->actionFunc = func_80AACC04; Animation_Change(&this->skelAnime, &object_mk_Anim_000724, 1.0f, 0.0f, Animation_GetLastFrame(&object_mk_Anim_000724), ANIMMODE_LOOP, -4.0f); @@ -179,7 +166,7 @@ void func_80AACD48(EnMk* this, PlayState* play) { this->actionFunc = func_80AACCA0; play->msgCtx.msgMode = MSGMODE_PAUSED; player->exchangeItemId = EXCH_ITEM_NONE; - this->timer = IS_RANDO ? 0 : 16; + this->timer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 16 : 0; Animation_Change(&this->skelAnime, &object_mk_Anim_000D88, 1.0f, 0.0f, Animation_GetLastFrame(&object_mk_Anim_000D88), ANIMMODE_LOOP, -4.0f); this->flags &= ~2; @@ -213,29 +200,20 @@ void func_80AACEE8(EnMk* this, PlayState* play) { } void func_80AACFA0(EnMk* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_LAB_DIVE, true, this)) { this->actor.parent = NULL; this->actionFunc = func_80AACA40; Flags_SetItemGetInf(ITEMGETINF_10); } else { - // not sure when/how/if this is getting called - if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); - } + func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 50.0f); } } void func_80AAD014(EnMk* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { this->actionFunc = func_80AACFA0; - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_LAB_DIVE, true, this)) { func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 50.0f); } } @@ -255,9 +233,9 @@ void EnMk_Wait(EnMk* this, PlayState* play) { player->actor.textId = this->actor.textId; this->actionFunc = func_80AACA40; } else { - // Skip eye drop text on rando if Link went in the water, so you can still receive the dive check - if (INV_CONTENT(ITEM_ODD_MUSHROOM) == ITEM_EYEDROPS && - (!IS_RANDO || this->swimFlag == 0)) { + if (GameInteractor_Should(GI_VB_USE_EYEDROP_DIALOGUE, ( + INV_CONTENT(ITEM_ODD_MUSHROOM) == ITEM_EYEDROPS + ), this)) { player->actor.textId = 0x4032; this->actionFunc = func_80AACA40; } else { diff --git a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c index b1d453f00..04b8166f7 100644 --- a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c +++ b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c @@ -6,6 +6,7 @@ #include "z_en_ms.h" #include "objects/object_ms/object_ms.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -127,20 +128,16 @@ void EnMs_Talk(EnMs* this, PlayState* play) { } else if (Message_ShouldAdvance(play)) { switch (play->msgCtx.choiceIndex) { case 0: // yes - if (gSaveContext.rupees < - ((IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) - ? 60 - : sPrices[BEANS_BOUGHT])) { + if (!GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_MAGIC_BEANS_PURCHASE, ( + gSaveContext.rupees >= sPrices[BEANS_BOUGHT]), this)) { Message_ContinueTextbox(play, 0x4069); // not enough rupees text return; } - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) { - GiveItemEntryFromActor(&this->actor, play, - Randomizer_GetItemFromKnownCheck(RC_ZR_MAGIC_BEAN_SALESMAN, GI_BEAN), 90.0f, 10.0f); - } else { + + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN, true, this)) { func_8002F434(&this->actor, play, GI_BEAN, 90.0f, 10.0f); + this->actionFunc = EnMs_Sell; } - this->actionFunc = EnMs_Sell; return; case 1: // no Message_ContinueTextbox(play, 0x4068); @@ -152,23 +149,14 @@ void EnMs_Talk(EnMs* this, PlayState* play) { void EnMs_Sell(EnMs* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { - Rupees_ChangeBy((IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) ? -60 : -sPrices[BEANS_BOUGHT]); + Rupees_ChangeBy(-sPrices[BEANS_BOUGHT]); this->actor.parent = NULL; - this->actionFunc = - (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) ? EnMs_Wait : EnMs_TalkAfterPurchase; + this->actionFunc = EnMs_TalkAfterPurchase; } else { - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_ZR_MAGIC_BEAN_SALESMAN, GI_BEAN); - gSaveContext.pendingSale = itemEntry.itemId; - gSaveContext.pendingSaleMod = itemEntry.modIndex; - GiveItemEntryFromActor(&this->actor, play, itemEntry, 90.0f, 10.0f); - BEANS_BOUGHT = 10; - } else { - GetItemEntry entry = ItemTable_Retrieve(GI_BEAN); - gSaveContext.pendingSaleMod = entry.modIndex; - gSaveContext.pendingSale = entry.itemId; - func_8002F434(&this->actor, play, GI_BEAN, 90.0f, 10.0f); - } + GetItemEntry entry = ItemTable_Retrieve(GI_BEAN); + gSaveContext.pendingSaleMod = entry.modIndex; + gSaveContext.pendingSale = entry.itemId; + func_8002F434(&this->actor, play, GI_BEAN, 90.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.h b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.h index 70b105073..e626056f0 100644 --- a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.h +++ b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.h @@ -18,4 +18,7 @@ typedef struct EnMs { /* 0x024C */ s16 activeTimer; } EnMs; // size = 0x0250 +void EnMs_TalkAfterPurchase(EnMs* enMs, PlayState* play); +void EnMs_Wait(EnMs* enMs, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c index a519209aa..9a3990cf8 100644 --- a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c +++ b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c @@ -8,6 +8,7 @@ #include "vt.h" #include "objects/object_nb/object_nb.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -326,7 +327,9 @@ void EnNb_GiveMedallion(EnNb* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0, 0xC); - Item_Give(play, ITEM_MEDALLION_SPIRIT); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SPIRIT_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_SPIRIT); + } } void EnNb_ComeUpImpl(EnNb* this, PlayState* play) { @@ -342,7 +345,9 @@ void EnNb_SetupChamberCsImpl(EnNb* this, PlayState* play) { this->action = NB_CHAMBER_UNDERGROUND; play->csCtx.segment = &D_80AB431C; gSaveContext.cutsceneTrigger = 2; - Item_Give(play, ITEM_MEDALLION_SPIRIT); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SPIRIT_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_SPIRIT); + } player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000; } } diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c index 8ddf52fad..b4e6d8892 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c @@ -3,7 +3,7 @@ #include "objects/object_os_anime/object_os_anime.h" #include "overlays/actors/ovl_En_Niw/z_en_niw.h" #include "vt.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -204,7 +204,9 @@ void func_80ABA244(EnNiwLady* this, PlayState* play) { EnNiw* currentCucco; s32 phi_s1; - this->cuccosInPen = IS_RANDO ? (7 - Randomizer_GetSettingValue(RSK_CUCCO_COUNT)) : 0; + if (GameInteractor_Should(GI_VB_SET_CUCCO_COUNT, true, this)) { + this->cuccosInPen = 0; + } currentCucco = (EnNiw*)play->actorCtx.actorLists[ACTORCAT_PROP].head; while (currentCucco != NULL) { if (currentCucco->actor.id == ACTOR_EN_NIW) { @@ -239,9 +241,11 @@ void func_80ABA244(EnNiwLady* this, PlayState* play) { phi_s1 = 7; } } + // Completed minigame and then threw Cucco(s) out of the pen if ((this->unk_26C != 0) && (phi_s1 < 7)) { phi_s1 = 9; } + this->actor.textId = sMissingCuccoTextIds[phi_s1]; if (Text_GetFaceReaction(play, 8) != 0) { this->actor.textId = Text_GetFaceReaction(play, 8); @@ -308,16 +312,18 @@ void func_80ABA654(EnNiwLady* this, PlayState* play) { if (!Flags_GetItemGetInf(ITEMGETINF_0C)) { this->actor.parent = NULL; - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ANJU_AS_CHILD, true, this)) { this->getItemId = GI_BOTTLE; func_8002F434(&this->actor, play, GI_BOTTLE, 100.0f, 50.0f); } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_ANJU_AS_CHILD, GI_BOTTLE); - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 100.0f, 50.0f); + // Circumvent the item offer action + this->actionFunc = func_80ABAC84; + return; } this->actionFunc = func_80ABAC00; return; + } if (this->unk_26C == 1) { this->getItemId = GI_RUPEE_PURPLE; @@ -398,15 +404,15 @@ void func_80ABA9B8(EnNiwLady* this, PlayState* play) { Message_CloseTextbox(play); this->actor.parent = NULL; - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ANJU_AS_ADULT, true, this)) { func_8002F434(&this->actor, play, GI_POCKET_EGG, 200.0f, 100.0f); + this->actionFunc = func_80ABAC00; } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG); - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 200.0f, 100.0f); - Flags_SetItemGetInf(ITEMGETINF_2C); + // Circumvent the item offer action + this->actionFunc = func_80ABAC84; + return; } - this->actionFunc = func_80ABAC00; break; case 1: this->actor.textId = sTradeItemTextIds[3]; @@ -433,15 +439,14 @@ void func_80ABAB08(EnNiwLady* this, PlayState* play) { case 0: Message_CloseTextbox(play); this->actor.parent = NULL; - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_TRADE_POCKET_CUCCO, true, this)) { func_8002F434(&this->actor, play, GI_COJIRO, 200.0f, 100.0f); + this->actionFunc = func_80ABAC00; } else { - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_TRADE_POCKET_CUCCO, GI_COJIRO); - Randomizer_ConsumeAdultTradeItem(play, ITEM_POCKET_CUCCO); - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 200.0f, 100.0f); - Flags_SetItemGetInf(ITEMGETINF_2E); + // Circumvent the item offer action + this->actionFunc = func_80ABAC84; + return; } - this->actionFunc = func_80ABAC00; break; case 1: Message_CloseTextbox(play); @@ -462,12 +467,6 @@ void func_80ABAC00(EnNiwLady* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->actionFunc = func_80ABAC84; } else { - if (IS_RANDO) { - getItemId = this->getItemEntry.getItemId; - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 200.0f, 100.0f); - return; - } - getItemId = this->getItemId; if (LINK_IS_ADULT) { getItemId = !Flags_GetItemGetInf(ITEMGETINF_2C) ? GI_POCKET_EGG : GI_COJIRO; @@ -482,8 +481,7 @@ void func_80ABAC84(EnNiwLady* this, PlayState* play) { } osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST); if (LINK_IS_ADULT) { - // Flags for randomizer gives are set in the original message prompt choice handling - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM, true, this)) { if (!Flags_GetItemGetInf(ITEMGETINF_2C)) { Flags_SetItemGetInf(ITEMGETINF_2C); } else { diff --git a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c index 303c58819..4ae7d366f 100644 --- a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c +++ b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c @@ -10,6 +10,7 @@ #include "scenes/overworld/spot16/spot16_scene.h" #include "vt.h" #include <assert.h> +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -42,6 +43,7 @@ void func_80ACAF74(EnOwl* this, PlayState* play); void func_80ACC30C(EnOwl* this, PlayState* play); void func_80ACB4FC(EnOwl* this, PlayState* play); void func_80ACB680(EnOwl* this, PlayState* play); +void func_80ACA62C(EnOwl* this, PlayState* play); void func_80ACC460(EnOwl* this); void func_80ACBEA0(EnOwl*, PlayState*); @@ -137,9 +139,7 @@ void EnOwl_Init(Actor* thisx, PlayState* play) { // "conversation owl %4x no = %d, sv = %d" osSyncPrintf(VT_FGCOL(CYAN) " 会話フクロウ %4x no = %d, sv = %d\n" VT_RST, this->actor.params, owlType, switchFlag); - if (((owlType != OWL_DEFAULT) && (switchFlag < 0x20) && Flags_GetSwitch(play, switchFlag)) || - // Owl shortcuts at SPOT06: Lake Hylia and SPOT16: Death Mountain Trail - (IS_RANDO && !(play->sceneNum == SCENE_LAKE_HYLIA || play->sceneNum == SCENE_DEATH_MOUNTAIN_TRAIL))) { + if ((owlType != OWL_DEFAULT) && (switchFlag < 0x20) && Flags_GetSwitch(play, switchFlag)) { osSyncPrintf("savebitでフクロウ退避\n"); // "Save owl with savebit" Actor_Kill(&this->actor); return; @@ -283,7 +283,7 @@ s32 EnOwl_CheckInitTalk(EnOwl* this, PlayState* play, u16 textId, f32 targetDist } else { this->actor.textId = textId; distCheck = (flags & 2) ? 200.0f : 1000.0f; - if (this->actor.xzDistToPlayer < targetDist) { + if (GameInteractor_Should(GI_VB_OWL_INTERACTION, this->actor.xzDistToPlayer < targetDist, this)) { this->actor.flags |= ACTOR_FLAG_WILL_TALK; func_8002F1C4(&this->actor, play, targetDist, distCheck, 0); } diff --git a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.h b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.h index 7a20eaa3a..a898dce2a 100644 --- a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.h +++ b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.h @@ -43,4 +43,6 @@ typedef struct EnOwl { /* 0x0410 */ OwlFunc unk_410; } EnOwl; // size = 0x0414 +void func_80ACA62C(EnOwl* enOwl, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c b/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c index 73996d58f..eafa8b82e 100644 --- a/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c +++ b/soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c @@ -7,6 +7,7 @@ #include "z_en_rl.h" #include "vt.h" #include "objects/object_rl/object_rl.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -126,7 +127,9 @@ void func_80AE7590(EnRl* this, PlayState* play) { pos.y = player->actor.world.pos.y + 80.0f; pos.z = player->actor.world.pos.z; Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_EFFECT, pos.x, pos.y, pos.z, 0, 0, 0, 0xE, true); - Item_Give(play, ITEM_MEDALLION_LIGHT); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_LIGHT_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_LIGHT); + } this->lightMedallionGiven = 1; } } diff --git a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c index fe4a77724..93d1fd99c 100644 --- a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c +++ b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c @@ -8,6 +8,7 @@ #include "objects/object_ru2/object_ru2.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -260,7 +261,9 @@ void func_80AF2A38(EnRu2* this, PlayState* play) { f32 posZ = player->actor.world.pos.z; Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0, 10); - Item_Give(play, ITEM_MEDALLION_WATER); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_WATER_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_WATER); + } } void func_80AF2AB4(EnRu2* this, PlayState* play) { @@ -273,7 +276,9 @@ void func_80AF2AB4(EnRu2* this, PlayState* play) { this->action = 1; play->csCtx.segment = &D_80AF411C; gSaveContext.cutsceneTrigger = 2; - Item_Give(play, ITEM_MEDALLION_WATER); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_WATER_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_WATER); + } temp = this->actor.world.rot.y + 0x8000; player->actor.shape.rot.y = temp; player->actor.world.rot.y = temp; diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c index 9e09a705c..f2b2db3f9 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c @@ -3,6 +3,7 @@ #include "objects/object_sa/object_sa.h" #include "scenes/overworld/spot04/spot04_scene.h" #include "scenes/overworld/spot05/spot05_scene.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -390,13 +391,10 @@ s32 func_80AF5DFC(EnSa* this, PlayState* play) { return 1; } if (play->sceneNum == SCENE_SACRED_FOREST_MEADOW && (Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER))) { - if (IS_RANDO) { - return 5; - } - return CHECK_QUEST_ITEM(QUEST_SONG_SARIA) ? 2 : 5; + return GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_SARIAS_SONG, !CHECK_QUEST_ITEM(QUEST_SONG_SARIA), NULL) ? 5 : 2; } if (play->sceneNum == SCENE_KOKIRI_FOREST && !CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) { - if (Flags_GetInfTable(INFTABLE_GREETED_BY_SARIA)) { + if (GameInteractor_Should(GI_VB_NOT_BE_GREETED_BY_SARIA, Flags_GetInfTable(INFTABLE_GREETED_BY_SARIA), NULL)) { return 1; } return 4; @@ -622,28 +620,17 @@ void func_80AF67D0(EnSa* this, PlayState* play) { } } -void GivePlayerRandoRewardSaria(EnSa* saria, PlayState* play, RandomizerCheck check) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SARIAS_SONG); - if (saria->actor.parent != NULL && saria->actor.parent->id == GET_PLAYER(play)->actor.id && - !Flags_GetTreasure(play, 0x1F)) { - Flags_SetTreasure(play, 0x1F); - } else if (!Flags_GetTreasure(play, 0x1F)) { - GiveItemEntryFromActor(&saria->actor, play, getItemEntry, 10000.0f, 100.0f); - } -} - void func_80AF683C(EnSa* this, PlayState* play) { Player* player = GET_PLAYER(play); if (!(player->actor.world.pos.z >= -2220.0f) && !Play_InCsMode(play)) { - if (IS_RANDO) { - GivePlayerRandoRewardSaria(this, play, RC_SONG_FROM_SARIA); - return; + // SOH [General] This flag was previously unused, but was named accordingly so we will make use of it. (Normally we should opt for soh_inf) + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SARIAS_SONG); + if (GameInteractor_Should(GI_VB_PLAY_SARIAS_SONG_CS, true, this)) { + play->csCtx.segment = SEGMENTED_TO_VIRTUAL(spot05_scene_Cs_005730); + gSaveContext.cutsceneTrigger = 1; + this->actionFunc = func_80AF68E4; } - - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(spot05_scene_Cs_005730); - gSaveContext.cutsceneTrigger = 1; - this->actionFunc = func_80AF68E4; } } @@ -721,7 +708,9 @@ void func_80AF68E4(EnSa* this, PlayState* play) { void func_80AF6B20(EnSa* this, PlayState* play) { if (play->sceneNum == SCENE_SACRED_FOREST_MEADOW) { - Item_Give(play, ITEM_SONG_SARIA); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SARIAS_SONG, true, NULL)) { + Item_Give(play, ITEM_SONG_SARIA); + } EnSa_ChangeAnim(this, ENSA_ANIM1_6); } diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h index 2965f04ab..56d368f13 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h @@ -30,4 +30,6 @@ typedef struct EnSa { /* 0x0286 */ Vec3s morphTable[17]; } EnSa; // size = 0x02EC +void func_80AF6B20(EnSa* enSa, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c index 6f48314ff..0f300d16f 100644 --- a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c +++ b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c @@ -1,5 +1,6 @@ #include "z_en_shopnuts.h" #include "objects/object_shopnuts/object_shopnuts.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) @@ -69,18 +70,11 @@ void EnShopnuts_Init(Actor* thisx, PlayState* play) { CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); Collider_UpdateCylinder(&this->actor, &this->collider); - if (IS_RANDO) { - s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - ScrubIdentity scrubIdentity = Randomizer_IdentifyScrub(play->sceneNum, this->actor.params, respawnData); - - if (scrubIdentity.isShuffled && Flags_GetRandomizerInf(scrubIdentity.randomizerInf)) { - Actor_Kill(&this->actor); - } - } - - if (((this->actor.params == 0x0002) && (Flags_GetItemGetInf(ITEMGETINF_0B))) || + if (GameInteractor_Should(GI_VB_BUSINESS_SCRUB_DESPAWN, + ((this->actor.params == 0x0002) && (Flags_GetItemGetInf(ITEMGETINF_0B))) || ((this->actor.params == 0x0009) && (Flags_GetInfTable(INFTABLE_192))) || - ((this->actor.params == 0x000A) && (Flags_GetInfTable(INFTABLE_193)))) { + ((this->actor.params == 0x000A) && (Flags_GetInfTable(INFTABLE_193))), + this)) { Actor_Kill(&this->actor); } else { EnShopnuts_SetupWait(this); diff --git a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c index 49e88f903..8eb669d2d 100644 --- a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c +++ b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c @@ -7,9 +7,6 @@ #include "z_en_si.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -extern void func_8083C148(Player*, PlayState*); -extern void func_80078884(uint16_t); - #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOOKSHOT_DRAGS) void EnSi_Init(Actor* thisx, PlayState* play); @@ -21,13 +18,6 @@ s32 func_80AFB748(EnSi* this, PlayState* play); void func_80AFB768(EnSi* this, PlayState* play); void func_80AFB89C(EnSi* this, PlayState* play); void func_80AFB950(EnSi* this, PlayState* play); -void Randomizer_UpdateSkullReward(EnSi* this, PlayState* play); -void Randomizer_GiveSkullReward(EnSi* this, PlayState* play); - -s32 textId = 0xB4; -s32 giveItemId = ITEM_SKULL_TOKEN; -s32 getItemId; -GetItemEntry getItem; static ColliderCylinderInit sCylinderInit = { { @@ -104,36 +94,12 @@ void func_80AFB768(EnSi* this, PlayState* play) { if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) { this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER; - - if (IS_RANDO) { - Randomizer_UpdateSkullReward(this, play); - } else { - Item_Give(play, giveItemId); - } - if ((!CVarGetInteger("gSkulltulaFreeze", 0) || giveItemId != ITEM_SKULL_TOKEN) && - getItemId != RG_ICE_TRAP) { - player->actor.freezeTimer = 20; - } - - if (getItemId == RG_ICE_TRAP && Message_GetState(&play->msgCtx) != TEXT_STATE_CLOSING) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SKULL_TOKEN, true, this)) { + Item_Give(play, ITEM_SKULL_TOKEN); player->actor.freezeTimer = 10; - } - - Message_StartTextbox(play, textId, NULL); - - if (IS_RANDO) { - if (getItemId != RG_ICE_TRAP) { - Randomizer_GiveSkullReward(this, play); - Audio_PlayFanfare_Rando(getItem); - } else { - gSaveContext.pendingIceTrapCount++; - Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); - } - } else { + Message_StartTextbox(play, 0xB4, NULL); Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); } - - player->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->actionFunc = func_80AFB950; } else { Collider_UpdateCylinder(&this->actor, &this->collider); @@ -146,32 +112,18 @@ void func_80AFB768(EnSi* this, PlayState* play) { void func_80AFB89C(EnSi* this, PlayState* play) { Player* player = GET_PLAYER(play); + Math_SmoothStepToF(&this->actor.scale.x, 0.25f, 0.4f, 1.0f, 0.0f); Actor_SetScale(&this->actor, this->actor.scale.x); this->actor.shape.rot.y += 0x400; if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) { - if (IS_RANDO) { - Randomizer_UpdateSkullReward(this, play); - } else { - Item_Give(play, giveItemId); - } - - Message_StartTextbox(play, textId, NULL); - - if (IS_RANDO) { - if (getItemId != RG_ICE_TRAP) { - Randomizer_GiveSkullReward(this, play); - Audio_PlayFanfare_Rando(getItem); - } else { - gSaveContext.pendingIceTrapCount++; - Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); - } - } else { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SKULL_TOKEN, true, this)) { + Item_Give(play, ITEM_SKULL_TOKEN); + player->actor.freezeTimer = 10; + Message_StartTextbox(play, 0xB4, NULL); Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); } - - player->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->actionFunc = func_80AFB950; } } @@ -179,19 +131,12 @@ void func_80AFB89C(EnSi* this, PlayState* play) { void func_80AFB950(EnSi* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (Message_GetState(&play->msgCtx) != TEXT_STATE_CLOSING && - (!CVarGetInteger("gSkulltulaFreeze", 0) || getItemId == RG_ICE_TRAP || giveItemId != ITEM_SKULL_TOKEN)) { + if (Message_GetState(&play->msgCtx) != TEXT_STATE_CLOSING && GameInteractor_Should(GI_VB_GIVE_ITEM_SKULL_TOKEN, true, this)) { player->actor.freezeTimer = 10; } else { SET_GS_FLAGS((this->actor.params & 0x1F00) >> 8, this->actor.params & 0xFF); GameInteractor_ExecuteOnFlagSet(FLAG_GS_TOKEN, this->actor.params); Actor_Kill(&this->actor); - if (gSaveContext.pendingIceTrapCount > 0 && player->heldItemId == 11) { - player->actor.freezeTimer = 0; - func_8083C148(GET_PLAYER(play), play); - func_80078884(NA_SE_SY_CAMERA_ZOOM_UP); - player->currentYaw = player->actor.shape.rot.y; - } } } @@ -210,44 +155,6 @@ void EnSi_Draw(Actor* thisx, PlayState* play) { if (this->actionFunc != func_80AFB950) { func_8002ED80(&this->actor, play, 0); func_8002EBCC(&this->actor, play, 0); - if (!IS_RANDO) { - GetItem_Draw(play, GID_SKULL_TOKEN_2); - } else { - getItem = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, this->actor.params, GI_SKULL_TOKEN); - EnItem00_CustomItemsParticles(&this->actor, play, getItem); - if (getItem.itemId != ITEM_SKULL_TOKEN) { - f32 mtxScale = 1.5f; - Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - } - GetItemEntry_Draw(play, getItem); - } - } -} - -void Randomizer_UpdateSkullReward(EnSi* this, PlayState* play) { - Player* player = GET_PLAYER(play); - - getItem = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, this->actor.params, GI_SKULL_TOKEN); - getItemId = getItem.getItemId; - if (getItemId == RG_ICE_TRAP) { - textId = 0xF8; - } else { - textId = getItem.textId; - giveItemId = getItem.itemId; - } - player->getItemEntry = getItem; -} - -void Randomizer_GiveSkullReward(EnSi* this, PlayState* play) { - Player* player = GET_PLAYER(play); - - if (getItem.modIndex == MOD_NONE) { - // RANDOTOD: Move this into Item_Give() or some other more central location - if (getItem.getItemId == GI_SWORD_BGS) { - gSaveContext.bgsFlag = true; - } - Item_Give(play, giveItemId); - } else if (getItem.modIndex == MOD_RANDOMIZER) { - Randomizer_Item_Give(play, getItem); + GetItem_Draw(play, GID_SKULL_TOKEN_2); } } diff --git a/soh/src/overlays/actors/ovl_En_Si/z_en_si.h b/soh/src/overlays/actors/ovl_En_Si/z_en_si.h index dc0a3b400..318876289 100644 --- a/soh/src/overlays/actors/ovl_En_Si/z_en_si.h +++ b/soh/src/overlays/actors/ovl_En_Si/z_en_si.h @@ -13,6 +13,9 @@ typedef struct EnSi { /* 0x014C */ EnSiActionFunc actionFunc; /* 0x0150 */ ColliderCylinder collider; /* 0x019C */ u8 unk_19C; + // #region SOH [Randomizer] Caching the get item entry for the draw function for performance + /* */ GetItemEntry sohGetItemEntry; + // #endregion } EnSi; // size = 0x01A0 #endif diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c index 0eb3e9095..2f47f7c2a 100644 --- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c +++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c @@ -7,6 +7,7 @@ #include "z_en_ta.h" #include "vt.h" #include "objects/object_ta/object_ta.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -466,7 +467,7 @@ void func_80B14B6C(EnTa* this, PlayState* play) { func_80B13AA0(this, func_80B14AF4, func_80B167C0); this->unk_2CC = 5; Flags_SetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE); - if (IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { OnePointCutscene_EndCutscene(play, csCamIdx); } Animation_PlayOnce(&this->skelAnime, &gTalonRunTransitionAnim); diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c index 55fbed824..342eed149 100644 --- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -8,12 +8,9 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_tk/object_tk.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) -#define COLLECTFLAG_GRAVEDIGGING_HEART_PIECE 0x19 -#define ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE 0x1000 - -bool heartPieceSpawned; void EnTk_Init(Actor* thisx, PlayState* play); void EnTk_Destroy(Actor* thisx, PlayState* play); @@ -408,10 +405,6 @@ s32 EnTk_ChooseReward(EnTk* this) { f32 luck; s32 reward; - if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE) && this->heartPieceSpawned == 0) { - return 3; - } - luck = Rand_ZeroOne(); if (luck < 0.4f) { @@ -502,12 +495,7 @@ void EnTk_Init(Actor* thisx, PlayState* play) { CollisionCheck_SetInfo2(&this->actor.colChkInfo, NULL, &sColChkInfoInit); - if (CVarGetInteger("gDampeAllNight", 0)) { - if (!!LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD) { - Actor_Kill(&this->actor); - return; - } - } else if (gSaveContext.dayTime <= 0xC000 || gSaveContext.dayTime >= 0xE000 || !!LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD) { + if (GameInteractor_Should(GI_VB_DAMPE_IN_GRAVEYARD_DESPAWN, gSaveContext.dayTime <= 0xC000 || gSaveContext.dayTime >= 0xE000 || LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD, this)) { Actor_Kill(&this->actor); return; } @@ -519,7 +507,6 @@ void EnTk_Init(Actor* thisx, PlayState* play) { this->currentReward = -1; this->currentSpot = NULL; this->actionFunc = EnTk_Rest; - heartPieceSpawned = false; } void EnTk_Destroy(Actor* thisx, PlayState* play) { @@ -599,7 +586,11 @@ void EnTk_Dig(EnTk* this, PlayState* play) { Vec3f rewardOrigin; Vec3f rewardPos; s32 rewardParams[] = { - ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_RUPEE_RED, ITEM00_RUPEE_PURPLE, ITEM00_HEART_PIECE, + ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_RUPEE_RED, ITEM00_RUPEE_PURPLE, + // #region SOH [General] Typically this heart piece would have no collectible flag set when it's picked up, but for both randomizer + // and gGravediggingTourFix we want to set one, and rely on it instead of the ItemGetInf flag that is set when the heart is spawned + ((COLLECTFLAG_GRAVEDIGGING_HEART_PIECE & 0x3F) << 8) | ITEM00_HEART_PIECE, + // #endregion }; EnTk_DigEff(this); @@ -610,7 +601,7 @@ void EnTk_Dig(EnTk* this, PlayState* play) { this->rewardTimer = 0; - if (this->validDigHere == 1 || IS_RANDO || CVarGetInteger("gDampeWin", 0)) { + if (GameInteractor_Should(GI_VB_BE_VALID_GRAVEDIGGING_SPOT, this->validDigHere == 1, this)) { rewardOrigin.x = 0.0f; rewardOrigin.y = 0.0f; rewardOrigin.z = -40.0f; @@ -624,51 +615,24 @@ void EnTk_Dig(EnTk* this, PlayState* play) { this->currentReward = EnTk_ChooseReward(this); - if (this->currentReward == 3) { - if (IS_RANDO || CVarGetInteger("gDampeWin", 0)) { - /* - * Upgrade the purple rupee reward to the heart piece if this - * is the first grand prize dig. - */ - if (!Flags_GetItemGetInf(ITEMGETINF_1C) && !(IS_RANDO || CVarGetInteger("gDampeWin", 0))) { - Flags_SetItemGetInf(ITEMGETINF_1C); - this->currentReward = 4; - } else if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE) && this->heartPieceSpawned == 0) { - this->currentReward = 4; - } - } + if (GameInteractor_Should(GI_VB_BE_DAMPE_GRAVEDIGGING_GRAND_PRIZE, this->currentReward == 3, this)) { /* - * Upgrade the purple rupee reward to the heart piece if this - * is the first grand prize dig. - */ - // If vanilla itemGetInf flag is not set, it's impossible for the new flag to be set, so return true. - // Otherwise if the gGravediggingTourFix is enabled and the new flag hasn't been set, return true. - // If true, spawn the heart piece and set the vanilla itemGetInf flag and new temp clear flag. - if (!heartPieceSpawned && - (!(gSaveContext.itemGetInf[1] & ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE) || - CVarGetInteger("gGravediggingTourFix", 0) && - !Flags_GetCollectible(play, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE))) { + * Upgrade the purple rupee reward to the heart piece if this + * is the first grand prize dig. + */ + if (GameInteractor_Should(GI_VB_DAMPE_GRAVEDIGGING_GRAND_PRIZE_BE_HEART_PIECE, !Flags_GetItemGetInf(ITEMGETINF_1C), this)) { + Flags_SetItemGetInf(ITEMGETINF_1C); this->currentReward = 4; - gSaveContext.itemGetInf[1] |= ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE; - heartPieceSpawned = true; } } - if (IS_RANDO && this->currentReward == 4) { - Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ITEM00, rewardPos.x, rewardPos.y, rewardPos.z, 0, 0, 0, 0x1906, true); - this->heartPieceSpawned = 1; - } else { - EnItem00* reward = Item_DropCollectible(play, &rewardPos, rewardParams[this->currentReward]); - if (this->currentReward == 4) { - reward->collectibleFlag = COLLECTFLAG_GRAVEDIGGING_HEART_PIECE; - } - } + Item_DropCollectible(play, &rewardPos, rewardParams[this->currentReward]); } } if (this->skelAnime.curFrame >= 32.0f && this->rewardTimer == 10) { /* Play a reward sound shortly after digging */ - if (!(IS_RANDO || CVarGetInteger("gDampeWin", 0)) && this->validDigHere == 0) { + if (this->validDigHere == 0) { /* Bad dig spot */ Audio_PlayActorSound2(&this->actor, NA_SE_SY_ERROR); } else if (this->currentReward == 4) { diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h index c60cb5200..c2dee0fce 100644 --- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h +++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h @@ -8,6 +8,8 @@ /* Dirt particle effect */ struct EnTkEff; +#define COLLECTFLAG_GRAVEDIGGING_HEART_PIECE 0x19 + typedef struct EnTkEff { /* 0x0000 */ u8 active; /* 0x0001 */ u8 timeLeft; diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c index d52b82d8d..c2ac2861b 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c @@ -6,7 +6,7 @@ #include "z_en_toryo.h" #include "objects/object_toryo/object_toryo.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -291,10 +291,7 @@ void func_80B20768(EnToryo* this, PlayState* play) { s16 sp32; s16 sp30; - // Animation Count should be no more than 1 to guarantee putaway is complete after giving the saw - // As this is vanilla behavior, it only applies with the Fix toggle or Skip Text enabled. - bool checkAnim = (CVarGetInteger("gFixSawSoftlock", 0) != 0 || CVarGetInteger("gSkipText", 0) != 0) ? play->animationCtx.animationCount <= 1 : true; - if (this->unk_1E4 == 3 && checkAnim) { + if (this->unk_1E4 == 3 && !GameInteractor_Should(GI_VB_FIX_SAW_SOFTLOCK, false, NULL)) { Actor_ProcessTalkRequest(&this->actor, play); Message_ContinueTextbox(play, this->actor.textId); this->unk_1E4 = 1; @@ -315,19 +312,12 @@ void func_80B20768(EnToryo* this, PlayState* play) { } if (this->unk_1E4 == 4) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_TRADE_SAW, true, this)) { this->actor.parent = NULL; this->unk_1E4 = 5; + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW); } else { - if (IS_RANDO) { - GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_GV_TRADE_SAW, GI_SWORD_BROKEN); - Randomizer_ConsumeAdultTradeItem(play, ITEM_SAW); - GiveItemEntryFromActor(&this->actor, play, itemEntry, 100.0f, 10.0f); - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW); - } else { - s32 itemId = GI_SWORD_BROKEN; - func_8002F434(&this->actor, play, itemId, 100.0f, 10.0f); - } + func_8002F434(&this->actor, play, GI_SWORD_BROKEN, 100.0f, 10.0f); } return; } diff --git a/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c b/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c index 2b90e1ff7..658dd63f8 100644 --- a/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c +++ b/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c @@ -6,6 +6,7 @@ #include "z_en_wonder_talk2.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_NO_LOCKON) @@ -194,7 +195,9 @@ void func_80B3A3D4(EnWonderTalk2* this, PlayState* play) { this->unk_15A = true; } this->actor.flags &= ~(ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED); - func_8002DF54(play, NULL, 7); + if (GameInteractor_Should(GI_VB_WONDER_TALK, true, this)) { + func_8002DF54(play, NULL, 7); + } this->unk_156 = true; this->actionFunc = func_80B3A4F8; break; @@ -252,42 +255,12 @@ void func_80B3A4F8(EnWonderTalk2* this, PlayState* play) { } this->unk_158 = 0; if (!this->unk_156) { - // Whether or not to skip the text in rando - bool randoSkipText = false; - if (IS_RANDO) { - // Scenes for which all of this type of wonder talk should be skipped. - switch (play->sceneNum) { - case SCENE_SHADOW_TEMPLE: // Shadow Temple - randoSkipText = true; - break; - case SCENE_GERUDO_TRAINING_GROUND: // Gerudo Training Grounds - randoSkipText = true; - break; - case SCENE_THIEVES_HIDEOUT: // Inside Gerudo Fortress - randoSkipText = true; - break; - default: - break; - } - // individual textIds that should be skipped, or that should be preserved - // in a scene that otherwise has all wonder talk skipped. - //switch (this->actor.textId) { - // case: 0x023c //textId we want to skip - // randoSkipText = true; - // break; - // case 0x023c: // textId in a skipped scene that we don't want to skip - // randoSkipText = false; - // break; - // default: - // break; - //} - } - if (!(randoSkipText)) { + if (GameInteractor_Should(GI_VB_WONDER_TALK, true, this)) { Message_StartTextbox(play, this->actor.textId, NULL); func_8002DF54(play, NULL, 8); - this->actor.flags |= ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED; - this->actionFunc = func_80B3A3D4; } + this->actor.flags |= ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED; + this->actionFunc = func_80B3A3D4; } } else { diff --git a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c index 83f799877..6436df29f 100644 --- a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c +++ b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c @@ -13,6 +13,7 @@ #include "scenes/indoors/tokinoma/tokinoma_scene.h" #include "scenes/dungeons/ice_doukutu/ice_doukutu_scene.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -277,6 +278,7 @@ void func_80B3C9EC(EnXc* this) { this->action = SHEIK_ACTION_BLOCK_PEDESTAL; this->drawMode = SHEIK_DRAW_DEFAULT; this->unk_30C = 1; + // SOH [Randomizer] We don't want sheik blocking the pedestal in randomizer if (IS_RANDO) { Actor_Kill(&this->actor); } @@ -292,24 +294,6 @@ void func_80B3CA38(EnXc* this, PlayState* play) { } } -void GivePlayerRandoRewardSheikSong(EnXc* sheik, PlayState* play, RandomizerCheck check, int sheikType, GetItemID ogSongId) { - Player* player = GET_PLAYER(play); - if (!(gSaveContext.eventChkInf[5] & sheikType)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, ogSongId); - if (check == RC_SHEIK_AT_TEMPLE && !Flags_GetTreasure(play, 0x1F)) { - if (GiveItemEntryFromActor(&sheik->actor, play, getItemEntry, 10000.0f, 100.0f)) { - player->pendingFlag.flagID = 0x1F; - player->pendingFlag.flagType = FLAG_SCENE_TREASURE; - } - } else if (check != RC_SHEIK_AT_TEMPLE) { - if (GiveItemEntryFromActor(&sheik->actor, play, getItemEntry, 10000.0f, 100.0f)) { - player->pendingFlag.flagID = (0x5 << 4) | (sheikType & 0xF) >> 1; - player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; - } - } - } -} - s32 EnXc_MinuetCS(EnXc* this, PlayState* play) { if (this->actor.params == SHEIK_TYPE_MINUET) { Player* player = GET_PLAYER(play); @@ -317,16 +301,17 @@ s32 EnXc_MinuetCS(EnXc* this, PlayState* play) { if (z < -2225.0f) { if (!Play_InCsMode(play)) { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_MINUET_OF_FOREST_CS, true, NULL)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(&gMinuetCs); gSaveContext.cutsceneTrigger = 1; - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_MINUET_OF_FOREST); + } + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_MINUET_OF_FOREST); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_MINUET_OF_FOREST, true, NULL)) { Item_Give(play, ITEM_SONG_MINUET); - } else { - GivePlayerRandoRewardSheikSong(this, play, RC_SHEIK_IN_FOREST, 1, RG_MINUET_OF_FOREST); - return false; } - return true; + if (GameInteractor_Should(GI_VB_PLAY_MINUET_OF_FOREST_CS, true, NULL)) { + return true; + } } } return false; @@ -353,16 +338,17 @@ s32 EnXc_BoleroCS(EnXc* this, PlayState* play) { if ((posRot->pos.x > -784.0f) && (posRot->pos.x < -584.0f) && (posRot->pos.y > 447.0f) && (posRot->pos.y < 647.0f) && (posRot->pos.z > -446.0f) && (posRot->pos.z < -246.0f) && !Play_InCsMode(play)) { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_BOLERO_OF_FIRE_CS, true, NULL)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(&gDeathMountainCraterBoleroCs); gSaveContext.cutsceneTrigger = 1; - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_BOLERO_OF_FIRE); + } + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_BOLERO_OF_FIRE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_BOLERO_OF_FIRE, true, NULL)) { Item_Give(play, ITEM_SONG_BOLERO); - } else { - GivePlayerRandoRewardSheikSong(this, play, RC_SHEIK_IN_CRATER, 2, RG_BOLERO_OF_FIRE); - return false; } - return true; + if (GameInteractor_Should(GI_VB_PLAY_BOLERO_OF_FIRE_CS, true, NULL)) { + return true; + } } return false; } @@ -370,13 +356,8 @@ s32 EnXc_BoleroCS(EnXc* this, PlayState* play) { } void EnXc_SetupSerenadeAction(EnXc* this, PlayState* play) { - if (IS_RANDO) { - this->action = SHEIK_ACTION_SERENADE; - return; - } - // Player is adult and does not have iron boots and has not learned Serenade - if ((!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT) { + if (GameInteractor_Should(GI_VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER, (!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT, NULL)) { this->action = SHEIK_ACTION_SERENADE; osSyncPrintf("水のセレナーデ シーク誕生!!!!!!!!!!!!!!!!!!\n"); } else { @@ -389,22 +370,20 @@ s32 EnXc_SerenadeCS(EnXc* this, PlayState* play) { if (this->actor.params == SHEIK_TYPE_SERENADE) { Player* player = GET_PLAYER(play); s32 stateFlags = player->stateFlags1; - - if (((CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !IS_RANDO) || - (Flags_GetTreasure(play, 2) && IS_RANDO)) && - !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && !(stateFlags & 0x20000000) && - !Play_InCsMode(play)) { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_SERENADE_OF_WATER, CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER), NULL) && + !(stateFlags & PLAYER_STATE1_IN_CUTSCENE) && !Play_InCsMode(play)) { + if (GameInteractor_Should(GI_VB_PLAY_SERENADE_OF_WATER_CS, true, NULL)) { Cutscene_SetSegment(play, &gIceCavernSerenadeCs); gSaveContext.cutsceneTrigger = 1; - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER); // Learned Serenade of Water Flag + } + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER); // Learned Serenade of Water Flag + if (GameInteractor_Should(GI_VB_GIVE_ITEM_SERENADE_OF_WATER, true, NULL)) { Item_Give(play, ITEM_SONG_SERENADE); - } else { - GivePlayerRandoRewardSheikSong(this, play, RC_SHEIK_IN_ICE_CAVERN, 4, RG_SERENADE_OF_WATER); - return false; } osSyncPrintf("ブーツを取った!!!!!!!!!!!!!!!!!!\n"); - return true; + if (GameInteractor_Should(GI_VB_PLAY_SERENADE_OF_WATER_CS, true, NULL)) { + return true; + } } osSyncPrintf("はやくブーツを取るべし!!!!!!!!!!!!!!!!!!\n"); return false; @@ -415,7 +394,7 @@ s32 EnXc_SerenadeCS(EnXc* this, PlayState* play) { void EnXc_DoNothing(EnXc* this, PlayState* play) { } -void EnXc_RandoStand(EnXc* this, PlayState* play) { +void SoH_EnXc_RandoStand(EnXc* this, PlayState* play) { //Replaces Ganondorf Light Arrow hint. also stands in ToT if (play->sceneNum == SCENE_TEMPLE_OF_TIME) { EnXc_ChangeAnimation(this, &gSheikArmsCrossedIdleAnim, ANIMMODE_LOOP, 0.0f, false); @@ -2209,22 +2188,21 @@ void EnXc_InitTempleOfTime(EnXc* this, PlayState* play) { if (LINK_IS_ADULT) { if (!Flags_GetEventChkInf(EVENTCHKINF_SHEIK_SPAWNED_AT_MASTER_SWORD_PEDESTAL)) { Flags_SetEventChkInf(EVENTCHKINF_SHEIK_SPAWNED_AT_MASTER_SWORD_PEDESTAL); - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gTempleOfTimeFirstAdultCs); - gSaveContext.cutsceneTrigger = 1; + if (GameInteractor_Should(GI_VB_PLAY_SHIEK_BLOCK_MASTER_SWORD_CS, true, NULL)) { + play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gTempleOfTimeFirstAdultCs); + gSaveContext.cutsceneTrigger = 1; + } func_80B3EBF0(this, play); - } else if ((!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) && - !IS_RANDO) || - (!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && - IS_RANDO)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT); + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT, !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), NULL)) { + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_PRELUDE_OF_LIGHT, true, NULL)) { Item_Give(play, ITEM_SONG_PRELUDE); + } + if (GameInteractor_Should(GI_VB_PLAY_PRELUDE_OF_LIGHT_CS, true, NULL)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gTempleOfTimePreludeCs); gSaveContext.cutsceneTrigger = 1; - this->action = SHEIK_ACTION_30; - } else { - GivePlayerRandoRewardSheikSong(this, play, RC_SHEIK_AT_TEMPLE, 0x20, RG_PRELUDE_OF_LIGHT); } + this->action = SHEIK_ACTION_30; // Not sure what this does exactly } else if (!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT)) { func_80B3C9EC(this); } else { @@ -2378,14 +2356,6 @@ void EnXc_Update(Actor* thisx, PlayState* play) { EnXc* this = (EnXc*)thisx; s32 action = this->action; - if (this->actor.params == SHEIK_TYPE_9) { - if (IS_RANDO && LINK_IS_ADULT) { - if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT)) { - GivePlayerRandoRewardSheikSong(this, play, RC_SHEIK_AT_TEMPLE, 0x20, RG_PRELUDE_OF_LIGHT); - } - } - } - if ((action < 0) || (action >= ARRAY_COUNT(sActionFuncs)) || (sActionFuncs[action] == NULL)) { osSyncPrintf(VT_FGCOL(RED) "メインモードがおかしい!!!!!!!!!!!!!!!!!!!!!!!!!\n" VT_RST); } else { @@ -2433,7 +2403,7 @@ void EnXc_Init(Actor* thisx, PlayState* play) { EnXc_DoNothing(this, play); break; case SHEIK_TYPE_RANDO: - EnXc_RandoStand(this, play); + SoH_EnXc_RandoStand(this, play); break; default: osSyncPrintf(VT_FGCOL(RED) " En_Oa2 の arg_data がおかしい!!!!!!!!!!!!!!!!!!!!!!!!!\n" VT_RST); diff --git a/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c b/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c index 4a47b456e..9bc53169b 100644 --- a/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c +++ b/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c @@ -10,6 +10,7 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "objects/object_zl2/object_zl2.h" #include "objects/object_zl2_anime1/object_zl2_anime1.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -633,7 +634,9 @@ void EnZl2_GiveLightArrows(EnZl2* this, PlayState* play) { posY = player->actor.world.pos.y + 80.0f; posZ = player->actor.world.pos.z; Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0, 0x17, true); - Item_Give(play, ITEM_ARROW_LIGHT); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_LIGHT_ARROW, true, NULL)) { + Item_Give(play, ITEM_ARROW_LIGHT); + } this->unk_244 = 1; } } diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c index 08c3857e0..f805e2fb5 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c @@ -7,6 +7,7 @@ #include "z_en_zl4.h" #include "objects/object_zl4/object_zl4.h" #include "scenes/indoors/nakaniwa/nakaniwa_scene.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -227,20 +228,6 @@ u16 EnZl4_GetText(PlayState* play, Actor* thisx) { return ret; } -void GivePlayerRandoRewardZeldaChild(EnZl4* zelda, PlayState* play, RandomizerCheck check) { - if (zelda->actor.parent != NULL && zelda->actor.parent->id == GET_PLAYER(play)->actor.id && - !Flags_GetTreasure(play, 0x1E)) { - Flags_SetTreasure(play, 0x1E); - } else if (!Flags_GetTreasure(play, 0x1E) && !Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA) && Actor_TextboxIsClosing(&zelda->actor, play) && - (play->msgCtx.textId == 0x703C || play->msgCtx.textId == 0x703D)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, GI_LETTER_ZELDA); - GiveItemEntryFromActor(&zelda->actor, play, getItemEntry, 10000.0f, 100.0f); - } else if (Flags_GetTreasure(play, 0x1E) && !Player_InBlockingCsMode(play, GET_PLAYER(play))) { - gSaveContext.unk_13EE = 0x32; - Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER); - } -} - s16 func_80B5B9B0(PlayState* play, Actor* thisx) { EnZl4* this = (EnZl4*)thisx; @@ -389,12 +376,6 @@ void EnZl4_Init(Actor* thisx, PlayState* play) { this->actor.textId = -1; this->eyeExpression = this->mouthExpression = ZL4_MOUTH_NEUTRAL; - if (IS_RANDO) { - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ZL4_ANIM_0); - this->actionFunc = EnZl4_Idle; - return; - } - if (gSaveContext.sceneSetupIndex >= 4) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ZL4_ANIM_0); this->actionFunc = EnZl4_TheEnd; @@ -1127,14 +1108,16 @@ s32 EnZl4_CsMakePlan(EnZl4* this, PlayState* play) { Camera_ChangeSetting(GET_ACTIVE_CAM(play), 1); this->talkState = 7; play->talkWithPlayer(play, &this->actor); - func_8002F434(&this->actor, play, GI_LETTER_ZELDA, fabsf(this->actor.xzDistToPlayer) + 1.0f, - fabsf(this->actor.yDistToPlayer) + 1.0f); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LETTER, true, NULL)) { + func_8002F434(&this->actor, play, GI_LETTER_ZELDA, fabsf(this->actor.xzDistToPlayer) + 1.0f, + fabsf(this->actor.yDistToPlayer) + 1.0f); + } play->msgCtx.stateTimer = 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; } break; case 7: - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LETTER, true, NULL)) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ZL4_ANIM_0); this->talkState++; } else { @@ -1225,11 +1208,6 @@ void EnZl4_Idle(EnZl4* this, PlayState* play) { Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 60.0f, EnZl4_GetText, func_80B5B9B0); func_80B5BB78(this, play); - - if (IS_RANDO) { - GivePlayerRandoRewardZeldaChild(this, play, RC_HC_ZELDAS_LETTER); - return; - } } void EnZl4_TheEnd(EnZl4* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h index 601ed6905..4b14121c6 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h @@ -31,4 +31,9 @@ typedef struct EnZl4 { /* 0x0284 */ Vec3s morphTable[18]; } EnZl4; // size = 0x02F0 +s16 func_80B5B9B0(PlayState* play, Actor* actor); +void func_80B5BB78(EnZl4* enZl4, PlayState* play); +void EnZl4_Cutscene(EnZl4* enZl4, PlayState* play); +s32 EnZl4_SetNextAnim(EnZl4* enZl4, s32 nextAnim); + #endif diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c index abb65c191..f511d5bbf 100644 --- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c +++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c @@ -59,12 +59,7 @@ void ItemBHeart_Update(Actor* thisx, PlayState* play) { Flags_SetCollectible(play, 0x1F); Actor_Kill(&this->actor); } else { - if (!IS_RANDO) { - func_8002F434(&this->actor, play, GI_HEART_CONTAINER_2, 30.0f, 40.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, this->actor.params, GI_HEART_CONTAINER_2); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 30.0f, 40.0f); - } + func_8002F434(&this->actor, play, GI_HEART_CONTAINER_2, 30.0f, 40.0f); } } @@ -98,23 +93,18 @@ void ItemBHeart_Draw(Actor* thisx, PlayState* play) { actorIt = actorIt->next; } - if (IS_RANDO) { - GetItemEntry_Draw(play, Randomizer_GetItemFromActor(this->actor.id, - play->sceneNum,this->actor.params, GI_HEART_CONTAINER_2)); + if (flag) { + Gfx_SetupDL_25Xlu(play->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGiHeartBorderDL); + gSPDisplayList(POLY_XLU_DISP++, gGiHeartContainerDL); } else { - if (flag) { - Gfx_SetupDL_25Xlu(play->state.gfxCtx); - gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, gGiHeartBorderDL); - gSPDisplayList(POLY_XLU_DISP++, gGiHeartContainerDL); - } else { - Gfx_SetupDL_25Opa(play->state.gfxCtx); - gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, gGiHeartBorderDL); - gSPDisplayList(POLY_OPA_DISP++, gGiHeartContainerDL); - } + Gfx_SetupDL_25Opa(play->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gGiHeartBorderDL); + gSPDisplayList(POLY_OPA_DISP++, gGiHeartContainerDL); } CLOSE_DISPS(play->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h index d9483b48c..434aa775b 100644 --- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h +++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h @@ -13,6 +13,11 @@ typedef struct ItemBHeart { /* 0x015C */ char unk_15C[0x8]; /* 0x0164 */ s16 unk_164; /* 0x0166 */ char unk_166[0x6]; + // #region SOH [Randomizer] Cached for drawing for performance + /* */ GetItemEntry sohItemEntry; + // #endregion } ItemBHeart; // size = 0x016C +void func_80B85264(ItemBHeart* itemBHeart, PlayState* play); + #endif diff --git a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c index a9cd36446..dba879115 100644 --- a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c +++ b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c @@ -6,6 +6,7 @@ #include "z_item_ocarina.h" #include "scenes/overworld/spot00/spot00_scene.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -169,31 +170,27 @@ void ItemOcarina_DoNothing(ItemOcarina* this, PlayState* play) { void ItemOcarina_StartSoTCutscene(ItemOcarina* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->actor, play)) { - if (!IS_RANDO) { - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gHyruleFieldZeldaSongOfTimeCs); - gSaveContext.cutsceneTrigger = 1; - } else { - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_WHITE; - gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; - play->nextEntranceIndex = ENTR_HYRULE_FIELD_16; - gSaveContext.nextCutsceneIndex = 0; - } + play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gHyruleFieldZeldaSongOfTimeCs); + gSaveContext.cutsceneTrigger = 1; } } void ItemOcarina_WaitInWater(ItemOcarina* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if ( + Actor_HasParent(&this->actor, play) || + ( + !GameInteractor_Should(GI_VB_GIVE_ITEM_OCARINA_OF_TIME, true, NULL) && + (this->actor.xzDistToPlayer < 20.0f) && (fabsf(this->actor.yDistToPlayer) < 10.0f) && + GET_PLAYER(play)->stateFlags2 & PLAYER_STATE2_DIVING + ) + ) { Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_OCARINA_OF_TIME); Flags_SetSwitch(play, 3); this->actionFunc = ItemOcarina_StartSoTCutscene; this->actor.draw = NULL; } else { - if (!IS_RANDO) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_OCARINA_OF_TIME, true, NULL)) { func_8002F434(&this->actor, play, GI_OCARINA_OOT, 30.0f, 50.0f); - } else { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT); - GiveItemEntryFromActor(&this->actor, play, getItemEntry, 30.0f, 50.0f); } if ((play->gameplayFrames & 13) == 0) { diff --git a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c index 34defede5..9220c6be4 100644 --- a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c +++ b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c @@ -7,6 +7,7 @@ #include "z_obj_switch.h" #include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -249,10 +250,12 @@ void ObjSwitch_SetOn(ObjSwitch* this, PlayState* play) { subType = (this->dyna.actor.params >> 4 & 7); Flags_SetSwitch(play, (this->dyna.actor.params >> 8 & 0x3F)); - if (subType == 0 || subType == 4) { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_CORRECT_CHIME); - } else { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + if (subType == 0 || subType == 4) { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_CORRECT_CHIME); + } else { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + } } this->cooldownOn = true; @@ -266,7 +269,9 @@ void ObjSwitch_SetOff(ObjSwitch* this, PlayState* play) { Flags_UnsetSwitch(play, (this->dyna.actor.params >> 8 & 0x3F)); if ((this->dyna.actor.params >> 4 & 7) == 1) { - OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) { + OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + } this->cooldownOn = true; } } diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 7489fa8fa..456955956 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -31,6 +31,7 @@ #include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "soh/Enhancements/randomizer/fishsanity.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include <string.h> #include <stdlib.h> @@ -6658,7 +6659,14 @@ s32 func_8083E5A8(Player* this, PlayState* play) { uint8_t showItemCutscene = play->sceneNum == SCENE_BOMBCHU_BOWLING_ALLEY || Item_CheckObtainability(giEntry.itemId) == ITEM_NONE || IS_RANDO; // Only skip cutscenes for drops when they're items/consumables from bushes/rocks/enemies. - uint8_t isDropToSkip = (interactedActor->id == ACTOR_EN_ITEM00 && interactedActor->params != 6 && interactedActor->params != 17) || + uint8_t isDropToSkip = + ( + interactedActor->id == ACTOR_EN_ITEM00 && + interactedActor->params != ITEM00_HEART_PIECE && + interactedActor->params != ITEM00_SMALL_KEY && + interactedActor->params != ITEM00_SOH_GIVE_ITEM_ENTRY && + interactedActor->params != ITEM00_SOH_GIVE_ITEM_ENTRY_GI + ) || interactedActor->id == ACTOR_EN_KAREBABA || interactedActor->id == ACTOR_EN_DEKUBABA; @@ -6716,8 +6724,10 @@ s32 func_8083E5A8(Player* this, PlayState* play) { } func_80836898(play, this, func_8083A434); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_CHEST, true, &giEntry)) { this->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_IN_CUTSCENE; func_8083AE40(this, giEntry.objectId); + } this->actor.world.pos.x = chest->dyna.actor.world.pos.x - (Math_SinS(chest->dyna.actor.shape.rot.y) * 29.4343f); this->actor.world.pos.z = @@ -10087,7 +10097,7 @@ void Player_Init(Actor* thisx, PlayState* play2) { if ((sp50 == 0) || (sp50 < -1)) { titleFileSize = scene->titleFile.vromEnd - scene->titleFile.vromStart; - if (gSaveContext.showTitleCard) { + if (GameInteractor_Should(GI_VB_SHOW_TITLE_CARD, gSaveContext.showTitleCard, NULL)) { if ((gSaveContext.sceneSetupIndex < 4) && (gEntranceTable[((void)0, gSaveContext.entranceIndex) + ((void)0, gSaveContext.sceneSetupIndex)].field & ENTRANCE_INFO_DISPLAY_TITLE_CARD_FLAG) && @@ -13393,7 +13403,7 @@ s32 func_8084DFF4(PlayState* play, Player* this) { play->msgCtx.msgMode = MSGMODE_TEXT_DONE; } else { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { - if (this->getItemId == GI_GAUNTLETS_SILVER && !IS_RANDO) { + if (GameInteractor_Should(GI_VB_PLAY_NABOORU_CAPTURED_CS, this->getItemId == GI_GAUNTLETS_SILVER, NULL)) { play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_0; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.nextCutsceneIndex = 0xFFF1; @@ -13409,11 +13419,13 @@ s32 func_8084DFF4(PlayState* play, Player* this) { this->unk_862 = 0; } + // #region SOH [Randomizer] TODO Better Ice trap handling? if (this->getItemEntry.itemId == RG_ICE_TRAP && this->getItemEntry.modIndex == MOD_RANDOMIZER) { this->unk_862 = 0; gSaveContext.pendingIceTrapCount++; Player_SetPendingFlag(this, play); } + // #endregion this->getItemId = GI_NONE; this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; @@ -15675,6 +15687,7 @@ void func_8085283C(PlayState* play, Player* this, CsCmdActorAction* arg2) { if (LinkAnimation_Update(play, &this->skelAnime)) { func_80852944(play, this, arg2); } else if (this->unk_850 == 0) { + // This is when link picks up the sword in the Ganon fight Item_Give(play, ITEM_SWORD_MASTER); func_80846720(play, this, 0); } else { |
