diff --git a/soh/soh/Enhancements/Fishing.cpp b/soh/soh/Enhancements/Fishing.cpp index 98235c8d415..bbfdc554112 100644 --- a/soh/soh/Enhancements/Fishing.cpp +++ b/soh/soh/Enhancements/Fishing.cpp @@ -3,7 +3,8 @@ extern "C" { #include - +extern PlayState* gPlayState; +extern SaveContext gSaveContext; f32 Fishing_GetMinimumRequiredScore(); } @@ -18,4 +19,28 @@ void RegisterFishingMessages() { COND_ID_HOOK(OnOpenText, 0x4080, CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0), BuildFishingMessage); } +// Vanilla bug: Not possible to fish with blank B because the blank B item value 0xFF gets saved +// as temp B, which also makes B button disabled - fishing pole gets unequipped. +// Fix: Disregard disabled B when fishing, and set used item to fishing pole on B press. +void RegisterAllowFishingBlankB() { + COND_VB_SHOULD( + VB_ALLOW_BLANK_B_FISHING_EQUIP, (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("FishingBlankB"), IS_RANDO)), { + if (gPlayState->interfaceCtx.unk_260 != 0 && gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE) { + *should = false; + } + }); + + COND_VB_SHOULD( + VB_ALLOW_BLANK_B_FISHING_ITEM, (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("FishingBlankB"), IS_RANDO)), { + s32* i = va_arg(args, s32*); + Player* player = va_arg(args, Player*); + s32* item = va_arg(args, s32*); + if (gPlayState->interfaceCtx.unk_260 != 0 && *i == 0 && player->itemAction == PLAYER_IA_FISHING_POLE) { + *item = ITEM_FISHING_POLE; + } + }); +} + static RegisterShipInitFunc initFunc(RegisterFishingMessages, { CVAR_ENHANCEMENT("CustomizeFishing") }); +static RegisterShipInitFunc initAllowFishingBlankB(RegisterAllowFishingBlankB, + { CVAR_ENHANCEMENT("FishingBlankB"), "IS_RANDO" }); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 6998709b663..beee4a4e2ed 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -3186,6 +3186,24 @@ typedef enum { // - `s16* (&this->actor.parent->id)` VB_PREVENT_HOOKSHOT_PARENT_SOFTLOCK, + // #### `result` + // ```c + // false if gPlayState->interfaceCtx.unk_260 != 0 && gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE + // ``` + // #### `args` + // - none + VB_ALLOW_BLANK_B_FISHING_EQUIP, + + // #### `result` + // ```c + // gPlayState->interfaceCtx.unk_260 != 0 && i == 0 && player->itemAction == PLAYER_IA_FISHING_POLE + // ``` + // #### `args` + // - `s32* i` + // - `Player*` + // - `s32* item` + VB_ALLOW_BLANK_B_FISHING_ITEM, + // #### `result` // ```c // true if Goron Link is talking diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 9af0303bd49..ad7a7d70d8a 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1645,6 +1645,10 @@ void SohMenu::AddMenuEnhancements() { .PreFunc(fishingDisabledFunc) .Options(IntSliderOptions().Min(6).Max(13).DefaultValue(13).Format("%d lbs.").Tooltip( "The minimum weight for the unique fishing reward as an adult.")); + AddWidget(path, "Allow fishing with blank B", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("FishingBlankB")) + .Options(CheckboxOptions().Tooltip("Allow fishing even when not having any item equipped on the B button, " + "fixing a vanilla bug. Always enabled in randomizer.")); // Extra Modes path.sidebarName = "Extra Modes"; 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 b1d2f4c47d1..92e4afdf401 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -2523,8 +2523,10 @@ void Player_ProcessItemButtons(Player* this, PlayState* play) { } if (!Player_ItemIsInUse(this, B_BTN_ITEM) && !Player_ItemIsInUse(this, C_BTN_ITEM(0)) && !Player_ItemIsInUse(this, C_BTN_ITEM(1)) && !Player_ItemIsInUse(this, C_BTN_ITEM(2)) && !hasOnDpad) { - Player_UseItem(play, this, ITEM_NONE); - return; + if (GameInteractor_Should(VB_ALLOW_BLANK_B_FISHING_EQUIP, true)) { + Player_UseItem(play, this, ITEM_NONE); + return; + } } } @@ -2535,6 +2537,7 @@ void Player_ProcessItemButtons(Player* this, PlayState* play) { } item = Player_GetItemOnButton(play, i); + GameInteractor_Should(VB_ALLOW_BLANK_B_FISHING_ITEM, true, &i, this, &item); if (item >= ITEM_NONE_FE) { for (i = 0; i < ARRAY_COUNT(sItemButtons); i++) {