diff --git a/soh/soh/Enhancements/AlwaysOnFixes.cpp b/soh/soh/Enhancements/AlwaysOnFixes.cpp index f6452ffd48..aa1436f7b7 100644 --- a/soh/soh/Enhancements/AlwaysOnFixes.cpp +++ b/soh/soh/Enhancements/AlwaysOnFixes.cpp @@ -5,6 +5,7 @@ extern "C" { #include "macros.h" #include "functions.h" #include "variables.h" +#include "src/overlays/actors/ovl_En_Go2/z_en_go2.h" extern void Player_UseItem(PlayState*, Player*, s32); extern PlayState* gPlayState; } @@ -57,7 +58,21 @@ void RegisterPreventHookshotParentSoftlock() { }); } +// Vanilla bug: If player starts talking with Goron Link for the first time (before getting tunic) +// but moves out of range, player will softlock because the text cannot progress to the question +// choice textbox when Goron Link is asleep (UpdateTalkState cannot run). +// Fix: Allow updating talkState even when Goron Link is asleep. +void RegisterPreventGoronLinkSoftlock() { + COND_VB_SHOULD(VB_PREVENT_GORON_LINK_SOFTLOCK, true, { + EnGo2* GoronLink = va_arg(args, EnGo2*); + if (GoronLink->interactInfo.talkState == NPC_TALK_STATE_TALKING) { + *should = true; + } + }); +} + static RegisterShipInitFunc initFuncFixOutsideTotCrash(RegisterFixOutsideTotCrash, { "" }); static RegisterShipInitFunc initFuncFixDekuShieldDropCrash(RegisterFixDekuShieldDropCrash, { "" }); static RegisterShipInitFunc initFuncHookshotNospawnSoftlock(RegisterPreventHookshotNoSpawnSoftlock, { "" }); static RegisterShipInitFunc initFuncHookshotParentSoftlock(RegisterPreventHookshotParentSoftlock, { "" }); +static RegisterShipInitFunc initFuncGoronLinkSoftlock(RegisterPreventGoronLinkSoftlock, { "" }); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 6e3f9e4a19..adb2076302 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -3111,6 +3111,14 @@ typedef enum { // - `s16* (&this->actor.parent->id)` VB_PREVENT_HOOKSHOT_PARENT_SOFTLOCK, + // #### `result` + // ```c + // true if Goron Link is talking + // ``` + // #### `args` + // - `*EnGo2` (Goron Link) + VB_PREVENT_GORON_LINK_SOFTLOCK, + // true // ``` // #### `args` 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 6ef04cfe7a..58835cc2ab 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 @@ -1100,7 +1100,8 @@ void func_80A45288(EnGo2* this, PlayState* play) { this->interactInfo.yOffset = D_80A482D8[this->actor.params & 0x1F][linkAge]; Npc_TrackPoint(&this->actor, &this->interactInfo, 4, this->trackingMode); } - if ((this->actionFunc != EnGo2_SetGetItem) && (this->isAwake == true)) { + if ((this->actionFunc != EnGo2_SetGetItem) && + GameInteractor_Should(VB_PREVENT_GORON_LINK_SOFTLOCK, this->isAwake, this)) { if (func_80A44790(this, play)) { EnGo2_BiggoronSetTextId(this, play, player); }