diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index d93bae983..47729c129 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -38,6 +38,7 @@ typedef enum { TEXT_CARPET_SALESMAN_1 = 0x6077, TEXT_CARPET_SALESMAN_2 = 0x6078, TEXT_MARKET_GUARD_NIGHT = 0x7003, + TEXT_FISHERMAN_LEAVE = 0x409E, TEXT_SHEIK_NEED_HOOK = 0x700F, TEXT_SHEIK_HAVE_HOOK = 0x7010, TEXT_SCRUB_RANDOM = 0x9000, diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index 020779216..bc87c47e2 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -136,6 +136,7 @@ const std::vector enhancementsCvars = { "gInjectItemCounts", "gDayGravePull", "gDampeAllNight", + "gQuitFishingAtDoor", "gSkipSwimDeepEndAnim", "gSkipScarecrow", "gBlueFireArrows", diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 1045c98f8..178a8f329 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2631,6 +2631,9 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { if (textId == TEXT_MARKET_GUARD_NIGHT && CVarGetInteger("gMarketSneak", 0) && play->sceneNum == SCENE_MARKET_ENTRANCE_NIGHT) { messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_MARKET_GUARD_NIGHT); } + if (textId == TEXT_FISHERMAN_LEAVE && CVarGetInteger("gQuitFishingAtDoor", 0)) { + messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_FISHERMAN_LEAVE); + } font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition(); switch (gSaveContext.language) { case LANGUAGE_FRA: diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index e656a3a90..3c77438e8 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -610,6 +610,8 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("Allows exiting Hyrule Castle Market Town to Hyrule Field at night by speaking to the guard next to the gate."); UIWidgets::PaddedEnhancementCheckbox("Link as default file name", "gLinkDefaultName", true, false); UIWidgets::Tooltip("Allows you to have \"Link\" as a premade file name"); + UIWidgets::PaddedEnhancementCheckbox("Quit Fishing At Door", "gQuitFishingAtDoor", true, false); + UIWidgets::Tooltip("Fisherman asks if you want to quit at the door when you still have the rod"); UIWidgets::PaddedText("Time Travel with the Song of Time", true, false); UIWidgets::EnhancementCombobox("gTimeTravel", timeTravelOptions, 0); UIWidgets::Tooltip("Allows Link to freely change age by playing the Song of Time.\n" diff --git a/soh/soh/z_message_OTR.cpp b/soh/soh/z_message_OTR.cpp index 10e6b0cfe..a4255d08a 100644 --- a/soh/soh/z_message_OTR.cpp +++ b/soh/soh/z_message_OTR.cpp @@ -182,4 +182,9 @@ extern "C" void OTRMessage_Init() CustomMessage("You look bored. Wanna go out for a&walk?\x1B&%gYes&No%w", "Du siehst gelangweilt aus.&Willst du einen Spaziergang machen?\x1B&%gJa&Nein%w", "Tu as l'air de t'ennuyer. Tu veux&aller faire un tour?\x1B&%gOui&Non%w")); + CustomMessageManager::Instance->CreateMessage( + customMessageTableID, TEXT_FISHERMAN_LEAVE, + CustomMessage("Hey! Hey!&You can't take the rod out of here!&I'm serious!^Do you want to quit?&\x1B&%gYes&No%w", + "Hey! Hey!&Du kannst die Angel doch nicht&einfach mitnehmen!&Ganz im Ernst!^Möchtest du aufhören?&\x1B&%gJa&Nein%w", //TODO Used AI translation as placeholder + "Holà! Holà!&Les cannes ne sortent pas d'ici!&Je suis sérieux!^Voulez-vous arrêter?&\x1B&%gOui&Non%w")); //TODO Used AI translation as placeholder } diff --git a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c index 3f8de83ba..727a20730 100644 --- a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c +++ b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c @@ -5174,6 +5174,37 @@ static Vec3s sSinkingLureLocationPos[] = { { 553, -48, -508 }, }; +// #region SOH [Enhancement] +void Fishing_QuitAtDoor(Fishing* this, PlayState* play) { + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) { + Message_CloseTextbox(play); + + switch (play->msgCtx.choiceIndex) { + case 0: + if (D_80B7E084 == 0) { + Message_ContinueTextbox(play, 0x4085); + } else if (sLinkAge == 1) { + Message_ContinueTextbox(play, 0x4092); + } + + if (Message_GetState(&play->msgCtx) == TEXT_STATE_DONE_FADING) { + + if (D_80B7A68C != 0) { + D_80B7A688 = 1; + D_80B7A68C = 0; + } + D_80B7E0AC = 0; + play->interfaceCtx.unk_260 = 0; + } + break; + case 1: + func_800A9F6C(0.0f, 150, 10, 10); + break; + } + } +} +// #endregion + void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { PlayState* play = play2; Fishing* this = (Fishing*)thisx; @@ -5480,6 +5511,12 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { case 11: player->actor.world.pos.z = 1360.0f; player->actor.speedXZ = 0.0f; + + // #region SOH [Enhancement] + if (CVarGetInteger("gQuitFishingAtDoor", 0)) { + Fishing_QuitAtDoor(this, play); + } + // #endregion if (Message_GetState(&play->msgCtx) == TEXT_STATE_NONE) { Camera* camera = Play_GetCamera(play, MAIN_CAM);