diff --git a/soh/assets/custom/lang/en_US.json b/soh/assets/custom/lang/en_US.json index a5667e882c..eeebbecbc8 100644 --- a/soh/assets/custom/lang/en_US.json +++ b/soh/assets/custom/lang/en_US.json @@ -892,6 +892,10 @@ "The Beggar will give separate rewards to child and adult." ] }, + "shuffle_fishermans_hat": { + "name": "Shuffle Fisherman's Hat", + "description": "The Fisherman gives a reward for returning his hat." + }, "shuffle_adult_trade": { "name": "Shuffle Adult Trade", "description": [ diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index 6867f5922c..ccae466c58 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -194,6 +194,7 @@ typedef enum { TEXT_FISHING_CLOUDY = 0x4096, TEXT_FISHING_RELEASE_THIS_ONE = 0x409C, TEXT_FISHING_TRY_ANOTHER_LURE_WITH_SINKING_LURE = 0x40AF, + TEXT_FISHING_HAT_RETURNED = 0x40B2, TEXT_DAMPES_DIARY = 0x5003, TEXT_GRANNYS_SHOP = 0x500C, TEXT_ANJU_PLEASE_BRING_MY_CUCCOS_BACK = 0x5036, 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 532793d2df..158ad0ae88 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 @@ -2538,6 +2538,10 @@ void StaticData::HintTable_Init_Exclude_Overworld() { /*german*/ "Man erzählt sich, daß das #Handeln mit einem Bettler in Kakariko# #[[1]]# gäbe.", /*french*/ "Selon moi, #échanger avec un mendiant dans le Village de Cocorico# donne #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_FISHERMANS_HAT] = HintText(CustomMessage("They say that #giving a Fisherman back his hat# is rewarded by #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Zurückgeben seines Hutes an einen Fischer# mit #[[1]]# belohnt werde.", + /*french*/ "Selon moi, #rendre son chapeau à un pêcheur# est récompensé par #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_RED_ICE_ZORAS_DOMAIN] = HintText(CustomMessage("They say that #melting red ice in Zora's Domain# gives #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Schmelzen von rotem Eis in Zoras Reich# #[[1]]# gäbe.", /*french*/ "Selon moi, #faire fondre la glace rouge dans le Domaine Zora# donne #[[1]]#.", {QM_RED, QM_GREEN})); diff --git a/soh/soh/Enhancements/randomizer/SeedContext.cpp b/soh/soh/Enhancements/randomizer/SeedContext.cpp index 44f9adf2a7..5dd354bbd7 100644 --- a/soh/soh/Enhancements/randomizer/SeedContext.cpp +++ b/soh/soh/Enhancements/randomizer/SeedContext.cpp @@ -184,6 +184,7 @@ void Context::GenerateLocationPool() { location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO)) || (location.GetRCType() == RCTYPE_BEGGAR && mOptions[RSK_SHUFFLE_BEGGAR].Is(RO_GENERIC_OFF)) || + (location.GetRCType() == RCTYPE_FISH_HAT && mOptions[RSK_SHUFFLE_FISHERMANS_HAT].Is(RO_GENERIC_OFF)) || (location.GetRCType() == RCTYPE_ADULT_TRADE && mOptions[RSK_SHUFFLE_ADULT_TRADE].Is(RO_GENERIC_OFF)) || (location.GetRCType() == RCTYPE_COW && mOptions[RSK_SHUFFLE_COWS].Is(RO_GENERIC_OFF)) || (location.GetRandomizerCheck() == RC_LH_HYRULE_LOACH && diff --git a/soh/soh/Enhancements/randomizer/ShuffleFishermanHat.cpp b/soh/soh/Enhancements/randomizer/ShuffleFishermanHat.cpp new file mode 100644 index 0000000000..de67d0ab90 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleFishermanHat.cpp @@ -0,0 +1,36 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/Enhancements/custom-message/CustomMessageTypes.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "overlays/actors/ovl_En_Hy/z_en_hy.h" +} + +void Fishing_GiveHatItem(uint16_t* textId, bool* loadFromMessageTable) { + if (Flags_GetRandomizerInf(RAND_INF_FISHERMANS_HAT)) { + return; + } + Flags_SetRandomizerInf(RAND_INF_FISHERMANS_HAT); + *loadFromMessageTable = true; +} + +void RegisterShuffleFishermansHat() { + bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_FISHERMANS_HAT).Get(); + + COND_ID_HOOK(OnOpenText, TEXT_FISHING_HAT_RETURNED, shouldRegister, Fishing_GiveHatItem); +} + +void Rando::StaticData::RegisterFishermansHatLocation() { + static bool registered = false; + if (registered) + return; + registered = true; + // clang-format off + // Randomizer Check Randomizer Check Quest RCType Area Actor ID Scene ID Params Short Name Hint Text Key Vanilla Item Spoiler Collection Check + locationTable[RC_FISHERMANS_HAT] = Location::Base(RC_FISHERMANS_HAT, RCQUEST_BOTH, RCTYPE_FISH_HAT, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, TEXT_FISHING_HAT_RETURNED, "Fisherman's Hat", RHT_FISHERMANS_HAT, RG_NONE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FISHERMANS_HAT)); + // clang-format on +} + +static RegisterShipInitFunc registerShuffleFishermansHat(RegisterShuffleFishermansHat, { "IS_RANDO" }); +static RegisterShipInitFunc registerFishermansHatLocation(Rando::StaticData::RegisterFishermansHatLocation); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index db854e7340..df2bce01d0 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -194,6 +194,7 @@ void RegionTable_Init_LakeHylia() { LOCATION(RC_LH_HYRULE_LOACH, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN)), LOCATION(RC_FISHING_POLE_HINT, logic->HasItem(RG_SPEAK_HYLIAN)), LOCATION(RC_LH_FISHING_POND_RECTANGLE_SIGN, logic->CanRead()), + LOCATION(RC_FISHERMANS_HAT, logic->CanUse(RG_FISHING_POLE) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->IsAdult), }, { //Exits ENTRANCE(RR_LH_FISHING_ISLAND, true), diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h index e06269f6a1..47814cb6a1 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h @@ -3338,6 +3338,8 @@ RANDO_ENUM_ITEM(RC_MK_BEGGAR_BLUE_FIRE) RANDO_ENUM_ITEM(RC_KAK_BEGGAR_BUGS) RANDO_ENUM_ITEM(RC_KAK_BEGGAR_FISH) RANDO_ENUM_ITEM(RC_KAK_BEGGAR_BLUE_FIRE) +// Fisherman's Hat +RANDO_ENUM_ITEM(RC_FISHERMANS_HAT) // Vanilla Icicles RANDO_ENUM_ITEM(RC_ICE_CAVERN_ENTRANCE_LEFT_STALAGMITE) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h index 4d923b06f8..4816204845 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerHintTextKey.h @@ -1692,6 +1692,8 @@ RANDO_ENUM_ITEM(RHT_SIGN_SPIRIT_TEMPLE) // BEGGAR RANDO_ENUM_ITEM(RHT_BEGGAR_MARKET) RANDO_ENUM_ITEM(RHT_BEGGAR_KAKARIKO_VILLAGE) +// FISHERMANS HAT +RANDO_ENUM_ITEM(RHT_FISHERMANS_HAT) // ICICLES RANDO_ENUM_ITEM(RHT_ICE_CAVERN_ICICLE) RANDO_ENUM_ITEM(RHT_GERUDO_TRAINING_GROUND_ICICLE) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h index d15be0ffad..309689dc92 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h @@ -2896,6 +2896,8 @@ RANDO_ENUM_ITEM(RAND_INF_MK_BEGGAR_BLUE_FIRE) RANDO_ENUM_ITEM(RAND_INF_KAK_BEGGAR_BUGS) RANDO_ENUM_ITEM(RAND_INF_KAK_BEGGAR_FISH) RANDO_ENUM_ITEM(RAND_INF_KAK_BEGGAR_BLUE_FIRE) +// Fisherman's Hat +RANDO_ENUM_ITEM(RAND_INF_FISHERMANS_HAT) // Vanilla Icicles RANDO_ENUM_ITEM(RAND_INF_ICE_CAVERN_ENTRANCE_LEFT_STALAGMITE) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h index 9e5309d8ff..bdf87793e2 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerMiscEnums.h @@ -137,6 +137,7 @@ RANDO_ENUM_ITEM(RCTYPE_BUTTERFLY_FAIRY) // Fairies from Butterflies RANDO_ENUM_ITEM(RCTYPE_GRASS) // Grass RANDO_ENUM_ITEM(RCTYPE_SIGN) // Signs RANDO_ENUM_ITEM(RCTYPE_BEGGAR) // Beggar +RANDO_ENUM_ITEM(RCTYPE_FISH_HAT) // Fisherman's Hat RANDO_ENUM_ITEM(RCTYPE_ICICLE) // Icicles RANDO_ENUM_ITEM(RCTYPE_RED_ICE) // Red Ice RANDO_ENUM_ITEM(RCTYPE_FIRE_GORON) // Fire Temple Gorons diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h index 1328ffb9d1..211cc0e122 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h @@ -203,6 +203,7 @@ RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT) RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT) RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_AFFORDABLE) RANDO_ENUM_ITEM(RSK_SHUFFLE_BEGGAR) +RANDO_ENUM_ITEM(RSK_SHUFFLE_FISHERMANS_HAT) RANDO_ENUM_ITEM(RSK_BLUE_FIRE_ARROWS) RANDO_ENUM_ITEM(RSK_SUNLIGHT_ARROWS) RANDO_ENUM_ITEM(RSK_BUNNY_HOOD) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index 0e1ba33220..ee0e666332 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -140,6 +140,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { RO_SHUFFLE_MERCHANTS_OFF) && (location.GetRCType() != RCTYPE_BEGGAR || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeggar"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_FISH_HAT || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFishermansHat"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_SONG_LOCATION || (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_SONG_LOCATIONS) != RO_SONG_SHUFFLE_SONG_LOCATIONS && diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index dbcfd9b409..a1fad81030 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -97,6 +97,7 @@ bool showDungeonSigns; bool showOverworldWonderItems; bool showDungeonWonderItems; bool showBeggar; +bool showFishHat; bool showIcicles; bool showRedIce; bool showFireGorons; @@ -1800,6 +1801,7 @@ void LoadSettings() { break; } showBeggar = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BEGGAR); + showFishHat = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FISHERMANS_HAT); showIcicles = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ICICLES); showRedIce = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_RED_ICE); showFireGorons = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FIRE_GORONS); @@ -1822,6 +1824,7 @@ void LoadSettings() { showOverworldSigns = false; showDungeonSigns = false; showBeggar = false; + showFishHat = false; showIcicles = false; showRedIce = false; showFireGorons = false; @@ -1914,6 +1917,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { ((loc->GetRCType() != RCTYPE_MERCHANT || (showMerchants && rc != RC_ZR_MAGIC_BEAN_SALESMAN)) || (rc == RC_ZR_MAGIC_BEAN_SALESMAN && showBeans)) && (loc->GetRCType() != RCTYPE_BEGGAR || showBeggar) && + (loc->GetRCType() != RCTYPE_FISH_HAT || showFishHat) && (loc->GetRCType() != RCTYPE_SONG_LOCATION || showSongs) && (loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) && (loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) && diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 860c1abc21..97aa82a507 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -1039,6 +1039,7 @@ void Settings::CreateOptions() { OPT_U8(RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT, {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE); OPT_BOOL(RSK_MERCHANT_PRICES_AFFORDABLE, CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable")); OPT_BOOL(RSK_SHUFFLE_BEGGAR, CVAR_RANDOMIZER_SETTING("ShuffleBeggar")); + OPT_BOOL(RSK_SHUFFLE_FISHERMANS_HAT, CVAR_RANDOMIZER_SETTING("ShuffleFishermansHat")); OPT_BOOL(RSK_SHUFFLE_FROG_SONG_RUPEES, CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees")); OPT_BOOL(RSK_SHUFFLE_ADULT_TRADE, CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade")); OPT_CALLBACK(RSK_SHUFFLE_ADULT_TRADE, { @@ -2106,6 +2107,7 @@ void Settings::CreateOptions() { &mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], &mOptions[RSK_MERCHANT_PRICES_AFFORDABLE], &mOptions[RSK_SHUFFLE_BEGGAR], + &mOptions[RSK_SHUFFLE_FISHERMANS_HAT], }, WidgetContainerType::SECTION); mOptionGroups[RSG_MENU_COLUMN_SHOP_SHUFFLES] = @@ -2308,6 +2310,7 @@ void Settings::CreateOptions() { &mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], &mOptions[RSK_MERCHANT_PRICES_AFFORDABLE], &mOptions[RSK_SHUFFLE_BEGGAR], + &mOptions[RSK_SHUFFLE_FISHERMANS_HAT], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_CHEST_MINIGAME], diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index 5694191712..68698fe91d 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -70,6 +70,7 @@ class StaticData { static void RegisterSignLocations(); static void RegisterWonderItemLocations(); static void RegisterBeggarLocations(); + static void RegisterFishermansHatLocation(); static void RegisterIcicleLocations(); static void RegisterRedIceLocations(); static void RegisterFireGoronLocations();