diff --git a/patches/input.c b/patches/input.c index 53f7eb3..c17c145 100644 --- a/patches/input.c +++ b/patches/input.c @@ -534,6 +534,13 @@ RECOMP_PATCH void Player_Action_86(Player *this, PlayState *play) { func_808550D0(play, this, this->unk_B10[4], this->unk_B10[5], (this->transformation == PLAYER_FORM_HUMAN) ? 0 : 1); } +bool no_bow_epona_fix = false; + +// @recomp_export void recomp_set_no_bow_epona_fix(bool new_val): Set whether to enable the fix for getting on Epona without a bow. +RECOMP_EXPORT void recomp_set_no_bow_epona_fix(bool new_val) { + no_bow_epona_fix = new_val; +} + extern s16 sPictoState; extern s16 sPictoPhotoBeingTaken; extern void* gWorkBuffer; @@ -603,21 +610,38 @@ RECOMP_PATCH void Interface_UpdateButtonsPart1(PlayState* play) { BUTTON_STATUS(EQUIP_SLOT_C_RIGHT) = BTN_DISABLED; set_extra_item_slot_status(BTN_DISABLED); } else { - BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_BOW; + // @recomp_use_export_var no_bow_epona_fix: Part of the no bow Epona fix. + if (no_bow_epona_fix) { + if (gSaveContext.save.saveInfo.inventory.items[SLOT_BOW] == ITEM_BOW) { + BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_BOW; + } + } else { + BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_BOW; + } if (play->unk_1887C >= 2) { Interface_LoadItemIconImpl(play, EQUIP_SLOT_B); } else if (gSaveContext.save.saveInfo.inventory.items[SLOT_BOW] == ITEM_NONE) { - BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_NONE; + // @recomp_use_export_var no_bow_epona_fix: Part of the no bow Epona fix. + if (no_bow_epona_fix) { + gSaveContext.buttonStatus[EQUIP_SLOT_B] = BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B); + BUTTON_STATUS(EQUIP_SLOT_B) = BTN_DISABLED; + } else { + BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_NONE; + } } else { Interface_LoadItemIconImpl(play, EQUIP_SLOT_B); } - BUTTON_STATUS(EQUIP_SLOT_C_LEFT) = BTN_DISABLED; - BUTTON_STATUS(EQUIP_SLOT_C_DOWN) = BTN_DISABLED; - BUTTON_STATUS(EQUIP_SLOT_C_RIGHT) = BTN_DISABLED; - set_extra_item_slot_status(BTN_DISABLED); - Interface_SetHudVisibility(HUD_VISIBILITY_A_HEARTS_MAGIC_MINIMAP_WITH_OVERWRITE); + // @recomp_use_export_var no_bow_epona_fix: If B item is a sword, don't disable the UI. + if (!no_bow_epona_fix || (BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) < ITEM_SWORD_KOKIRI || + BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) > ITEM_SWORD_GILDED)) { + BUTTON_STATUS(EQUIP_SLOT_C_LEFT) = BTN_DISABLED; + BUTTON_STATUS(EQUIP_SLOT_C_DOWN) = BTN_DISABLED; + BUTTON_STATUS(EQUIP_SLOT_C_RIGHT) = BTN_DISABLED; + set_extra_item_slot_status(BTN_DISABLED); + Interface_SetHudVisibility(HUD_VISIBILITY_A_HEARTS_MAGIC_MINIMAP_WITH_OVERWRITE); + } } } @@ -662,27 +686,44 @@ RECOMP_PATCH void Interface_UpdateButtonsPart1(PlayState* play) { BUTTON_STATUS(EQUIP_SLOT_C_RIGHT) = BTN_DISABLED; set_extra_item_slot_status(BTN_DISABLED); } else { - BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_BOW; + // @recomp_use_export_var no_bow_epona_fix: Part of the no bow Epona fix. + if (no_bow_epona_fix) { + if (gSaveContext.save.saveInfo.inventory.items[SLOT_BOW] == ITEM_BOW) { + BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_BOW; + } + } else { + BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_BOW; + } } if (play->unk_1887C >= 2) { Interface_LoadItemIconImpl(play, EQUIP_SLOT_B); } else if (gSaveContext.save.saveInfo.inventory.items[SLOT_BOW] == ITEM_NONE) { - BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_NONE; + // @recomp_use_export_var no_bow_epona_fix: Part of the no bow Epona fix. + if (no_bow_epona_fix) { + gSaveContext.buttonStatus[EQUIP_SLOT_B] = BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B); + BUTTON_STATUS(EQUIP_SLOT_B) = BTN_DISABLED; + } else { + BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_NONE; + } } else { Interface_LoadItemIconImpl(play, EQUIP_SLOT_B); } - if (BUTTON_STATUS(EQUIP_SLOT_B) == BTN_DISABLED) { + // @recomp_use_export_var no_bow_epona_fix: Don't enable the B button or restore hud visibility from Epona without a sword. + if ((player->stateFlags1 & PLAYER_STATE1_800000) == 0 || (!no_bow_epona_fix && BUTTON_STATUS(EQUIP_SLOT_B) == BTN_DISABLED)) { BUTTON_STATUS(EQUIP_SLOT_B) = BTN_ENABLED; restoreHudVisibility = true; } - BUTTON_STATUS(EQUIP_SLOT_C_LEFT) = BTN_DISABLED; - BUTTON_STATUS(EQUIP_SLOT_C_DOWN) = BTN_DISABLED; - BUTTON_STATUS(EQUIP_SLOT_C_RIGHT) = BTN_DISABLED; - set_extra_item_slot_status(BTN_DISABLED); - Interface_SetHudVisibility(HUD_VISIBILITY_A_HEARTS_MAGIC_MINIMAP_WITH_OVERWRITE); + // @recomp_use_export_var no_bow_epona_fix: If B item is a sword, don't disable the UI. + if (!no_bow_epona_fix) { + BUTTON_STATUS(EQUIP_SLOT_C_LEFT) = BTN_DISABLED; + BUTTON_STATUS(EQUIP_SLOT_C_DOWN) = BTN_DISABLED; + BUTTON_STATUS(EQUIP_SLOT_C_RIGHT) = BTN_DISABLED; + set_extra_item_slot_status(BTN_DISABLED); + Interface_SetHudVisibility(HUD_VISIBILITY_A_HEARTS_MAGIC_MINIMAP_WITH_OVERWRITE); + } if (play->transitionMode != TRANS_MODE_OFF) { Interface_SetHudVisibility(HUD_VISIBILITY_NONE); @@ -802,6 +843,13 @@ RECOMP_PATCH void Interface_UpdateButtonsPart1(PlayState* play) { } } +bool fd_anywhere = false; + +// @recomp_export void recomp_set_fd_anywhere(bool new_val): Set whether the Fierce Deity's Mask has scene restrictions. +RECOMP_EXPORT void recomp_set_fd_anywhere(bool new_val) { + fd_anywhere = new_val; +} + /** * A continuation of the if-else chain from Interface_UpdateButtonsPart1 * Also used directly when opening the pause menu i.e. skips part 1 @@ -1181,7 +1229,8 @@ RECOMP_PATCH void Interface_UpdateButtonsPart2(PlayState* play) { } } else if (GET_CUR_FORM_BTN_ITEM(i) == ITEM_MASK_FIERCE_DEITY) { // Fierce Deity's Mask is equipped - if ((play->sceneId != SCENE_MITURIN_BS) && (play->sceneId != SCENE_HAKUGIN_BS) && + // @recomp_use_export_var fd_anywhere: Allow the player to use the Fierce Deity's Mask anywhere if mods enable it. + if (!fd_anywhere && (play->sceneId != SCENE_MITURIN_BS) && (play->sceneId != SCENE_HAKUGIN_BS) && (play->sceneId != SCENE_SEA_BS) && (play->sceneId != SCENE_INISIE_BS) && (play->sceneId != SCENE_LAST_BS)) { if (BUTTON_STATUS(i) != BTN_DISABLED) {