diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index 39fa9edbc..53f0319ac 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -104,6 +104,14 @@ typedef enum { TEXT_BEAN_SALESMAN_SET_A_BEAN_TO_C = 0x406A, TEXT_BEAN_SALESMAN_SOLD_OUT = 0x406B, TEXT_BEAN_SALESMAN_WANT_TO_PLANT = 0x406C, + TEXT_FISHING_TALK_ABOUT_SOMETHING = 0x4088, + TEXT_FISHING_TRY_ANOTHER_LURE = 0x408D, + TEXT_FISHING_SECRETS = 0x408E, + TEXT_FISHING_GOOD_FISHERMAN = 0x408F, + TEXT_FISHING_DIFFERENT_POND = 0x4094, + TEXT_FISHING_SCRATCHING = 0x4095, + TEXT_FISHING_CLOUDY = 0x4096, + TEXT_FISHING_TRY_ANOTHER_LURE_WITH_SINKING_LURE = 0x40AF, TEXT_DAMPES_DIARY = 0x5003, TEXT_GRANNYS_SHOP = 0x500C, TEXT_CARPET_SALESMAN_1 = 0x6077, diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index dec733f3e..cbc6a973d 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -522,6 +522,8 @@ const std::vector flagTables = { { RAND_INF_HAS_OCARINA_C_DOWN, "RAND_INF_HAS_OCARINA_C_DOWN" }, { RAND_INF_HAS_OCARINA_C_LEFT, "RAND_INF_HAS_OCARINA_C_LEFT"}, { RAND_INF_HAS_OCARINA_C_RIGHT, "RAND_INF_HAS_OCARINA_C_RIGHT"}, + + { RAND_INF_CAUGHT_LOACH, "RAND_INF_CAUGHT_LOACH" }, } }, }; diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index 5e5a003ec..d808c2b35 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp @@ -230,6 +230,14 @@ void HintTable_Init_Exclude_Overworld() { Text{"#fishing in maturity# bestows", /*french*/"#pêcher dans sa maturité# promet", /*spanish*/"#pescar en la madurez# conduce a"}, }); + hintTable[RHT_LH_HYRULE_LOACH] = HintText::Exclude({ + //obscure text + Text{"#fishing the legend# bestows", /*french*/"!!!", /*spanish*/"#pescar a la leyenda# conduce a"}, + }, {}, + //clear text + Text{"#fishing the hyrule loach# will give you", /*french*/"!!!", /*spanish*/"si #pescas a la Locha de Hyrule# encontrarás"} + ); + hintTable[RHT_LH_LAB_DIVE] = HintText::Exclude({ //obscure text Text{"a #diving experiment# is rewarded with", /*french*/"l'#expérience de plongée# donne", /*spanish*/"#bucear para un experimento# se premia con"}, diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index c4fad91eb..09e80d554 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -738,6 +738,12 @@ void GenerateItemPool() { ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_RIGHT_BUTTON); } + if (ctx->GetOption(RSK_SHUFFLE_HYRULE_LOACH_REWARD)) { + AddItemToMainPool(RG_PURPLE_RUPEE); + } else { + ctx->PlaceItemInLocation(RC_LH_HYRULE_LOACH, RG_PURPLE_RUPEE, false, true); + } + if (ctx->GetOption(RSK_SHUFFLE_COWS)) { //9 total cow locations for (uint8_t i = 0; i < 9; i++) { diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp index 9259846fb..410816292 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp @@ -160,6 +160,7 @@ void AreaTable_Init_HyruleField() { //Locations LocationAccess(RC_LH_CHILD_FISHING, {[]{return IsChild;}}), LocationAccess(RC_LH_ADULT_FISHING, {[]{return IsAdult;}}), + LocationAccess(RC_LH_HYRULE_LOACH, {[]{return true;}}), }, { //Exits Entrance(RR_LH_FISHING_ISLAND, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 2e3122cb8..0ae9a13e8 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -155,6 +155,7 @@ std::vector Rando::StaticData::overworldLocations = { // Lake Hylia RC_LH_CHILD_FISHING, RC_LH_ADULT_FISHING, + RC_LH_HYRULE_LOACH, RC_LH_LAB_DIVE, RC_LH_TRADE_FROG, RC_LH_UNDERWATER_ITEM, @@ -583,6 +584,7 @@ void Rando::StaticData::InitLocationTable() { // Lake Hylia locationTable[RC_LH_CHILD_FISHING] = Location::Base(RC_LH_CHILD_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, 0x3E, "Child Fishing", "LH Child Fishing", RHT_LH_CHILD_FISHING, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::RandomizerInf(SCENE_FISHING_POND, RAND_INF_CHILD_FISHING), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); locationTable[RC_LH_ADULT_FISHING] = Location::Base(RC_LH_ADULT_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, 0x38, "Adult Fishing", "LH Adult Fishing", RHT_LH_ADULT_FISHING, RG_PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::RandomizerInf(SCENE_FISHING_POND, RAND_INF_ADULT_FISHING), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); + locationTable[RC_LH_HYRULE_LOACH] = Location::Base(RC_LH_HYRULE_LOACH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, 0x00, "Hyrule Loach Reward", "LH Hyrule Loach Reward", RHT_LH_HYRULE_LOACH, RG_PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::RandomizerInf(SCENE_FISHING_POND, RAND_INF_CAUGHT_LOACH), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); locationTable[RC_LH_LAB_DIVE] = Location::Base(RC_LH_LAB_DIVE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, 0x3E, "Lab Dive", "LH Lab Dive", RHT_LH_LAB_DIVE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(24), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); locationTable[RC_LH_TRADE_FROG] = Location::Base(RC_LH_TRADE_FROG, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, 0x25, "Lab Trade Eyeball Frog", "LH Lab Trade Eyeball Frog", RHT_LH_TRADE_FROG, RG_EYEDROPS, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(0x38, 0x1F), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); locationTable[RC_LH_UNDERWATER_ITEM] = Location::Base(RC_LH_UNDERWATER_ITEM, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, 0x15, "Underwater Item", "LH Underwater Item", RHT_LH_UNDERWATER_ITEM, RG_RUTOS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x31), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 85e5affe8..670fb84a6 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -280,6 +280,8 @@ void Settings::CreateOptionDescriptions() { "\n" "This setting does not effect the item earned from playing\n" "the Song of Storms and the frog song minigame."; + mOptionDescriptions[RSK_SHUFFLE_HYRULE_LOACH_REWARD] = "Shuffles a Purple Rupee into to the item pool, and allows" + "you to earn an item by catching the hyrule loach at the fishing pond."; mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE] = "Adds all of the adult trade quest items into the pool, each of which " "can be traded for a unique reward.\n" @@ -483,6 +485,8 @@ void Settings::CreateOptionDescriptions() { "Reading the diary of Dampé the gravekeeper as adult will tell you the location of one of the Hookshots."; mOptionDescriptions[RSK_GREG_HINT] = "Talking to the chest game owner after buying a key will tell you the location of Greg the Green Rupee."; + mOptionDescriptions[RSK_LOACH_HINT] = + "Talking to the fishing pond owner and asking to talk about something will tell you what's the reward for the Hyrule Loach."; mOptionDescriptions[RSK_SARIA_HINT] = "Talking to Saria either in person or through Saria's Song will tell you the " "location of a progressive magic meter."; mOptionDescriptions[RSK_FROGS_HINT] = "Standing near the pedestal for the frogs in Zora's River will tell you the " diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index a7ba16c49..448db06d1 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -87,7 +87,7 @@ static const char* englishRupeeNames[171] = { "Frog Coins", "Gald", "Gekz", "Gems", "Geo", "Gil", "Glimmer", "Glitches", "Gold", "Gold Dragons", "Goober Dollars", "Green Herbs", "Greg Siblings", "Gummybears", "Hell", - "Hylian Loaches", "Ice Traps", "ISK", "Jiggies", "KF7 Ammo", + "Hyrule Loaches", "Ice Traps", "ISK", "Jiggies", "KF7 Ammo", "Kinstones", "Kremcoins", "Kroner", "Leaves ", "Lemmings", "Lien", "Lira", "Lumber", "Lungmen Dollars", "Macca", "Mana", "Mann Co. Keys", "Meat", "Meat Stacks", "Medaparts", @@ -344,6 +344,15 @@ void Randomizer::LoadHintMessages() { "Unter Wasser gibt es Frösche,&die %g{{item}}%w&bei sich haben und Dich neugierig&beobachten...", "Des grenouilles se trouvant&sous l'eau vous fixent attentivement,&tenant fermement&%g{{item}}%w.", TEXTBOX_TYPE_BLUE) ); + CustomMessageManager::Instance->CreateMessage( + Randomizer::randoMiscHintsTableID, + TEXT_FISHING_TALK_ABOUT_SOMETHING, + CustomMessage( + "What?^You wanna know about the&%rHyrule Loach%w?^It's a big fish, but it's so rare that&I'll give my %g{{item}}%w&to anyone who catches it. Seriously!", + "%g{{item}}%w",//TODO: Translations + "%g{{item}}%w" + ) + ); CustomMessageManager::Instance->CreateMessage( Randomizer::randoMiscHintsTableID, TEXT_SARIAS_SONG_FACE_TO_FACE, CustomMessage("{{message}}", "{{message}}", "{{message}}", TEXTBOX_TYPE_BLUE) @@ -2486,6 +2495,25 @@ CustomMessage Randomizer::GetFrogsMessage(u16 originalTextId) { return messageEntry; } +CustomMessage Randomizer::GetLoachMessage() { + auto ctx = Rando::Context::GetInstance(); + CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::randoMiscHintsTableID, TEXT_FISHING_TALK_ABOUT_SOMETHING); + RandomizerGet loachGet = ctx->GetItemLocation(RC_LH_HYRULE_LOACH)->GetPlacedRandomizerGet(); + std::array loachItemName; + if (loachGet == RG_ICE_TRAP) { + loachGet = ctx->overrides[RC_LH_HYRULE_LOACH].LooksLike(); + loachItemName = { + ctx->overrides[RC_LH_HYRULE_LOACH].GetTrickName().english, + ctx->overrides[RC_LH_HYRULE_LOACH].GetTrickName().french, + ctx->overrides[RC_LH_HYRULE_LOACH].GetTrickName().english + }; + } else { + loachItemName = EnumToSpoilerfileGetName[loachGet]; + } + messageEntry.Replace("{{item}}", std::move(loachItemName[0]), std::move(loachItemName[1]), std::move(loachItemName[2])); + return messageEntry; +} + CustomMessage Randomizer::GetSheikMessage(s16 scene, u16 originalTextId) { auto ctx = Rando::Context::GetInstance(); CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, originalTextId); diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 9dab10b99..eddca2e37 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -62,6 +62,7 @@ class Randomizer { CustomMessage GetWarpSongMessage(u16 textId, bool mysterious = false); CustomMessage GetSheikMessage(s16 scene, u16 originalTextId); CustomMessage GetFrogsMessage(u16 originalTextId); + CustomMessage GetLoachMessage(); CustomMessage GetSariaMessage(u16 originalTextId); CustomMessage GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious = false); CustomMessage GetCursedSkullMessage(s16 params); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 9cb8d9ef5..5a4cce031 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -906,6 +906,7 @@ typedef enum { RC_LH_UNDERWATER_ITEM, RC_LH_CHILD_FISHING, RC_LH_ADULT_FISHING, + RC_LH_HYRULE_LOACH, RC_LH_LAB_DIVE, RC_LH_TRADE_FROG, RC_LH_FREESTANDING_POH, @@ -2410,6 +2411,7 @@ typedef enum { RHT_LH_UNDERWATER_ITEM, RHT_LH_CHILD_FISHING, RHT_LH_ADULT_FISHING, + RHT_LH_HYRULE_LOACH, RHT_LH_LAB_DIVE, RHT_LH_TRADE_FROG, RHT_LH_FREESTANDING_POH, @@ -3421,6 +3423,7 @@ typedef enum { RSK_SHUFFLE_WEIRD_EGG, RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, RSK_SHUFFLE_FROG_SONG_RUPEES, + RSK_SHUFFLE_HYRULE_LOACH_REWARD, RSK_ITEM_POOL, RSK_ICE_TRAPS, RSK_GOSSIP_STONE_HINTS, @@ -3428,6 +3431,7 @@ typedef enum { RSK_LIGHT_ARROWS_HINT, RSK_DAMPES_DIARY_HINT, RSK_GREG_HINT, + RSK_LOACH_HINT, RSK_SARIA_HINT, RSK_FROGS_HINT, RSK_KAK_10_SKULLS_HINT, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index 14335db68..41f31a784 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -157,6 +157,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger("gRandomizeShuffleAdultTrade", RO_GENERIC_NO)) && (location.GetRandomizerCheck() != RC_KF_KOKIRI_SWORD_CHEST || CVarGetInteger("gRandomizeShuffleKokiriSword", RO_GENERIC_NO)) && + (location.GetRandomizerCheck() != RC_LH_HYRULE_LOACH || + CVarGetInteger("gRandomizeShuffleHyruleLoachReward", RO_GENERIC_NO)) && (location.GetRandomizerCheck() != RC_ZR_MAGIC_BEAN_SALESMAN || CVarGetInteger("gRandomizeShuffleBeans", RO_GENERIC_NO)) && (location.GetRandomizerCheck() != RC_HC_MALON_EGG || diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 798b11d97..fc09d533b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -62,6 +62,7 @@ bool showCows; bool showAdultTrade; bool showKokiriSword; bool showMasterSword; +bool showHyruleLoach; bool showWeirdEgg; bool showGerudoCard; bool showFrogSongRupees; @@ -1087,6 +1088,9 @@ void LoadSettings() { showMasterSword = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MASTER_SWORD) == RO_GENERIC_YES : true; + showHyruleLoach = IS_RANDO ? + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_HYRULE_LOACH_REWARD) == RO_GENERIC_YES + : false; showWeirdEgg = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_WEIRD_EGG) == RO_GENERIC_YES : true; @@ -1201,6 +1205,7 @@ bool IsVisibleInCheckTracker(RandomizerCheck rc) { ) && (rc != RC_KF_KOKIRI_SWORD_CHEST || showKokiriSword) && (rc != RC_TOT_MASTER_SWORD || showMasterSword) && + (rc != RC_LH_HYRULE_LOACH || showHyruleLoach) && (rc != RC_ZR_MAGIC_BEAN_SALESMAN || showBeans) && (rc != RC_HC_MALON_EGG || showWeirdEgg) && (loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) && diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 39f84ba2a..2dc8d7dde 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -177,6 +177,8 @@ typedef enum { RAND_INF_HAS_OCARINA_C_LEFT, RAND_INF_HAS_OCARINA_C_RIGHT, + RAND_INF_CAUGHT_LOACH, + // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) RAND_INF_MAX, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index d858bb567..78b01e374 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -109,6 +109,7 @@ void Settings::CreateOptions() { mOptions[RSK_SHUFFLE_MAGIC_BEANS] = Option::Bool("Shuffle Magic Beans", "gRandomizeShuffleBeans", mOptionDescriptions[RSK_SHUFFLE_MAGIC_BEANS]); mOptions[RSK_SHUFFLE_MERCHANTS] = Option::U8("Shuffle Merchants", {"Off", "On (No Hints)", "On (With Hints)"}, OptionCategory::Setting, "gRandomizeShuffleMerchants", mOptionDescriptions[RSK_SHUFFLE_MERCHANTS], WidgetType::Combobox, RO_SHUFFLE_MERCHANTS_OFF); mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES] = Option::Bool("Shuffle Frog Song Rupees", "gRandomizeShuffleFrogSongRupees", mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES]); + mOptions[RSK_SHUFFLE_HYRULE_LOACH_REWARD] = Option::Bool("Shuffle Hyrule Loach Reward", "gRandomizeShuffleHyruleLoachReward", mOptionDescriptions[RSK_SHUFFLE_HYRULE_LOACH_REWARD]); mOptions[RSK_SHUFFLE_ADULT_TRADE] = Option::Bool("Shuffle Adult Trade", "gRandomizeShuffleAdultTrade", mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]); mOptions[RSK_SHUFFLE_CHEST_MINIGAME] = Option::U8("Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}); mOptions[RSK_SHUFFLE_100_GS_REWARD] = Option::Bool("Shuffle 100 GS Reward", "gRandomizeShuffle100GSReward", mOptionDescriptions[RSK_SHUFFLE_100_GS_REWARD], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); @@ -151,6 +152,7 @@ void Settings::CreateOptions() { mOptions[RSK_LIGHT_ARROWS_HINT] = Option::Bool("Light Arrow Hint", {"Off", "On"}, OptionCategory::Setting, "gRandomizeLAHint", mOptionDescriptions[RSK_LIGHT_ARROWS_HINT], WidgetType::Checkbox, RO_GENERIC_ON, false, IMFLAG_NONE); mOptions[RSK_DAMPES_DIARY_HINT] = Option::Bool("Dampe's Diary Hint", "gRandomizeDampeHint", mOptionDescriptions[RSK_DAMPES_DIARY_HINT], IMFLAG_NONE); mOptions[RSK_GREG_HINT] = Option::Bool("Greg the Green Rupee Hint", "gRandomizeGregHint", mOptionDescriptions[RSK_GREG_HINT], IMFLAG_NONE); + mOptions[RSK_LOACH_HINT] = Option::Bool("Hyrule Loach Hint", "gRandomizeLoachHint", mOptionDescriptions[RSK_LOACH_HINT], IMFLAG_NONE); mOptions[RSK_SARIA_HINT] = Option::Bool("Saria's Hint", "gRandomizeSariaHint", mOptionDescriptions[RSK_SARIA_HINT], IMFLAG_NONE); mOptions[RSK_FROGS_HINT] = Option::Bool("Frog Ocarina Game Hint", "gRandomizeFrogsHint", mOptionDescriptions[RSK_FROGS_HINT], IMFLAG_NONE); mOptions[RSK_WARP_SONG_HINTS] = Option::Bool("Warp Song Hints", "gRandomizeWarpSongText", mOptionDescriptions[RSK_WARP_SONG_HINTS], IMFLAG_NONE, WidgetType::Checkbox, RO_GENERIC_ON); @@ -632,6 +634,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_MAGIC_BEANS], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], + &mOptions[RSK_SHUFFLE_HYRULE_LOACH_REWARD], &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BOSS_SOULS], @@ -688,6 +691,7 @@ void Settings::CreateOptions() { &mOptions[RSK_LIGHT_ARROWS_HINT], &mOptions[RSK_DAMPES_DIARY_HINT], &mOptions[RSK_GREG_HINT], + &mOptions[RSK_LOACH_HINT], &mOptions[RSK_SARIA_HINT], &mOptions[RSK_FROGS_HINT], &mOptions[RSK_WARP_SONG_HINTS], @@ -826,6 +830,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_MAGIC_BEANS], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], + &mOptions[RSK_SHUFFLE_HYRULE_LOACH_REWARD], &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_CHEST_MINIGAME], &mOptions[RSK_SHUFFLE_100_GS_REWARD], @@ -903,6 +908,7 @@ void Settings::CreateOptions() { &mOptions[RSK_LIGHT_ARROWS_HINT], &mOptions[RSK_DAMPES_DIARY_HINT], &mOptions[RSK_GREG_HINT], + &mOptions[RSK_LOACH_HINT], &mOptions[RSK_SARIA_HINT], &mOptions[RSK_FROGS_HINT], &mOptions[RSK_WARP_SONG_HINTS], @@ -1033,6 +1039,7 @@ void Settings::CreateOptions() { { "Shuffle Settings:Shuffle Master Sword", RSK_SHUFFLE_MASTER_SWORD }, { "Shuffle Settings:Shuffle Weird Egg", RSK_SHUFFLE_WEIRD_EGG }, { "Shuffle Settings:Shuffle Frog Song Rupees", RSK_SHUFFLE_FROG_SONG_RUPEES }, + { "Shuffle Settings:Shuffle Hyrule Loach Reward", RSK_SHUFFLE_HYRULE_LOACH_REWARD }, { "Shuffle Settings:Shuffle Merchants", RSK_SHUFFLE_MERCHANTS }, { "Shuffle Settings:Shuffle 100 GS Reward", RSK_SHUFFLE_100_GS_REWARD }, { "Shuffle Settings:Shuffle Boss Souls", RSK_SHUFFLE_BOSS_SOULS }, @@ -1101,6 +1108,7 @@ void Settings::CreateOptions() { { "Miscellaneous Settings:Light Arrow Hint", RSK_LIGHT_ARROWS_HINT }, { "Miscellaneous Settings:Dampe's Diary Hint", RSK_DAMPES_DIARY_HINT }, { "Miscellaneous Settings:Greg the Rupee Hint", RSK_GREG_HINT }, + { "Miscellaneous Settings:Hyrule Loach Hint", RSK_LOACH_HINT }, { "Miscellaneous Settings:Saria's Hint", RSK_SARIA_HINT }, { "Miscellaneous Settings:Frog Ocarina Game Hint", RSK_FROGS_HINT }, { "Miscellaneous Settings:10 GS Hint", RSK_KAK_10_SKULLS_HINT }, @@ -2118,6 +2126,7 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) { case RSK_SHUFFLE_100_GS_REWARD: case RSK_SHUFFLE_OCARINA: case RSK_SHUFFLE_OCARINA_BUTTONS: + case RSK_SHUFFLE_HYRULE_LOACH_REWARD: case RSK_STARTING_DEKU_SHIELD: case RSK_STARTING_KOKIRI_SWORD: case RSK_STARTING_ZELDAS_LULLABY: @@ -2143,6 +2152,7 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) { case RSK_LIGHT_ARROWS_HINT: case RSK_DAMPES_DIARY_HINT: case RSK_GREG_HINT: + case RSK_LOACH_HINT: case RSK_SARIA_HINT: case RSK_FROGS_HINT: case RSK_KAK_10_SKULLS_HINT: diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 74273c22d..4802f901d 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2618,6 +2618,17 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { } else if (textId == 0x3052 || (textId >= 0x3069 && textId <= 0x3070)) { //Fire Temple gorons u16 choice = Random(0, NUM_GORON_MESSAGES); messageEntry = OTRGlobals::Instance->gRandomizer->GetGoronMessage(choice); + } else if (Randomizer_GetSettingValue(RSK_LOACH_HINT) && + ( + textId == TEXT_FISHING_CLOUDY || + textId == TEXT_FISHING_TRY_ANOTHER_LURE || + textId == TEXT_FISHING_SECRETS || + textId == TEXT_FISHING_GOOD_FISHERMAN || + textId == TEXT_FISHING_DIFFERENT_POND || + textId == TEXT_FISHING_SCRATCHING || + textId == TEXT_FISHING_TRY_ANOTHER_LURE_WITH_SINKING_LURE + )) { + messageEntry = OTRGlobals::Instance->gRandomizer->GetLoachMessage(); } else if (Randomizer_GetSettingValue(RSK_FROGS_HINT) && textId == TEXT_FROGS_UNDERWATER) { messageEntry = OTRGlobals::Instance->gRandomizer->GetFrogsMessage(textId); } else if (Randomizer_GetSettingValue(RSK_SARIA_HINT)) { diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 81fa63c55..0158e5797 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -875,6 +875,10 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("The minimum weight for the unique fishing reward as a child"); UIWidgets::PaddedEnhancementSliderInt("Adult Minimum Weight: %d", "##aMinimumWeight", "gAdultMinimumWeightFish", 6, 13, "", 13, true, true, false, disabled, disabledTooltip); UIWidgets::Tooltip("The minimum weight for the unique fishing reward as an adult"); + UIWidgets::PaddedEnhancementCheckbox("Always Hyrule Loaches", "gAlwaysHyruleLoaches", true, false, disabled, disabledTooltip); + UIWidgets::Tooltip("There will always be Hyrule Loaches in the fishing pond instead of only every 4 attempts"); + UIWidgets::PaddedEnhancementCheckbox("All fish are Hyrule Loaches", "gAllHyruleLoaches", true, false, disabled, disabledTooltip); + UIWidgets::Tooltip("Every fish in the fishing pond will always be a Hyrule Loach"); ImGui::EndMenu(); } diff --git a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c index 3f8de83ba..83a6142b8 100644 --- a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c +++ b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c @@ -968,7 +968,7 @@ void Fishing_Init(Actor* thisx, PlayState* play2) { ENKANBAN_FISHING); Actor_Spawn(&play->actorCtx, play, ACTOR_FISHING, 0.0f, 0.0f, 0.0f, 0, 0, 0, 200, true); - if ((KREG(1) == 1) || ((D_80B7E07D & 3) == 3)) { + if ((KREG(1) == 1) || ((D_80B7E07D & 3) == 3 || (CVarGetInteger("gCustomizeFishing", 0) && CVarGetInteger("gAlwaysHyruleLoaches", 0)))) { if (sLinkAge != 1) { fishCount = 16; } else { @@ -983,7 +983,8 @@ void Fishing_Init(Actor* thisx, PlayState* play2) { sFishInits[i].pos.z, 0, Rand_ZeroFloat(0x10000), 0, 100 + i, true); } } else { - if ((thisx->params < 115) || (thisx->params == 200)) { + u8 allHyruleLoaches = CVarGetInteger("gCustomizeFishing", 0) && CVarGetInteger("gAllHyruleLoaches", 0); + if ((thisx->params < 115 && !allHyruleLoaches) || (thisx->params == 200)) { SkelAnime_InitFlex(play, &this->skelAnime, &gFishingFishSkel, &gFishingFishAnim, NULL, NULL, 0); Animation_MorphToLoop(&this->skelAnime, &gFishingFishAnim, 0.0f); } else { @@ -1003,7 +1004,7 @@ void Fishing_Init(Actor* thisx, PlayState* play2) { this->unk_158 = 10; this->unk_15A = 10; - this->unk_150 = sFishInits[thisx->params - 100].unk_00; + this->unk_150 = allHyruleLoaches ? 1 : sFishInits[thisx->params - 100].unk_00; this->unk_1A8 = sFishInits[thisx->params - 100].unk_0C; this->unk_1AC = sFishInits[thisx->params - 100].unk_08; @@ -5079,7 +5080,13 @@ void Fishing_HandleOwnerDialog(Fishing* this, PlayState* play) { } } } else { - getItemId = GI_RUPEE_PURPLE; + if (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_CAUGHT_LOACH)) { + Flags_SetRandomizerInf(RAND_INF_CAUGHT_LOACH); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_HYRULE_LOACH, GI_RUPEE_PURPLE); + getItemId = getItemEntry.getItemId; + } else { + getItemId = GI_RUPEE_PURPLE; + } D_80B7A670 = 0.0f; }