diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index 6d25d9f8a..93681ebe9 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -138,7 +138,15 @@ typedef enum { TEXT_BEAN_SALESMAN_SOLD_OUT = 0x406B, TEXT_BEAN_SALESMAN_WANT_TO_PLANT = 0x406C, TEXT_FISHING_POND_START = 0x407B, + TEXT_FISHING_TALK_ABOUT_SOMETHING = 0x4088, + TEXT_FISHING_TRY_ANOTHER_LURE = 0x408D, + TEXT_FISHING_SECRETS = 0x408E, + TEXT_FISHING_GOOD_FISHERMAN = 0x408F, TEXT_FISHING_POND_START_MET = 0x4093, + 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_ANJU_PLEASE_BRING_MY_CUCCOS_BACK = 0x5036, diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 4199b7172..c3e01b657 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -510,6 +510,8 @@ const std::vector flagTables = { { 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" }, + { RAND_INF_CAN_SWIM, "RAND_INF_CAN_SWIM" }, { RAND_INF_HAS_WALLET, "RAND_INF_HAS_WALLET" }, diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index 3d0ae5940..ca60835e6 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -2752,6 +2752,9 @@ void StaticData::HintTable_Init() { /*french*/ "As-tu récemment ressenti une vague de #puissance magique#? Un mystérieux hibou m'a dit qu'elle provenait du #[[1]]#. Tu devrais aller y jeter un coup d'oeil, @!\x0B", {QM_GREEN, QM_RED}, {}, TEXTBOX_TYPE_BLUE)); + hintTextTable[RHT_LOACH_HINT] = HintText(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[[1]]%w to anyone who catches it. Seriously!", + {QM_RED})); + hintTextTable[RHT_FISHING_POLE_HINT] = HintText(CustomMessage("^If I remember correctly, I lost it somewhere in #[[1]]#...&Let me know if you find it!", {QM_RED})); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 514e81ce4..fd78f1843 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -836,6 +836,12 @@ void GenerateItemPool() { } else { PlaceVanillaOverworldFish(); } + + if (fsMode.Is(RO_FISHSANITY_HYRULE_LOACH)) { + AddItemToMainPool(RG_PURPLE_RUPEE); + } else { + ctx->PlaceItemInLocation(RC_LH_HYRULE_LOACH, RG_PURPLE_RUPEE, false, true); + } } else { PlaceVanillaOverworldFish(); } 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 d5d966308..860b90e8b 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 @@ -167,42 +167,43 @@ void AreaTable_Init_HyruleField() { // TODO: should some of these helpers be done via events instead? areaTable[RR_LH_FISHING_HOLE] = Area("LH Fishing Hole", "LH Fishing Hole", RA_NONE, DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_LH_CHILD_FISHING, logic->CanFish && logic->IsChild), - LOCATION(RC_LH_CHILD_FISH_1, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_2, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_3, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_4, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_5, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_6, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_7, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_8, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_9, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_10, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_11, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_12, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_13, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_14, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_15, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_LOACH_1, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_LOACH_2, logic->CanGetChildFish), - LOCATION(RC_LH_ADULT_FISHING, logic->CanFish && logic->IsAdult), - LOCATION(RC_LH_ADULT_FISH_1, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_2, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_3, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_4, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_5, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_6, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_7, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_8, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_9, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_10, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_11, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_12, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_13, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_14, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_15, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_LOACH, logic->CanGetAdultFish), - LOCATION(RC_FISHING_POLE_HINT,true), + LOCATION(RC_LH_CHILD_FISHING, logic->CanFish && logic->IsChild), + LOCATION(RC_LH_CHILD_FISH_1, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_2, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_3, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_4, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_5, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_6, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_7, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_8, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_9, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_10, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_11, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_12, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_13, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_14, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_FISH_15, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_LOACH_1, logic->CanGetChildFish), + LOCATION(RC_LH_CHILD_LOACH_2, logic->CanGetChildFish), + LOCATION(RC_LH_ADULT_FISHING, logic->CanFish && logic->IsAdult), + LOCATION(RC_LH_ADULT_FISH_1, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_2, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_3, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_4, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_5, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_6, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_7, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_8, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_9, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_10, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_11, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_12, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_13, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_14, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_FISH_15, logic->CanGetAdultFish), + LOCATION(RC_LH_ADULT_LOACH, logic->CanGetAdultFish), + LOCATION(RC_LH_HYRULE_LOACH, logic->CanFish), + LOCATION(RC_FISHING_POLE_HINT, 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 987565352..ad09e683d 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -157,6 +157,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, @@ -643,6 +644,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", RHT_LH_CHILD_FISHING, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::RandomizerInf(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", RHT_LH_ADULT_FISHING, RG_PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::RandomizerInf(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", RHT_LH_HYRULE_LOACH, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CAUGHT_LOACH), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); 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", RHT_LH_LAB_DIVE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(16), 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", RHT_LH_TRADE_FROG, RG_EYEDROPS, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG), 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", 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 6b5ebc893..36c270642 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -279,6 +279,7 @@ void Settings::CreateOptionDescriptions() { "Affordable prices per tier: starter = 10, adult = 105, giant = 205, tycoon = 505\n\n" "Use this to enable wallet tier locking, but make shop items not as expensive as they could be."; mOptionDescriptions[RSK_FISHSANITY] = "Off - Fish will not be shuffled. No changes will be made to fishing behavior.\n\n" + "Shuffle only Hyrule Loach - Allows you to earn an item by catching the hyrule loach at the fishing pond and giving it to the owner.\n\n" "Shuffle Fishing Pond - The fishing pond's fish will be shuffled. Catching a fish in the fishing pond will grant a reward.\n\n" "Shuffle Overworld Fish - Fish in generic grottos and Zora's Domain will be shuffled. Catching a fish in a bottle will give a reward.\n\n" "Shuffle Both - Both overworld fish and fish in the fishing pond will be shuffled."; @@ -526,6 +527,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_FISHING_POLE_HINT] = "Talking to the fishing pond owner without the fishing pole will tell you its location."; diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index b2c047e63..01b3f49c9 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -86,7 +86,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", diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index b423b5235..1b772367d 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -945,6 +945,7 @@ typedef enum { RC_LH_CHILD_LOACH_1, RC_LH_CHILD_LOACH_2, RC_LH_ADULT_FISHING, + RC_LH_HYRULE_LOACH, RC_LH_ADULT_FISH_1, RC_LH_ADULT_FISH_2, RC_LH_ADULT_FISH_3, @@ -2076,6 +2077,7 @@ typedef enum { RH_ALTAR_CHILD, RH_ALTAR_ADULT, RH_SARIA_HINT, + RH_LOACH_HINT, RH_FISHING_POLE, RH_MINUET_WARP_LOC, RH_BOLERO_WARP_LOC, @@ -3448,6 +3450,7 @@ typedef enum { RHT_GREG_HINT, RHT_SARIA_TALK_HINT, RHT_SARIA_SONG_HINT, + RHT_LOACH_HINT, RHT_FISHING_POLE_HINT, // Static Entrance Hints RHT_WARP_SONG, @@ -3625,6 +3628,7 @@ typedef enum { RSK_SHEIK_LA_HINT, RSK_DAMPES_DIARY_HINT, RSK_GREG_HINT, + RSK_LOACH_HINT, RSK_SARIA_HINT, RSK_FROGS_HINT, RSK_OOT_HINT, @@ -3865,9 +3869,10 @@ typedef enum { RO_BOSS_SOULS_ON_PLUS_GANON, } RandoOptionBossSouls; -//Fishsanity settings (off, pond only, grottos only, both) +//Fishsanity settings (off, loach only, pond only, grottos only, both) typedef enum { RO_FISHSANITY_OFF, + RO_FISHSANITY_HYRULE_LOACH, RO_FISHSANITY_POND, RO_FISHSANITY_OVERWORLD, RO_FISHSANITY_BOTH diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index ddedd5b53..3b5eed450 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -161,6 +161,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), RO_GENERIC_NO)) && (location.GetRandomizerCheck() != RC_KF_KOKIRI_SWORD_CHEST || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), RO_GENERIC_NO)) && + (location.GetRandomizerCheck() != RC_LH_HYRULE_LOACH || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_GENERIC_NO) == RO_FISHSANITY_HYRULE_LOACH) && (location.GetRandomizerCheck() != RC_ZR_MAGIC_BEAN_SALESMAN || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeans"), 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 76c293950..de46a4496 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -65,6 +65,7 @@ bool showCows; bool showAdultTrade; bool showKokiriSword; bool showMasterSword; +bool showHyruleLoach; bool showWeirdEgg; bool showGerudoCard; bool showFrogSongRupees; @@ -1167,6 +1168,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_FISHSANITY) == RO_FISHSANITY_HYRULE_LOACH + : false; showWeirdEgg = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_WEIRD_EGG) == RO_GENERIC_YES : true; @@ -1287,6 +1291,7 @@ bool IsCheckShuffled(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 8a9e8be1f..8d3e96239 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -202,6 +202,8 @@ typedef enum { RAND_INF_HAS_OCARINA_C_LEFT, RAND_INF_HAS_OCARINA_C_RIGHT, + RAND_INF_CAUGHT_LOACH, + RAND_INF_CAN_SWIM, RAND_INF_HAS_WALLET, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index f3077cf3e..f3f860800 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -122,7 +122,7 @@ void Settings::CreateOptions() { mOptions[RSK_SHUFFLE_BOSS_SOULS] = Option::U8("Shuffle Boss Souls", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WidgetType::Combobox); mOptions[RSK_SHUFFLE_DEKU_STICK_BAG] = Option::Bool("Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); mOptions[RSK_SHUFFLE_DEKU_NUT_BAG] = Option::Bool("Shuffle Deku Nut Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); - mOptions[RSK_FISHSANITY] = Option::U8("Fishsanity", {"Off", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WidgetType::Combobox, RO_FISHSANITY_OFF); + mOptions[RSK_FISHSANITY] = Option::U8("Fishsanity", {"Off", "Shuffle only Hyrule Loach", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WidgetType::Combobox, RO_FISHSANITY_OFF); mOptions[RSK_FISHSANITY_POND_COUNT] = Option::U8("Pond Fish Count", {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), mOptionDescriptions[RSK_FISHSANITY_POND_COUNT], WidgetType::Slider, 0, true, IMFLAG_NONE); mOptions[RSK_FISHSANITY_AGE_SPLIT] = Option::Bool("Pond Age Split", CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT]); mOptions[RSK_SHUFFLE_MAPANDCOMPASS] = Option::U8("Maps/Compasses", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), mOptionDescriptions[RSK_SHUFFLE_MAPANDCOMPASS], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); @@ -163,6 +163,7 @@ void Settings::CreateOptions() { mOptions[RSK_SHEIK_LA_HINT] = Option::Bool("Sheik Light Arrow Hint", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SheikLAHint"), mOptionDescriptions[RSK_SHEIK_LA_HINT], WidgetType::Checkbox, RO_GENERIC_ON, false, IMFLAG_NONE); mOptions[RSK_DAMPES_DIARY_HINT] = Option::Bool("Dampe's Diary Hint", CVAR_RANDOMIZER_SETTING("DampeHint"), mOptionDescriptions[RSK_DAMPES_DIARY_HINT], IMFLAG_NONE); mOptions[RSK_GREG_HINT] = Option::Bool("Greg the Green Rupee Hint", CVAR_RANDOMIZER_SETTING("GregHint"), mOptionDescriptions[RSK_GREG_HINT], IMFLAG_NONE); + mOptions[RSK_LOACH_HINT] = Option::Bool("Hyrule Loach Hint", CVAR_RANDOMIZER_SETTING("LoachHint"), mOptionDescriptions[RSK_LOACH_HINT], IMFLAG_NONE); mOptions[RSK_SARIA_HINT] = Option::Bool("Saria's Hint", CVAR_RANDOMIZER_SETTING("SariaHint"), mOptionDescriptions[RSK_SARIA_HINT], IMFLAG_NONE); mOptions[RSK_FISHING_POLE_HINT] = Option::Bool("Fishing Pole Hint", CVAR_RANDOMIZER_SETTING("FishingPoleHint"), mOptionDescriptions[RSK_FISHING_POLE_HINT], IMFLAG_NONE); mOptions[RSK_FROGS_HINT] = Option::Bool("Frog Ocarina Game Hint", CVAR_RANDOMIZER_SETTING("FrogsHint"), mOptionDescriptions[RSK_FROGS_HINT], IMFLAG_NONE); @@ -738,6 +739,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHEIK_LA_HINT], &mOptions[RSK_DAMPES_DIARY_HINT], &mOptions[RSK_GREG_HINT], + &mOptions[RSK_LOACH_HINT], &mOptions[RSK_SARIA_HINT], &mOptions[RSK_FROGS_HINT], &mOptions[RSK_OOT_HINT], @@ -974,6 +976,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHEIK_LA_HINT], &mOptions[RSK_DAMPES_DIARY_HINT], &mOptions[RSK_GREG_HINT], + &mOptions[RSK_LOACH_HINT], &mOptions[RSK_SARIA_HINT], &mOptions[RSK_FROGS_HINT], &mOptions[RSK_OOT_HINT], @@ -1198,6 +1201,7 @@ void Settings::CreateOptions() { { "Miscellaneous Settings:Sheik Light Arrow Hint", RSK_SHEIK_LA_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:Ocarina of Time Hint", RSK_OOT_HINT }, @@ -1763,16 +1767,22 @@ void Settings::UpdateOptionProperties() { if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCows"), RO_GENERIC_OFF)) { mOptions[RSK_MALON_HINT].Enable(); - } else { + } else { mOptions[RSK_MALON_HINT].Disable("Malon's hint points to a cow, so requires cows to be shuffled."); } if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), RO_GENERIC_OFF)) { mOptions[RSK_KAK_100_SKULLS_HINT].Enable(); - } else { + } else { mOptions[RSK_KAK_100_SKULLS_HINT].Disable("There is no point to hinting 100 skulls if it is not shuffled"); } + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_FISHSANITY_OFF) == RO_FISHSANITY_HYRULE_LOACH) { + mOptions[RSK_LOACH_HINT].Enable(); + } else { + mOptions[RSK_LOACH_HINT].Disable("Loach hint is only avaliable with \"Fishsanity\" set to \"Shuffle only Hyrule Loach\"\nas that's the only setting where you present the loach to the fishing pond owner"); + } + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 7) == 0) { mOptions[RSK_CHICKENS_HINT].Disable("Anju will just give you the item instead with 0 chickens"); } else { @@ -2125,6 +2135,10 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio mOptions[RSK_KAK_100_SKULLS_HINT].SetSelectedIndex(RO_GENERIC_OFF); } + if (mOptions[RSK_FISHSANITY].IsNot(RO_FISHSANITY_HYRULE_LOACH)) { + mOptions[RSK_LOACH_HINT].SetSelectedIndex(RO_FISHSANITY_OFF); + } + if (mOptions[RSK_CUCCO_COUNT].Is(0)) { mOptions[RSK_CHICKENS_HINT].SetSelectedIndex(RO_GENERIC_OFF); } @@ -2375,6 +2389,7 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) { case RSK_SHEIK_LA_HINT: case RSK_DAMPES_DIARY_HINT: case RSK_GREG_HINT: + case RSK_LOACH_HINT: case RSK_SARIA_HINT: case RSK_FROGS_HINT: case RSK_OOT_HINT: diff --git a/soh/soh/Enhancements/randomizer/static_data.cpp b/soh/soh/Enhancements/randomizer/static_data.cpp index f413a86e0..5a091552b 100644 --- a/soh/soh/Enhancements/randomizer/static_data.cpp +++ b/soh/soh/Enhancements/randomizer/static_data.cpp @@ -71,6 +71,7 @@ std::unordered_map StaticData::hintNames = { {RH_ALTAR_CHILD, CustomMessage("ToT Altar as Child")}, {RH_ALTAR_ADULT, CustomMessage("ToT Altar as Adult")}, {RH_SARIA_HINT, CustomMessage("Saria's Magic Hint")}, + {RH_LOACH_HINT, CustomMessage("Loach Hint")}, {RH_FISHING_POLE, CustomMessage("Fishing Pole Hint")}, {RH_MINUET_WARP_LOC, CustomMessage("Minuet of Forest Destination")}, {RH_BOLERO_WARP_LOC, CustomMessage("Bolero of Fire Destination")}, @@ -199,6 +200,7 @@ std::unordered_map StaticData::staticHintInfoMap {RH_DAMPES_DIARY, StaticHintInfo(HINT_TYPE_AREA, {RHT_DAMPE_DIARY}, RSK_DAMPES_DIARY_HINT, true, {}, {RG_PROGRESSIVE_HOOKSHOT}, {RC_DAMPE_HINT})}, {RH_GREG_RUPEE, StaticHintInfo(HINT_TYPE_AREA, {RHT_GREG_HINT}, RSK_GREG_HINT, true, {}, {RG_GREG_RUPEE}, {RC_GREG_HINT})}, {RH_SARIA_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SARIA_TALK_HINT, RHT_SARIA_SONG_HINT}, RSK_SARIA_HINT, true, {}, {RG_PROGRESSIVE_MAGIC_METER}, {RC_SARIA_SONG_HINT, RC_SONG_FROM_SARIA}, true)}, + {RH_LOACH_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_LOACH_HINT}, RSK_LOACH_HINT, true, {RC_LH_HYRULE_LOACH})}, {RH_FISHING_POLE, StaticHintInfo(HINT_TYPE_AREA, {RHT_FISHING_POLE_HINT}, RSK_FISHING_POLE_HINT, true, {}, {RG_FISHING_POLE}, {RC_FISHING_POLE_HINT}, true)}, {RH_MEDIGORON, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_MEDIGORON_HINT}, RSK_SHUFFLE_MERCHANTS, (uint8_t)RO_SHUFFLE_MERCHANTS_ON_HINT, {RC_GC_MEDIGORON})}, {RH_GRANNY, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_GRANNY_HINT}, RSK_SHUFFLE_MERCHANTS, (uint8_t)RO_SHUFFLE_MERCHANTS_ON_HINT, {RC_KAK_GRANNYS_SHOP})}, diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 18da01c2c..43f3e2f00 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2707,7 +2707,21 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { else if (textId == TEXT_FROGS_UNDERWATER && ctx->GetOption(RSK_FROGS_HINT)) { messageEntry = ctx->GetHint(RH_FROGS_HINT)->GetHintMessage(MF_AUTO_FORMAT), TEXTBOX_TYPE_BLUE; } - else if ((textId == TEXT_FISHING_POND_START || textId == TEXT_FISHING_POND_START_MET) && + 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 = ctx->GetHint(RH_LOACH_HINT)->GetHintMessage(MF_AUTO_FORMAT); + } + else if ((textId == TEXT_FISHING_POND_START || textId == TEXT_FISHING_POND_START_MET) && ctx->GetOption(RSK_SHUFFLE_FISHING_POLE) && !Flags_GetRandomizerInf(RAND_INF_FISHING_POLE_FOUND)) { messageEntry = OTRGlobals::Instance->gRandomizer->GetFishingPondOwnerMessage(textId); } diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 587e2d0c1..8adeaa429 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -924,7 +924,6 @@ void DrawEnhancementsMenu() { } UIWidgets::Spacer(0); - if (ImGui::BeginMenu("Fishing")) { UIWidgets::EnhancementCheckbox("Customize Behavior", CVAR_ENHANCEMENT("CustomizeFishing")); UIWidgets::Tooltip("Turn on/off changes to the fishing behavior"); @@ -944,6 +943,8 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("The minimum weight for the unique fishing reward as a child"); UIWidgets::PaddedEnhancementSliderInt("Adult Minimum Weight: %d", "##aMinimumWeight", CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 6, 13, "", 13, true, true, false, disabled, disabledTooltip); UIWidgets::Tooltip("The minimum weight for the unique fishing reward as an adult"); + UIWidgets::PaddedEnhancementCheckbox("All fish are Hyrule Loaches", CVAR_ENHANCEMENT("AllHyruleLoaches"), true, false, disabled, disabledTooltip); + UIWidgets::Tooltip("Every fish in the fishing pond will always be a Hyrule Loach"); ImGui::EndMenu(); } UIWidgets::Spacer(0); diff --git a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c index a0ead103c..b3be105dd 100644 --- a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c +++ b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c @@ -17,6 +17,7 @@ #define WATER_SURFACE_Y(play) play->colCtx.colHeader->waterBoxes->ySurface #define IS_FISHSANITY (IS_RANDO && Randomizer_GetPondFishShuffled()) #define FISHID(params) (Randomizer_IdentifyFish(play->sceneNum, params)) +bool getShouldSpawnLoaches(); void Fishing_Init(Actor* thisx, PlayState* play); void Fishing_Destroy(Actor* thisx, PlayState* play); @@ -26,8 +27,6 @@ void Fishing_DrawFish(Actor* thisx, PlayState* play); void Fishing_DrawOwner(Actor* thisx, PlayState* play); void Fishing_Reset(void); -bool getShouldSpawnLoaches(); - typedef struct { /* 0x00 */ u8 isLoach; /* 0x02 */ Vec3s pos; @@ -436,6 +435,10 @@ static Vec3f sStreamSoundProjectedPos; static s16 sFishOnHandParams; static Color_RGBA16 fsPulseColor = { 30, 240, 200 }; +u8 AllHyruleLoaches() { + return CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0) && CVarGetInteger(CVAR_ENHANCEMENT("AllHyruleLoaches"), 0); +} + void Fishing_SetColliderElement(s32 index, ColliderJntSph* collider, Vec3f* pos, f32 scale) { collider->elements[index].dim.worldSphere.center.x = pos->x; collider->elements[index].dim.worldSphere.center.y = pos->y; @@ -1001,7 +1004,7 @@ void Fishing_Init(Actor* thisx, PlayState* play2) { sFishInits[i].pos.z, 0, Rand_ZeroFloat(0x10000), 0, 100 + i, true); } } else { - if ((thisx->params < (EN_FISH_PARAM + 15)) || (thisx->params == EN_FISH_AQUARIUM)) { + if ((thisx->params < (EN_FISH_PARAM + 15) && !AllHyruleLoaches()) || (thisx->params == EN_FISH_AQUARIUM)) { SkelAnime_InitFlex(play, &this->skelAnime, &gFishingFishSkel, &gFishingFishAnim, NULL, NULL, 0); Animation_MorphToLoop(&this->skelAnime, &gFishingFishAnim, 0.0f); } else { @@ -2847,7 +2850,7 @@ void Fishing_FishLeapSfx(Fishing* this, u8 outOfWater) { s16 sfxId; u8 length; - if (this->isLoach == 0) { + if (this->isLoach == 0 && !AllHyruleLoaches()) { length = this->fishLength; } else { length = 2.0f * this->fishLength; @@ -2992,7 +2995,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { this->actor.uncullZoneForward = 700.0f; this->actor.uncullZoneScale = 50.0f; - if (this->isLoach == 0) { + if (this->isLoach == 0 && !AllHyruleLoaches()) { playerSpeedMod = (player->actor.speedXZ * 0.15f) + 0.25f; } else { playerSpeedMod = (player->actor.speedXZ * 0.3f) + 0.25f; @@ -3054,7 +3057,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { Math_ApproachS(&this->fishLimbDRotZDelta, 0, 5, 0x1F4); - if (this->isLoach == 0) { + if (this->isLoach == 0 && !AllHyruleLoaches()) { Actor_SetScale(&this->actor, this->fishLength * 15.0f * 0.00001f); this->fishLimbRotPhase += this->fishLimbRotPhaseStep; @@ -3223,7 +3226,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { break; case 1: - if (this->isLoach == 1) { + if (this->isLoach == 1 || AllHyruleLoaches()) { this->fishState = -1; this->unk_1A4 = 20000; this->unk_1A2 = 20000; @@ -3376,7 +3379,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { if (sLureEquipped == FS_LURE_SINKING) { this->fishTargetPos.y = sLurePos.y; - } else if (this->isLoach == 0) { + } else if (this->isLoach == 0 && !AllHyruleLoaches()) { this->fishTargetPos.y = sLurePos.y - 15.0f; } else { this->fishTargetPos.y = sLurePos.y - 5.0f; @@ -3451,8 +3454,8 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { } if (getGuaranteeBite() == 1 || ((this->timerArray[0] == 1) || (Rand_ZeroOne() < chance)) && - ((Rand_ZeroOne() < (this->perception * multiplier)) || ((this->isLoach + 1) == KREG(69)))) { - if (this->isLoach == 0) { + ((Rand_ZeroOne() < (this->perception * multiplier)) || (((this->isLoach || AllHyruleLoaches()) + 1) == KREG(69)))) { + if (this->isLoach == 0 && !AllHyruleLoaches()) { this->fishState = 3; this->unk_190 = 1.2f; this->unk_194 = 5000.0f; @@ -3673,7 +3676,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_ENEMY | 0x800); sFishingMusicDelay = 0; - if (this->isLoach == 1) { + if (this->isLoach == 1 || AllHyruleLoaches()) { rumbleStrength = (this->fishLength * 3.0f) + 120.0f; } else { rumbleStrength = (2.0f * this->fishLength) + 120.0f; @@ -3776,7 +3779,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { Math_ApproachF(&this->actor.speedXZ, 5.0f, 1.0f, 0.5f); } - if (this->isLoach == 0) { + if (this->isLoach == 0 && !AllHyruleLoaches()) { sRodReelingSpeed = 1.0f - (this->fishLength * 0.00899f); } else { sRodReelingSpeed = 1.0f - (this->fishLength * 0.00899f * 1.4f); @@ -3792,7 +3795,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { this->unk_190 = 1.0f; this->unk_194 = 4500.0f; - if (this->isLoach == 0) { + if (this->isLoach == 0 && !AllHyruleLoaches()) { sRodReelingSpeed = 1.3f - (this->fishLength * 0.00899f); } else { sRodReelingSpeed = 1.3f - (this->fishLength * 0.00899f * 1.4f); @@ -3946,7 +3949,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_HEART_GET | 0x900); sFishingCaughtTextDelay = 40; - if (this->isLoach == 0) { + if (this->isLoach == 0 && !AllHyruleLoaches()) { sFishLengthToWeigh = this->fishLength; if (sFishLengthToWeigh >= 75) { @@ -3993,13 +3996,13 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { if (play->msgCtx.choiceIndex == 0) { if (sFishOnHandLength == 0.0f) { sFishOnHandLength = this->fishLength; - sFishOnHandIsLoach = this->isLoach; + sFishOnHandIsLoach = (this->isLoach || AllHyruleLoaches()); sLureCaughtWith = sLureEquipped; if (IS_FISHSANITY) { sFishOnHandParams = this->fishsanityParams; } Actor_Kill(&this->actor); - } else if (getShouldConfirmKeep() && (this->isLoach == 0) && (sFishOnHandIsLoach == 0) && + } else if (getShouldConfirmKeep() && (this->isLoach == 0 && !AllHyruleLoaches()) && (sFishOnHandIsLoach == 0) && ((s16)this->fishLength < (s16)sFishOnHandLength)) { this->keepState = 1; this->timerArray[0] = 0x3C; @@ -4061,7 +4064,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { this->unk_194 = 2000.0f; SkelAnime_Free(&this->skelAnime, play); - if (this->isLoach == 0) { + if (this->isLoach == 0 && !AllHyruleLoaches()) { SkelAnime_InitFlex(play, &this->skelAnime, &gFishingFishSkel, &gFishingFishAnim, 0, 0, 0); Animation_MorphToLoop(&this->skelAnime, &gFishingFishAnim, 0.0f); } else { @@ -4397,7 +4400,7 @@ void Fishing_DrawFish(Actor* thisx, PlayState* play) { Matrix_RotateZ(((this->unk_164 + this->actor.shape.rot.z) / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); - if (this->isLoach == 0) { + if (this->isLoach == 0 && !AllHyruleLoaches()) { Matrix_RotateY((this->fishLimb23RotYDelta * (M_PI / 32768)) - (M_PI / 2), MTXMODE_APPLY); Matrix_Translate(0.0f, 0.0f, this->fishLimb23RotYDelta * 10.0f * 0.01f, MTXMODE_APPLY); @@ -4998,7 +5001,7 @@ void Fishing_HandleOwnerDialog(Fishing* this, PlayState* play) { if (sFishOnHandLength == 0.0f) { this->actor.textId = 0x408C; this->stateAndTimer = 20; - } else if (sFishOnHandIsLoach == 0 && !IS_RANDO) { + } else if (sFishOnHandIsLoach == 0) { sFishLengthToWeigh = sFishOnHandLength; if ((s16)sFishingRecordLength < (s16)sFishOnHandLength) { if (sLureCaughtWith == FS_LURE_SINKING) { @@ -5011,14 +5014,10 @@ void Fishing_HandleOwnerDialog(Fishing* this, PlayState* play) { this->actor.textId = 0x408B; this->stateAndTimer = 20; } - } else if (!IS_RANDO) { + } else { this->actor.textId = 0x409B; this->stateAndTimer = 11; } - else { - this->actor.textId = 0x4086; - this->stateAndTimer = 11; - } Message_ContinueTextbox(play, this->actor.textId); break; case 1: @@ -5154,7 +5153,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; + } sFishOnHandLength = 0.0f; // doesn't record loach }