diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index 508836819cf..4de9debeea8 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -138,8 +138,6 @@ endforeach() if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set_source_files_properties(soh/OTRGlobals.cpp PROPERTIES COMPILE_FLAGS "/utf-8") set_source_files_properties(soh/Enhancements/tts/tts.cpp PROPERTIES COMPILE_FLAGS "/utf-8") - set_source_files_properties(soh/Enhancements/custom-message/CustomMessageManager.cpp PROPERTIES COMPILE_FLAGS "/utf-8") - set_source_files_properties(soh/Enhancements/custom-message/CustomMessageManager.h PROPERTIES COMPILE_FLAGS "/utf-8") endif() # handle Network removals diff --git a/soh/assets/extractor/filelists/ntsc_12_oot.txt b/soh/assets/extractor/filelists/ntsc_12_oot.txt index 0cf6ab9063e..a5f50dcfd28 100644 --- a/soh/assets/extractor/filelists/ntsc_12_oot.txt +++ b/soh/assets/extractor/filelists/ntsc_12_oot.txt @@ -1507,4 +1507,4 @@ anime_texture_3_static anime_texture_4_static anime_texture_5_static anime_texture_6_static -softsprite_matrix_static +softsprite_matrix_static \ No newline at end of file diff --git a/soh/assets/extractor/filelists/ntsc_oot.txt b/soh/assets/extractor/filelists/ntsc_oot.txt index 21cebcbf2e9..dbdb8f1c81a 100644 --- a/soh/assets/extractor/filelists/ntsc_oot.txt +++ b/soh/assets/extractor/filelists/ntsc_oot.txt @@ -1507,4 +1507,4 @@ anime_texture_3_static anime_texture_4_static anime_texture_5_static anime_texture_6_static -softsprite_matrix_static +softsprite_matrix_static \ No newline at end of file diff --git a/soh/assets/extractor/symbols/SymbolMap_OotMqDbg.txt b/soh/assets/extractor/symbols/SymbolMap_OotMqDbg.txt new file mode 100644 index 00000000000..015e7e88a39 --- /dev/null +++ b/soh/assets/extractor/symbols/SymbolMap_OotMqDbg.txt @@ -0,0 +1 @@ +8012DB20 gMtxClear \ No newline at end of file diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp index d743bead94b..123523e14c1 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp @@ -1,6 +1,7 @@ #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ShipInit.hpp" +#include "soh/Enhancements/randomizer/context.h" extern "C" { #include "z64save.h" @@ -17,9 +18,12 @@ void RegisterSkipLostWoodsBridge() { COND_VB_SHOULD(VB_PLAY_TRANSITION_CS, CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), { if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_BRIDGE_EAST_EXIT) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) { - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); - if (GameInteractor_Should(VB_GIVE_ITEM_FAIRY_OCARINA, true)) { - Item_Give(gPlayState, ITEM_OCARINA_FAIRY); + if (!IS_RANDO || !Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_NPC_SOULS).Get() || + Flags_GetRandomizerInf(RAND_INF_SARIA_SOUL)) { + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); + if (GameInteractor_Should(VB_GIVE_ITEM_FAIRY_OCARINA, true)) { + Item_Give(gPlayState, ITEM_OCARINA_FAIRY); + } } *should = false; } diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.h b/soh/soh/Enhancements/custom-message/CustomMessageManager.h index 51bb84eb880..f0edd307951 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.h @@ -154,9 +154,9 @@ class CustomMessage { void InsertNumber(uint8_t num); /** - * @brief A € sign at the end of an item name signals that it is plural. + * @brief A € sign at the end of an item name signals that it is plural. * If a hint text has |singular|plural| forms specified, the unused one get's deleted. - * If no € sign is present, the singular form is used. + * If no € sign is present, the singular form is used. */ void SetSingularPlural(); diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index b5bc0fd6e82..ada40d730c9 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -79,8 +79,38 @@ typedef enum { TEXT_SARIAS_SONG_CHANNELING_POWER = 0x016D, TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI = 0x01B3, // 0x1yy for Navi msg range TEXT_MASK_SHOP_SIGN = 0x0207, + TEXT_WATERFALL = 0x022D, TEXT_FROGS_UNDERWATER = 0x022E, + TEXT_OUTSIDE_FISHING_POND = 0x023A, + TEXT_HF_SIGN = 0x0301, + TEXT_HC_GF = 0x0304, + TEXT_KAK_SIGN = 0x0305, + TEXT_KAK_GY = 0x0306, + TEXT_KAK_WELL = 0x0307, + TEXT_KAK_DMT = 0x0308, + TEXT_DMT_DC = 0x030A, + TEXT_GC_SIGN = 0x030B, + TEXT_HF_ZR = 0x030C, + TEXT_ZD_SIGN = 0x030E, + TEXT_ZF_JABU_SIGN = 0x030F, + TEXT_KF_LW = 0x0314, + TEXT_HF_LON_LON = 0x0315, + TEXT_LA_SIGN = 0x0317, + TEXT_LA_LAB = 0x0318, + TEXT_GV_SIGN = 0x0319, TEXT_GF_HBA_SIGN = 0x031A, + TEXT_KF_SHOP_SIGN = 0x031E, + TEXT_LINKS_HOUSE_SIGN = 0x031F, + TEXT_KOKIRI_EXIT_SIGN = 0x0320, + TEXT_DMT_DMC = 0x0323, + TEXT_ZD_SHOP_SIGN = 0x0333, + TEXT_OUTSIDE_KOKIRI_SIGN = 0x0339, + TEXT_OUTSIDE_MARKET_SIGN = 0x033A, + TEXT_MIDO_HOUSE_SIGN = 0x033C, + TEXT_KNOW_IT_ALL_HOUSE = 0x033D, + TEXT_TWINS_HOUSE_SIGN = 0x033E, + TEXT_SARIAS_HOUSE_SIGN = 0x033F, + TEXT_NO_DIVING_SIGN = 0x0342, TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN = 0x0346, // 0x3yy for cuttable sign range TEXT_WARP_MINUET_OF_FOREST = 0x088D, TEXT_WARP_BOLERO_OF_FIRE = 0x088E, diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 186307aede3..f0025b6670c 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -142,6 +142,16 @@ typedef enum { // - None VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW, + // #### `result` + // ```c + // CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY) && + // CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) && !Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE) && + // LINK_IS_CHILD + // ``` + // #### `args` + // - None + VB_BE_ELIGIBLE_FOR_OCARINA_OF_TIME, + // #### `result` // ```c // !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && @@ -236,6 +246,15 @@ typedef enum { // - `*Actor` (interactRangeActor) VB_BOTTLE_ACTOR, + // #### `result` + // Actor is ACTOR_OBJ_BOMBIWA, or ACTOR_OBJ_HAMISHI + // ```c + // Flags_GetSwitch(play, this->actor.params & 0x3F) + // ``` + // #### `args` + // - `*Actor` (interactRangeActor) + VB_BOULDER_BREAK_FLAG, + // #### `result` // ```c // true @@ -278,6 +297,14 @@ typedef enum { // - `*EnGm` VB_CHECK_RANDO_PRICE_OF_MEDIGORON, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + VB_CLIMB, + // #### `result` // ```c // CHECK_BTN_ALL(input->press.button, BTN_START) @@ -310,6 +337,15 @@ typedef enum { // - `*ObjKibako2` VB_CRATE_SETUP_DRAW, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + + VB_CRAWL, + // #### `result` // ```c // true @@ -1786,6 +1822,14 @@ typedef enum { // - None VB_REVERT_SPOILING_ITEMS, + // #### `result` + // ```c + // false + // ``` + // #### `args` + // - `*EnIshi` + VB_ROCK_DROP_ITEM, + // #### `result` // ```c // !Flags_GetInfTable(INFTABLE_145) @@ -2155,6 +2199,22 @@ typedef enum { // - `*EnWood02` VB_TREE_DROP_COLLECTIBLE, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*ObjWood02` + VB_TREE_SETUP_DRAW, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*ObjWood02` + VB_TREE_DROP_ITEM, + // ```c // true // ``` diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp index aa375716f68..87880711616 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp @@ -131,6 +131,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Deku-Baum# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans l'Arbre Mojo# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DEKU_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Deku Tree# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | DODONGOS CAVERN | ---------------------------*/ @@ -313,6 +317,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste in Dodongos Höhle# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans la Caverne Dodongo# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DODONGOS_BOULDER] = HintText(CustomMessage("They say that a #boulder in Dodongo's Cavern# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | JABU JABUS BELLY | ---------------------------*/ @@ -480,6 +488,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste in Jabu-Jabus Bauch# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Ventre de Jabu-Jabu# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_JABU_BOULDER] = HintText(CustomMessage("They say that a #boulder in Jabu Jabu's Belly# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | FOREST TEMPLE | ---------------------------*/ @@ -1322,6 +1334,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Geistertempel# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Temple de l'Esprit# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_SPIRIT_TEMPLE_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Spirit Temple# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | SHADOW TEMPLE | ---------------------------*/ @@ -1735,6 +1751,9 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß etwas #Gras auf dem Grund des Brunnens# #[[1]]# verstecke.", /*french*/ "Selon moi, de l'#herbe dans le Puits# cache #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_BOTW_BOULDER] = HintText(CustomMessage("They say that a #boulder in Bottom of the Well# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); /*-------------------------- | ICE CAVERN | 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 a8afd7cb2b5..6de6dbe357a 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 @@ -2081,6 +2081,152 @@ void StaticData::HintTable_Init_Exclude_Overworld() { /*german*/ "Man erzählt sich, daß eine #Kiste im Labor am See# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans un laboratoire# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun in a royal tomb# reveals #[[1]]#.", { QM_RED, QM_GREEN })); + + hintTextTable[RHT_KF_ROCK] = HintText(CustomMessage("They say that a #rock in Kokiri Forest# contains #[[1]]#.", + /*german*/ "", + /*french*/ "Selon moi, une #roche dans la Fôret Kokiri# contient #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LW_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Lost Woods# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HC_ROCK] = HintText(CustomMessage("They say that a #rock at Hyrule Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HC_BOULDER] = HintText(CustomMessage("They say that a #boulder at Hyrule Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_OGC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder outside Ganon's Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_OGC_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder outside Ganon's Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMC_ROCK] = HintText(CustomMessage("They say that a #rock in Death Mountain Crater# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMC_BOULDER] = HintText(CustomMessage("They say that a #boulder in Death Mountain Crater# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Death Mountain Crater# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GV_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_ROCK] = HintText(CustomMessage("They say that a #rock in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_BOULDER] = HintText(CustomMessage("They say that a #boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HF_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_ROCK] = HintText(CustomMessage("They say that a #rock on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_BOULDER] = HintText(CustomMessage("They say that a #boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KAK_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder at Kakariko Village# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_KAK_ROCK] = HintText(CustomMessage("They say that a #rock at Kakariko Village# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GY_ROCK] = HintText(CustomMessage("They say that a #rock in a graveyard# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LA_ROCK] = HintText(CustomMessage("They say that a #rock at Lake Hylia# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZD_ROCK] = HintText(CustomMessage("They say that a #rock in Zora's Domain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZF_BOULDER] = HintText(CustomMessage("They say that a #boulder in Zora's Fountain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_ZF_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Zora's Fountain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZR_ROCK] = HintText(CustomMessage("They say that a #rock along a river# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_ZR_BOULDER] = HintText(CustomMessage("They say that a #boulder along a river# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMT_ROCK] = HintText(CustomMessage("They say that a #rock on Death Mountain Trail# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMT_BOULDER] = HintText(CustomMessage("They say that a #boulder on Death Mountain Trail# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMT_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder on Death Mountain Trail# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_ROCK] = HintText(CustomMessage("They say that a #rock in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_BOULDER] = HintText(CustomMessage("They say that a #boulder in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_COLOSSUS_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in a desert# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_COLOSSUS_ROCK] = HintText(CustomMessage("They say that a #rock in a desert# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_TREE_HYRULE_FIELD] = + HintText(CustomMessage("They say that a #tree in Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); + hintTextTable[RHT_TREE_MARKET] = + HintText(CustomMessage("They say that a #tree in Hyrule Market# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); + hintTextTable[RHT_TREE_HYRULE_CASTLE] = + HintText(CustomMessage("They say that a #tree in Hyrule Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); + hintTextTable[RHT_TREE_ZORAS_RIVER] = + HintText(CustomMessage("They say that a #tree in Zora's River# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); + hintTextTable[RHT_TREE_ZORAS_FOUNTAIN] = + HintText(CustomMessage("They say that a #tree in Zora's Fountain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); + hintTextTable[RHT_TREE_LON_LON_RANCH] = + HintText(CustomMessage("They say that a #tree in Lon Lon Ranch# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); // clang-format on } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index f5195c91d2b..35758319db8 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -2028,6 +2028,55 @@ void StaticData::HintTable_Init_Item() { CustomMessage("an evil soul", /*german*/"eine böse Seele", /*french*/"une âme maléfique"), CustomMessage("some powerful essence", /*german*/"etwas mächtige Essenz", /*french*/"une essence incroyablement puissante")}); + hintTextTable[RHT_ANJU_SOUL] = HintText(CustomMessage("Anju's Soul")); + hintTextTable[RHT_TALON_SOUL] = HintText(CustomMessage("Talon's Soul")); + hintTextTable[RHT_GROG_SOUL] = HintText(CustomMessage("Grog's Soul")); + hintTextTable[RHT_GRANNY_SOUL] = HintText(CustomMessage("Granny's Soul")); + hintTextTable[RHT_FADO_SOUL] = HintText(CustomMessage("Fado's Soul")); + hintTextTable[RHT_LINK_SOUL] = HintText(CustomMessage("Darunia's Son's Soul")); + hintTextTable[RHT_BIGGORON_SOUL] = HintText(CustomMessage("Biggoron's Soul")); + hintTextTable[RHT_HOT_RODDER_SOUL] = HintText(CustomMessage("Hot Rodder's Soul")); + hintTextTable[RHT_MEDIGORON_SOUL] = HintText(CustomMessage("Medigoron's Soul")); + hintTextTable[RHT_CARPENTER_BOSS_SOUL] = HintText(CustomMessage("Carpenter Boss's Soul")); + hintTextTable[RHT_ICHIRO_SOUL] = HintText(CustomMessage("Ichiro's Soul")); + hintTextTable[RHT_SABOORO_SOUL] = HintText(CustomMessage("Sabooro's Soul")); + hintTextTable[RHT_JIRO_SOUL] = HintText(CustomMessage("Jiro's Soul")); + hintTextTable[RHT_SHIRO_SOUL] = HintText(CustomMessage("Shiro's Soul")); + hintTextTable[RHT_HW_GATEKEEPER_SOUL] = HintText(CustomMessage("Haunted Wasteland Gate Operator's Soul")); + hintTextTable[RHT_GTG_GATEKEEPER_SOUL] = HintText(CustomMessage("Training Ground Gate Operator's Soul")); + hintTextTable[RHT_ARCHER_SOUL] = HintText(CustomMessage("Horseback Archer's Soul")); + hintTextTable[RHT_GREAT_FAIRY_SOUL] = HintText(CustomMessage("Great Fairy's Soul")); + hintTextTable[RHT_POE_COLLECTOR_SOUL] = HintText(CustomMessage("Poe Collector's Soul")); + hintTextTable[RHT_DAMPE_SOUL] = HintText(CustomMessage("Dampe's Soul")); + hintTextTable[RHT_WINDMILL_MAN_SOUL] = HintText(CustomMessage("Windmill Man's Soul")); + hintTextTable[RHT_MAN_ON_ROOF_SOUL] = HintText(CustomMessage("Man on Roof's Soul")); + hintTextTable[RHT_KAKARIKO_GATEKEEPER_SOUL] = HintText(CustomMessage("Kakariko Gatekeeper's Soul")); + hintTextTable[RHT_MALON_SOUL] = HintText(CustomMessage("Malon's Soul")); + hintTextTable[RHT_BEGGAR_SOUL] = HintText(CustomMessage("Beggar's Soul")); + hintTextTable[RHT_DOG_LADY_SOUL] = HintText(CustomMessage("Dog Lady's Soul")); + hintTextTable[RHT_ARMS_DEALER_SOUL] = HintText(CustomMessage("Arms Dealer's Soul")); + hintTextTable[RHT_BEAN_SALESMAN_SOUL] = HintText(CustomMessage("Bean Salesman's Soul")); + hintTextTable[RHT_SHOOTING_SOUL] = HintText(CustomMessage("Shooter's Soul")); + hintTextTable[RHT_KOKIRI_SHOPKEEPER_SOUL] = HintText(CustomMessage("Kokiri Shopkeeper's Soul")); + hintTextTable[RHT_POTION_SHOPKEEPER_SOUL] = HintText(CustomMessage("Potion Shopkeeper's Soul")); + hintTextTable[RHT_BAZAAR_SHOPKEEPER_SOUL] = HintText(CustomMessage("Bazaar Shopkeeper's Soul")); + hintTextTable[RHT_GORON_SHOPKEEPER_SOUL] = HintText(CustomMessage("Goron Shopkeeper's Soul")); + hintTextTable[RHT_ZORA_SHOPKEEPER_SOUL] = HintText(CustomMessage("Zora Shopkeeper's Soul")); + hintTextTable[RHT_BOMBCHU_SHOPKEEPER_SOUL] = HintText(CustomMessage("Bombchu Shopkeeper's Soul")); + hintTextTable[RHT_MASK_SALESMAN_SOUL] = HintText(CustomMessage("Mask Salesman's Soul")); + hintTextTable[RHT_TREASURE_MAN_SOUL] = HintText(CustomMessage("Treasure Man's Soul")); + hintTextTable[RHT_BOMBCHU_LADY_SOUL] = HintText(CustomMessage("Bombchu Lady's Soul")); + hintTextTable[RHT_DIVING_SOUL] = HintText(CustomMessage("Diver's Soul")); + hintTextTable[RHT_SCIENTIST_SOUL] = HintText(CustomMessage("Scientist's Soul")); + hintTextTable[RHT_KAEPORA_SOUL] = HintText(CustomMessage("Kaepora's Soul")); + hintTextTable[RHT_RAURU_SOUL] = HintText(CustomMessage("Rauru's Soul")); + hintTextTable[RHT_SARIA_SOUL] = HintText(CustomMessage("Saria's Soul")); + hintTextTable[RHT_DARUNIA_SOUL] = HintText(CustomMessage("Darunia's Soul")); + hintTextTable[RHT_RUTO_SOUL] = HintText(CustomMessage("Ruto's Soul")); + hintTextTable[RHT_NABOORU_SOUL] = HintText(CustomMessage("Nabooru's Soul")); + hintTextTable[RHT_IMPA_SOUL] = HintText(CustomMessage("Impa's Soul")); + hintTextTable[RHT_ZELDA_SOUL] = HintText(CustomMessage("Zelda's Soul")); + hintTextTable[RHT_OCARINA_A_BUTTON] = HintText(CustomMessage("an Ocarina A Button", /*german*/"die A-Taste der Okarina", /*french*/"la Touche A de l'Ocarina"), // /*spanish*/un botón A de Ocarina { @@ -2073,6 +2122,15 @@ void StaticData::HintTable_Init_Item() { CustomMessage("a rightward tone", /*german*/"ein rechtsseitiger Ton", /*french*/"une tonalité vers la droite")}); // /*spanish*/un tono hacia la derecha + hintTextTable[RHT_MASK_KEATON] = HintText(CustomMessage("a keaton mask", /*german*/"!!!", /*french*/"!!!"), {CustomMessage("a mask", /*german*/"!!!", /*french*/"!!!")}); + hintTextTable[RHT_MASK_SKULL] = HintText(CustomMessage("a skull mask", /*german*/"!!!", /*french*/"!!!"), {CustomMessage("a mask", /*german*/"!!!", /*french*/"!!!")}); + hintTextTable[RHT_MASK_SPOOKY] = HintText(CustomMessage("a spooky mask", /*german*/"!!!", /*french*/"!!!"), {CustomMessage("a mask", /*german*/"!!!", /*french*/"!!!")}); + hintTextTable[RHT_MASK_BUNNY] = HintText(CustomMessage("a bunny hood", /*german*/"!!!", /*french*/"!!!"), {CustomMessage("a mask", /*german*/"!!!", /*french*/"!!!")}); + hintTextTable[RHT_MASK_GORON] = HintText(CustomMessage("a goron mask", /*german*/"!!!", /*french*/"!!!"), {CustomMessage("a mask", /*german*/"!!!", /*french*/"!!!")}); + hintTextTable[RHT_MASK_ZORA] = HintText(CustomMessage("a zora mask", /*german*/"!!!", /*french*/"!!!"), {CustomMessage("a mask", /*german*/"!!!", /*french*/"!!!")}); + hintTextTable[RHT_MASK_GERUDO] = HintText(CustomMessage("a gerudo mask", /*german*/"!!!", /*french*/"!!!"), {CustomMessage("a mask", /*german*/"!!!", /*french*/"!!!")}); + hintTextTable[RHT_MASK_TRUTH] = HintText(CustomMessage("a mask of truth", /*german*/"!!!", /*french*/"!!!"), {CustomMessage("a mask", /*german*/"!!!", /*french*/"!!!")}); + hintTextTable[RHT_FISHING_POLE] = HintText(CustomMessage("a fishing pole", /*german*/"eine Angelrute", /*french*/"une canne à pêche"), // /*spanish*/caña de pescar { @@ -2100,7 +2158,11 @@ void StaticData::HintTable_Init_Item() { { CustomMessage("a master unlocker", /*german*/ "ein Meisterentsperrer", /*french*/ "un Kit de Déverrouillage") }); // /*spanish*/un desbloqueador maestro - //RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints + hintTextTable[RHT_CRAWL] = HintText(CustomMessage("the ability to crawl", /*german*/"!!!", /*french*/"!!!")); + + //RANDOTODO if these are ever used for anything other than name, they want obscure and ambiguous hints + hintTextTable[RHT_CLIMB] = HintText(CustomMessage("the ability to climb", /*german*/"!!!", /*french*/"!!!")); + hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("an infinite Quiver", /*german*/"der unendliche Köcher", /*french*/"un Carquois Infini")); hintTextTable[RHT_BOMB_BAG_INF] = HintText(CustomMessage("an infinite Bomb Bag", /*german*/"die unendliche Bombentasche", /*french*/"un Sac de Bombe sans fond")); diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index 65cc6eb8c02..c289b653153 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -278,7 +278,7 @@ std::vector>> conditionalAlways std::make_pair(RC_DEKU_THEATER_MASK_OF_TRUTH, []() { auto ctx = Rando::Context::GetInstance(); - return !ctx->GetOption(RSK_MASK_SHOP_HINT) && !ctx->GetOption(RSK_COMPLETE_MASK_QUEST); + return !ctx->GetOption(RSK_MASK_SHOP_HINT) && !ctx->GetOption(RSK_MASK_QUEST); }), std::make_pair(RC_SONG_FROM_OCARINA_OF_TIME, []() { diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index c97ae35ce13..918db6170b4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -587,10 +587,29 @@ void GenerateItemPool() { AddItemToMainPool(RG_SKELETON_KEY); } + if (ctx->GetOption(RSK_MASK_QUEST).Is(RO_MASK_QUEST_SHUFFLE)) { + AddItemToMainPool(RG_MASK_KEATON); + AddItemToMainPool(RG_MASK_SKULL); + AddItemToMainPool(RG_MASK_SPOOKY); + AddItemToMainPool(RG_MASK_BUNNY); + AddItemToMainPool(RG_MASK_GORON); + AddItemToMainPool(RG_MASK_ZORA); + AddItemToMainPool(RG_MASK_GERUDO); + AddItemToMainPool(RG_MASK_TRUTH); + } + if (ctx->GetOption(RSK_SHUFFLE_SWIM)) { AddItemToMainPool(RG_PROGRESSIVE_SCALE); } + if (ctx->GetOption(RSK_SHUFFLE_CLIMB)) { + AddItemToMainPool(RG_CLIMB); + } + + if (ctx->GetOption(RSK_SHUFFLE_CRAWL)) { + AddItemToMainPool(RG_CRAWL); + } + if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations AddItemToPool(PendingJunkPool, RG_RED_RUPEE, 23); @@ -604,18 +623,36 @@ void GenerateItemPool() { ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL); PlaceItemsForType(RCTYPE_POT, overworldPotsActive, dungeonPotsActive); + // Shuffle Trees + bool treesActive = (bool)ctx->GetOption(RSK_SHUFFLE_TREES); + PlaceItemsForType(RCTYPE_TREE, treesActive, false); + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC)) { + PlaceItemsForType(RCTYPE_NLTREE, treesActive, false); + } + // Shuffle Crates bool overworldCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) || ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL); - bool overworldNLCratesActive = ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) && - (ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) || - ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL)); bool dungeonCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_DUNGEONS) || ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL); PlaceItemsForType(RCTYPE_CRATE, overworldCratesActive, dungeonCratesActive); - PlaceItemsForType(RCTYPE_NLCRATE, overworldNLCratesActive, dungeonCratesActive); PlaceItemsForType(RCTYPE_SMALL_CRATE, overworldCratesActive, dungeonCratesActive); + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC)) { + PlaceItemsForType(RCTYPE_NLCRATE, overworldCratesActive, dungeonCratesActive); + } + + // Shuffle Rocks + bool rocksActive = ctx->GetOption(RSK_SHUFFLE_ROCKS).Get(); + PlaceItemsForType(RCTYPE_ROCK, rocksActive, rocksActive); + + // Shuffle Boulders + bool overworldBouldersActive = ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_OVERWORLD) || + ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_ALL); + bool dungeonBouldersActive = ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_DUNGEONS) || + ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_ALL); + PlaceItemsForType(RCTYPE_BOULDER, overworldBouldersActive, dungeonBouldersActive); + auto fsMode = ctx->GetOption(RSK_FISHSANITY); if (fsMode.IsNot(RO_FISHSANITY_OFF)) { if (fsMode.Is(RO_FISHSANITY_POND) || fsMode.Is(RO_FISHSANITY_BOTH)) { @@ -753,29 +790,23 @@ void GenerateItemPool() { } if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) { - AddItemToMainPool(RG_GOHMA_SOUL); - AddItemToMainPool(RG_KING_DODONGO_SOUL); - AddItemToMainPool(RG_BARINADE_SOUL); - AddItemToMainPool(RG_PHANTOM_GANON_SOUL); - AddItemToMainPool(RG_VOLVAGIA_SOUL); - AddItemToMainPool(RG_MORPHA_SOUL); - AddItemToMainPool(RG_BONGO_BONGO_SOUL); - AddItemToMainPool(RG_TWINROVA_SOUL); - - ctx->possibleIceTrapModels.push_back(RG_GOHMA_SOUL); - ctx->possibleIceTrapModels.push_back(RG_KING_DODONGO_SOUL); - ctx->possibleIceTrapModels.push_back(RG_BARINADE_SOUL); - ctx->possibleIceTrapModels.push_back(RG_PHANTOM_GANON_SOUL); - ctx->possibleIceTrapModels.push_back(RG_VOLVAGIA_SOUL); - ctx->possibleIceTrapModels.push_back(RG_MORPHA_SOUL); - ctx->possibleIceTrapModels.push_back(RG_BONGO_BONGO_SOUL); - ctx->possibleIceTrapModels.push_back(RG_TWINROVA_SOUL); + for (int rg = RG_GOHMA_SOUL; rg <= RG_TWINROVA_SOUL; rg++) { + AddItemToMainPool((RandomizerGet)rg); + ctx->possibleIceTrapModels.push_back((RandomizerGet)rg); + } + if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) { AddItemToMainPool(RG_GANON_SOUL); ctx->possibleIceTrapModels.push_back(RG_GANON_SOUL); } } + if (ctx->GetOption(RSK_SHUFFLE_NPC_SOULS)) { + for (int rg = RG_ANJU_SOUL; rg <= RG_ZELDA_SOUL; rg++) { + AddItemToMainPool((RandomizerGet)rg); + } + } + if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET)) { AddItemToMainPool(RG_PROGRESSIVE_WALLET); } diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index 441454cd074..e80af27ccb8 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -967,6 +967,10 @@ void InitTrickNames() { Text{ "Overworld C Right Button", "Trou Droit de l'Ocarina", "C-Rechts-Taste der E-Gitarre" }, }; + for (size_t i = 108; i < 241; ++i) { + trickNameTable[i].push_back(Text("Mysterious Ice Trap")); + } + /* //Names for individual upgrades, in case progressive names are replaced trickNameTable[GI_HOOKSHOT] = { @@ -1162,11 +1166,11 @@ void InitTrickNames() { // Generate a fake name for the ice trap based on the item it's displayed as Text GetIceTrapName(uint8_t id) { - // If the trick names table has not been initialized, do so - if (!initTrickNames) { - InitTrickNames(); - initTrickNames = true; + if (id < 0 || id >= trickNameTable.size()) { + return Text("Mysterious Ice Trap"); + } + if (trickNameTable[id].empty()) { + return Text("Mysterious Ice Trap"); } - // Randomly get the easy, medium, or hard name for the given item id - return RandomElement(trickNameTable[id]); + return trickNameTable[id][0]; } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp index c94c68511c3..83b2b482c77 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp @@ -138,4 +138,4 @@ void Rando::StaticData::RegisterBeehiveLocations() { } static ObjectExtension::Register RegisterBeehiveIdentity; -static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterBeehiveLocations); +static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterBeehiveLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShufflePots.cpp b/soh/soh/Enhancements/randomizer/ShufflePots.cpp index ad23f9d26e2..f5c2e923207 100644 --- a/soh/soh/Enhancements/randomizer/ShufflePots.cpp +++ b/soh/soh/Enhancements/randomizer/ShufflePots.cpp @@ -250,7 +250,7 @@ void Rando::StaticData::RegisterPotLocations() { locationTable[RC_HC_STORMS_GROTTO_POT_2] = Location::Pot(RC_HC_STORMS_GROTTO_POT_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1769, 954), "Storms Grotto Pot 2", RHT_POT_HYRULE_CASTLE, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_2)); locationTable[RC_HC_STORMS_GROTTO_POT_3] = Location::Pot(RC_HC_STORMS_GROTTO_POT_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1857, 897), "Storms Grotto Pot 3", RHT_POT_HYRULE_CASTLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_3)); locationTable[RC_HC_STORMS_GROTTO_POT_4] = Location::Pot(RC_HC_STORMS_GROTTO_POT_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1764, 847), "Storms Grotto Pot 4", RHT_POT_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_4)); - + // Dungeon Pots // Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Vanilla Spoiler Collection Check locationTable[RC_DODONGOS_CAVERN_LIZALFOS_POT_3] = Location::Pot(RC_DODONGOS_CAVERN_LIZALFOS_POT_3, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2673, -2060), "Lizalfos Pot 3", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3)); diff --git a/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp b/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp new file mode 100644 index 00000000000..04b25806077 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp @@ -0,0 +1,631 @@ +#include "ShuffleRocks.h" +#include "soh_assets.h" +#include "static_data.h" + +extern "C" { +#include "variables.h" +#include "overlays/actors/ovl_En_Ishi/z_en_ishi.h" +#include "overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h" +#include "overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "objects/object_bombiwa/object_bombiwa.h" +extern PlayState* gPlayState; +} + +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get() + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + +extern "C" void EnIshi_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((EnIshi*)thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + gDPSetGrayscaleColor(POLY_OPA_DISP++, 175, 255, 0, 255); + + if (rockActor->rockIdentity.randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockActor->rockIdentity.randomizerInf) == 0) { + gSPGrayscale(POLY_OPA_DISP++, true); + } + + if (rockActor->actor.params & 1) { + Gfx_SetupDL_25Opa(play->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL); + } else { + Gfx_DrawDListOpa(play, (Gfx*)gFieldKakeraDL); + } + + gSPGrayscale(POLY_OPA_DISP++, false); + + CLOSE_DISPS(play->state.gfxCtx); +} + +extern "C" void ObjBombiwa_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((ObjBombiwa*)thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + gDPSetGrayscaleColor(POLY_OPA_DISP++, 175, 255, 0, 255); + + if (rockActor->rockIdentity.randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockActor->rockIdentity.randomizerInf) == 0) { + gSPGrayscale(POLY_OPA_DISP++, true); + } + + Gfx_DrawDListOpa(play, (Gfx*)object_bombiwa_DL_0009E0); + + gSPGrayscale(POLY_OPA_DISP++, false); + + CLOSE_DISPS(play->state.gfxCtx); +} + +extern "C" void ObjHamishi_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((ObjHamishi*)thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + gDPSetGrayscaleColor(POLY_OPA_DISP++, 175, 255, 0, 255); + + if (rockActor->rockIdentity.randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockActor->rockIdentity.randomizerInf) == 0) { + gSPGrayscale(POLY_OPA_DISP++, true); + } + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 170, 130, 255); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL); + + gSPGrayscale(POLY_OPA_DISP++, false); + + CLOSE_DISPS(play->state.gfxCtx); +} + +uint8_t Rock_RandomizerHoldsItem(RockIdentity rockIdentity, PlayState* play, bool isBoulder) { + RandomizerCheck rc = rockIdentity.randomizerCheck; + if (rc == RC_MAX) + return false; + + uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); + uint8_t setting = + Rando::Context::GetInstance()->GetOption(isBoulder ? RSK_SHUFFLE_BOULDERS : RSK_SHUFFLE_ROCKS).Get(); + + // Don't pull randomized item if rock isn't randomized or is already checked + return IS_RANDO && + ((!isBoulder && setting) || (isBoulder && (setting == RO_SHUFFLE_BOULDERS_ALL || + (isDungeon && setting == RO_SHUFFLE_BOULDERS_DUNGEONS) || + (!isDungeon && setting == RO_SHUFFLE_BOULDERS_OVERWORLD)))) && + !Flags_GetRandomizerInf(rockIdentity.randomizerInf) && rockIdentity.randomizerCheck != RC_UNKNOWN_CHECK; +} + +void Rock_RandomizerSpawnCollectible(Actor* actor, RockIdentity rockIdentity, PlayState* play) { + LUSLOG_INFO("ROCKdrop %d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &actor->world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = rockIdentity.randomizerInf; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rockIdentity.randomizerCheck, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + item00->actor.velocity.y = 9.0f; + item00->actor.speedXZ = 2.0f; + item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f); +} + +void EnIshi_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_EN_ISHI) + return; + + EnIshi* rockActor = static_cast(actorRef); + + rockActor->rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock( + gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + if (rockActor->rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_WARN("ROCK ishi %d\t:\t%d, %d", rockActor->rockIdentity.randomizerCheck, actor->params & 1, + (s16)actor->world.pos.x, (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK ishi%d %d\t:\t%d, %d", rockActor->rockIdentity.randomizerCheck, actor->params & 1, + (s16)actor->world.pos.x, (s16)actor->world.pos.z); + } + + if (Rock_RandomizerHoldsItem(rockActor->rockIdentity, gPlayState, actor->params & 1)) { + rockActor->actor.draw = EnIshi_RandomizerDraw; + } +} + +void ObjBombiwa_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_BOMBIWA) + return; + + ObjBombiwa* rockActor = static_cast(actorRef); + + rockActor->rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock( + gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + if (rockActor->rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_INFO("ROCK bombiwa\t:\t%d, %d", rockActor->rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK bombiwa%d\t:\t%d, %d", rockActor->rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } + if (Rock_RandomizerHoldsItem(rockActor->rockIdentity, gPlayState, true)) { + rockActor->actor.draw = ObjBombiwa_RandomizerDraw; + } +} + +void ObjHamishi_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_HAMISHI) + return; + + ObjHamishi* rockActor = static_cast(actorRef); + + rockActor->rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock( + gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + if (rockActor->rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_WARN("ROCK hamishi\t:\t%d, %d", rockActor->rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK hamishi%d\t:\t%d, %d", rockActor->rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } + if (Rock_RandomizerHoldsItem(rockActor->rockIdentity, gPlayState, true)) { + rockActor->actor.draw = ObjHamishi_RandomizerDraw; + } +} + +void ObjBombiwa_RandomizerKill(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_BOMBIWA) + return; + + ObjBombiwa* rockActor = static_cast(actorRef); + + if (Rock_RandomizerHoldsItem(rockActor->rockIdentity, gPlayState, true)) { + Rock_RandomizerSpawnCollectible(&rockActor->actor, rockActor->rockIdentity, gPlayState); + rockActor->rockIdentity.randomizerCheck = RC_MAX; + rockActor->rockIdentity.randomizerInf = RAND_INF_MAX; + } +} + +void ObjHamishi_RandomizerKill(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_HAMISHI) + return; + + ObjHamishi* rockActor = static_cast(actorRef); + + if (Rock_RandomizerHoldsItem(rockActor->rockIdentity, gPlayState, true)) { + Rock_RandomizerSpawnCollectible(&rockActor->actor, rockActor->rockIdentity, gPlayState); + rockActor->rockIdentity.randomizerCheck = RC_MAX; + rockActor->rockIdentity.randomizerInf = RAND_INF_MAX; + } +} + +void RegisterShuffleRock() { + bool shouldRegister = IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_ROCKS) || RAND_GET_OPTION(RSK_SHUFFLE_BOULDERS)); + bool shouldRegisterBoulder = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_BOULDERS); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_ISHI, shouldRegister, EnIshi_RandomizerInit); + COND_ID_HOOK(OnActorInit, ACTOR_OBJ_BOMBIWA, shouldRegisterBoulder, ObjBombiwa_RandomizerInit); + COND_ID_HOOK(OnActorInit, ACTOR_OBJ_HAMISHI, shouldRegisterBoulder, ObjHamishi_RandomizerInit); + COND_ID_HOOK(OnActorKill, ACTOR_OBJ_BOMBIWA, shouldRegisterBoulder, ObjBombiwa_RandomizerKill); + COND_ID_HOOK(OnActorKill, ACTOR_OBJ_HAMISHI, shouldRegisterBoulder, ObjHamishi_RandomizerKill); + + COND_VB_SHOULD(VB_ROCK_DROP_ITEM, shouldRegister, { + EnIshi* rockActor = va_arg(args, EnIshi*); + if (Rock_RandomizerHoldsItem(rockActor->rockIdentity, gPlayState, rockActor->actor.params & 1)) { + Rock_RandomizerSpawnCollectible(&rockActor->actor, rockActor->rockIdentity, gPlayState); + rockActor->rockIdentity.randomizerCheck = RC_MAX; + rockActor->rockIdentity.randomizerInf = RAND_INF_MAX; + *should = false; + } + }); + + COND_VB_SHOULD(VB_BOULDER_BREAK_FLAG, shouldRegisterBoulder, { + Actor* rockActor = va_arg(args, Actor*); + auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock( + gPlayState->sceneNum, (s16)rockActor->world.pos.x, (s16)rockActor->world.pos.z); + if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true)) { + Flags_UnsetSwitch(gPlayState, rockActor->params & 0x3F); + *should = false; + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterShuffleRock, { "IS_RANDO" }); + +void Rando::StaticData::RegisterRockLocations() { +#define ROCKLOC(id, area, scene, hint, x, z) \ + (locationTable[RC_##id] = Location::Rock(RC_##id, RCQUEST_BOTH, area, scene, TWO_ACTOR_PARAMS(x, z), #id, hint, \ + RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) +#define BOLDLOC(id, area, scene, hint, x, z) \ + (locationTable[RC_##id] = Location::Boulder(RC_##id, RCQUEST_BOTH, area, scene, TWO_ACTOR_PARAMS(x, z), #id, hint, \ + SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) + ROCKLOC(KF_CIRCLE_ROCK_1, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -292, -350); + ROCKLOC(KF_CIRCLE_ROCK_2, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -235, -373); + ROCKLOC(KF_CIRCLE_ROCK_3, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -212, -430); + ROCKLOC(KF_CIRCLE_ROCK_4, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -235, -486); + ROCKLOC(KF_CIRCLE_ROCK_5, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -292, -510); + ROCKLOC(KF_CIRCLE_ROCK_6, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -348, -486); + ROCKLOC(KF_CIRCLE_ROCK_7, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -372, -430); + ROCKLOC(KF_CIRCLE_ROCK_8, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -348, -373); + ROCKLOC(KF_ROCK_BY_SARIAS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, 248, 601); + ROCKLOC(KF_ROCK_BEHIND_SARIAS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, 726, 961); + ROCKLOC(KF_ROCK_BY_MIDOS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -672, -623); + ROCKLOC(KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -1361, 145); + BOLDLOC(LW_BOULDER_BY_GORON_CITY, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 915, -925); + BOLDLOC(LW_BOULDER_BY_SACRED_FOREST_MEADOW, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 670, -2520); + BOLDLOC(LW_RUPEE_BOULDER, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 1720, -2510); + + locationTable[RC_HC_ROCK_1] = Location::Rock( + RC_HC_ROCK_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-216, 2977), + "HC Rock 1", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_1)); + locationTable[RC_HC_ROCK_2] = Location::Rock( + RC_HC_ROCK_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-110, 3006), + "HC Rock 2", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_2)); + locationTable[RC_HC_ROCK_3] = Location::Rock( + RC_HC_ROCK_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-129, 2897), + "HC Rock 3", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_3)); + BOLDLOC(HC_BOULDER, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, RHT_HC_BOULDER, 2730, 2540); + BOLDLOC(OGC_BRONZE_BOULDER_1, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 2324, 533); + BOLDLOC(OGC_BRONZE_BOULDER_2, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 1590, 787); + BOLDLOC(OGC_BRONZE_BOULDER_3, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 1661, 748); + BOLDLOC(OGC_SILVER_BOULDER_1, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1606, 685); + BOLDLOC(OGC_SILVER_BOULDER_2, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1766, 726); + BOLDLOC(OGC_SILVER_BOULDER_3, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1701, 661); + BOLDLOC(OGC_SILVER_BOULDER_4, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 2260, 560); + + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -50, + -714); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -26, + -807); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 61, + -763); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 71, + -610); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_5, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 79, + -700); + ROCKLOC(DMC_CIRCLE_ROCK_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 40, 1850); + ROCKLOC(DMC_CIRCLE_ROCK_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 96, 1826); + ROCKLOC(DMC_CIRCLE_ROCK_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 120, 1770); + ROCKLOC(DMC_CIRCLE_ROCK_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 96, 1713); + ROCKLOC(DMC_CIRCLE_ROCK_5, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 40, 1690); + ROCKLOC(DMC_CIRCLE_ROCK_6, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -16, 1713); + ROCKLOC(DMC_CIRCLE_ROCK_7, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -40, 1770); + ROCKLOC(DMC_CIRCLE_ROCK_8, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -16, 1826); + ROCKLOC(DMC_GOSSIP_ROCK_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 1261, 1533); + ROCKLOC(DMC_GOSSIP_ROCK_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 1356, 1541); + BOLDLOC(DMC_BOULDER_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, -504, 1070); + BOLDLOC(DMC_BOULDER_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, 236, 1199); + BOLDLOC(DMC_BOULDER_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, 40, 1770); + BOLDLOC(DMC_BRONZE_BOULDER_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1699, -472); + BOLDLOC(DMC_BRONZE_BOULDER_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1332, 921); + BOLDLOC(DMC_BRONZE_BOULDER_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1303, 975); + BOLDLOC(DMC_BRONZE_BOULDER_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1060, 944); + + BOLDLOC(GV_SILVER_BOULDER, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_SILVER_BOULDER, 280, 1470); + ROCKLOC(GV_ROCK_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2738, 297); + ROCKLOC(GV_ROCK_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2715, 316); + ROCKLOC(GV_ROCK_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2699, 275); + ROCKLOC(GV_UNDERWATER_ROCK_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1559, -63); + ROCKLOC(GV_UNDERWATER_ROCK_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1605, 26); + ROCKLOC(GV_UNDERWATER_ROCK_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1686, -33); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -666, -899); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -526, -890); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -607, -791); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_4, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -458, -782); + BOLDLOC(GV_BOULDER_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, 751, 569); + BOLDLOC(GV_BOULDER_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, 545, -510); + BOLDLOC(GV_BOULDER_ACROSS_BRIDGE, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, -954, 577); + BOLDLOC(GV_BRONZE_BOULDER_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, 861, -778); + BOLDLOC(GV_BRONZE_BOULDER_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, 735, 375); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1352, + 767); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1695, + -350); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1001, + 637); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1291, + 787); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1416, + 778); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1256, + 856); + + BOLDLOC(HF_SILVER_BOULDER, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_SILVER_BOULDER, 674, 8256); + ROCKLOC(HF_ROCK_1, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7875, 6995); + ROCKLOC(HF_ROCK_2, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7818, 6971); + ROCKLOC(HF_ROCK_3, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7795, 6915); + ROCKLOC(HF_ROCK_4, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7818, 6858); + ROCKLOC(HF_ROCK_5, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7875, 6835); + ROCKLOC(HF_ROCK_6, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7931, 6858); + ROCKLOC(HF_ROCK_7, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7955, 6915); + ROCKLOC(HF_ROCK_8, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7931, 6971); + BOLDLOC(HF_BOULDER_NORTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -4450, -425); + BOLDLOC(HF_BOULDER_BY_MARKET, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -1425, 810); + BOLDLOC(HF_BOULDER_SOUTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -270, 12350); + BOLDLOC(HF_BRONZE_BOULDER_1, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -7870, 6920); + BOLDLOC(HF_BRONZE_BOULDER_2, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -7804, 7983); + BOLDLOC(HF_BRONZE_BOULDER_3, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -8397, 7947); + BOLDLOC(HF_BRONZE_BOULDER_4, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -6461, 8220); + + BOLDLOC(KAK_SILVER_BOULDER, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_SILVER_BOULDER, 1436, 1361); + ROCKLOC(KAK_ROCK_1, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_ROCK, 220, -1236); + ROCKLOC(KAK_ROCK_2, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_ROCK, -664, 1288); + ROCKLOC(GY_ROCK, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, RHT_GY_ROCK, -1193, 693); + ROCKLOC(LA_ROCK, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, RHT_LA_ROCK, 1222, 3953); + + ROCKLOC(ZD_CIRCLE_ROCK_1, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 462, -696); + ROCKLOC(ZD_CIRCLE_ROCK_2, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 518, -719); + ROCKLOC(ZD_CIRCLE_ROCK_3, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 542, -776); + ROCKLOC(ZD_CIRCLE_ROCK_4, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 518, -832); + ROCKLOC(ZD_CIRCLE_ROCK_5, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 462, -856); + ROCKLOC(ZD_CIRCLE_ROCK_6, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 405, -832); + ROCKLOC(ZD_CIRCLE_ROCK_7, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 382, -776); + ROCKLOC(ZD_CIRCLE_ROCK_8, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 405, -719); + BOLDLOC(ZF_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_BOULDER, 189, 2586); + BOLDLOC(ZF_SILVER_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_SILVER_BOULDER, 316, 2634); + BOLDLOC(ZF_UNDERGROUND_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_BOULDER, 317, 2631); + BOLDLOC(ZR_BOULDER_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1456, 434); + BOLDLOC(ZR_BOULDER_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1518, 435); + BOLDLOC(ZR_BOULDER_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1576, 430); + BOLDLOC(ZR_BOULDER_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1400, 482); + ROCKLOC(ZR_CIRCLE_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1635, -53); + ROCKLOC(ZR_CIRCLE_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1578, -76); + ROCKLOC(ZR_CIRCLE_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1555, -133); + ROCKLOC(ZR_CIRCLE_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1578, -189); + ROCKLOC(ZR_CIRCLE_ROCK_5, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1635, -213); + ROCKLOC(ZR_CIRCLE_ROCK_6, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1691, -189); + ROCKLOC(ZR_CIRCLE_ROCK_7, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1715, -133); + ROCKLOC(ZR_CIRCLE_ROCK_8, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1691, -76); + ROCKLOC(ZR_UPPER_CIRCLE_BOULDER, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, 672, -366); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 668, -290); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 724, -313); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 748, -370); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 724, -426); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_5, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 668, -450); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_6, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 611, -426); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_7, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 588, -370); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_8, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 611, -313); + ROCKLOC(ZR_ROCK, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2044, -786); + ROCKLOC(ZR_UNDERWATER_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2425, -446); + ROCKLOC(ZR_UNDERWATER_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2425, -524); + ROCKLOC(ZR_UNDERWATER_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2503, -571); + ROCKLOC(ZR_UNDERWATER_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2550, -415); + + // 5 rocks by dc + ROCKLOC(DMT_ROCK_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1816, -513); + ROCKLOC(DMT_ROCK_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1831, -614); + ROCKLOC(DMT_ROCK_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1857, -536); + ROCKLOC(DMT_ROCK_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1878, -465); + ROCKLOC(DMT_ROCK_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1787, -550); + // child only + ROCKLOC(DMT_SUMMIT_ROCK, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -327, -4286); + // ring in front of gc + ROCKLOC(DMT_CIRCLE_ROCK_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -383, -1126); + ROCKLOC(DMT_CIRCLE_ROCK_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -326, -1149); + ROCKLOC(DMT_CIRCLE_ROCK_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -303, -1206); + ROCKLOC(DMT_CIRCLE_ROCK_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -326, -1262); + ROCKLOC(DMT_CIRCLE_ROCK_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -383, -1286); + ROCKLOC(DMT_CIRCLE_ROCK_6, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -439, -1262); + ROCKLOC(DMT_CIRCLE_ROCK_7, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -463, -1206); + ROCKLOC(DMT_CIRCLE_ROCK_8, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -439, -1149); + BOLDLOC(DMT_BOULDER_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -625, -55); + BOLDLOC(DMT_BOULDER_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -808, -59); + BOLDLOC(DMT_BOULDER_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -1060, -51); + BOLDLOC(DMT_COW_BOULDER, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -688, -285); + BOLDLOC(DMT_BRONZE_BOULDER_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1175, -803); + BOLDLOC(DMT_BRONZE_BOULDER_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1948, 1706); + BOLDLOC(DMT_BRONZE_BOULDER_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -2019, 1101); + BOLDLOC(DMT_BRONZE_BOULDER_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1658, -88); + BOLDLOC(DMT_BRONZE_BOULDER_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1753, 445); + BOLDLOC(DMT_BRONZE_BOULDER_6, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1018, 1283); + BOLDLOC(DMT_BRONZE_BOULDER_7, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1986, 727); + BOLDLOC(DMT_BRONZE_BOULDER_8, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, -23, + -3196); + BOLDLOC(DMT_BRONZE_BOULDER_9, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, -343, + -2794); + BOLDLOC(DMT_BRONZE_BOULDER_10, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -154, -2484); + BOLDLOC(DMT_BRONZE_BOULDER_11, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1590, -402); + BOLDLOC(GC_LW_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 416, 1049); + BOLDLOC(GC_LW_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 470, 1031); + BOLDLOC(GC_LW_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 367, 1078); + BOLDLOC(GC_ENTRANCE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -670, 470); + BOLDLOC(GC_ENTRANCE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -607, 419); + BOLDLOC(GC_ENTRANCE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -756, 474); + BOLDLOC(GC_MAZE_SILVER_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1479, -794); + BOLDLOC(GC_MAZE_SILVER_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1478, -855); + BOLDLOC(GC_MAZE_SILVER_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1474, -624); + BOLDLOC(GC_MAZE_SILVER_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1471, -993); + BOLDLOC(GC_MAZE_SILVER_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1467, -1064); + BOLDLOC(GC_MAZE_SILVER_BOULDER_6, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1460, -1121); + BOLDLOC(GC_MAZE_SILVER_BOULDER_7, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1451, -567); + BOLDLOC(GC_MAZE_SILVER_BOULDER_8, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1448, -672); + BOLDLOC(GC_MAZE_SILVER_BOULDER_9, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1440, -1174); + BOLDLOC(GC_MAZE_SILVER_BOULDER_10, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1437, -1342); + BOLDLOC(GC_MAZE_SILVER_BOULDER_11, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1424, -1245); + BOLDLOC(GC_MAZE_SILVER_BOULDER_12, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1424, -609); + BOLDLOC(GC_MAZE_SILVER_BOULDER_13, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1399, -1300); + BOLDLOC(GC_MAZE_SILVER_BOULDER_14, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1394, -654); + BOLDLOC(GC_MAZE_SILVER_BOULDER_15, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1343, -698); + BOLDLOC(GC_MAZE_SILVER_BOULDER_16, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1319, -1086); + BOLDLOC(GC_MAZE_SILVER_BOULDER_17, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1312, -1039); + BOLDLOC(GC_MAZE_SILVER_BOULDER_18, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1306, -837); + BOLDLOC(GC_MAZE_SILVER_BOULDER_19, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1279, -656); + BOLDLOC(GC_MAZE_SILVER_BOULDER_20, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1255, -840); + BOLDLOC(GC_MAZE_SILVER_BOULDER_21, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1246, -1075); + BOLDLOC(GC_MAZE_SILVER_BOULDER_22, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1244, -589); + BOLDLOC(GC_MAZE_SILVER_BOULDER_23, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1210, -852); + BOLDLOC(GC_MAZE_SILVER_BOULDER_24, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1206, -627); + BOLDLOC(GC_MAZE_SILVER_BOULDER_25, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1187, -896); + BOLDLOC(GC_MAZE_SILVER_BOULDER_26, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1157, -954); + BOLDLOC(GC_MAZE_SILVER_BOULDER_27, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1130, -1137); + BOLDLOC(GC_MAZE_SILVER_BOULDER_28, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1120, -1001); + BOLDLOC(GC_MAZE_SILVER_BOULDER_29, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1179, -1098); + BOLDLOC(GC_MAZE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1342, -628); + BOLDLOC(GC_MAZE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1456, -501); + BOLDLOC(GC_MAZE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1233, -511); + BOLDLOC(GC_MAZE_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1137, -657); + BOLDLOC(GC_MAZE_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1124, -913); + BOLDLOC(GC_MAZE_BOULDER_6, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1326, -771); + BOLDLOC(GC_MAZE_BOULDER_7, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1469, -737); + BOLDLOC(GC_MAZE_BOULDER_8, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1476, -921); + BOLDLOC(GC_MAZE_BOULDER_9, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1391, -1087); + BOLDLOC(GC_MAZE_BOULDER_10, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1222, -997); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1541, -631); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -861); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -1102); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1534, -752); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -991); + ROCKLOC(GC_MAZE_ROCK, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_ROCK, -1197, -1329); + BOLDLOC(COLOSSUS_SILVER_BOULDER, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_SILVER_BOULDER, 61, + -1301); + ROCKLOC(COLOSSUS_ROCK, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, 1537, 667); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_1, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -250, -1272); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_2, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -193, -1295); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_3, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -170, -1352); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_4, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -193, -1408); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_5, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -250, -1432); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_6, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -306, -1408); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_7, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -330, -1352); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_8, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -306, -1295); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_1, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -834, -766); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_2, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -777, -789); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_3, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -754, -846); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_4, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -777, -902); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_5, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -834, -926); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_6, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -890, -902); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_7, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -914, -846); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_8, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -890, -789); + ROCKLOC(HC_STORMS_GROTTO_ROCK_1, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1811, 813); + ROCKLOC(HC_STORMS_GROTTO_ROCK_2, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1867, 789); + ROCKLOC(HC_STORMS_GROTTO_ROCK_3, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1891, 733); + ROCKLOC(HC_STORMS_GROTTO_ROCK_4, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1867, 676); + ROCKLOC(HC_STORMS_GROTTO_ROCK_5, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1811, 653); + ROCKLOC(HC_STORMS_GROTTO_ROCK_6, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1754, 676); + ROCKLOC(HC_STORMS_GROTTO_ROCK_7, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1731, 733); + ROCKLOC(HC_STORMS_GROTTO_ROCK_8, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1754, 789); + locationTable[RC_BOTW_BOULDER_1] = + Location::Boulder(RC_BOTW_BOULDER_1, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(-684, -734), "BOTW Boulder 1", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_1)); + locationTable[RC_BOTW_BOULDER_2] = + Location::Boulder(RC_BOTW_BOULDER_2, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(-632, -805), "BOTW Boulder 2", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_2)); + locationTable[RC_BOTW_BOULDER_3] = + Location::Boulder(RC_BOTW_BOULDER_3, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(333, -681), "BOTW Boulder 3", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_3)); + locationTable[RC_BOTW_BOULDER_4] = + Location::Boulder(RC_BOTW_BOULDER_4, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(409, -637), "BOTW Boulder 4", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_4)); + locationTable[RC_BOTW_BOULDER_5] = + Location::Boulder(RC_BOTW_BOULDER_5, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(334, -8), "BOTW Boulder 5", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_5)); + locationTable[RC_BOTW_BOULDER_6] = + Location::Boulder(RC_BOTW_BOULDER_6, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(312, 64), "BOTW Boulder 6", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_6)); +#define MQBOLD(id, area, hint, x, z) \ + (locationTable[RC_##id] = \ + Location::Boulder(RC_##id, RCQUEST_MQ, RCAREA_##area, SCENE_##area, TWO_ACTOR_PARAMS(x, z), #id, hint, \ + SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) + MQBOLD(DEKU_TREE_MQ_BOULDER_1, DEKU_TREE, RHT_DEKU_BOULDER, -1237, 1558); + MQBOLD(DEKU_TREE_MQ_BOULDER_2, DEKU_TREE, RHT_DEKU_BOULDER, -1183, 1522); + MQBOLD(DEKU_TREE_MQ_BOULDER_3, DEKU_TREE, RHT_DEKU_BOULDER, -1129, 1469); + MQBOLD(DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, -435, -1720); + MQBOLD(DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 432, -1719); + MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 807, -874); + MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 802, -972); + MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 783, -923); + MQBOLD(DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 2464, -402); + MQBOLD(DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 2942, -495); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4219, -1651); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4178, -1602); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4162, -1581); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4133, -1561); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4091, -1510); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4067, -1487); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4028, -1472); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3965, -1473); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3898, -1467); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3832, -1437); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3799, -1383); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3760, -1318); + locationTable[RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER] = + Location::Boulder(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-1, -296), "RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(350, -3533), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-192, -3211), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(245, -2792), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(220, -2790), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(274, -2790), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3)); + locationTable[RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(31, -5177), "RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-37, -5173), "RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-885, -5907), "RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER)); + locationTable[RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-411, -5682), "RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER)); + // skip spirit temple boulder, so adult can clear without collecting check for child to pass + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, -160, 270); + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 160, 270); + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 350, 220); + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 0, -60); + MQBOLD(SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 1070, -290); + MQBOLD(BOTW_MQ_BOULDER_1, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -370, -160); + MQBOLD(BOTW_MQ_BOULDER_2, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -521, -353); + MQBOLD(BOTW_MQ_BOULDER_3, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -541, -404); +} + +static RegisterShipInitFunc initFunc2(Rando::StaticData::RegisterRockLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleRocks.h b/soh/soh/Enhancements/randomizer/ShuffleRocks.h new file mode 100644 index 00000000000..ad7ea4d7a83 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleRocks.h @@ -0,0 +1,15 @@ +#ifndef SHUFFLEROCKS_H +#define SHUFFLEROCKS_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +void EnIshi_RandomizerInit(void* actorRef); +#ifdef __cplusplus +}; +#endif + +#endif // SHUFFLEROCKS_H \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp new file mode 100644 index 00000000000..17866b0f8f1 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -0,0 +1,249 @@ +#include +#include "soh_assets.h" +#include "static_data.h" + +extern "C" { +#include "variables.h" +#include "src/overlays/actors/ovl_En_Wood02/z_en_wood02.h" +#include "objects/object_wood02/object_wood02.h" +#include "soh/Enhancements/enhancementTypes.h" +extern PlayState* gPlayState; +void EnWood02_Draw(Actor*, PlayState*); +} + +static Gfx* D_80B3BF54[] = { + (Gfx*)object_wood02_DL_0078D0, (Gfx*)object_wood02_DL_007CA0, (Gfx*)object_wood02_DL_0080D0, + (Gfx*)object_wood02_DL_000090, (Gfx*)object_wood02_DL_000340, (Gfx*)object_wood02_DL_000340, + (Gfx*)object_wood02_DL_000700, +}; + +static Gfx* D_80B3BF70[] = { + (Gfx*)object_wood02_DL_007968, + (Gfx*)object_wood02_DL_007D38, + (Gfx*)object_wood02_DL_0081A8, + NULL, + NULL, + NULL, + (Gfx*)object_wood02_DL_007AD0, + (Gfx*)object_wood02_DL_007E20, + (Gfx*)object_wood02_DL_008350, + (Gfx*)object_wood02_DL_000160, + (Gfx*)object_wood02_DL_000440, + (Gfx*)object_wood02_DL_000700, +}; + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + +uint8_t EnWood02_RandomizerHoldsItem(EnWood02* treeActor, PlayState* play) { + // Don't pull randomized item if tree isn't randomized or is already checked + return IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get() && + !Flags_GetRandomizerInf(treeActor->treeId.randomizerInf) && + treeActor->treeId.randomizerCheck != RC_UNKNOWN_CHECK; +} + +extern "C" void EnWood02_RandomizerDraw(Actor* thisx, PlayState* play) { + GetItemCategory getItemCategory; + auto treeActor = (EnWood02*)thisx; + int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); + + int isVanilla = + csmc == CSMC_DISABLED || csmc == CSMC_SIZE || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); + + if (isVanilla || treeActor->treeId.randomizerCheck == RC_UNKNOWN_CHECK) { + return; + } + + GetItemEntry smallCrateItem = + Rando::Context::GetInstance()->GetFinalGIEntry(treeActor->treeId.randomizerCheck, true, GI_NONE); + getItemCategory = smallCrateItem.getItemCategory; + + // If they have bombchus, don't consider the bombchu item major + if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU && + ((smallCrateItem.modIndex == MOD_RANDOMIZER && smallCrateItem.getItemId == RG_PROGRESSIVE_BOMBCHUS) || + (smallCrateItem.modIndex == MOD_NONE && + (smallCrateItem.getItemId == GI_BOMBCHUS_5 || smallCrateItem.getItemId == GI_BOMBCHUS_10 || + smallCrateItem.getItemId == GI_BOMBCHUS_20)))) { + getItemCategory = ITEM_CATEGORY_JUNK; + // If it's a bottle and they already have one, consider the item lesser + } else if ((smallCrateItem.modIndex == MOD_RANDOMIZER && smallCrateItem.getItemId >= RG_BOTTLE_WITH_RED_POTION && + smallCrateItem.getItemId <= RG_BOTTLE_WITH_POE) || + (smallCrateItem.modIndex == MOD_NONE && + (smallCrateItem.getItemId == GI_BOTTLE || smallCrateItem.getItemId == GI_MILK_BOTTLE))) { + if (gSaveContext.inventory.items[SLOT_BOTTLE_1] != ITEM_NONE) { + getItemCategory = ITEM_CATEGORY_LESSER; + } + } + + GraphicsContext* gfxCtx = play->state.gfxCtx; + OPEN_DISPS(gfxCtx); + Matrix_Push(); + + // Change texture + switch (getItemCategory) { + case ITEM_CATEGORY_MAJOR: + Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY); + Gfx_DrawDListOpa(play, (Gfx*)gSmallMajorCrateDL); + break; + case ITEM_CATEGORY_SKULLTULA_TOKEN: + Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY); + Gfx_DrawDListOpa(play, (Gfx*)gSmallTokenCrateDL); + break; + case ITEM_CATEGORY_SMALL_KEY: + Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY); + Gfx_DrawDListOpa(play, (Gfx*)gSmallSmallKeyCrateDL); + break; + case ITEM_CATEGORY_BOSS_KEY: + Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY); + Gfx_DrawDListOpa(play, (Gfx*)gSmallBossKeyCrateDL); + break; + case ITEM_CATEGORY_LESSER: + Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY); + switch (smallCrateItem.itemId) { + case ITEM_HEART_PIECE: + case ITEM_HEART_PIECE_2: + case ITEM_HEART_CONTAINER: + Gfx_DrawDListOpa(play, (Gfx*)gSmallHeartCrateDL); + break; + default: + Gfx_DrawDListOpa(play, (Gfx*)gSmallMinorCrateDL); + break; + } + case ITEM_CATEGORY_JUNK: + default: + Matrix_Scale(0.04, 0.02, 0.04, MTXMODE_APPLY); + Gfx_DrawDListOpa(play, (Gfx*)gLargeJunkCrateDL); + break; + } + + Matrix_Pop(); + CLOSE_DISPS(gfxCtx); +} + +void EnWood02_RandomizerSpawnCollectible(EnWood02* treeActor, PlayState* play) { + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &treeActor->actor.world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = treeActor->treeId.randomizerInf; + item00->itemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(treeActor->treeId.randomizerCheck, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + item00->actor.velocity.y = 0.0f; + item00->actor.world.pos.y += 120.0f; + item00->actor.speedXZ = 2.0f; + item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f); + // clear randomizerCheck to prevent multiple bonks, + // reloading area without collecting drop won't persist this + treeActor->treeId.randomizerCheck = RC_UNKNOWN_CHECK; +} + +void EnWood02_RandomizerInit(void* actorRef) { + EnWood02* treeActor = static_cast(actorRef); + if (treeActor->actor.params <= WOOD_TREE_KAKARIKO_ADULT) { + treeActor->treeId = OTRGlobals::Instance->gRandomizer->IdentifyTree( + gPlayState->sceneNum, (s16)treeActor->actor.world.pos.x, (s16)treeActor->actor.world.pos.z); + } +} + +void RegisterShuffleTrees() { + bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get(); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_WOOD02, shouldRegister, EnWood02_RandomizerInit); + + COND_VB_SHOULD(VB_TREE_SETUP_DRAW, shouldRegister, { + EnWood02* treeActor = va_arg(args, EnWood02*); + if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) { + EnWood02_RandomizerDraw(&treeActor->actor, gPlayState); + } + }); + + COND_VB_SHOULD(VB_TREE_DROP_ITEM, shouldRegister, { + EnWood02* treeActor = va_arg(args, EnWood02*); + if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) { + EnWood02_RandomizerSpawnCollectible(treeActor, gPlayState); + // QoL, drop golden skulltula alongside item + if ((treeActor->unk_14C < 0 || treeActor->unk_14C >= 0x64) && treeActor->actor.home.rot.z != 0) { + Vec3f dropsSpawnPt = treeActor->actor.world.pos; + dropsSpawnPt.y += 200.0f; + treeActor->actor.home.rot.z &= 0x1FFF; + treeActor->actor.home.rot.z |= 0xE000; + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y, + dropsSpawnPt.z, 0, treeActor->actor.world.rot.y, 0, treeActor->actor.home.rot.z, true); + treeActor->actor.home.rot.z = 0; + } + *should = false; + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterShuffleTrees, { "IS_RANDO" }); + +void Rando::StaticData::RegisterTreeLocations() { + // clang-format off + // Trees + // Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Vanilla Spoiler Collection Check + locationTable[RC_MARKET_TREE] = Location::Tree(RC_MARKET_TREE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_DAY, TWO_ACTOR_PARAMS(-100, 240), "Tree in Hyrule Market", RHT_TREE_MARKET, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREE)); + locationTable[RC_HC_NEAR_GUARDS_TREE_1] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1209, 2242), "Tree Near Guards 1", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_1)); + locationTable[RC_HC_NEAR_GUARDS_TREE_2] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(943, 2051), "Tree Near Guards 2", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_2)); + locationTable[RC_HC_NEAR_GUARDS_TREE_3] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(827, 1428), "Tree Near Guards 3", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_3)); + locationTable[RC_HC_NEAR_GUARDS_TREE_4] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(421, 1397), "Tree Near Guards 4", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_4)); + locationTable[RC_HC_NEAR_GUARDS_TREE_5] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-73, 1459), "Tree Near Guards 5", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_5)); + locationTable[RC_HC_NEAR_GUARDS_TREE_6] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1494, 2108), "Tree Near Guards 6", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_6)); + locationTable[RC_HC_SKULLTULA_TREE] = Location::Tree(RC_HC_SKULLTULA_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-145, 2961), "HC GS Tree", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_SKULLTULA_TREE)); + locationTable[RC_HC_GROTTO_TREE] = Location::Tree(RC_HC_GROTTO_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(924, 872), "Tree Near Storms Grotto", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_GROTTO_TREE)); + locationTable[RC_HC_NL_TREE_1] = Location::NLTree(RC_HC_NL_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-331, 1438), "NL Tree Near Guards 1", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NL_TREE_1)); + locationTable[RC_HC_NL_TREE_2] = Location::NLTree(RC_HC_NL_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1022, 1444), "NL Tree Near Guards 2", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NL_TREE_2)); + locationTable[RC_HF_NEAR_KAK_TREE] = Location::Tree(RC_HF_NEAR_KAK_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3276, 971), "Tree Outside Kakariko", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_KAK_TREE)); + locationTable[RC_HF_NEAR_KAK_SMALL_TREE] = Location::Tree(RC_HF_NEAR_KAK_SMALL_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2076, -91), "Small Tree Outside Kakariko", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_KAK_SMALL_TREE)); + locationTable[RC_HF_NEAR_MARKET_TREE_1] = Location::Tree(RC_HF_NEAR_MARKET_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1041, 1022), "Tree Near HC Entrance Grotto 1", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_1)); + locationTable[RC_HF_NEAR_MARKET_TREE_2] = Location::Tree(RC_HF_NEAR_MARKET_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1244, 819), "Tree Near HC Entrance Grotto 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_2)); + locationTable[RC_HF_NEAR_MARKET_TREE_3] = Location::Tree(RC_HF_NEAR_MARKET_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1448, 620), "Tree Near HC Entrance Grotto 3", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_3)); + locationTable[RC_HF_NEAR_LLR_TREE] = Location::Tree(RC_HF_NEAR_LLR_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1907, 5409), "Tree Outside Lon Lon Ranch", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_LLR_TREE)); + locationTable[RC_HF_NEAR_LH_TREE] = Location::Tree(RC_HF_NEAR_LH_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4377, 13662), "Tree Outside Lake Hylia", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_LH_TREE)); + locationTable[RC_HF_CHILD_NEAR_GV_TREE] = Location::Tree(RC_HF_CHILD_NEAR_GV_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6270, 8579), "Child Near Gerudo Valley Tree", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NEAR_GV_TREE)); + locationTable[RC_HF_ADULT_NEAR_GV_TREE] = Location::Tree(RC_HF_ADULT_NEAR_GV_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6241, 7097), "Adult Near Gerudo Valley Tree", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ADULT_NEAR_GV_TREE)); + locationTable[RC_HF_NEAR_ZR_TREE] = Location::Tree(RC_HF_NEAR_ZR_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3117, 4239), "Tree Outside Zora's River", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_ZR_TREE)); + locationTable[RC_HF_NORTHWEST_TREE_1] = Location::Tree(RC_HF_NORTHWEST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4777, 136), "Tree in Northwest 1", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_1)); + locationTable[RC_HF_NORTHWEST_TREE_2] = Location::Tree(RC_HF_NORTHWEST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4188, 263), "Tree in Northwest 2", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_2)); + locationTable[RC_HF_NORTHWEST_TREE_3] = Location::Tree(RC_HF_NORTHWEST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5000, -147), "Tree in Northwest 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_3)); + locationTable[RC_HF_NORTHWEST_TREE_4] = Location::Tree(RC_HF_NORTHWEST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4463, -182), "Tree in Northwest 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_4)); + locationTable[RC_HF_NORTHWEST_TREE_5] = Location::Tree(RC_HF_NORTHWEST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5262, 398), "Tree in Northwest 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_5)); + locationTable[RC_HF_NORTHWEST_TREE_6] = Location::Tree(RC_HF_NORTHWEST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4391, 891), "Tree in Northwest 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_6)); + locationTable[RC_HF_EAST_TREE_1] = Location::Tree(RC_HF_EAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3817, 7119), "Tree in East 1", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_1)); + locationTable[RC_HF_EAST_TREE_2] = Location::Tree(RC_HF_EAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(4365, 7182), "Tree in East 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_2)); + locationTable[RC_HF_EAST_TREE_3] = Location::Tree(RC_HF_EAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3837, 7479), "Tree in East 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_3)); + locationTable[RC_HF_EAST_TREE_4] = Location::Tree(RC_HF_EAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3377, 7201), "Tree in East 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_4)); + locationTable[RC_HF_EAST_TREE_5] = Location::Tree(RC_HF_EAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3408, 6676), "Tree in East 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_5)); + locationTable[RC_HF_EAST_TREE_6] = Location::Tree(RC_HF_EAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3935, 6279), "Tree in East 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_6)); + locationTable[RC_HF_SOUTHEAST_TREE_1] = Location::Tree(RC_HF_SOUTHEAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(915, 12557), "Tree in Southeast 1", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_1)); + locationTable[RC_HF_SOUTHEAST_TREE_2] = Location::Tree(RC_HF_SOUTHEAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(350, 11605), "Tree in Southeast 2", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_2)); + locationTable[RC_HF_SOUTHEAST_TREE_3] = Location::Tree(RC_HF_SOUTHEAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(470, 12494), "Tree in Southeast 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_3)); + locationTable[RC_HF_SOUTHEAST_TREE_4] = Location::Tree(RC_HF_SOUTHEAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(614, 12357), "Tree in Southeast 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_4)); + locationTable[RC_HF_SOUTHEAST_TREE_5] = Location::Tree(RC_HF_SOUTHEAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1114, 12156), "Tree in Southeast 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_5)); + locationTable[RC_HF_SOUTHEAST_TREE_6] = Location::Tree(RC_HF_SOUTHEAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(549, 11204), "Tree in Southeast 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_6)); + locationTable[RC_HF_SOUTHEAST_TREE_7] = Location::Tree(RC_HF_SOUTHEAST_TREE_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(49, 11405), "Tree in Southeast 7", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_7)); + locationTable[RC_HF_SOUTHEAST_TREE_8] = Location::Tree(RC_HF_SOUTHEAST_TREE_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-29, 12005), "Tree in Southeast 8", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_8)); + locationTable[RC_HF_SOUTHEAST_TREE_9] = Location::Tree(RC_HF_SOUTHEAST_TREE_9, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1514,13157), "Tree in Southeast 9", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_9)); + locationTable[RC_HF_SOUTHEAST_TREE_10] = Location::Tree(RC_HF_SOUTHEAST_TREE_10, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-509,12954), "Tree in Southeast 10", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_10)); + locationTable[RC_HF_SOUTHEAST_TREE_11] = Location::Tree(RC_HF_SOUTHEAST_TREE_11, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-430,12354), "Tree in Southeast 11", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_11)); + locationTable[RC_HF_SOUTHEAST_TREE_12] = Location::Tree(RC_HF_SOUTHEAST_TREE_12, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(69,12153), "Tree in Southeast 12", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_12)); + locationTable[RC_HF_SOUTHEAST_TREE_13] = Location::Tree(RC_HF_SOUTHEAST_TREE_13, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-129,12554), "Tree in Southeast 13", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_13)); + locationTable[RC_HF_SOUTHEAST_TREE_14] = Location::Tree(RC_HF_SOUTHEAST_TREE_14, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(950,11545), "Tree in Southeast 14", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_14)); + locationTable[RC_HF_SOUTHEAST_TREE_15] = Location::Tree(RC_HF_SOUTHEAST_TREE_15, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(949,12205), "Tree in Southeast 15", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_15)); + locationTable[RC_HF_SOUTHEAST_TREE_16] = Location::Tree(RC_HF_SOUTHEAST_TREE_16, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(469,13154), "Tree in Southeast 16", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_16)); + locationTable[RC_HF_SOUTHEAST_TREE_17] = Location::Tree(RC_HF_SOUTHEAST_TREE_17, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(535,12957), "Tree in Southeast 17", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_17)); + locationTable[RC_HF_SOUTHEAST_TREE_18] = Location::Tree(RC_HF_SOUTHEAST_TREE_18, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1515,12497), "Tree in Southeast 18", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_18)); + locationTable[RC_HF_SOUTHEAST_TREE_19] = Location::Tree(RC_HF_SOUTHEAST_TREE_19, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-786,11293), "Tree in Southeast 19", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_19)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_1] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1535, 11943), "Child Tree in Southeast Corner 1", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_1)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_2] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2135,11883), "Child Tree in Southeast Corner 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_2)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_3] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2134,12543), "Child Tree in Southeast Corner 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_3)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_4] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1734,11542), "Child Tree in Southeast Corner 4", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_4)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_5] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1234,11743), "Child Tree in Southeast Corner 5", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_5)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_6] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1155,12343), "Child Tree in Southeast Corner 6", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_6)); + locationTable[RC_HF_TEKTITE_GROTTO_TREE] = Location::Tree(RC_HF_TEKTITE_GROTTO_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4976, 2812), "Tektite Grotto Tree", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_TEKTITE_GROTTO_TREE)); + locationTable[RC_ZF_TREE] = Location::Tree(RC_ZF_TREE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(186, 2222), "Tree in Zora's Fountain", RHT_TREE_ZORAS_FOUNTAIN, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_TREE)); + locationTable[RC_ZR_TREE] = Location::Tree(RC_ZR_TREE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1690, 554), "Tree in Zoras River", RHT_TREE_ZORAS_RIVER, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_TREE)); + locationTable[RC_KAK_TREE] = Location::Tree(RC_KAK_TREE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-860, 522), "Kakariko GS Tree", RHT_TREE_KAKARIKO, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_TREE)); + locationTable[RC_LLR_TREE] = Location::Tree(RC_LLR_TREE, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(1309, -2241), "Lon Lon Ranch GS Tree", RHT_TREE_LON_LON_RANCH, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TREE)); + // clang-format on +} + +static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterTreeLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index 2ee39006d0b..84c1b400795 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -47,6 +47,8 @@ Context::Context() { &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_ROCKS], + &mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], @@ -189,9 +191,14 @@ void Context::GenerateLocationPool() { (location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_OFF)) || (location.GetRCType() == RCTYPE_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) || (location.GetRCType() == RCTYPE_NLCRATE && (mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF) || - !mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC))) || + mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) || (location.GetRCType() == RCTYPE_SMALL_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) || + (location.GetRCType() == RCTYPE_ROCK && !mOptions[RSK_SHUFFLE_ROCKS]) || + (location.GetRCType() == RCTYPE_BOULDER && mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_OFF)) || (location.GetRCType() == RCTYPE_FAIRY && !mOptions[RSK_SHUFFLE_FAIRIES]) || + (location.GetRCType() == RCTYPE_TREE && !mOptions[RSK_SHUFFLE_TREES]) || + (location.GetRCType() == RCTYPE_NLTREE && + (!mOptions[RSK_SHUFFLE_TREES] || mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) || (location.GetRCType() == RCTYPE_FREESTANDING && mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) || (location.GetRCType() == RCTYPE_BEEHIVE && !mOptions[RSK_SHUFFLE_BEEHIVES])) { @@ -209,7 +216,9 @@ void Context::GenerateLocationPool() { mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS) && mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC)) || (location.GetRCType() == RCTYPE_SMALL_CRATE && - mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS))) { + mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS)) && + (location.GetRCType() == RCTYPE_BOULDER && + mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_DUNGEONS))) { continue; } // If we've gotten past all the conditions where an overworld location should not be @@ -230,7 +239,9 @@ void Context::GenerateLocationPool() { mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD) && mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC)) || (location.GetRCType() == RCTYPE_SMALL_CRATE && - mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD))) { + mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD)) && + (location.GetRCType() == RCTYPE_BOULDER && + mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_OVERWORLD))) { continue; } // also add to that dungeon's location list. diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index b9cc0b10b38..73dd4e046e9 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -963,11 +963,16 @@ extern "C" void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry* getItemEn Matrix_ReplaceRotation(&play->billboardMtxF); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); - gDPSetGrayscaleColor(POLY_XLU_DISP++, flameColors[slot][0], flameColors[slot][1], flameColors[slot][2], 255); + if (slot >= 0 && slot < 9) { + gDPSetGrayscaleColor(POLY_XLU_DISP++, flameColors[slot][0], flameColors[slot][1], flameColors[slot][2], 255); + } else { + gDPSetGrayscaleColor(POLY_XLU_DISP++, 255, 255, 255, 255); + } gSPGrayscale(POLY_XLU_DISP++, true); gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiBlueFireFlameDL); gSPGrayscale(POLY_XLU_DISP++, false); Matrix_Pop(); + CLOSE_DISPS(play->state.gfxCtx); // Draw the generic boss soul model diff --git a/soh/soh/Enhancements/randomizer/entrance.cpp b/soh/soh/Enhancements/randomizer/entrance.cpp index 00a7a5adbf5..114106a5402 100644 --- a/soh/soh/Enhancements/randomizer/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/entrance.cpp @@ -264,8 +264,8 @@ void SetAllEntrancesData() { { EntranceType::Dungeon, RR_JABU_JABUS_BELLY_ENTRYWAY, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_JABU_JABU } }, { { EntranceType::Dungeon, RR_SACRED_FOREST_MEADOW, RR_FOREST_TEMPLE_ENTRYWAY, ENTR_FOREST_TEMPLE_ENTRANCE }, { EntranceType::Dungeon, RR_FOREST_TEMPLE_ENTRYWAY, RR_SACRED_FOREST_MEADOW, ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE } }, - { { EntranceType::Dungeon, RR_DMC_CENTRAL_LOCAL, RR_FIRE_TEMPLE_ENTRYWAY, ENTR_FIRE_TEMPLE_ENTRANCE }, - { EntranceType::Dungeon, RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_CENTRAL_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE } }, + { { EntranceType::Dungeon, RR_DMC_OUTSIDE_FIRE_TEMPLE, RR_FIRE_TEMPLE_ENTRYWAY, ENTR_FIRE_TEMPLE_ENTRANCE }, + { EntranceType::Dungeon, RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_OUTSIDE_FIRE_TEMPLE, ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE } }, { { EntranceType::Dungeon, RR_LH_FROM_WATER_TEMPLE, RR_WATER_TEMPLE_ENTRYWAY, ENTR_WATER_TEMPLE_ENTRANCE }, { EntranceType::Dungeon, RR_WATER_TEMPLE_ENTRYWAY, RR_LH_FROM_WATER_TEMPLE, ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE } }, { { EntranceType::Dungeon, RR_DESERT_COLOSSUS, RR_SPIRIT_TEMPLE_ENTRYWAY, ENTR_SPIRIT_TEMPLE_ENTRANCE }, @@ -356,8 +356,8 @@ void SetAllEntrancesData() { { { EntranceType::Interior, RR_ZORAS_FOUNTAIN, RR_ZF_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF }, { EntranceType::Interior, RR_ZF_GREAT_FAIRY_FOUNTAIN, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY } }, - { { EntranceType::SpecialInterior, RR_KOKIRI_FOREST, RR_KF_LINKS_HOUSE, ENTR_LINKS_HOUSE_1 }, - { EntranceType::SpecialInterior, RR_KF_LINKS_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE } }, + { { EntranceType::SpecialInterior, RR_KF_LINKS_PORCH, RR_KF_LINKS_HOUSE, ENTR_LINKS_HOUSE_1 }, + { EntranceType::SpecialInterior, RR_KF_LINKS_HOUSE, RR_KF_LINKS_PORCH, ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE } }, { { EntranceType::SpecialInterior, RR_TOT_ENTRANCE, RR_TEMPLE_OF_TIME, ENTR_TEMPLE_OF_TIME_ENTRANCE }, { EntranceType::SpecialInterior, RR_TEMPLE_OF_TIME, RR_TOT_ENTRANCE, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_OUTSIDE_TEMPLE } }, { { EntranceType::SpecialInterior, RR_KAKARIKO_VILLAGE, RR_KAK_WINDMILL, ENTR_WINDMILL_AND_DAMPES_GRAVE_WINDMILL }, @@ -377,10 +377,10 @@ void SetAllEntrancesData() { { EntranceType::GrottoGrave, RR_LH_GROTTO, RR_LAKE_HYLIA, ENTRANCE_GROTTO_EXIT(GROTTO_LH_OFFSET) } }, { { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_STORMS_OFFSET) }, { EntranceType::GrottoGrave, RR_ZR_STORMS_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_STORMS_OFFSET) } }, - { { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_FAIRY_OFFSET) }, - { EntranceType::GrottoGrave, RR_ZR_FAIRY_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_FAIRY_OFFSET) } }, - { { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_OPEN_OFFSET) }, - { EntranceType::GrottoGrave, RR_ZR_OPEN_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_OPEN_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_ZR_UPPER_GROTTOS, RR_ZR_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_FAIRY_OFFSET) }, + { EntranceType::GrottoGrave, RR_ZR_FAIRY_GROTTO, RR_ZR_UPPER_GROTTOS, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_FAIRY_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_ZR_UPPER_GROTTOS, RR_ZR_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_OPEN_OFFSET) }, + { EntranceType::GrottoGrave, RR_ZR_OPEN_GROTTO, RR_ZR_UPPER_GROTTOS, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_OPEN_OFFSET) } }, { { EntranceType::GrottoGrave, RR_DMC_LOWER_NEARBY, RR_DMC_HAMMER_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET) }, { EntranceType::GrottoGrave, RR_DMC_HAMMER_GROTTO, RR_DMC_LOWER_LOCAL, ENTRANCE_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET) } }, { { EntranceType::GrottoGrave, RR_DMC_UPPER_NEARBY, RR_DMC_UPPER_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMC_UPPER_OFFSET) }, @@ -389,14 +389,14 @@ void SetAllEntrancesData() { { EntranceType::GrottoGrave, RR_GC_GROTTO, RR_GC_GROTTO_PLATFORM, ENTRANCE_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET) } }, { { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_TRAIL, RR_DMT_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_STORMS_OFFSET) }, { EntranceType::GrottoGrave, RR_DMT_STORMS_GROTTO, RR_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_STORMS_OFFSET) } }, - { { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMT_COW_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_COW_OFFSET) }, - { EntranceType::GrottoGrave, RR_DMT_COW_GROTTO, RR_DEATH_MOUNTAIN_SUMMIT, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_COW_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_AVALANCHE, RR_DMT_COW_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_COW_OFFSET) }, + { EntranceType::GrottoGrave, RR_DMT_COW_GROTTO, RR_DEATH_MOUNTAIN_AVALANCHE, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_COW_OFFSET) } }, { { EntranceType::GrottoGrave, RR_KAK_BACKYARD, RR_KAK_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KAK_OPEN_OFFSET) }, { EntranceType::GrottoGrave, RR_KAK_OPEN_GROTTO, RR_KAK_BACKYARD, ENTRANCE_GROTTO_EXIT(GROTTO_KAK_OPEN_OFFSET) } }, { { EntranceType::GrottoGrave, RR_KAKARIKO_VILLAGE, RR_KAK_REDEAD_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KAK_REDEAD_OFFSET) }, { EntranceType::GrottoGrave, RR_KAK_REDEAD_GROTTO, RR_KAKARIKO_VILLAGE, ENTRANCE_GROTTO_EXIT(GROTTO_KAK_REDEAD_OFFSET) } }, - { { EntranceType::GrottoGrave, RR_HYRULE_CASTLE_GROUNDS, RR_HC_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET) }, - { EntranceType::GrottoGrave, RR_HC_STORMS_GROTTO, RR_CASTLE_GROUNDS, ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_HC_MOAT, RR_HC_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET) }, + { EntranceType::GrottoGrave, RR_HC_STORMS_GROTTO, RR_HC_MOAT, ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET) } }, { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_TEKTITE_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_TEKTITE_OFFSET) }, { EntranceType::GrottoGrave, RR_HF_TEKTITE_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_TEKTITE_OFFSET) } }, { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_NEAR_KAK_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_KAK_OFFSET) }, @@ -419,14 +419,14 @@ void SetAllEntrancesData() { { EntranceType::GrottoGrave, RR_SFM_WOLFOS_GROTTO, RR_SFM_ENTRYWAY, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_WOLFOS_OFFSET) } }, { { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_STORMS_OFFSET) }, { EntranceType::GrottoGrave, RR_SFM_STORMS_GROTTO, RR_SACRED_FOREST_MEADOW, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_STORMS_OFFSET) } }, - { { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_FAIRY_OFFSET) }, - { EntranceType::GrottoGrave, RR_SFM_FAIRY_GROTTO, RR_SACRED_FOREST_MEADOW, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_FAIRY_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_SFM_OUTSIDE_FAIRY_GROTTO, RR_SFM_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_FAIRY_OFFSET) }, + { EntranceType::GrottoGrave, RR_SFM_FAIRY_GROTTO, RR_SFM_OUTSIDE_FAIRY_GROTTO, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_FAIRY_OFFSET) } }, { { EntranceType::GrottoGrave, RR_LW_BEYOND_MIDO, RR_LW_SCRUBS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET) }, { EntranceType::GrottoGrave, RR_LW_SCRUBS_GROTTO, RR_LW_BEYOND_MIDO, ENTRANCE_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET) } }, { { EntranceType::GrottoGrave, RR_THE_LOST_WOODS, RR_LW_NEAR_SHORTCUTS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) }, { EntranceType::GrottoGrave, RR_LW_NEAR_SHORTCUTS_GROTTO, RR_THE_LOST_WOODS, ENTRANCE_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) } }, - { { EntranceType::GrottoGrave, RR_KOKIRI_FOREST, RR_KF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET) }, - { EntranceType::GrottoGrave, RR_KF_STORMS_GROTTO, RR_KOKIRI_FOREST, ENTRANCE_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_KF_OUTSIDE_LOST_WOODS, RR_KF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET) }, + { EntranceType::GrottoGrave, RR_KF_STORMS_GROTTO, RR_KF_OUTSIDE_LOST_WOODS, ENTRANCE_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET) } }, { { EntranceType::GrottoGrave, RR_ZORAS_DOMAIN_ISLAND, RR_ZD_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZD_STORMS_OFFSET) }, { EntranceType::GrottoGrave, RR_ZD_STORMS_GROTTO, RR_ZORAS_DOMAIN_ISLAND, ENTRANCE_GROTTO_EXIT(GROTTO_ZD_STORMS_OFFSET) } }, { { EntranceType::GrottoGrave, RR_GF_NEAR_GROTTO, RR_GF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GF_STORMS_OFFSET) }, @@ -450,8 +450,8 @@ void SetAllEntrancesData() { { { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_LW_BRIDGE_FROM_FOREST, ENTR_LOST_WOODS_BRIDGE_EAST_EXIT }, { EntranceType::Overworld, RR_LW_BRIDGE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_LOWER_EXIT } }, - { { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_SOUTH_EXIT }, - { EntranceType::Overworld, RR_LW_FOREST_EXIT, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_UPPER_EXIT } }, + { { EntranceType::Overworld, RR_KF_OUTSIDE_LOST_WOODS, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_SOUTH_EXIT }, + { EntranceType::Overworld, RR_LW_FOREST_EXIT, RR_KF_OUTSIDE_LOST_WOODS, ENTR_KOKIRI_FOREST_UPPER_EXIT } }, { { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_GC_WOODS_WARP, ENTR_GORON_CITY_TUNNEL_SHORTCUT }, { EntranceType::Overworld, RR_GC_WOODS_WARP, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_TUNNEL_SHORTCUT } }, { { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_ZR_FROM_SHORTCUT, ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT }, @@ -460,8 +460,8 @@ void SetAllEntrancesData() { { EntranceType::Overworld, RR_SFM_ENTRYWAY, RR_LW_BEYOND_MIDO, ENTR_LOST_WOODS_NORTH_EXIT } }, { { EntranceType::Overworld, RR_LW_BRIDGE, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_WOODED_EXIT }, { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LW_BRIDGE, ENTR_LOST_WOODS_BRIDGE_WEST_EXIT } }, - { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_NORTH_EXIT }, - { EntranceType::Overworld, RR_LAKE_HYLIA, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_FENCE_EXIT } }, + { { EntranceType::Overworld, RR_HF_TO_LAKE_HYLIA, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_NORTH_EXIT }, + { EntranceType::Overworld, RR_LAKE_HYLIA, RR_HF_TO_LAKE_HYLIA, ENTR_HYRULE_FIELD_FENCE_EXIT } }, { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_GERUDO_VALLEY, ENTR_GERUDO_VALLEY_EAST_EXIT }, { EntranceType::Overworld, RR_GERUDO_VALLEY, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_ROCKY_PATH } }, { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_MARKET_ENTRANCE, ENTR_MARKET_ENTRANCE_NEAR_GUARD_EXIT }, @@ -1499,7 +1499,7 @@ int EntranceShuffler::ShuffleAllEntrances() { { EntranceNameByRegions(RR_FOREST_TEMPLE_BOSS_ROOM, RR_FOREST_TEMPLE_BOSS_ENTRYWAY), GetEntrance(RR_FOREST_TEMPLE_ENTRYWAY, RR_SACRED_FOREST_MEADOW) }, { EntranceNameByRegions(RR_FIRE_TEMPLE_BOSS_ROOM, RR_FIRE_TEMPLE_BOSS_ENTRYWAY), - GetEntrance(RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_CENTRAL_LOCAL) }, + GetEntrance(RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_OUTSIDE_FIRE_TEMPLE) }, { EntranceNameByRegions(RR_WATER_TEMPLE_BOSS_ROOM, RR_WATER_TEMPLE_BOSS_ENTRYWAY), GetEntrance(RR_WATER_TEMPLE_ENTRYWAY, RR_LH_FROM_WATER_TEMPLE) }, { EntranceNameByRegions(RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY), @@ -1519,7 +1519,7 @@ int EntranceShuffler::ShuffleAllEntrances() { GetEntrance(RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_ZORAS_FOUNTAIN) }, { EntranceNameByRegions(RR_FOREST_TEMPLE_ENTRYWAY, RR_SACRED_FOREST_MEADOW), GetEntrance(RR_FOREST_TEMPLE_BOSS_ROOM, RR_SACRED_FOREST_MEADOW) }, - { EntranceNameByRegions(RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_CENTRAL_LOCAL), + { EntranceNameByRegions(RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_OUTSIDE_FIRE_TEMPLE), GetEntrance(RR_FIRE_TEMPLE_BOSS_ROOM, RR_DMC_CENTRAL_LOCAL) }, { EntranceNameByRegions(RR_WATER_TEMPLE_ENTRYWAY, RR_LH_FROM_WATER_TEMPLE), GetEntrance(RR_WATER_TEMPLE_BOSS_ROOM, RR_LAKE_HYLIA) }, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 92d210300df..da6e07236e1 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -23,6 +23,7 @@ extern "C" { #include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" #include "src/overlays/actors/ovl_En_Si/z_en_si.h" +#include "src/overlays/actors/ovl_En_Ossan/z_en_ossan.h" #include "src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.h" #include "src/overlays/actors/ovl_En_Dns/z_en_dns.h" #include "src/overlays/actors/ovl_En_Gb/z_en_gb.h" @@ -778,6 +779,12 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l va_copy(args, originalArgs); switch (id) { + case VB_CRAWL: + *should = !RAND_GET_OPTION(RSK_SHUFFLE_CRAWL) || Flags_GetRandomizerInf(RAND_INF_CAN_CRAWL); + break; + case VB_CLIMB: + *should = !RAND_GET_OPTION(RSK_SHUFFLE_CLIMB) || Flags_GetRandomizerInf(RAND_INF_CAN_CLIMB); + break; case VB_ALLOW_ENTRANCE_CS_FOR_EITHER_AGE: { s32 entranceIndex = va_arg(args, s32); @@ -820,17 +827,20 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = false; break; case VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER: { - *should = - !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && !Flags_GetTreasure(gPlayState, 0x2); + *should = !(RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) && !Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)) && + !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && + !Flags_GetTreasure(gPlayState, 0x2); break; } case VB_BE_ELIGIBLE_FOR_SERENADE_OF_WATER: - *should = - !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && Flags_GetTreasure(gPlayState, 0x2); + *should = !(RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) && !Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)) && + !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && + Flags_GetTreasure(gPlayState, 0x2); break; case VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT: - *should = - !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST); + *should = !(RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) && !Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)) && + !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST); break; case VB_MIDO_SPAWN: if (RAND_GET_OPTION(RSK_FOREST) != RO_CLOSED_FOREST_OFF && @@ -853,16 +863,25 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD: *should = !Flags_GetRandomizerInf(RAND_INF_DARUNIAS_JOY); break; + case VB_BE_ELIGIBLE_FOR_OCARINA_OF_TIME: + if (RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) && + (!Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL) || !Flags_GetRandomizerInf(RAND_INF_IMPA_SOUL))) { + *should = false; + } + break; case VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS: *should = LINK_IS_ADULT && (gEntranceTable[gSaveContext.entranceIndex].scene == SCENE_TEMPLE_OF_TIME) && !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && + (RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) != RO_NPC_SOULS_ON_PLUS_SAGES || + Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)) && MeetsLACSRequirements(); break; case VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW: *should = !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) && LINK_IS_ADULT && gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KAKARIKO_VILLAGE && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && - CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER); + CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && + (!RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) || Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)); break; case VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD: { // Don't require a bomb bag to get prize in rando @@ -1461,6 +1480,32 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_PLAY_BLUE_WARP_CS: { + if (RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) == RO_NPC_SOULS_ON_PLUS_SAGES) { + bool hasSoul = true; + switch (gPlayState->sceneNum) { + case SCENE_FOREST_TEMPLE_BOSS: + hasSoul = Flags_GetRandomizerInf(RAND_INF_SARIA_SOUL); + break; + case SCENE_DODONGOS_CAVERN_BOSS: + case SCENE_FIRE_TEMPLE_BOSS: + hasSoul = Flags_GetRandomizerInf(RAND_INF_DARUNIA_SOUL); + break; + case SCENE_JABU_JABU_BOSS: + case SCENE_WATER_TEMPLE_BOSS: + hasSoul = Flags_GetRandomizerInf(RAND_INF_RUTO_SOUL); + break; + case SCENE_SPIRIT_TEMPLE_BOSS: + hasSoul = Flags_GetRandomizerInf(RAND_INF_NABOORU_SOUL); + break; + case SCENE_SHADOW_TEMPLE_BOSS: + hasSoul = Flags_GetRandomizerInf(RAND_INF_IMPA_SOUL); + break; + } + if (!hasSoul) { + *should = false; + break; + } + } // We need to override just these two temples because they check medallions instead of flags if (gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) { *should = !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE); @@ -1800,7 +1845,9 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { updateHook = GameInteractor::Instance->RegisterGameHook([]() { if (!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && LINK_IS_ADULT && - CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && gPlayState->roomCtx.curRoom.num == 0) { + CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && + (!RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) || Flags_GetRandomizerInf(RAND_INF_ZELDA_SOUL)) && + gPlayState->roomCtx.curRoom.num == 0) { Flags_SetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT); } @@ -1992,6 +2039,11 @@ void RandomizerOnActorInitHandler(void* actorRef) { } } + if (actor->id == ACTOR_EN_OSSAN && actor->params == OSSAN_TYPE_MASK && + RAND_GET_OPTION(RSK_MASK_QUEST) == RO_MASK_QUEST_SHUFFLE) { + Actor_Kill(actor); + } + if (actor->id == ACTOR_BG_TREEMOUTH && LINK_IS_ADULT && RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF && (RAND_GET_OPTION(RSK_FOREST) == RO_CLOSED_FOREST_OFF || @@ -2063,6 +2115,195 @@ void RandomizerOnActorInitHandler(void* actorRef) { } } + if (RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS)) { + auto inf = RAND_INF_MAX; + switch (actor->id) { + case ACTOR_EN_NIW_LADY: + inf = RAND_INF_ANJU_SOUL; + break; + case ACTOR_BG_SPOT15_RRBOX: + // milk crates, prevent reaching Zelda without Talon's Soul + if (gPlayState->sceneNum == SCENE_HYRULE_CASTLE) { + inf = RAND_INF_TALON_SOUL; + } + break; + case ACTOR_EN_TA: + inf = RAND_INF_TALON_SOUL; + break; + case ACTOR_EN_HS: + case ACTOR_EN_HS2: + inf = RAND_INF_GROG_SOUL; + break; + case ACTOR_EN_DS: + inf = RAND_INF_GRANNY_SOUL; + break; + case ACTOR_EN_KO: + if ((actor->params & 0xFF) == ENKO_TYPE_CHILD_FADO) { + inf = RAND_INF_FADO_SOUL; + } + break; + case ACTOR_EN_GO2: + switch (actor->params & 0x1F) { + case GORON_CITY_LINK: + inf = RAND_INF_LINK_SOUL; + break; + case GORON_DMT_BIGGORON: + inf = RAND_INF_BIGGORON_SOUL; + break; + case GORON_CITY_ROLLING_BIG: + inf = RAND_INF_HOT_RODDER_SOUL; + break; + } + break; + case ACTOR_EN_GM: + inf = RAND_INF_MEDIGORON_SOUL; + break; + case ACTOR_EN_TORYO: + inf = RAND_INF_CARPENTER_BOSS_SOUL; + break; + case ACTOR_EN_DAIKU: + case ACTOR_EN_DAIKU_KAKARIKO: + inf = (RandomizerInf)(RAND_INF_ICHIRO_SOUL + (actor->params & 3)); + break; + case ACTOR_EN_GE1: + switch (actor->params & 0xFF) { + case GE1_TYPE_HORSEBACK_ARCHERY: + inf = RAND_INF_ARCHER_SOUL; + break; + case GE1_TYPE_TRAINING_GROUND_GUARD: + inf = RAND_INF_GTG_GATEKEEPER_SOUL; + break; + case GE1_TYPE_GATE_OPERATOR: + inf = RAND_INF_HW_GATEKEEPER_SOUL; + break; + } + break; + case ACTOR_EN_OKARINA_TAG: + if (gPlayState->sceneNum == SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC || + gPlayState->sceneNum == SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS) { + inf = RAND_INF_GREAT_FAIRY_SOUL; + } + break; + case ACTOR_EN_GB: + inf = RAND_INF_POE_COLLECTOR_SOUL; + break; + case ACTOR_EN_TK: + case ACTOR_EN_PO_RELAY: + inf = RAND_INF_DAMPE_SOUL; + break; + case ACTOR_EN_FU: + inf = RAND_INF_WINDMILL_MAN_SOUL; + break; + case ACTOR_EN_ANI: + inf = RAND_INF_MAN_ON_ROOF_SOUL; + break; + case ACTOR_EN_HEISHI2: + if ((actor->params & 0xFF) == 5) { + inf = RAND_INF_KAKARIKO_GATEKEEPER_SOUL; + } + break; + case ACTOR_EN_MA1: + case ACTOR_EN_MA2: + case ACTOR_EN_MA3: + inf = RAND_INF_MALON_SOUL; + break; + case ACTOR_EN_SA: + inf = RAND_INF_SARIA_SOUL; + break; + case ACTOR_EN_DU: + inf = RAND_INF_DARUNIA_SOUL; + break; + case ACTOR_EN_RU1: + case ACTOR_EN_RU2: + inf = RAND_INF_RUTO_SOUL; + break; + case ACTOR_EN_NB: + inf = RAND_INF_NABOORU_SOUL; + break; + case ACTOR_EN_XC: + case ACTOR_EN_ZL1: + case ACTOR_EN_ZL4: + inf = RAND_INF_ZELDA_SOUL; + break; + case ACTOR_EN_ZL2: + case ACTOR_EN_ZL3: + case ACTOR_BOSS_GANON: + case ACTOR_BOSS_GANON2: + if (RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) == RO_NPC_SOULS_ON_PLUS_SAGES) { + inf = RAND_INF_ZELDA_SOUL; + } + break; + case ACTOR_EN_HY: + switch (actor->params & 0x7F) { + case ENHY_TYPE_BOJ_5: + inf = RAND_INF_BEGGAR_SOUL; + break; + case ENHY_TYPE_AOB: + inf = RAND_INF_DOG_LADY_SOUL; + break; + } + break; + case ACTOR_EN_JS: + inf = RAND_INF_ARMS_DEALER_SOUL; + break; + case ACTOR_EN_MS: + inf = RAND_INF_BEAN_SALESMAN_SOUL; + break; + case ACTOR_EN_SYATEKI_MAN: + inf = RAND_INF_SHOOTING_SOUL; + break; + case ACTOR_EN_OSSAN: + switch (actor->params) { + case OSSAN_TYPE_KOKIRI: + inf = RAND_INF_KOKIRI_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_KAKARIKO_POTION: + case OSSAN_TYPE_MARKET_POTION: + inf = RAND_INF_POTION_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_BAZAAR: + case OSSAN_TYPE_ADULT: + inf = RAND_INF_BAZAAR_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_GORON: + inf = RAND_INF_GORON_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_ZORA: + inf = RAND_INF_ZORA_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_BOMBCHUS: + inf = RAND_INF_BOMBCHU_SHOPKEEPER_SOUL; + break; + case OSSAN_TYPE_MASK: + inf = RAND_INF_MASK_SALESMAN_SOUL; + break; + } + break; + case ACTOR_EN_TAKARA_MAN: + inf = RAND_INF_TREASURE_MAN_SOUL; + break; + case ACTOR_EN_BOM_BOWL_MAN: + case ACTOR_EN_WALL_TUBO: // crashes when bombchu lady missing + inf = RAND_INF_BOMBCHU_LADY_SOUL; + break; + case ACTOR_EN_DIVING_GAME: + inf = RAND_INF_DIVING_SOUL; + break; + case ACTOR_EN_MK: + inf = RAND_INF_SCIENTIST_SOUL; + break; + case ACTOR_EN_OWL: + inf = RAND_INF_KAEPORA_SOUL; + break; + } + if (inf != RAND_INF_MAX && !Flags_GetRandomizerInf(inf)) { + if (inf == RAND_INF_KAEPORA_SOUL) { + Flags_SetSwitch(gPlayState, 0x23); // allow child link to pull Lake Hylia grave + } + Actor_Kill(actor); + } + } + // In MQ Spirit, remove the large silver block in the hole as child so the chest in the silver block hallway // can be guaranteed accessible if (actor->id == ACTOR_OBJ_OSHIHIKI && LINK_IS_CHILD && ResourceMgr_IsGameMasterQuest() && diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 786717c8092..9006499726d 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -316,7 +316,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_BUY_BOMBS_535] = Item(RG_BUY_BOMBS_535, Text{ "Buy Bombs (5) [35]", "Acheter: Bombes (5) [35]", "Bomben kaufen (5) [35]" }, ITEMTYPE_SHOP, GI_BOMBS_5, true, LOGIC_BUY_BOMB, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 35); itemTable[RG_BUY_RED_POTION_40] = Item(RG_BUY_RED_POTION_40, Text{ "Buy Red Potion [40]", "Acheter: Potion Rouge [40]", "Rotes Elixier kaufen [40]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 40); itemTable[RG_BUY_RED_POTION_50] = Item(RG_BUY_RED_POTION_50, Text{ "Buy Red Potion [50]", "Acheter: Potion Rouge [50]", "Rotes Elixier kaufen [50]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50); - // Misc. + // Boss souls itemTable[RG_GOHMA_SOUL] = Item(RG_GOHMA_SOUL, Text{ "Gohma's Soul", "Âme de Gohma", "Gohmas Seele" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_CAN_SUMMON_GOHMA, RHT_GOHMA_SOUL, RG_GOHMA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_GOHMA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_KING_DODONGO_SOUL] = Item(RG_KING_DODONGO_SOUL, Text{ "King Dodongo's Soul", "Âme du Roi Dodongo", "König Dodongos Seele" }, ITEMTYPE_ITEM, 0xE1, true, LOGIC_CAN_SUMMON_KINGDODONGO, RHT_KING_DODONGO_SOUL, RG_KING_DODONGO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); @@ -335,6 +335,104 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_TWINROVA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_GANON_SOUL] = Item(RG_GANON_SOUL, Text{ "Ganon's Soul", "Âme de Ganon", "Ganons Seele" }, ITEMTYPE_ITEM, 0xE8, true, LOGIC_CAN_SUMMON_GANON, RHT_GANON_SOUL, RG_GANON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_GANON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + // NPC souls + itemTable[RG_ANJU_SOUL] = Item(RG_ANJU_SOUL, Text{ "Anju's Soul", "Âme de Anju", "Anjus Seele" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ANJU, RHT_ANJU_SOUL, RG_ANJU_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ANJU_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_TALON_SOUL] = Item(RG_TALON_SOUL, Text{ "Talon's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_TALON, RHT_TALON_SOUL, RG_TALON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_TALON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_GROG_SOUL] = Item(RG_GROG_SOUL, Text{ "Grog's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_GROG, RHT_GROG_SOUL, RG_GROG_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GROG_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_GRANNY_SOUL] = Item(RG_GRANNY_SOUL, Text{ "Granny's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_GRANNY, RHT_GRANNY_SOUL, RG_GRANNY_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GRANNY_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_FADO_SOUL] = Item(RG_FADO_SOUL, Text{ "Fado's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_FADO, RHT_FADO_SOUL, RG_FADO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_FADO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_LINK_SOUL] = Item(RG_LINK_SOUL, Text{ "Darunia's Son's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_LINK, RHT_LINK_SOUL, RG_LINK_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_LINK_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BIGGORON_SOUL] = Item(RG_BIGGORON_SOUL, Text{ "Biggoron's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BIGGORON, RHT_BIGGORON_SOUL, RG_BIGGORON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BIGGORON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_HOT_RODDER_SOUL] = Item(RG_HOT_RODDER_SOUL, Text{ "Hot Rodder's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_HOT_RODDER, RHT_HOT_RODDER_SOUL, RG_HOT_RODDER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_HOT_RODDER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_MEDIGORON_SOUL] = Item(RG_MEDIGORON_SOUL, Text{ "Medigoron's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_MEDIGORON, RHT_MEDIGORON_SOUL, RG_MEDIGORON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MEDIGORON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_CARPENTER_BOSS_SOUL] = Item(RG_CARPENTER_BOSS_SOUL, Text{ "Carpenter Boss's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_CARPENTER_BOSS, RHT_CARPENTER_BOSS_SOUL, RG_CARPENTER_BOSS_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_CARPENTER_BOSS_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_ICHIRO_SOUL] = Item(RG_ICHIRO_SOUL, Text{ "Ichiro's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ICHIRO, RHT_ICHIRO_SOUL, RG_ICHIRO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_FADO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_SABOORO_SOUL] = Item(RG_SABOORO_SOUL, Text{ "Sabooro's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_SABOORO, RHT_SABOORO_SOUL, RG_FADO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SABOORO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_JIRO_SOUL] = Item(RG_JIRO_SOUL, Text{ "Jiro's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_JIRO, RHT_JIRO_SOUL, RG_JIRO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_JIRO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_SHIRO_SOUL] = Item(RG_SHIRO_SOUL, Text{ "Shiro's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_SHIRO, RHT_SHIRO_SOUL, RG_SHIRO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SHIRO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_HW_GATEKEEPER_SOUL] = Item(RG_HW_GATEKEEPER_SOUL, Text{ "Haunted Wasteland Gate Operator's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_HW_GATEKEEPER, RHT_HW_GATEKEEPER_SOUL, RG_HW_GATEKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_HW_GATEKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_GTG_GATEKEEPER_SOUL] = Item(RG_GTG_GATEKEEPER_SOUL, Text{ "Training Ground Gate Operator's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_GTG_GATEKEEPER, RHT_GTG_GATEKEEPER_SOUL, RG_GTG_GATEKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GTG_GATEKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_ARCHER_SOUL] = Item(RG_ARCHER_SOUL, Text{ "Horseback Archer's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ARCHER, RHT_ARCHER_SOUL, RG_ARCHER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ARCHER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_GREAT_FAIRY_SOUL] = Item(RG_GREAT_FAIRY_SOUL, Text{ "Great Fairy's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_GREAT_FAIRY, RHT_GREAT_FAIRY_SOUL, RG_GREAT_FAIRY_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GREAT_FAIRY_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_POE_COLLECTOR_SOUL] = Item(RG_POE_COLLECTOR_SOUL, Text{ "Poe Collector's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_POE_COLLECTOR, RHT_POE_COLLECTOR_SOUL, RG_POE_COLLECTOR_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_POE_COLLECTOR_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_DAMPE_SOUL] = Item(RG_DAMPE_SOUL, Text{ "Dampe's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_DAMPE, RHT_DAMPE_SOUL, RG_DAMPE_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_DAMPE_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_WINDMILL_MAN_SOUL] = Item(RG_WINDMILL_MAN_SOUL, Text{ "Windmill Man's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_WINDMILL_MAN, RHT_WINDMILL_MAN_SOUL, RG_WINDMILL_MAN_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_WINDMILL_MAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_MAN_ON_ROOF_SOUL] = Item(RG_MAN_ON_ROOF_SOUL, Text{ "Man on Roof's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_MAN_ON_ROOF, RHT_MAN_ON_ROOF_SOUL, RG_MAN_ON_ROOF_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MAN_ON_ROOF_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_KAKARIKO_GATEKEEPER_SOUL] = Item(RG_KAKARIKO_GATEKEEPER_SOUL, Text{ "Kakariko Gatekeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_KAKARIKO_GATEKEEPER, RHT_KAKARIKO_GATEKEEPER_SOUL, RG_KAKARIKO_GATEKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_KAKARIKO_GATEKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_MALON_SOUL] = Item(RG_MALON_SOUL, Text{ "Malon's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_MALON, RHT_MALON_SOUL, RG_MALON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MALON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BEGGAR_SOUL] = Item(RG_BEGGAR_SOUL, Text{ "Beggar's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BEGGAR, RHT_BEGGAR_SOUL, RG_BEGGAR_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BEGGAR_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_DOG_LADY_SOUL] = Item(RG_DOG_LADY_SOUL, Text{ "Dog Lady's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_DOG_LADY, RHT_DOG_LADY_SOUL, RG_DOG_LADY_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_DOG_LADY_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_ARMS_DEALER_SOUL] = Item(RG_ARMS_DEALER_SOUL, Text{ "Arms Dealer's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ARMS_DEALER, RHT_ARMS_DEALER_SOUL, RG_ARMS_DEALER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ARMS_DEALER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BEAN_SALESMAN_SOUL] = Item(RG_BEAN_SALESMAN_SOUL, Text{ "Bean Salesman's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BEAN_SALESMAN, RHT_BEAN_SALESMAN_SOUL, RG_BEAN_SALESMAN_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BEAN_SALESMAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_SHOOTING_SOUL] = Item(RG_SHOOTING_SOUL, Text{ "Shooter's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_SHOOTING, RHT_SHOOTING_SOUL, RG_SHOOTING_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SHOOTING_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_KOKIRI_SHOPKEEPER_SOUL] = Item(RG_KOKIRI_SHOPKEEPER_SOUL, Text{ "Kokiri Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_KOKIRI_SHOPKEEPER, RHT_KOKIRI_SHOPKEEPER_SOUL, RG_KOKIRI_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_KOKIRI_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_POTION_SHOPKEEPER_SOUL] = Item(RG_POTION_SHOPKEEPER_SOUL, Text{ "Potion Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_POTION_SHOPKEEPER, RHT_POTION_SHOPKEEPER_SOUL, RG_POTION_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_POTION_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BAZAAR_SHOPKEEPER_SOUL] = Item(RG_BAZAAR_SHOPKEEPER_SOUL, Text{ "Bazaar Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BAZAAR_SHOPKEEPER, RHT_BAZAAR_SHOPKEEPER_SOUL, RG_BAZAAR_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BAZAAR_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_GORON_SHOPKEEPER_SOUL] = Item(RG_GORON_SHOPKEEPER_SOUL, Text{ "Goron Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_GORON_SHOPKEEPER, RHT_GORON_SHOPKEEPER_SOUL, RG_GORON_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GORON_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_ZORA_SHOPKEEPER_SOUL] = Item(RG_ZORA_SHOPKEEPER_SOUL, Text{ "Zora Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ZORA_SHOPKEEPER, RHT_ZORA_SHOPKEEPER_SOUL, RG_ZORA_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ZORA_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BOMBCHU_SHOPKEEPER_SOUL] = Item(RG_BOMBCHU_SHOPKEEPER_SOUL, Text{ "Bombchu Shopkeeper's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BOMBCHU_SHOPKEEPER, RHT_BOMBCHU_SHOPKEEPER_SOUL, RG_BOMBCHU_SHOPKEEPER_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BOMBCHU_SHOPKEEPER_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_MASK_SALESMAN_SOUL] = Item(RG_MASK_SALESMAN_SOUL, Text{ "Mask Salesman's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_MASK_SALESMAN, RHT_MASK_SALESMAN_SOUL, RG_MASK_SALESMAN_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MASK_SALESMAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_TREASURE_MAN_SOUL] = Item(RG_TREASURE_MAN_SOUL, Text{ "Treasure Man's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_TREASURE_MAN, RHT_TREASURE_MAN_SOUL, RG_TREASURE_MAN_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_TREASURE_MAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_BOMBCHU_LADY_SOUL] = Item(RG_BOMBCHU_LADY_SOUL, Text{ "Bombchu Lady's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_BOMBCHU_LADY, RHT_BOMBCHU_LADY_SOUL, RG_BOMBCHU_LADY_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BOMBCHU_LADY_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_DIVING_SOUL] = Item(RG_DIVING_SOUL, Text{ "Diver's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_DIVING, RHT_DIVING_SOUL, RG_DIVING_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_DIVING_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_SCIENTIST_SOUL] = Item(RG_SCIENTIST_SOUL, Text{ "Scientist's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_SCIENTIST, RHT_SCIENTIST_SOUL, RG_SCIENTIST_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SCIENTIST_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_KAEPORA_SOUL] = Item(RG_KAEPORA_SOUL, Text{ "Kaepora's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_KAEPORA, RHT_KAEPORA_SOUL, RG_KAEPORA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_KAEPORA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_RAURU_SOUL] = Item(RG_RAURU_SOUL, Text{ "Rauru's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_RAURU, RHT_RAURU_SOUL, RG_RAURU_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_RAURU_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_SARIA_SOUL] = Item(RG_SARIA_SOUL, Text{ "Saria's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_SARIA, RHT_SARIA_SOUL, RG_SARIA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SARIA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_DARUNIA_SOUL] = Item(RG_DARUNIA_SOUL, Text{ "Darunia's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_DARUNIA, RHT_DARUNIA_SOUL, RG_DARUNIA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_DARUNIA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_RUTO_SOUL] = Item(RG_RUTO_SOUL, Text{ "Ruto's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_RUTO, RHT_RUTO_SOUL, RG_RUTO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_RUTO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_NABOORU_SOUL] = Item(RG_NABOORU_SOUL, Text{ "Nabooru's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_NABOORU, RHT_NABOORU_SOUL, RG_NABOORU_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_NABOORU_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_IMPA_SOUL] = Item(RG_IMPA_SOUL, Text{ "Impa's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_IMPA, RHT_IMPA_SOUL, RG_IMPA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_IMPA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + itemTable[RG_ZELDA_SOUL] = Item(RG_ZELDA_SOUL, Text{ "Zelda's Soul" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_ZELDA, RHT_ZELDA_SOUL, RG_ZELDA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ZELDA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); + // Misc. itemTable[RG_FISHING_POLE] = Item(RG_FISHING_POLE, Text{ "Fishing Pole", "Canne à Pêche", "Angelrute" }, ITEMTYPE_ITEM, RG_FISHING_POLE, true, LOGIC_FISHING_POLE, RHT_FISHING_POLE, RG_FISHING_POLE, OBJECT_GI_FISH, GID_FISHING_POLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_FISHING_POLE].SetCustomDrawFunc(Randomizer_DrawFishingPoleGI); @@ -349,12 +447,27 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_OCARINA_C_RIGHT_BUTTON] = Item(RG_OCARINA_C_RIGHT_BUTTON, Text{ "Ocarina C Right Button", "Touche C-Droit de l'Ocarina", "C-Rechts-Taste der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_RIGHT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, RG_OCARINA_C_RIGHT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OCARINA_C_RIGHT_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); + itemTable[RG_MASK_KEATON] = Item(RG_MASK_KEATON, Text{ "Keaton Mask", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_MASK_KEATON, true, LOGIC_NONE, RHT_MASK_KEATON, RG_MASK_KEATON, OBJECT_GI_KI_TAN_MASK, GID_MASK_KEATON, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MASK_SKULL] = Item(RG_MASK_SKULL, Text{ "Skull Mask", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_MASK_SKULL, true, LOGIC_NONE, RHT_MASK_SKULL, RG_MASK_SKULL, OBJECT_GI_SKJ_MASK, GID_MASK_SKULL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MASK_SPOOKY] = Item(RG_MASK_SPOOKY, Text{ "Spooky Mask", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_MASK_SPOOKY, true, LOGIC_NONE, RHT_MASK_SPOOKY, RG_MASK_SPOOKY, OBJECT_GI_REDEAD_MASK, GID_MASK_SPOOKY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MASK_BUNNY] = Item(RG_MASK_BUNNY, Text{ "Bunny Hood", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_MASK_BUNNY, true, LOGIC_NONE, RHT_MASK_BUNNY, RG_MASK_BUNNY, OBJECT_GI_RABIT_MASK, GID_MASK_BUNNY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MASK_GORON] = Item(RG_MASK_GORON, Text{ "Goron Mask", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_MASK_GORON, true, LOGIC_NONE, RHT_MASK_GORON, RG_MASK_GORON, OBJECT_GI_GOLONMASK, GID_MASK_GORON, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MASK_ZORA] = Item(RG_MASK_ZORA, Text{ "Zora Mask", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_MASK_ZORA, true, LOGIC_NONE, RHT_MASK_ZORA, RG_MASK_ZORA, OBJECT_GI_ZORAMASK, GID_MASK_ZORA, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MASK_GERUDO] = Item(RG_MASK_GERUDO, Text{ "Gerudo Mask", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_MASK_GERUDO, true, LOGIC_NONE, RHT_MASK_GERUDO, RG_MASK_GERUDO, OBJECT_GI_GERUDOMASK, GID_MASK_GERUDO, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_MASK_TRUTH] = Item(RG_MASK_TRUTH, Text{ "Mask of Truth", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_MASK_TRUTH, true, LOGIC_NONE, RHT_MASK_TRUTH, RG_MASK_TRUTH, OBJECT_GI_TRUTH_MASK, GID_MASK_TRUTH, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_WALLET, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale); + itemTable[RG_CLIMB] = Item(RG_CLIMB, Text{ "Climb", "", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_WALLET, RHT_CLIMB, RG_CLIMB, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_CLIMB].SetCustomDrawFunc(Randomizer_DrawBronzeScale); + + itemTable[RG_CRAWL] = Item(RG_CRAWL, Text{ "Crawl", "Ramper", "Kriechen" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_WALLET, RHT_CRAWL, RG_CRAWL, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_CRAWL].SetCustomDrawFunc(Randomizer_DrawBronzeScale); + itemTable[RG_BOMBCHU_BAG] = Item(RG_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag); - + itemTable[RG_QUIVER_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Quiver", "Carquois Infini", "Unendlicher Köcher" }, ITEMTYPE_ITEM, RG_QUIVER_INF, true, LOGIC_PROGRESSIVE_BOW, RHT_QUIVER_INF, RG_QUIVER_INF, OBJECT_GI_ARROWCASE, GID_QUIVER_50, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_BOMB_BAG_INF] = Item(RG_BOMB_BAG_INF, Text{ "Infinite Bomb Bag", "Sac de Bombes Infini", "Unendliche Bombentasche" }, ITEMTYPE_ITEM, RG_BOMB_BAG_INF, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BOMB_BAG_INF, RG_BOMB_BAG_INF, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_BULLET_BAG_INF] = Item(RG_BULLET_BAG_INF, Text{ "Infinite Bullet Bag", "Sac de Graines Infinis", "Unendliche Munitionstasche" }, ITEMTYPE_ITEM, RG_BULLET_BAG_INF, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_BULLET_BAG_INF, RG_BULLET_BAG_INF, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index f474397aa4a..19ea53fcda4 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -566,6 +566,41 @@ Rando::Location Rando::Location::SmallCrate(RandomizerCheck rc, RandomizerCheckQ false, collectionCheck }; } +Rando::Location Rando::Location::Tree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_TREE, area_, ACTOR_EN_WOOD02, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; +} + +Rando::Location Rando::Location::NLTree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_NLTREE, area_, ACTOR_EN_WOOD02, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; +} + +Rando::Location Rando::Location::Rock(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_ROCK, area_, ACTOR_EN_ISHI, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; +} + +Rando::Location Rando::Location::Boulder(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_BOULDER, area_, ACTOR_EN_ISHI, + scene_, actorParams_, std::move(shortName_), hintKey, RG_BOMBS_5, + false, collectionCheck }; +} + Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_) { return { rc, quest_, RCTYPE_GOSSIP_STONE, area_, ACTOR_EN_GS, diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index f9949965249..4b9c09efdfd 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -67,15 +67,7 @@ class Location { actorParams(actorParams_), shortName(std::move(shortName_)), spoilerName(std::move(spoilerName_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) { - if (spoilerName.length() < 23) { - excludedOption = LocationOption(rc, spoilerName); - } else { - const size_t lastSpace = spoilerName.rfind(' ', 23); - std::string settingText = spoilerName; - settingText.replace(lastSpace, 1, "\n "); - - excludedOption = LocationOption(rc, spoilerName); - } + excludedOption = LocationOption(rc, spoilerName); } Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, @@ -87,15 +79,7 @@ class Location { actorParams(actorParams_), shortName(shortName_), spoilerName(SpoilerNameFromShortName(shortName_, area_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) { - if (spoilerName.length() < 23) { - excludedOption = LocationOption(rc, spoilerName); - } else { - const size_t lastSpace = spoilerName.rfind(' ', 23); - std::string settingText = spoilerName; - settingText.replace(lastSpace, 1, "\n "); - - excludedOption = LocationOption(rc, spoilerName); - } + excludedOption = LocationOption(rc, spoilerName); } static std::string SpoilerNameFromShortName(std::string shortName, RandomizerCheckArea area) { @@ -246,6 +230,22 @@ class Location { RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + static Location Rock(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + + static Location Boulder(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + SpoilerCollectionCheck collectionCheck); + + static Location Tree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + + static Location NLTree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_, std::string&& spoilerName_); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp index 001ad5d81d9..9da1dc206cc 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp @@ -10,8 +10,8 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_ENTRYWAY] = Region("Bottom of the Well Entryway", SCENE_BOTTOM_OF_THE_WELL, {}, {}, { //Exits //Technically involves an fake wall, but passing it lensless is intended in vanilla and it is well telegraphed - Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() && logic->IsChild && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ() && logic->IsChild;}), + Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() && logic->CanUse(RG_CRAWL) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ() && logic->CanUse(RG_CRAWL);}), Entrance(RR_KAK_WELL, []{return true;}), }); @@ -32,12 +32,12 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, (logic->CanBreakPots() && logic->LoweredWaterInsideBotw) || logic->CanUse(RG_BOOMERANG)), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), + Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->CanUse(RG_CRAWL) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), Entrance(RR_BOTTOM_OF_THE_WELL_BEHIND_FAKE_WALLS, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), Entrance(RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), - Entrance(RR_BOTTOM_OF_THE_WELL_KEESE_BEAMOS_ROOM, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3);}), - Entrance(RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM, []{return logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE);}), - Entrance(RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM, []{return logic->LoweredWaterInsideBotw && logic->IsChild;}), + Entrance(RR_BOTTOM_OF_THE_WELL_KEESE_BEAMOS_ROOM, []{return logic->CanUse(RG_CRAWL) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3);}), + Entrance(RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE) || (logic->HasItem(RG_CLIMB) && logic->CanUse(RG_IRON_BOOTS))) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM, []{return logic->LoweredWaterInsideBotw && logic->CanUse(RG_CRAWL) && logic->HasItem(RG_CLIMB);}), //Falling down into basement requires nothing, but falling down somewhere specific requires lens or lens trick //kinda questionable given several drops are blocked by rocks, but that's how it was handled before and on N64 Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, []{return true;}), @@ -79,7 +79,7 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, logic->CanBreakPots() && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH));}), + Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->CanUse(RG_CRAWL) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH));}), Entrance(RR_BOTTOM_OF_THE_WELL_LIKE_LIKE_CAGE, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), //not sure if this lens check is needed, these holes are a bit too easy to find, but it matches existing logic Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT_USEFUL_BOMB_FLOWERS, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), @@ -115,7 +115,7 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE);}), + Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE) || (logic->HasItem(RG_CLIMB) && logic->CanUse(RG_IRON_BOOTS))) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));}), }); areaTable[RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM] = Region("Bottom of the Well Dead Hand Room", SCENE_BOTTOM_OF_THE_WELL, {}, { @@ -125,7 +125,7 @@ void RegionTable_Init_BottomOfTheWell() { }, { //Exits //This assumes we spawned in dead hand's room, if whatever trick made this relevant instead puts us in the previous room, remove the kill Dead Hand check. - Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->IsChild && logic->CanKillEnemy(RE_DEAD_HAND);}), + Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->CanUse(RG_CRAWL) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->CanKillEnemy(RE_DEAD_HAND);}), }); areaTable[RR_BOTTOM_OF_THE_WELL_BASEMENT] = Region("Bottom of the Well Basement", SCENE_BOTTOM_OF_THE_WELL, {}, { @@ -156,9 +156,15 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_7, logic->CanCutShrubs() && logic->BlastOrSmash()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_8, logic->CanCutShrubs() && logic->BlastOrSmash()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_9, logic->CanCutShrubs() && logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_3, logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_BASEMENT))), + LOCATION(RC_BOTW_BOULDER_4, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_6, logic->BlastOrSmash()), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM, []{return logic->IsChild && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), + Entrance(RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM, []{return logic->CanUse(RG_CRAWL) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), //It's possible to abuse boulder's limited range of collision detection to detonate the flowers through the boulder with bow, but this is a glitch //the exact range is just past the furthest away plank in the green goo section Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT_USEFUL_BOMB_FLOWERS, []{return Here(RR_BOTTOM_OF_THE_WELL_BASEMENT, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_BASEMENT));});}), @@ -168,6 +174,12 @@ void RegionTable_Init_BottomOfTheWell() { //Locations //Assumes RR_BOTTOM_OF_THE_WELL_BASEMENT access LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_1, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_2, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_3, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_4, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_5, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_6, logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, []{return logic->CanDetonateUprightBombFlower();}), @@ -203,13 +215,16 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, logic->HasExplosives()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives()), + LOCATION(RC_BOTW_MQ_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_BOTW_MQ_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_BOTW_MQ_BOULDER_3, logic->BlastOrSmash()), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild;}), + Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->CanUse(RG_CRAWL) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_WEST_ROOM_SWITCH, []{return Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}), - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_LOCKED_CAGE, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2) && logic->CanUseProjectile();}), - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_ROOM, []{return logic->IsChild && logic->LoweredWaterInsideBotw;}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE) || (logic->HasItem(RG_CLIMB) && logic->CanUse(RG_IRON_BOOTS))) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_LOCKED_CAGE, []{return logic->CanUse(RG_CRAWL) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2) && logic->CanUseProjectile();}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_ROOM, []{return logic->IsChild && logic->LoweredWaterInsideBotw && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT, []{return true;}), }); @@ -231,7 +246,7 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE) || (logic->HasItem(RG_CLIMB) && logic->CanUse(RG_IRON_BOOTS))) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}), }); areaTable[RR_BOTTOM_OF_THE_WELL_MQ_LOCKED_CAGE] = Region("Bottom of the Well MQ Locked Cage", SCENE_BOTTOM_OF_THE_WELL, { @@ -239,7 +254,7 @@ void RegionTable_Init_BottomOfTheWell() { EventAccess(&logic->OpenedMiddleHoleMQBotw, []{return logic->HasExplosives();}), }, {}, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->CanUse(RG_CRAWL) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}), }); areaTable[RR_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_ROOM] = Region("Bottom of the Well MQ Dead Hand Room", SCENE_BOTTOM_OF_THE_WELL, {}, { @@ -253,7 +268,7 @@ void RegionTable_Init_BottomOfTheWell() { }, { //Exits //This assumes we spawned in dead hand's room, if whatever trick made this relevant instead puts us in the previous room, remove the kill Dead Hand check. - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->IsChild && logic->CanKillEnemy(RE_DEAD_HAND);}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->CanUse(RG_CRAWL) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->CanKillEnemy(RE_DEAD_HAND);}), }); areaTable[RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE] = Region("Bottom of the Well MQ Middle", SCENE_BOTTOM_OF_THE_WELL, {}, { @@ -293,7 +308,7 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return true;}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}), }); areaTable[RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SWITCH_PLATFORM] = Region("Bottom of the Well MQ Basement Switch Platform", SCENE_BOTTOM_OF_THE_WELL, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index 1d98e861a79..31e1087ea00 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -9,8 +9,8 @@ void RegionTable_Init_DekuTree() { // Vanilla/MQ Decider areaTable[RR_DEKU_TREE_ENTRYWAY] = Region("Deku Tree Entryway", SCENE_DEKU_TREE, {}, {}, { //Exits - Entrance(RR_DEKU_TREE_LOBBY, []{return ctx->GetDungeon(DEKU_TREE)->IsVanilla();}), - Entrance(RR_DEKU_TREE_MQ_1F, []{return ctx->GetDungeon(DEKU_TREE)->IsMQ();}), + Entrance(RR_DEKU_TREE_LOBBY, []{return ctx->GetDungeon(DEKU_TREE)->IsVanilla() && logic->HasItem(RG_CLIMB);}), + Entrance(RR_DEKU_TREE_MQ_1F, []{return ctx->GetDungeon(DEKU_TREE)->IsMQ() && logic->HasItem(RG_CLIMB);}), Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return true;}), }); @@ -33,13 +33,33 @@ void RegionTable_Init_DekuTree() { }, { //Exits Entrance(RR_DEKU_TREE_ENTRYWAY, []{return true;}), - Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return true;}), - Entrance(RR_DEKU_TREE_COMPASS_ROOM, []{return true;}), - Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return Here(RR_DEKU_TREE_LOBBY, []{return logic->CanAttack() || logic->CanUse(RG_NUTS);});}), + Entrance(RR_DEKU_TREE_LOBBY_2F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return Here(RR_DEKU_TREE_LOBBY, []{return logic->HasFireSource();});}), Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return false;}), Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, []{return false;}), }); + areaTable[RR_DEKU_TREE_LOBBY_2F] = Region("Deku Tree Lobby 2F", SCENE_DEKU_TREE, {}, { + //Locations + LOCATION(RC_DEKU_TREE_MAP_CHEST, true), + LOCATION(RC_DEKU_TREE_LOBBY_LOWER_HEART, true), + }, { + //Exits + Entrance(RR_DEKU_TREE_LOBBY, []{return true;}), + Entrance(RR_DEKU_TREE_LOBBY_3F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return true;}), + }); + + areaTable[RR_DEKU_TREE_LOBBY_3F] = Region("Deku Tree Lobby 3F", SCENE_DEKU_TREE, {}, { + //Locations + LOCATION(RC_DEKU_TREE_LOBBY_UPPER_HEART, logic->CanPassEnemy(RE_BIG_SKULLTULA)), + }, { + //Exits + Entrance(RR_DEKU_TREE_LOBBY_2F, []{return true;}), + Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return Here(RR_DEKU_TREE_LOBBY, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);});}), + Entrance(RR_DEKU_TREE_COMPASS_ROOM, []{return true;}), + }); + areaTable[RR_DEKU_TREE_2F_MIDDLE_ROOM] = Region("Deku Tree 2F Middle Room", SCENE_DEKU_TREE, {}, {}, { //Exits Entrance(RR_DEKU_TREE_LOBBY, []{return Here(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return logic->CanReflectNuts() || logic->CanUse(RG_MEGATON_HAMMER);});}), @@ -48,8 +68,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_SLINGSHOT_ROOM] = Region("Deku Tree Slingshot Room", SCENE_DEKU_TREE, {}, { //Locations - LOCATION(RC_DEKU_TREE_SLINGSHOT_CHEST, true), - LOCATION(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, true), + LOCATION(RC_DEKU_TREE_SLINGSHOT_CHEST, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)), LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_1, logic->CanCutShrubs() && logic->CanReflectNuts()), LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_2, logic->CanCutShrubs() && logic->CanReflectNuts()), LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_3, logic->CanCutShrubs() && logic->CanReflectNuts()), @@ -89,7 +109,7 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_BASEMENT_GRASS_2, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_DEKU_TREE_LOBBY, []{return true;}), + Entrance(RR_DEKU_TREE_LOBBY, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}), Entrance(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, []{return Here(RR_DEKU_TREE_BASEMENT_LOWER, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}), Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || HasAccessTo(RR_DEKU_TREE_BASEMENT_UPPER);}), Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return false;}), @@ -103,7 +123,7 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_4, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return true;}), + Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return logic->HasItem(RG_CLIMB);}), Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_FRONT, []{return Here(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, []{return logic->CanHitEyeTargets();});}), }); @@ -149,7 +169,7 @@ void RegionTable_Init_DekuTree() { //Exits Entrance(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, []{return true;}), Entrance(RR_DEKU_TREE_BASEMENT_BACK_ROOM, []{return Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->BlastOrSmash();});}), - Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && logic->IsChild;}), + Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && logic->CanUse(RG_CRAWL);}), }); areaTable[RR_DEKU_TREE_BASEMENT_BACK_ROOM] = Region("Deku Tree Basement Back Room", SCENE_DEKU_TREE, {}, { @@ -167,7 +187,7 @@ void RegionTable_Init_DekuTree() { }, {}, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return true;}), - Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->IsChild;}), + Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->CanUse(RG_CRAWL);}), Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return Here(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_DEKU_B1_BOW_WEBS) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));});}), }); @@ -204,7 +224,7 @@ void RegionTable_Init_DekuTree() { //Exits Entrance(RR_DEKU_TREE_ENTRYWAY, []{return true;}), //may need canAvoid logic with enemy shuffle - Entrance(RR_DEKU_TREE_MQ_2F, []{return true;}), + Entrance(RR_DEKU_TREE_MQ_2F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}), //Swim is not required because you can jump with enough momentum to hit land. //You even avoid fall damage if you hit the shallow water, though it's obscure knowledge so may be a trick //if it is, then we need a landing room with (IsAdult || HasItem(RG_BRONZE_SCALE) || TakeDamage() || that trick) to reach basement @@ -224,7 +244,7 @@ void RegionTable_Init_DekuTree() { //Exits Entrance(RR_DEKU_TREE_MQ_1F, []{return true;}), //Will need canAvoid logic with enemy shuffle - Entrance(RR_DEKU_TREE_MQ_3F, []{return true;}), + Entrance(RR_DEKU_TREE_MQ_3F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}), Entrance(RR_DEKU_TREE_MQ_EYE_TARGET_ROOM, []{return Here(RR_DEKU_TREE_MQ_2F, []{return logic->HasFireSource();});}), }); @@ -271,7 +291,7 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_COMPASS_ROOM] = Region("Deku Tree MQ Compass Room", SCENE_DEKU_TREE, {}, { //Locations - LOCATION(RC_DEKU_TREE_MQ_COMPASS_CHEST, true), + LOCATION(RC_DEKU_TREE_MQ_COMPASS_CHEST, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)), LOCATION(RC_DEKU_TREE_MQ_COMPASS_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_COMPASS_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_COMPASS_GRASS_3, logic->CanCutShrubs()), @@ -279,13 +299,16 @@ void RegionTable_Init_DekuTree() { }, { //Exits Entrance(RR_DEKU_TREE_MQ_EYE_TARGET_ROOM, []{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_HOVER_BOOTS);}), - Entrance(RR_DEKU_TREE_MQ_PAST_BOULDER_VINES, []{return Here(RR_DEKU_TREE_MQ_COMPASS_ROOM, []{return logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS))) || (logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS)));});}), + Entrance(RR_DEKU_TREE_MQ_PAST_BOULDER_VINES, []{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && Here(RR_DEKU_TREE_MQ_COMPASS_ROOM, []{return logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS))) || (logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) && logic->HasItem(RG_CLIMB))));});}), }); areaTable[RR_DEKU_TREE_MQ_PAST_BOULDER_VINES] = Region("Deku Tree MQ Past Boulder Vines", SCENE_DEKU_TREE, {}, { //Locations LOCATION(RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, true), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_1, true), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_2, true), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_3, true), }, { //Exits Entrance(RR_DEKU_TREE_MQ_COMPASS_ROOM, []{return logic->BlastOrSmash();}), @@ -304,7 +327,7 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_4, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_DEKU_TREE_MQ_1F, []{return true;}), + Entrance(RR_DEKU_TREE_MQ_1F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM, []{return Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanHitEyeTargets();});}), //includes RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM Access, other fire sources clear directly from there Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanHitEyeTargets();}) && logic->ClearedMQDekuSERoom && Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanUse(RG_STICKS);});}), @@ -384,7 +407,7 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_5, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->IsChild && Here(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->CanUse(RG_CRAWL) && Here(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHWEST_ROOM, []{return true;}), //Using a bow to get past here as adult is a bit precise on standing position but simple, doing as as child requires a side-hop with the bow out to shoot through the torch and may be trick worthy Entrance(RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM, []{return Here(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}), @@ -412,7 +435,7 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, []{return logic->IsChild;}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, []{return logic->CanUse(RG_CRAWL);}), Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return true;}), //If strength 0 is shuffled, add hovers or block push to the stick check //recoiling to skip swim is possible, but would be a trick @@ -429,7 +452,7 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_3, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->HasItem(RG_CLIMB) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT));}), Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, []{return Here(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, []{return logic->CanReflectNuts();});}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index d8e64f9969d..5dfd7c600f4 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -124,7 +124,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_STAIRS_UPPER] = Region("Dodongos Cavern Stairs Upper", SCENE_DODONGOS_CAVERN, {}, { //Locations LOCATION(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, Here(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->HookshotOrBoomerang();}) || logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, logic->IsAdult || logic->CanAttack() || (HasAccessTo(RR_DODONGOS_CAVERN_STAIRS_LOWER) && logic->CanUse(RG_LONGSHOT) && ctx->GetTrickOption(RT_DC_VINES_GS))), + LOCATION(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, logic->HasItem(RG_CLIMB) ? (logic->IsAdult || logic->CanAttack() || (HasAccessTo(RR_DODONGOS_CAVERN_STAIRS_LOWER) && logic->CanUse(RG_LONGSHOT) && ctx->GetTrickOption(RT_DC_VINES_GS))) : logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_1, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_3, logic->CanBreakPots()), @@ -157,7 +157,7 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_BLADE_GRASS, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_ARMOS_ROOM, []{return true;}), + Entrance(RR_DODONGOS_CAVERN_ARMOS_ROOM, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_DODONGOS_CAVERN_2F_SIDE_ROOM, []{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->CanBreakMudWalls() || (ctx->GetTrickOption(RT_DC_SCRUB_ROOM) && logic->HasItem(RG_GORONS_BRACELET));});}), Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, []{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}), Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, []{return (logic->IsAdult && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}), @@ -266,6 +266,8 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku()), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_BEGINNING, []{return true;}), @@ -293,7 +295,12 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE] = Region("Dodongos Cavern MQ Mouth Side Bridge", SCENE_DODONGOS_CAVERN, { //Events EventAccess(&logic->ClearMQDCUpperLobbyRocks, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}), - }, {}, { + }, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, logic->ClearMQDCUpperLobbyRocks), + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, logic->ClearMQDCUpperLobbyRocks), + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, logic->ClearMQDCUpperLobbyRocks), + }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return true;}), Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return logic->ClearMQDCUpperLobbyRocks;}), @@ -420,6 +427,18 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, logic->BlastOrSmash() && logic->TakeDamage()), }, { //Exits //Falling down gets you stuck with nothing there, not a useful exit for logic @@ -461,6 +480,8 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return true;}), @@ -573,19 +594,20 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BOSS_ROOM] = Region("Dodongos Cavern Boss Room", SCENE_DODONGOS_CAVERN_BOSS, { // Events // Blue Fire Arrows need similar accuracy as hammer trick, only put in logic when both hammer & blue fire tricks enabled - EventAccess(&logic->DodongosCavernClear, []{return Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || + EventAccess(&logic->DodongosCavernWin, []{return Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || (ctx->GetTrickOption(RT_DC_HAMMER_FLOOR) ? logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->BlueFire()) : ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE));}) && logic->CanKillEnemy(RE_KING_DODONGO);}), + EventAccess(&logic->DodongosCavernClear, []{return logic->DodongosCavernWin && logic->HasSage(RG_DARUNIA_SOUL);}), }, { // Locations LOCATION(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, true), - LOCATION(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, logic->DodongosCavernClear), + LOCATION(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, logic->DodongosCavernWin), LOCATION(RC_KING_DODONGO, logic->DodongosCavernClear), }, { // Exits Entrance(RR_DODONGOS_CAVERN_BOSS_EXIT, []{return true;}), - Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->DodongosCavernClear;}, false), + Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->DodongosCavernWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index f57d6bd2186..d911f57acbf 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -11,7 +11,7 @@ void RegionTable_Init_FireTemple() { //Exits Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla();}), Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ();}), - Entrance(RR_DMC_CENTRAL_LOCAL, []{return true;}), + Entrance(RR_DMC_OUTSIDE_FIRE_TEMPLE, []{return true;}), }); #pragma region Vanilla @@ -130,13 +130,13 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM] = Region("Fire Temple Fire Pillar Room", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, logic->FireTimer() >= 56), - LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, logic->FireTimer() >= 56), - LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, logic->FireTimer() >= 56), + LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, logic->FireTimer() >= 56 && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, logic->FireTimer() >= 56 && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, logic->FireTimer() >= 56 && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT))), }, { //Exits Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}), - Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return logic->FireTimer() >= 56 && logic->SmallKeys(RR_FIRE_TEMPLE, 4);}), + Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return logic->FireTimer() >= 56 && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->SmallKeys(RR_FIRE_TEMPLE, 4);}), }); areaTable[RR_FIRE_TEMPLE_SHORTCUT_ROOM] = Region("Fire Temple Shortcut Room", SCENE_FIRE_TEMPLE, {}, { @@ -146,13 +146,13 @@ void RegionTable_Init_FireTemple() { //Exits Entrance(RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 4);}), Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return Here(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return true;});}), - Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH)) && (logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT));}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->IsAdult && logic->HasItem(RG_CLIMB) && (logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH)) && (logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT));}), }); areaTable[RR_FIRE_TEMPLE_SHORTCUT_CLIMB] = Region("Fire Temple Shortcut Climb", SCENE_FIRE_TEMPLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return logic->HasItem(RG_CLIMB);}), }); areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER] = Region("Fire Temple Boulder Maze Lower", SCENE_FIRE_TEMPLE, {}, { @@ -222,11 +222,11 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_SCARECROW_ROOM] = Region("Fire Temple Scarecrow Room", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, logic->CanJumpslashExceptHammer() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, logic->HasItem(RG_CLIMB) && (logic->CanJumpslashExceptHammer() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE))), }, { //Exits Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_EAST_PEAK, []{return true;}), + Entrance(RR_FIRE_TEMPLE_EAST_PEAK, []{return logic->HasItem(RG_CLIMB);}), }); areaTable[RR_FIRE_TEMPLE_EAST_PEAK] = Region("Fire Temple East Peak", SCENE_FIRE_TEMPLE, {}, { @@ -314,7 +314,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_WEST_CLIMB] = Region("Fire Temple West Climb", SCENE_FIRE_TEMPLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_WEST_PEAK, []{return logic->CanUseProjectile();}), + Entrance(RR_FIRE_TEMPLE_WEST_PEAK, []{return logic->HasItem(RG_CLIMB) && logic->CanUseProjectile();}), }); areaTable[RR_FIRE_TEMPLE_WEST_PEAK] = Region("Fire Temple West Peak", SCENE_FIRE_TEMPLE, {}, { @@ -505,20 +505,20 @@ void RegionTable_Init_FireTemple() { //This room assumes Goron Tunic until looser tunic requirements tricks are made areaTable[RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM] = Region("Fire Temple MQ Elevator Room", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, true), - LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, true), - LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, true), + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}), }); areaTable[RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM] = Region("Fire Temple MQ Big Torch Room", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, []{return (logic->HasFireSource() && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, []{return logic->HasItem(RG_CLIMB) && ((logic->HasFireSource() && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->CanUse(RG_HOVER_BOOTS)));}), Entrance(RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM, []{return logic->CanUse(RG_GORON_TUNIC);}), - Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE, []{return logic->OpenedUpperFireShortcut;}), + Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE, []{return logic->OpenedUpperFireShortcut && logic->HasItem(RG_CLIMB);}), }); areaTable[RR_FIRE_TEMPLE_MQ_LOWER_MAZE] = Region("Fire Temple MQ Lower Maze", SCENE_FIRE_TEMPLE, {}, { @@ -605,11 +605,11 @@ void RegionTable_Init_FireTemple() { }, { //Locations //There's definitely ways to do this hammerless, but with one points on it's a trick - LOCATION(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, logic->HasItem(RG_CLIMB) && logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, []{return logic->TakeDamage();}), + Entrance(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, []{return logic->HasItem(RG_CLIMB) && logic->TakeDamage();}), }); areaTable[RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM] = Region("Fire Temple MQ Narrow Path Room", SCENE_FIRE_TEMPLE, { @@ -712,14 +712,14 @@ void RegionTable_Init_FireTemple() { //Locations //This requires nothing in N64 logic, but is tight enough to need rollspam with the one-point on which is stricter than I would normally consider in logic //Child basically needs the scarecrow or a bunny hood though due to a worse ledge grab. - LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, logic->IsAdult || logic->CanUse(RG_SCARECROW)), + LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, logic->HasItem(RG_CLIMB) && (logic->IsAdult || logic->CanUse(RG_SCARECROW))), }, { //The dropdown here is unusual in that it hits 1 of 3 locations: RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS and the section of RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS with the hammer switch //Using this dropdown is in N64 logic elsewhere, but not here, probably because it requires good foreknowlege to determine where to land //This would be a logical method to reach the hammer switch without hookshot, but it practically requires access to the area that switch unlocks already. It could also be first child access to PLATFORMS if tricks ever enable that //If a practical use for this drop is found, it should be made a trick Entrance(RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 4);}), - Entrance(RR_FIRE_TEMPLE_MQ_COLLAPSED_STAIRS, []{return Here(RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && logic->SmallKeys(RR_FIRE_TEMPLE, 5);}), + Entrance(RR_FIRE_TEMPLE_MQ_COLLAPSED_STAIRS, []{return logic->HasItem(RG_CLIMB) && Here(RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && logic->SmallKeys(RR_FIRE_TEMPLE, 5);}), }); //The peg knocked down from here could have logical implications for child in the fire maze if tricks to gain height like bomb jumps exist @@ -744,15 +744,16 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_BOSS_ROOM] = Region("Fire Temple Boss Room", SCENE_FIRE_TEMPLE_BOSS, { // Events - EventAccess(&logic->FireTempleClear, []{return logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA);}), + EventAccess(&logic->FireTempleWin, []{return logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA);}), + EventAccess(&logic->FireTempleClear, []{return logic->FireTempleWin && logic->HasSage(RG_DARUNIA_SOUL);}), }, { // Locations - LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->FireTempleClear), + LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->FireTempleWin), LOCATION(RC_VOLVAGIA, logic->FireTempleClear), }, { // Exits Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTempleClear;}, false), + Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTempleWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index a4a55829795..6c62d0c65b9 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -18,8 +18,8 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_FIRST_ROOM] = Region("Forest Temple First Room", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, true), - LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->IsAdult && logic->CanUse(RG_BOMB_BAG)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_FOREST_FIRST_GS) && (logic->CanJumpslashExceptHammer() || (logic->IsChild && logic->CanUse(RG_BOMB_BAG))))), + LOCATION(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && ((logic->IsAdult && logic->CanUse(RG_BOMB_BAG)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_FOREST_FIRST_GS) && (logic->CanJumpslashExceptHammer() || (logic->IsChild && logic->CanUse(RG_BOMB_BAG)))))), }, { //Exits Entrance(RR_FOREST_TEMPLE_ENTRYWAY, []{return true;}), @@ -87,8 +87,8 @@ void RegionTable_Init_ForestTemple() { }, { //Exits Entrance(RR_FOREST_TEMPLE_LOBBY, []{return logic->CanUse(RG_SONG_OF_TIME);}), - Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS);}), - Entrance(RR_FOREST_TEMPLE_MAP_ROOM, []{return true;}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}), Entrance(RR_FOREST_TEMPLE_SEWER, []{return logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS) || HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER);}), Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return false;}), }); @@ -152,8 +152,8 @@ void RegionTable_Init_ForestTemple() { LOCATION(RC_FOREST_TEMPLE_WELL_EAST_HEART, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)), }, { //Exits - Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, []{return true;}), - Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, []{return true;}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, []{return logic->HasItem(RG_CLIMB);}), + Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}), }); areaTable[RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST] = Region("Forest Temple Below Boss Key Chest", SCENE_FOREST_TEMPLE, {}, {}, { @@ -177,13 +177,13 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM] = Region("Forest Temple Block Push Room", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, logic->HasItem(RG_CLIMB) && logic->HasItem(RG_GORONS_BRACELET) && logic->CanHitEyeTargets()), }, { //Exits Entrance(RR_FOREST_TEMPLE_WEST_CORRIDOR, []{return true;}), - Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && logic->CanJumpslashExceptHammer() && logic->HasItem(RG_GORONS_BRACELET));}), - Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED, []{return logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET) && logic->SmallKeys(RR_FOREST_TEMPLE, 2);}), - Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED, []{return logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)) && logic->HasItem(RG_GORONS_BRACELET) && logic->SmallKeys(RR_FOREST_TEMPLE, 2);}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return logic->HasItem(RG_CLIMB) && logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && logic->CanJumpslashExceptHammer() && logic->HasItem(RG_GORONS_BRACELET));}), + Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED, []{return logic->IsAdult && logic->HasItem(RG_CLIMB) && logic->HasItem(RG_GORONS_BRACELET) && logic->SmallKeys(RR_FOREST_TEMPLE, 2);}), + Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED, []{return logic->IsAdult && logic->HasItem(RG_CLIMB) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)) && logic->HasItem(RG_GORONS_BRACELET) && logic->SmallKeys(RR_FOREST_TEMPLE, 2);}), }); areaTable[RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED] = Region("Forest Temple NW Corridor Twisted", SCENE_FOREST_TEMPLE, {}, {}, { @@ -307,7 +307,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_LOBBY] = Region("Forest Temple MQ Lobby", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA, ED_SHORT_JUMPSLASH, false) || logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && (logic->CanPassEnemy(RE_BIG_SKULLTULA, ED_SHORT_JUMPSLASH, false) || logic->CanUse(RG_HOVER_BOOTS))), //Implies CanPassEnemy(RE_BIG_SKULLTULA) LOCATION(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, logic->HookshotOrBoomerang()), }, { @@ -362,9 +362,9 @@ void RegionTable_Init_ForestTemple() { }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return Here(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->CanKillEnemy(RE_STALFOS);});}), - Entrance(RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE, []{return logic->HasItem(RG_GORONS_BRACELET) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE, []{return (logic->HasItem(RG_CLIMB) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_HOOKSHOT));}), //Assumes RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE access - Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return (logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return (logic->IsAdult && logic->HasItem(RG_CLIMB) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_HOOKSHOT));}), Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, []{return logic->ForestCanTwistHallway && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}), }); @@ -375,7 +375,7 @@ void RegionTable_Init_ForestTemple() { }, {}, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE, []{return true;}), - Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return (logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return (logic->IsAdult && logic->HasItem(RG_CLIMB) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_HOOKSHOT));}), //Hammer cannot recoil from here, but can make the jump forwards with a hammer jumpslash as adult Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, []{return logic->ForestCanTwistHallway && logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && (logic->CanJumpslashExceptHammer() || (logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER))));}), }); @@ -433,8 +433,8 @@ void RegionTable_Init_ForestTemple() { LOCATION(RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, []{return (((logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_MQ_WELL_SWIM) && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_BRONZE_SCALE)) || logic->HasItem(RG_GOLDEN_SCALE)) && logic->WaterTimer() >= 16;}), - Entrance(RR_FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES, []{return logic->CanUse(RG_FIRE_ARROWS);}), + Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, []{return logic->HasItem(RG_CLIMB) && (((logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_MQ_WELL_SWIM) && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_BRONZE_SCALE)) || logic->HasItem(RG_GOLDEN_SCALE)) && logic->WaterTimer() >= 16;}), + Entrance(RR_FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES, []{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->CanUse(RG_FIRE_ARROWS);}), }); //The well only coniders the eye target here because the eye target is a temp flag, making it unwieldy to use as an EventAccess to make it it's own room @@ -453,7 +453,7 @@ void RegionTable_Init_ForestTemple() { LOCATION(RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) || logic->CanHitEyeTargets()), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, []{return (((logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_BRONZE_SCALE)) || logic->HasItem(RG_GOLDEN_SCALE)) && logic->WaterTimer() >= 16;}), + Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, []{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && (((logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_BRONZE_SCALE)) || logic->HasItem(RG_GOLDEN_SCALE)) && logic->WaterTimer() >= 16;}), Entrance(RR_FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES, []{return logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && ((logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanUse(RG_SONG_OF_TIME)));}), Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, []{return logic->CanUse(RG_LONGSHOT);}), }); @@ -606,15 +606,16 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Region("Forest Temple Boss Room", SCENE_FOREST_TEMPLE_BOSS, { // Events - EventAccess(&logic->ForestTempleClear, []{return logic->CanKillEnemy(RE_PHANTOM_GANON);}), + EventAccess(&logic->ForestTempleWin, []{return logic->CanKillEnemy(RE_PHANTOM_GANON);}), + EventAccess(&logic->ForestTempleClear, []{return logic->ForestTempleWin && logic->HasSage(RG_SARIA_SOUL);}), }, { // Locations - LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->ForestTempleClear), + LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->ForestTempleWin), LOCATION(RC_PHANTOM_GANON, logic->ForestTempleClear), }, { // Exits Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->ForestTempleClear;}, false), + Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->ForestTempleWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index 8571ba38442..73f8a82af0f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -19,7 +19,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_LOBBY] = Region("Ganon's Castle Lobby", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_SHEIK_HINT_GC, true), + LOCATION(RC_SHEIK_HINT_GC, logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_GANONS_CASTLE_ENTRYWAY, []{return true;}), @@ -147,7 +147,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_MAIN] = Region("Ganon's Castle MQ Main", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_SHEIK_HINT_MQ_GC, true), + LOCATION(RC_SHEIK_HINT_MQ_GC, logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_LOBBY, []{return true;}), @@ -483,7 +483,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_TOWER_GANONDORF_LAIR] = Region("Ganondorf's Lair", SCENE_GANONDORF_BOSS, {}, { //Locations - LOCATION(RC_GANONDORF_HINT, logic->HasBossSoul(RG_GANON_SOUL)), + LOCATION(RC_GANONDORF_HINT, logic->HasSoul(RG_GANON_SOUL)), }, { //Exits Entrance(RR_GANONS_CASTLE_ESCAPE, []{return logic->CanKillEnemy(RE_GANONDORF);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index 2eb8764e13f..de2be209bef 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -35,7 +35,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE] = Region("Gerudo Training Ground Central Maze", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || logic->HasItem(RG_CLIMB))), LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 4)), LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 6)), LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 7)), @@ -125,7 +125,7 @@ void RegionTable_Init_GerudoTrainingGround() { }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, []{return true;}), - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_HIDDEN_ROOM, []{return ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_HIDDEN_ROOM, []{return ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH) && (logic->CanUse(RG_HOOKSHOT) || logic->HasItem(RG_CLIMB));}), Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_FIRST_LOCK, []{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 1);}), //It's possible to use the torch in RR_GERUDO_TRAINING_GROUND_MQ_MAZE_HIDDEN_ROOM with flame storage to light these Entrance(RR_GERUDO_TRAINING_GROUND_MQ_SAND_ROOM, []{return Here(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return logic->HasFireSource();});}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 5151377ce20..83ea456e126 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -33,7 +33,7 @@ void RegionTable_Init_IceCavern() { LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->IsAdult), LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->BlueFire()), LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS)), - LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS) && logic->IsAdult), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS) && logic->IsAdult && logic->HasSoul(RG_ZELDA_SOUL)), LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->BlueFire()), LOCATION(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, logic->HookshotOrBoomerang()), LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->BlueFire() && logic->HookshotOrBoomerang()), @@ -123,7 +123,7 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MQ_STALFOS_ROOM] = Region("Ice Cavern MQ Stalfos Room", SCENE_ICE_CAVERN, {}, { //Locations LOCATION(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, logic->CanKillEnemy(RE_STALFOS)), - LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_STALFOS)), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_STALFOS) && logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_ICE_CAVERN_MQ_WEST_CORRIDOR, []{return Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp index c40ccf80554..2f6e7f3ee84 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp @@ -48,7 +48,7 @@ void RegionTable_Init_JabuJabusBelly() { //contains B1 of hole room (aside from the ledge leading to big octo), 2 octorock room and north water switch room areaTable[RR_JABU_JABUS_BELLY_B1_NORTH] = Region("Jabu Jabus Belly B1 North", SCENE_JABU_JABU, { //Events - EventAccess(&logic->JabuRutoIn1F, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}), + EventAccess(&logic->JabuRutoIn1F, []{return logic->HasSoul(RG_RUTO_SOUL) && (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE));}), EventAccess(&logic->FairyPot, []{return logic->CanUse(RG_BOOMERANG) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_OCTOROK));}), }, { //Locations @@ -64,7 +64,7 @@ void RegionTable_Init_JabuJabusBelly() { //Exits Entrance(RR_JABU_JABUS_BELLY_MAIN, []{return true;}), //there's tricks for getting here with bunny-jumps or just side-hops - Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->HasItem(RG_HOVER_BOOTS);}), + Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return (logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CLIMB)) || logic->HasItem(RG_HOVER_BOOTS);}), Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_SOUTH, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}), }); @@ -90,7 +90,7 @@ void RegionTable_Init_JabuJabusBelly() { }, { //Exits Entrance(RR_JABU_JABUS_BELLY_B1_NORTH, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}), - Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->HasItem(RG_HOVER_BOOTS);}), + Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CLIMB) || logic->HasItem(RG_HOVER_BOOTS);}), Entrance(RR_JABU_JABUS_BELLY_MAIN, []{return logic->CanUseProjectile();}), }); @@ -155,11 +155,11 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM] = Region("Jabu Jabus Belly Near Boss Room", SCENE_JABU_JABU, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)), + LOCATION(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) && (logic->HasItem(RG_CLIMB) || logic->HookshotOrBoomerang())), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MAIN, []{return true;}), - Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, []{return logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_EXPLOSIVES) && (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_BOMB_BAG))));}), + Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, []{return (logic->HasItem(RG_CLIMB) && logic->CanUse(RG_BOOMERANG)) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_EXPLOSIVES) && (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_BOMB_BAG))));}), }); #pragma endregion @@ -177,6 +177,7 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, logic->BlastOrSmash()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, []{return true;}), @@ -229,6 +230,11 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, logic->HasExplosives()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, []{return true;}), @@ -241,8 +247,8 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM] = Region("Jabu Jabus Belly MQ Water Switch Room", SCENE_JABU_JABU, {}, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, true), - //Implies logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_STINGER). Without swim, jump from the song of time block to the vines. - LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, logic->CanKillEnemy(RE_LIZALFOS)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, (logic->IsAdult || logic->HasItem(RG_CLIMB)) && logic->CanKillEnemy(RE_LIZALFOS)), + //Implies logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_STINGER). Without swim, jump from the song of time block to the vines. LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, (logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || (ctx->GetTrickOption(RT_JABU_MQ_SOT_GS) && logic->CanUse(RG_BOOMERANG))), LOCATION(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, logic->CanBreakPots()), @@ -267,6 +273,8 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, logic->CanBreakSmallCrates()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, logic->BlastOrSmash()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return logic->CanUse(RG_BOOMERANG);}), @@ -280,6 +288,8 @@ void RegionTable_Init_JabuJabusBelly() { }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, Here(RR_JABU_JABUS_BELLY_MQ_WEST_FORKED_ROOMS, []{return logic->HasExplosives();}) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, logic->HasExplosives()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, []{return true;}), @@ -339,7 +349,7 @@ void RegionTable_Init_JabuJabusBelly() { }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, logic->HasItem(RG_CLIMB) && (logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_HOOKSHOT)))), LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2, logic->CanCutShrubs()), @@ -365,7 +375,8 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_BOSS_ROOM] = Region("Jabu Jabus Belly Boss Room", SCENE_JABU_JABU_BOSS, { // Events //todo: add pot kill trick - EventAccess(&logic->JabuJabusBellyClear, []{return logic->CanKillEnemy(RE_BARINADE);}), + EventAccess(&logic->JabuJabusBellyWin, []{return logic->CanKillEnemy(RE_BARINADE);}), + EventAccess(&logic->JabuJabusBellyClear, []{return logic->JabuJabusBellyWin && logic->HasSage(RG_RUTO_SOUL);}), }, { // Locations LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_1, logic->CanBreakPots()), @@ -374,12 +385,12 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_4, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_5, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_6, logic->CanBreakPots()), - LOCATION(RC_JABU_JABUS_BELLY_BARINADE_HEART, logic->JabuJabusBellyClear), + LOCATION(RC_JABU_JABUS_BELLY_BARINADE_HEART, logic->JabuJabusBellyWin), LOCATION(RC_BARINADE, logic->JabuJabusBellyClear), }, { // Exits Entrance(RR_JABU_JABUS_BELLY_BOSS_EXIT, []{return false;}), - Entrance(RR_ZORAS_FOUNTAIN, []{return logic->JabuJabusBellyClear;}, false), + Entrance(RR_ZORAS_FOUNTAIN, []{return logic->JabuJabusBellyWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index d276fc41899..aab680b5eae 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -409,15 +409,16 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", SCENE_SHADOW_TEMPLE_BOSS, { // Events - EventAccess(&logic->ShadowTempleClear, []{return logic->CanKillEnemy(RE_BONGO_BONGO);}), + EventAccess(&logic->ShadowTempleWin, []{return logic->CanKillEnemy(RE_BONGO_BONGO);}), + EventAccess(&logic->ShadowTempleClear, []{ return logic->ShadowTempleWin && logic->HasSage(RG_IMPA_SOUL); }), }, { // Locations - LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->ShadowTempleClear), + LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->ShadowTempleWin), LOCATION(RC_BONGO_BONGO, logic->ShadowTempleClear), }, { // Exits Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return logic->ShadowTempleClear;}, false), + Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return logic->ShadowTempleWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index 2755fe453be..63fa6d21c72 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -23,7 +23,7 @@ void RegionTable_Init_SpiritTemple() { }, { //Exits Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}), - Entrance(RR_SPIRIT_TEMPLE_CHILD, []{return logic->IsChild;}), + Entrance(RR_SPIRIT_TEMPLE_CHILD, []{return logic->CanUse(RG_CRAWL);}), Entrance(RR_SPIRIT_TEMPLE_EARLY_ADULT, []{return logic->CanUse(RG_SILVER_GAUNTLETS);}), }); @@ -32,18 +32,20 @@ void RegionTable_Init_SpiritTemple() { EventAccess(&logic->NutCrate, []{return true;}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))), - LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_1, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_2, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_3, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_4, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, logic->CanBreakSmallCrates()), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))), + LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && ((logic->CanUse(RG_STICKS) && logic->HasItem(RG_CLIMB)) || logic->CanUse(RG_DINS_FIRE))), + LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_1, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_2, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_3, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_4, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, logic->CanBreakSmallCrates()), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}), + Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, []{return logic->CanUse(RG_CRAWL) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 1) && logic->HasItem(RG_CLIMB);}), }); areaTable[RR_SPIRIT_TEMPLE_CHILD_CLIMB] = Region("Child Spirit Temple Climb", SCENE_SPIRIT_TEMPLE, {}, { @@ -64,13 +66,13 @@ void RegionTable_Init_SpiritTemple() { //Locations LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY)), LOCATION(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslashExceptHammer())), - LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)), - LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)), + LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT))), + LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT))), LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH)))), LOCATION(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash())), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}), + Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));}), }); areaTable[RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER] = Region("Spirit Temple Central Chamber", SCENE_SPIRIT_TEMPLE, {}, { @@ -162,10 +164,14 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, logic->CanUse(RG_BOMBCHU_5)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}), - Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->IsChild;}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanUse(RG_CRAWL);}), Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH, []{return logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_BOMBCHU_5);}), }); @@ -179,11 +185,12 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, logic->CanHitEyeTargets()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, logic->CanHitEyeTargets()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->MQSpiritTimeTravelChest), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH, []{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}), Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH, []{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}), - Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, []{return logic->IsChild && logic->MQSpiritCrawlBoulder;}), + Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, []{return logic->CanUse(RG_CRAWL) && logic->MQSpiritCrawlBoulder;}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH] = Region("Spirit Temple MQ 1F Gibdo Room South", SCENE_SPIRIT_TEMPLE, {}, {}, { @@ -249,7 +256,7 @@ void RegionTable_Init_SpiritTemple() { EventAccess(&logic->MQSpiritCrawlBoulder, []{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}), }, {}, { //Exits - Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->IsChild && logic->MQSpiritCrawlBoulder;}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanUse(RG_CRAWL) && logic->MQSpiritCrawlBoulder;}), //This tracks possible child access, if adult has not entered STATUE_ROOM. Certain Child Access is checked for separately as 7 Keys Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}), }); @@ -261,7 +268,7 @@ void RegionTable_Init_SpiritTemple() { //Exits //This covers adult access only, as child arrives here from the other side of this door Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}), - Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanHitSwitch();}), + Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanHitSwitch() && logic->HasItem(RG_CLIMB);}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM] = Region("Spirit Temple MQ Broken Wall Room", SCENE_SPIRIT_TEMPLE, {}, { @@ -394,6 +401,7 @@ void RegionTable_Init_SpiritTemple() { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, logic->BlastOrSmash()), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->CanUse(RG_MEGATON_HAMMER);}), @@ -556,15 +564,16 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", SCENE_SPIRIT_TEMPLE_BOSS, { // Events - EventAccess(&logic->SpiritTempleClear, []{return logic->CanKillEnemy(RE_TWINROVA);}), + EventAccess(&logic->SpiritTempleWin, []{return logic->CanKillEnemy(RE_TWINROVA);}), + EventAccess(&logic->SpiritTempleClear, []{return logic->SpiritTempleWin && logic->HasSage(RG_NABOORU_SOUL);}), }, { // Locations - LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->SpiritTempleClear), + LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->SpiritTempleWin), LOCATION(RC_TWINROVA, logic->SpiritTempleClear), }, { // Exits Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_DESERT_COLOSSUS, []{return logic->SpiritTempleClear;}, false), + Entrance(RR_DESERT_COLOSSUS, []{return logic->SpiritTempleWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index 03cc4464582..433e5d60578 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -772,7 +772,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - + }, { //Exits @@ -847,15 +847,16 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", SCENE_WATER_TEMPLE_BOSS, { // Events - EventAccess(&logic->WaterTempleClear, []{return logic->CanKillEnemy(RE_MORPHA);}), + EventAccess(&logic->WaterTempleWin, []{return logic->CanKillEnemy(RE_MORPHA);}), + EventAccess(&logic->WaterTempleClear, []{return logic->WaterTempleWin && logic->HasSage(RG_RUTO_SOUL);}), }, { // Locations - LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->WaterTempleClear), + LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->WaterTempleWin), LOCATION(RC_MORPHA, logic->WaterTempleClear), }, { // Exits Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_LAKE_HYLIA, []{return logic->WaterTempleClear;}, false), + Entrance(RR_LAKE_HYLIA, []{return logic->WaterTempleWin;}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index b9525386ca8..9fe7b759f79 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -12,33 +12,64 @@ void RegionTable_Init_CastleGrounds() { areaTable[RR_CASTLE_GROUNDS] = Region("Castle Grounds", SCENE_OUTSIDE_GANONS_CASTLE, TIME_DOESNT_PASS, {RA_CASTLE_GROUNDS}, {}, {}, { //Exits Entrance(RR_THE_MARKET, []{return true;}), - Entrance(RR_HYRULE_CASTLE_GROUNDS, []{return logic->IsChild;}), + Entrance(RR_HC_GATE, []{return logic->IsChild;}), Entrance(RR_GANONS_CASTLE_GROUNDS, []{return logic->IsAdult;}), }); + areaTable[RR_HC_GATE] = Region("Hyrule Castle Gate", SCENE_HYRULE_CASTLE, { + //Events + EventAccess(&logic->BugRock, []{return true;}), + }, { + //Locations + LOCATION(RC_HC_MALON_EGG, logic->HasSoul(RG_MALON_SOUL)), + LOCATION(RC_HC_GS_TREE, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()), + }, { + //Exits + Entrance(RR_HYRULE_CASTLE_GROUNDS, []{return logic->HasItem(RG_ZELDAS_LETTER) || logic->HasItem(RG_CLIMB);}), + }); + areaTable[RR_HYRULE_CASTLE_GROUNDS] = Region("Hyrule Castle Grounds", SCENE_HYRULE_CASTLE, { //Events EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}), EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}), - EventAccess(&logic->BugRock, []{return true;}), }, { //Locations - LOCATION(RC_HC_MALON_EGG, true), - LOCATION(RC_HC_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), - LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), - LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + // jumping past guard would be a trick + LOCATION(RC_HC_MALON_GOSSIP_STONE, logic->HasItem(RG_CLIMB)), + }, { + //Exits + Entrance(RR_HC_MOAT, []{return logic->HasItem(RG_CLIMB);}), + Entrance(RR_HC_GREAT_FAIRY_FOUNTAIN, []{return logic->CanUse(RG_CRAWL) && logic->BlastOrSmash();}), + }); + + areaTable[RR_HC_MOAT] = Region("Hyrule Castle Grounds", SCENE_HYRULE_CASTLE, {}, { + //Locations + LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true), LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_HC_MALON_GOSSIP_STONE, true), - LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true), + LOCATION(RC_HC_ROCK_1, true), + LOCATION(RC_HC_ROCK_2, true), + LOCATION(RC_HC_ROCK_3, true), + LOCATION(RC_HC_BOULDER, logic->BlastOrSmash()), LOCATION(RC_HC_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_HC_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_HC_GROTTO_TREE, logic->CanBonkTrees()), + LOCATION(RC_HC_NL_TREE_1, false), + LOCATION(RC_HC_NL_TREE_2, false), + LOCATION(RC_HC_SKULLTULA_TREE, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_6, logic->CanBonkTrees()), }, { //Exits - Entrance(RR_CASTLE_GROUNDS, []{return true;}), - Entrance(RR_HC_GARDEN, []{return logic->CanUse(RG_WEIRD_EGG) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}), - Entrance(RR_HC_GREAT_FAIRY_FOUNTAIN, []{return logic->BlastOrSmash();}), - Entrance(RR_HC_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), + Entrance(RR_HC_GATE, []{return true;}), + Entrance(RR_HC_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), + Entrance(RR_HC_GARDEN, []{return logic->CanUse(RG_CRAWL) && logic->CanUse(RG_WEIRD_EGG) || !ctx->GetOption(RSK_SHUFFLE_WEIRD_EGG) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}), }); areaTable[RR_HC_GARDEN] = Region("HC Garden", SCENE_CASTLE_COURTYARD_ZELDA, {}, { @@ -52,7 +83,7 @@ void RegionTable_Init_CastleGrounds() { areaTable[RR_HC_GREAT_FAIRY_FOUNTAIN] = Region("HC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, {}, { //Locations - LOCATION(RC_HC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_HC_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_CASTLE_GROUNDS, []{return true;}), @@ -63,7 +94,7 @@ void RegionTable_Init_CastleGrounds() { LOCATION(RC_HC_GS_STORMS_GROTTO, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_HC_STORMS_GS)), }, { //Exits - Entrance(RR_CASTLE_GROUNDS, []{return true;}), + Entrance(RR_HC_MOAT, []{return true;}), Entrance(RR_HC_STORMS_GROTTO_BEHIND_WALLS, []{return logic->CanBreakMudWalls();}), }); @@ -82,6 +113,14 @@ void RegionTable_Init_CastleGrounds() { LOCATION(RC_HC_STORMS_GROTTO_POT_2, logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_3, logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_4, logic->CanBreakPots()), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_1, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_2, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_3, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_4, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_5, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_6, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_7, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_8, true), }, { //Exits Entrance(RR_HC_STORMS_GROTTO, []{return true;}), @@ -92,7 +131,14 @@ void RegionTable_Init_CastleGrounds() { EventAccess(&logic->BuiltRainbowBridge, []{return logic->CanBuildRainbowBridge();}), }, { //Locations - LOCATION(RC_OGC_GS, logic->CanJumpslashExceptHammer() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_OGC_GS, logic->CanJumpslashExceptHammer() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_OGC_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_SILVER_BOULDER_1, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_2, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_3, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_4, logic->CanUse(RG_SILVER_GAUNTLETS)), }, { //Exits Entrance(RR_CASTLE_GROUNDS, []{return logic->AtNight;}), @@ -102,7 +148,7 @@ void RegionTable_Init_CastleGrounds() { areaTable[RR_OGC_GREAT_FAIRY_FOUNTAIN] = Region("OGC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, {}, { //Locations - LOCATION(RC_OGC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_OGC_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_CASTLE_GROUNDS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp index be1b2043afa..f8ef4a8a7d6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp @@ -5,7 +5,21 @@ using namespace Rando; void RegionTable_Init_DeathMountainCrater() { // clang-format off - areaTable[RR_DMC_UPPER_NEARBY] = Region("DMC Upper Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, {}, { + areaTable[RR_DMC_UPPER_NEARBY] = Region("DMC Upper Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, { + LOCATION(RC_DMC_CIRCLE_ROCK_1, true), + LOCATION(RC_DMC_CIRCLE_ROCK_2, true), + LOCATION(RC_DMC_CIRCLE_ROCK_3, true), + LOCATION(RC_DMC_CIRCLE_ROCK_4, true), + LOCATION(RC_DMC_CIRCLE_ROCK_5, true), + LOCATION(RC_DMC_CIRCLE_ROCK_6, true), + LOCATION(RC_DMC_CIRCLE_ROCK_7, true), + LOCATION(RC_DMC_CIRCLE_ROCK_8, true), + LOCATION(RC_DMC_GOSSIP_ROCK_1, logic->IsChild), + LOCATION(RC_DMC_GOSSIP_ROCK_2, logic->IsChild), + LOCATION(RC_DMC_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_DMC_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_DMC_BOULDER_3, logic->BlastOrSmash()), + }, { //Exits Entrance(RR_DMC_UPPER_LOCAL, []{return logic->FireTimer() >= 48;}), Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return true;}), @@ -38,16 +52,20 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_DEKU_SCRUB, logic->IsChild && logic->CanStunDeku()), }, { //Exits - Entrance(RR_DMC_UPPER_NEARBY, []{return logic->Hearts() >= 3;}), + Entrance(RR_DMC_UPPER_NEARBY, []{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->Hearts() >= 3;}), Entrance(RR_DMC_LOWER_NEARBY, []{return logic->Hearts() >= 3 && (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DMC_BOULDER_JS) && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)) || (ctx->GetTrickOption(RT_DMC_BOULDER_SKIP) && logic->IsAdult));}), }); areaTable[RR_DMC_LOWER_NEARBY] = Region("DMC Lower Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, { // Locations - LOCATION(RC_DMC_NEAR_GC_POT_1, logic->CanBreakPots()), - LOCATION(RC_DMC_NEAR_GC_POT_2, logic->CanBreakPots()), - LOCATION(RC_DMC_NEAR_GC_POT_3, logic->CanBreakPots()), - LOCATION(RC_DMC_NEAR_GC_POT_4, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_1, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_2, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_3, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_4, logic->CanBreakPots()), + LOCATION(RC_DMC_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_4, logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_DMC_LOWER_LOCAL, []{return logic->FireTimer() >= 48;}), @@ -67,7 +85,7 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_CENTRAL_NEARBY] = Region("DMC Central Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, { //Locations LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, logic->IsAdult && logic->Hearts() >= 3 && (CanPlantBean(RR_DMC_CENTRAL_LOCAL) || (ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)))), - LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult && (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTimer() >= 48;}), @@ -90,18 +108,23 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_1, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_2, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_3, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_4, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_5, logic->IsAdult), }, { //Exits - Entrance(RR_DMC_CENTRAL_NEARBY, []{return true;}), - Entrance(RR_DMC_LOWER_NEARBY, []{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_DMC_UPPER_NEARBY, []{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL);}), - Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return (logic->IsChild && logic->Hearts() >= 3 && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || (logic->IsAdult && logic->FireTimer() >= 24);}), - Entrance(RR_DMC_DISTANT_PLATFORM, []{return logic->FireTimer() >= 48 && logic->CanUse(RG_DISTANT_SCARECROW);}), + Entrance(RR_DMC_CENTRAL_NEARBY, []{return true;}), + Entrance(RR_DMC_LOWER_NEARBY, []{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_DMC_UPPER_NEARBY, []{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL);}), + Entrance(RR_DMC_OUTSIDE_FIRE_TEMPLE, []{return (logic->IsChild && logic->Hearts() >= 3 && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || (logic->IsAdult && logic->FireTimer() >= 24);}), + Entrance(RR_DMC_DISTANT_PLATFORM, []{return logic->FireTimer() >= 48 && logic->CanUse(RG_DISTANT_SCARECROW);}), }); areaTable[RR_DMC_GREAT_FAIRY_FOUNTAIN] = Region("DMC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, {}, { //Locations - LOCATION(RC_DMC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_DMC_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_DMC_LOWER_LOCAL, []{return true;}), @@ -150,5 +173,11 @@ void RegionTable_Init_DeathMountainCrater() { Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTimer() >= 48 && logic->CanUse(RG_DISTANT_SCARECROW);}), }); + areaTable[RR_DMC_OUTSIDE_FIRE_TEMPLE] = Region("DMC Outside Fire Temple", SCENE_DEATH_MOUNTAIN_CRATER, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return true;}), + Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTimer() >= 48 && logic->HasItem(RG_CLIMB);}), + }); + // clang-format on } diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp index dbf2189476b..b50bbf1b232 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp @@ -13,7 +13,7 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_CHEST, logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)))), LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_DMT_SOIL_GS) && (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_BOOMERANG)))), - LOCATION(RC_DMT_GS_NEAR_KAK, logic->BlastOrSmash()), + LOCATION(RC_DMT_GS_NEAR_KAK, logic->BlastOrSmash() && (logic->HasItem(RG_CLIMB) || logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG))), LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DMT_HOOKSHOT_LOWER_GS) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_DMT_JS_LOWER_GS)) && logic->CanGetNightTimeGS()), LOCATION(RC_DMT_BLUE_RUPEE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_DMT_RED_RUPEE, logic->IsChild && logic->BlastOrSmash()), @@ -21,40 +21,77 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_DMT_ROCK_1, true), + LOCATION(RC_DMT_ROCK_2, true), + LOCATION(RC_DMT_ROCK_3, true), + LOCATION(RC_DMT_ROCK_4, true), + LOCATION(RC_DMT_ROCK_5, true), + LOCATION(RC_DMT_CIRCLE_ROCK_1, true), + LOCATION(RC_DMT_CIRCLE_ROCK_2, true), + LOCATION(RC_DMT_CIRCLE_ROCK_3, true), + LOCATION(RC_DMT_CIRCLE_ROCK_4, true), + LOCATION(RC_DMT_CIRCLE_ROCK_5, true), + LOCATION(RC_DMT_CIRCLE_ROCK_6, true), + LOCATION(RC_DMT_CIRCLE_ROCK_7, true), + LOCATION(RC_DMT_CIRCLE_ROCK_8, true), + LOCATION(RC_DMT_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_DMT_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_DMT_BOULDER_3, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_DMT_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_5, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_6, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_7, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_8, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_9, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_10, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_11, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_KAK_BEHIND_GATE, []{return true;}), Entrance(RR_GORON_CITY, []{return true;}), - Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return Here(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->BlastOrSmash();}) || (logic->IsAdult && ((CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_DMT_CLIMB_HOVERS))));}), + Entrance(RR_DEATH_MOUNTAIN_AVALANCHE, []{return logic->BlastOrSmash() || (logic->IsAdult && ((CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_DMT_CLIMB_HOVERS))));}), Entrance(RR_DODONGOS_CAVERN_ENTRYWAY, []{return logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->IsAdult;}), Entrance(RR_DMT_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), }); + areaTable[RR_DEATH_MOUNTAIN_AVALANCHE] = Region("Death Mountain Avalanche", SCENE_DEATH_MOUNTAIN_TRAIL, {}, { + //Locations + LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || ctx->GetTrickOption(RT_DMT_UPPER_GS)) && logic->CanGetNightTimeGS()), + }, { + //Exits + Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return true;}), + Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->HasItem(RG_CLIMB);}), + Entrance(RR_DMT_COW_GROTTO, []{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->BlastOrSmash();});}), + }); + areaTable[RR_DEATH_MOUNTAIN_SUMMIT] = Region("Death Mountain Summit", SCENE_DEATH_MOUNTAIN_TRAIL, { //Events EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}), EventAccess(&logic->BugRock, []{return logic->IsChild;}), }, { //Locations - LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->CanUse(RG_BROKEN_SWORD)), - LOCATION(RC_DMT_TRADE_EYEDROPS, logic->IsAdult && logic->CanUse(RG_EYEDROPS)), - LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->CanUse(RG_CLAIM_CHECK)), - LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || ctx->GetTrickOption(RT_DMT_UPPER_GS)) && logic->CanGetNightTimeGS()), + LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->HasSoul(RG_BIGGORON_SOUL) && logic->CanUse(RG_BROKEN_SWORD)), + LOCATION(RC_DMT_TRADE_EYEDROPS, logic->IsAdult && logic->HasSoul(RG_BIGGORON_SOUL) && logic->CanUse(RG_EYEDROPS)), + LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->HasSoul(RG_BIGGORON_SOUL) && logic->CanUse(RG_CLAIM_CHECK)), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DMT_COW_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_DMT_SUMMIT_ROCK, logic->IsChild), LOCATION(RC_DMT_GOSSIP_STONE, true), }, { //Exits - Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return true;}), + Entrance(RR_DEATH_MOUNTAIN_AVALANCHE, []{return true;}), Entrance(RR_DMC_UPPER_LOCAL, []{return true;}), - Entrance(RR_DMT_OWL_FLIGHT, []{return logic->IsChild;}, false), - Entrance(RR_DMT_COW_GROTTO, []{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->BlastOrSmash();});}), + Entrance(RR_DMT_OWL_FLIGHT, []{return logic->IsChild && logic->HasSoul(RG_KAEPORA_SOUL);}), Entrance(RR_DMT_GREAT_FAIRY_FOUNTAIN, []{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->BlastOrSmash();});}), }); areaTable[RR_DMT_OWL_FLIGHT] = Region("DMT Owl Flight", SCENE_DEATH_MOUNTAIN_TRAIL, {}, {}, { //Exits - Entrance(RR_KAK_IMPAS_ROOFTOP, []{return true;}), + Entrance(RR_KAK_IMPAS_ROOFTOP, []{return true;}, false), }); areaTable[RR_DMT_COW_GROTTO] = Region("DMT Cow Grotto", SCENE_GROTTOS, {}, { @@ -77,7 +114,7 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_COW_GROTTO_GRASS_2, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return true;}), + Entrance(RR_DEATH_MOUNTAIN_AVALANCHE, []{return true;}), }); areaTable[RR_DMT_STORMS_GROTTO] = Region("DMT Storms Grotto", SCENE_GROTTOS, grottoEvents, { @@ -100,7 +137,7 @@ void RegionTable_Init_DeathMountainTrail() { areaTable[RR_DMT_GREAT_FAIRY_FOUNTAIN] = Region("DMT Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, {}, { //Locations - LOCATION(RC_DMT_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_DMT_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp index f4b8b01c349..3c2675512b0 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -20,6 +20,24 @@ void RegionTable_Init_DesertColossus() { LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_COLOSSUS_ROCK, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_1, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_2, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_3, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_4, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_5, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_6, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_7, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_8, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_1, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_2, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_3, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_4, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_5, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_6, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_7, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_8, true), LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), }, { //Exits @@ -52,7 +70,7 @@ void RegionTable_Init_DesertColossus() { areaTable[RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE] = Region("Desert Colossus From Spirit Entryway", SCENE_DESERT_COLOSSUS, {}, { //Locations - LOCATION(RC_SHEIK_AT_COLOSSUS, true), + LOCATION(RC_SHEIK_AT_COLOSSUS, logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exist Entrance(RR_DESERT_COLOSSUS, []{return true;}), @@ -60,7 +78,7 @@ void RegionTable_Init_DesertColossus() { areaTable[RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN] = Region("Colossus Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, {}, { //Locations - LOCATION(RC_COLOSSUS_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_COLOSSUS_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_DESERT_COLOSSUS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index e26e841f0d9..7dffd315400 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -9,7 +9,7 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_OUTSKIRTS] = Region("Gerudo Fortress Outskirts", SCENE_GERUDOS_FORTRESS, { //Events - EventAccess(&logic->GF_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}), //needs climb + EventAccess(&logic->GF_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_CLIMB) && logic->HasSoul(RG_HW_GATEKEEPER_SOUL);}), }, { //Locations LOCATION(RC_GF_OUTSKIRTS_NE_CRATE, (logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)) && logic->CanBreakCrates()), @@ -49,7 +49,7 @@ void RegionTable_Init_GerudoFortress() { EventAccess(&logic->GtG_GateOpen, []{return (logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET));}), }, {}, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, []{return logic->GtG_GateOpen && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}), + Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, []{return logic->GtG_GateOpen && (logic->IsAdult && logic->HasSoul(RG_GTG_GATEKEEPER_SOUL) || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}), //Jail Entrance(RR_GF_JAIL_WINDOW, []{return logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_GF_OUTSKIRTS, []{return true;}), @@ -81,7 +81,7 @@ void RegionTable_Init_GerudoFortress() { //Exits Entrance(RR_TH_STEEP_SLOPE_CELL, []{return true;}), Entrance(RR_GF_NEAR_GROTTO, []{return true;}), - Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true /* logic->CanClimb() */;}), + Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return logic->CanUse(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_GF_ABOVE_GTG, []{return true;}), }); @@ -122,7 +122,7 @@ void RegionTable_Init_GerudoFortress() { Entrance(RR_GF_OUTSIDE_GTG, []{return true;}), Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true;}), Entrance(RR_GF_SLOPED_ROOF, []{return logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS);}), - Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return true /* logic->CanClimb() */;}), + Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return logic->CanUse(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}), }); areaTable[RR_GF_TOP_OF_UPPER_VINES] = Region("GF Top of Upper Vines", SCENE_GERUDOS_FORTRESS, {}, { @@ -196,8 +196,8 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_HBA_RANGE] = Region("GF HBA Range", SCENE_GERUDOS_FORTRESS, {}, { //Locations - LOCATION(RC_GF_HBA_1000_POINTS, logic->IsAdult && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), - LOCATION(RC_GF_HBA_1500_POINTS, logic->IsAdult && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), + LOCATION(RC_GF_HBA_1000_POINTS, logic->IsAdult && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay && logic->HasSoul(RG_ARCHER_SOUL)), + LOCATION(RC_GF_HBA_1500_POINTS, logic->IsAdult && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay && logic->HasSoul(RG_ARCHER_SOUL)), LOCATION(RC_GF_HBA_RANGE_GS, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) && logic->CanGetNightTimeGS()), LOCATION(RC_GF_HBA_RANGE_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_GF_HBA_RANGE_CRATE_2, logic->CanBreakCrates()), @@ -221,7 +221,7 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_OUTSIDE_GATE] = Region("GF Outside Gate", SCENE_GERUDOS_FORTRESS, { //Events - EventAccess(&logic->GF_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}), + EventAccess(&logic->GF_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasSoul(RG_HW_GATEKEEPER_SOUL);}), }, {}, { //Exits Entrance(RR_GF_OUTSKIRTS, []{return logic->GF_GateOpen;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index a9f0299ba95..2a5625937d6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -10,7 +10,18 @@ void RegionTable_Init_GerudoValley() { EventAccess(&logic->BugRock, []{return logic->IsChild;}), }, { //Locations - LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_ROCK_1, true), + LOCATION(RC_GV_ROCK_2, true), + LOCATION(RC_GV_ROCK_3, true), + LOCATION(RC_GV_UNDERWATER_ROCK_1, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5) && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_GV_UNDERWATER_ROCK_2, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5) && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_GV_UNDERWATER_ROCK_3, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5) && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_GV_BOULDER_1, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BOULDER_2, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild), //can use cucco as child }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), @@ -27,7 +38,7 @@ void RegionTable_Init_GerudoValley() { EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), }, { //Locations - LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->HasItem(RG_BRONZE_SCALE)),//can use cucco as child + LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CLIMB)), LOCATION(RC_GV_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_GV_COW, logic->IsChild && logic->CanUse(RG_EPONAS_SONG)), LOCATION(RC_GV_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), @@ -45,10 +56,13 @@ void RegionTable_Init_GerudoValley() { // scale/boots logic is outside lower stream, as lower stream combines access to lake hylia for entrance randomizer's sake areaTable[RR_GV_LOWER_STREAM] = Region("GV Lower Stream", SCENE_GERUDO_VALLEY, {}, {}, { //Exits - Entrance(RR_LAKE_HYLIA, []{return true;}), + Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE);}), }); - areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, {}, { + areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, { + //Locations + LOCATION(RC_GV_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + }, { //Exits Entrance(RR_GV_UPPER_STREAM, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}), Entrance(RR_GV_LOWER_STREAM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), @@ -68,14 +82,37 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GV_FORTRESS_SIDE] = Region("GV Fortress Side", SCENE_GERUDO_VALLEY, {}, { //Locations - LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), - LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_GV_CRATE_BRIDGE_1, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->HasSoul(RG_CARPENTER_BOSS_SOUL) && logic->CanUse(RG_POACHERS_SAW)), + LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_CRATE_BRIDGE_1, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), + LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_CRATE_BRIDGE_1, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), + LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_1, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_2, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_3, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_4, logic->IsAdult), + LOCATION(RC_GV_BOULDER_ACROSS_BRIDGE, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_GF_OUTSKIRTS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp index 7027ab6c6fc..b2b5a74e814 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp @@ -14,19 +14,18 @@ void RegionTable_Init_GoronCity() { EventAccess(&logic->GCWoodsWarpOpen, []{return logic->CanDetonateUprightBombFlower() || logic->CanUse(RG_MEGATON_HAMMER) || logic->GoronCityChildFire;}), EventAccess(&logic->GCDaruniasDoorOpenChild, []{return logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY);}), // bottle animation causes similar complications as stopping goron with Din's Fire, only put in logic when both din's & blue fire tricks enabled - EventAccess(&logic->StopGCRollingGoronAsAdult, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || - (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && (logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)))));}), + EventAccess(&logic->StopGCRollingGoronAsAdult, []{return logic->IsAdult && logic->HasSoul(RG_LINK_SOUL) && + (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && (logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)))));}), }, { //Locations LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))), - LOCATION(RC_GC_MAZE_CENTER_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_RIGHT_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_CENTER_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_RIGHT_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->GoronCityChildFire && (logic->CanUse(RG_BOMB_BAG) || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_GC_POT)))), - LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && (logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), + LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && logic->HasSoul(RG_HOT_RODDER_SOUL) && (logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->StopGCRollingGoronAsAdult), LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_GC_GS_CENTER_PLATFORM, logic->IsAdult && logic->CanAttack()), - LOCATION(RC_GC_MEDIGORON, logic->IsAdult && (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CallGossipFairyExceptSuns()), LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), @@ -36,7 +35,57 @@ void RegionTable_Init_GoronCity() { LOCATION(RC_GC_UPPER_STAIRCASE_POT_2, logic->CanBreakPots()), LOCATION(RC_GC_UPPER_STAIRCASE_POT_3, logic->CanBreakPots()), LOCATION(RC_GC_MAZE_CRATE, logic->BlastOrSmash() || (logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanBreakCrates())), - + LOCATION(RC_GC_ENTRANCE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_GC_ENTRANCE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_GC_ENTRANCE_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_GC_LW_BOULDER_1, logic->GCWoodsWarpOpen), + LOCATION(RC_GC_LW_BOULDER_2, logic->GCWoodsWarpOpen), + LOCATION(RC_GC_LW_BOULDER_3, logic->GCWoodsWarpOpen), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_1, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_2, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_3, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_4, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_5, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_6, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_7, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_8, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_9, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_10, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_11, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_12, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_13, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_14, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_15, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_16, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_17, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_18, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_19, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_20, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_21, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_22, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_23, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_24, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_25, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_26, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_27, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_28, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_29, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_4, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_6, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_7, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_8, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_9, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_10, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_4, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_5, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_ROCK, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return true;}), @@ -49,6 +98,7 @@ void RegionTable_Init_GoronCity() { areaTable[RR_GC_MEDIGORON] = Region("GC Medigoron", SCENE_GORON_CITY, {}, { //Locations + LOCATION(RC_GC_MEDIGORON, logic->IsAdult && logic->HasSoul(RG_MEDIGORON_SOUL)), LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE, true), @@ -72,7 +122,7 @@ void RegionTable_Init_GoronCity() { EventAccess(&logic->GoronCityChildFire, []{return logic->IsChild && logic->CanUse(RG_STICKS);}), }, { //Locations - LOCATION(RC_GC_DARUNIAS_JOY, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), + LOCATION(RC_GC_DARUNIAS_JOY, logic->IsChild && logic->HasSoul(RG_DARUNIA_SOUL) && logic->CanUse(RG_SARIAS_SONG)), LOCATION(RC_GC_DARUNIA_POT_1, logic->CanBreakPots()), LOCATION(RC_GC_DARUNIA_POT_2, logic->CanBreakPots()), LOCATION(RC_GC_DARUNIA_POT_3, logic->CanBreakPots()), @@ -90,14 +140,14 @@ void RegionTable_Init_GoronCity() { areaTable[RR_GC_SHOP] = Region("GC Shop", SCENE_GORON_SHOP, {}, { //Locations - LOCATION(RC_GC_SHOP_ITEM_1, true), - LOCATION(RC_GC_SHOP_ITEM_2, true), - LOCATION(RC_GC_SHOP_ITEM_3, true), - LOCATION(RC_GC_SHOP_ITEM_4, true), - LOCATION(RC_GC_SHOP_ITEM_5, true), - LOCATION(RC_GC_SHOP_ITEM_6, true), - LOCATION(RC_GC_SHOP_ITEM_7, true), - LOCATION(RC_GC_SHOP_ITEM_8, true), + LOCATION(RC_GC_SHOP_ITEM_1, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_2, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_3, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_4, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_5, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_6, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_7, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), + LOCATION(RC_GC_SHOP_ITEM_8, logic->HasSoul(RG_GORON_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_GORON_CITY, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index 763d1257577..762e25da59f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -13,7 +13,7 @@ void RegionTable_Init_Graveyard() { }, { //Locations LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtNight), //TODO: This needs to change + LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->HasSoul(RG_DAMPE_SOUL) && logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtNight), //TODO: This needs to change LOCATION(RC_GRAVEYARD_GS_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), @@ -32,6 +32,7 @@ void RegionTable_Init_Graveyard() { LOCATION(RC_GY_GRASS_11, logic->CanCutShrubs()), LOCATION(RC_GY_GRASS_12, logic->CanCutShrubs()), LOCATION(RC_GRAVEYARD_CRATE, ((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()), + LOCATION(RC_GY_ROCK, true), }, { //Exits Entrance(RR_GRAVEYARD_SHIELD_GRAVE, []{return logic->IsAdult || logic->AtNight;}), @@ -88,11 +89,11 @@ void RegionTable_Init_Graveyard() { areaTable[RR_GRAVEYARD_DAMPES_GRAVE] = Region("Graveyard Dampes Grave", SCENE_WINDMILL_AND_DAMPES_GRAVE, { //Events EventAccess(&logic->NutPot, []{return true;}), - EventAccess(&logic->DampesWindmillAccess, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}), + EventAccess(&logic->DampesWindmillAccess, []{return logic->IsAdult && logic->HasSoul(RG_DAMPE_SOUL) && logic->CanUse(RG_SONG_OF_TIME);}), }, { //Locations - LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, logic->IsAdult || ctx->GetTrickOption(RT_GY_CHILD_DAMPE_RACE_POH)), + LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, logic->HasSoul(RG_DAMPE_SOUL)), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, logic->HasSoul(RG_DAMPE_SOUL) && (logic->IsAdult || ctx->GetTrickOption(RT_GY_CHILD_DAMPE_RACE_POH))), LOCATION(RC_GY_DAMPES_GRAVE_POT_1, logic->CanBreakPots()), LOCATION(RC_GY_DAMPES_GRAVE_POT_2, logic->CanBreakPots()), LOCATION(RC_GY_DAMPES_GRAVE_POT_3, logic->CanBreakPots()), @@ -102,15 +103,15 @@ void RegionTable_Init_Graveyard() { LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_1, true), LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_2, true), LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_3, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_4, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_5, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_6, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_7, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_8, true), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_4, logic->HasSoul(RG_DAMPE_SOUL)), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_5, logic->HasSoul(RG_DAMPE_SOUL)), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_6, logic->HasSoul(RG_DAMPE_SOUL)), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_7, logic->HasSoul(RG_DAMPE_SOUL)), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_8, logic->HasSoul(RG_DAMPE_SOUL)), }, { //Exits Entrance(RR_THE_GRAVEYARD, []{return true;}), - Entrance(RR_KAK_WINDMILL, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}, false), + Entrance(RR_KAK_WINDMILL, []{return logic->DampesWindmillAccess;}, false), }); areaTable[RR_GRAVEYARD_DAMPES_HOUSE] = Region("Graveyard Dampes House", SCENE_GRAVEKEEPERS_HUT, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp index 930ffcb4f6c..a1d4fbc4c88 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp @@ -19,11 +19,11 @@ void RegionTable_Init_HauntedWasteland() { //Events EventAccess(&logic->FairyPot, []{return true;}), EventAccess(&logic->NutPot, []{return true;}), - EventAccess(&logic->CarpetMerchant, []{return logic->HasItem(RG_ADULT_WALLET) && CanBuyAnother(RC_WASTELAND_BOMBCHU_SALESMAN) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), + EventAccess(&logic->CarpetMerchant, []{return logic->HasSoul(RG_ARMS_DEALER_SOUL) && logic->HasItem(RG_ADULT_WALLET) && CanBuyAnother(RC_WASTELAND_BOMBCHU_SALESMAN) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), }, { //Locations LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource()), - LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->HasSoul(RG_ARMS_DEALER_SOUL) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS))), LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang()), LOCATION(RC_WASTELAND_NEAR_GS_POT_1, logic->CanBreakPots()), LOCATION(RC_WASTELAND_NEAR_GS_POT_2, logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index 5bc3aeb269f..bda5cb302ad 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -10,8 +10,8 @@ void RegionTable_Init_HyruleField() { EventAccess(&logic->BigPoeKill, []{return logic->HasBottle() && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_EPONA) || ctx->GetTrickOption(RT_HF_BIG_POE_WITHOUT_EPONA));}), }, { //Locations - LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)), - LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE) && logic->HasSoul(RG_ZELDA_SOUL) && logic->HasSoul(RG_IMPA_SOUL)), + LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE) && logic->HasSoul(RG_ZELDA_SOUL) && logic->HasSoul(RG_IMPA_SOUL)), LOCATION(RC_HF_POND_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_HF_CENTRAL_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_HF_CENTRAL_GRASS_2, logic->CanCutShrubs()), @@ -61,15 +61,79 @@ void RegionTable_Init_HyruleField() { LOCATION(RC_HF_NEAR_KF_GRASS_10, logic->CanCutShrubs()), LOCATION(RC_HF_NEAR_KF_GRASS_11, logic->CanCutShrubs()), LOCATION(RC_HF_NEAR_KF_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_HF_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_HF_ROCK_1, true), + LOCATION(RC_HF_ROCK_2, true), + LOCATION(RC_HF_ROCK_3, true), + LOCATION(RC_HF_ROCK_4, true), + LOCATION(RC_HF_ROCK_5, true), + LOCATION(RC_HF_ROCK_6, true), + LOCATION(RC_HF_ROCK_7, true), + LOCATION(RC_HF_ROCK_8, true), + LOCATION(RC_HF_BOULDER_NORTH, logic->BlastOrSmash()), + LOCATION(RC_HF_BOULDER_BY_MARKET, logic->BlastOrSmash()), + LOCATION(RC_HF_BOULDER_SOUTH, logic->BlastOrSmash()), + LOCATION(RC_HF_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_NEAR_LLR_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_LH_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_NEAR_GV_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_ADULT_NEAR_GV_TREE, logic->IsAdult && logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_ZR_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_KAK_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_KAK_SMALL_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_MARKET_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_MARKET_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_MARKET_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_6, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_6, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_6, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_7, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_8, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_9, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_10, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_11, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_12, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_13, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_14, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_15, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_16, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_17, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_18, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_19, logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_1, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_2, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_3, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_4, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_5, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_6, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_TEKTITE_GROTTO_TREE, logic->CanBonkTrees()), }, { //Exits Entrance(RR_LW_BRIDGE, []{return true;}), - Entrance(RR_LAKE_HYLIA, []{return true;}), Entrance(RR_GERUDO_VALLEY, []{return true;}), Entrance(RR_MARKET_ENTRANCE, []{return true;}), Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), Entrance(RR_ZR_FRONT, []{return true;}), Entrance(RR_LON_LON_RANCH, []{return true;}), + Entrance(RR_HF_TO_LAKE_HYLIA, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_EPONA);}), Entrance(RR_HF_SOUTHEAST_GROTTO, []{return Here(RR_HYRULE_FIELD, []{return logic->BlastOrSmash();});}), Entrance(RR_HF_OPEN_GROTTO, []{return true;}), Entrance(RR_HF_INSIDE_FENCE_GROTTO, []{return logic->CanOpenBombGrotto();}), @@ -80,6 +144,12 @@ void RegionTable_Init_HyruleField() { Entrance(RR_HF_TEKTITE_GROTTO, []{return logic->CanOpenBombGrotto();}), }); + areaTable[RR_HF_TO_LAKE_HYLIA] = Region("HF to Lake Hylia", SCENE_HYRULE_FIELD, {}, {}, { + //Exits + Entrance(RR_LAKE_HYLIA, []{return true;}), + Entrance(RR_HYRULE_FIELD, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_EPONA);}), + }); + areaTable[RR_HF_SOUTHEAST_GROTTO] = Region("HF Southeast Grotto", SCENE_GROTTOS, grottoEvents, { //Locations LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 13490c9a444..45d346de050 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -9,19 +9,19 @@ void RegionTable_Init_Kakariko() { //Events EventAccess(&logic->BugRock, []{return true;}), //Open Gate setting is applied in RR_ROOT - EventAccess(&logic->KakarikoVillageGateOpen, []{return logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER);}), + EventAccess(&logic->KakarikoVillageGateOpen, []{return logic->IsChild && logic->HasSoul(RG_KAKARIKO_GATEKEEPER_SOUL) && logic->HasItem(RG_ZELDAS_LETTER);}), }, { //Locations - LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION) && logic->HasItem(RG_FIRE_MEDALLION) && logic->HasItem(RG_WATER_MEDALLION)), - LOCATION(RC_KAK_ANJU_AS_CHILD, logic->IsChild && logic->AtDay), - LOCATION(RC_KAK_ANJU_AS_ADULT, logic->IsAdult && logic->AtDay), - LOCATION(RC_KAK_TRADE_POCKET_CUCCO, logic->IsAdult && logic->AtDay && (logic->CanUse(RG_POCKET_EGG) && logic->WakeUpAdultTalon)), + LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION) && logic->HasItem(RG_FIRE_MEDALLION) && logic->HasItem(RG_WATER_MEDALLION) && logic->HasSoul(RG_ZELDA_SOUL)), + LOCATION(RC_KAK_ANJU_AS_CHILD, logic->IsChild && logic->AtDay && logic->HasSoul(RG_ANJU_SOUL) && logic->HasItem(RG_CLIMB)), // RANDOTODO only require climb if all 7 cuccos required + LOCATION(RC_KAK_ANJU_AS_ADULT, logic->IsAdult && logic->AtDay && logic->HasSoul(RG_ANJU_SOUL)), + LOCATION(RC_KAK_TRADE_POCKET_CUCCO, logic->IsAdult && logic->AtDay && logic->HasSoul(RG_ANJU_SOUL) && (logic->CanUse(RG_POCKET_EGG) && logic->WakeUpAdultTalon)), //Can kill lower kak skulls with pots LOCATION(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, logic->IsChild && logic->CanGetNightTimeGS()), LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->CanGetNightTimeGS()), LOCATION(RC_KAK_GS_GUARDS_HOUSE, logic->IsChild && logic->CanGetNightTimeGS()), - LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->CanGetNightTimeGS()), - LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->CanGetNightTimeGS() && logic->CanBonkTrees()), + LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && logic->HasItem(RG_CLIMB) && (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_1, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_2, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_3, logic->IsChild && logic->CanBreakPots()), @@ -57,6 +57,10 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_NEAR_FENCE_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_NEAR_BAZAAR_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_KAK_SILVER_BOULDER, logic->IsAdult && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_CLIMB)), + LOCATION(RC_KAK_ROCK_1, true), + LOCATION(RC_KAK_ROCK_2, true), + LOCATION(RC_KAK_TREE, logic->CanBonkTrees()), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), @@ -70,8 +74,8 @@ void RegionTable_Init_Kakariko() { Entrance(RR_KAK_POTION_SHOP_FRONT, []{return (logic->AtDay || logic->IsChild) && logic->CanOpenOverworldDoor(RG_KAK_POTION_SHOP_KEY);}), Entrance(RR_KAK_REDEAD_GROTTO, []{return logic->CanOpenBombGrotto();}), Entrance(RR_KAK_IMPAS_LEDGE, []{return (logic->IsChild && logic->AtDay) || (logic->IsAdult && ctx->GetTrickOption(RT_VISIBLE_COLLISION));}), - Entrance(RR_KAK_WATCHTOWER, []{return logic->IsAdult || logic->AtDay || logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer());}), - Entrance(RR_KAK_ROOFTOP, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && logic->IsAdult);}), + Entrance(RR_KAK_WATCHTOWER, []{return logic->HasItem(RG_CLIMB) && (logic->IsAdult || logic->AtDay || logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer()));}), + Entrance(RR_KAK_ROOFTOP, []{return logic->HasSoul(RG_MAN_ON_ROOF_SOUL) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && logic->IsAdult));}), Entrance(RR_KAK_IMPAS_ROOFTOP, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_ROOFTOP_GS) && logic->CanUse(RG_HOVER_BOOTS));}), Entrance(RR_THE_GRAVEYARD, []{return true;}), Entrance(RR_KAK_BEHIND_GATE, []{return logic->IsAdult || logic->KakarikoVillageGateOpen;}), @@ -128,7 +132,7 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_CARPENTER_BOSS_HOUSE] = Region("Kak Carpenter Boss House", SCENE_KAKARIKO_CENTER_GUEST_HOUSE, { //Events - EventAccess(&logic->WakeUpAdultTalon, []{return logic->IsAdult && logic->CanUse(RG_POCKET_EGG);}), + EventAccess(&logic->WakeUpAdultTalon, []{return logic->IsAdult && logic->CanUse(RG_POCKET_EGG) && logic->HasSoul(RG_TALON_SOUL);}), }, {}, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -170,7 +174,7 @@ void RegionTable_Init_Kakariko() { }, { //Locations LOCATION(RC_KAK_WINDMILL_FREESTANDING_POH, logic->CanUse(RG_BOOMERANG) || logic->DampesWindmillAccess || (logic->IsAdult && ctx->GetTrickOption(RT_KAK_ADULT_WINDMILL_POH)) || (logic->IsChild && logic->CanJumpslashExceptHammer() && ctx->GetTrickOption(RT_KAK_CHILD_WINDMILL_POH))), - LOCATION(RC_SONG_FROM_WINDMILL, logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA)), + LOCATION(RC_SONG_FROM_WINDMILL, logic->IsAdult && logic->HasSoul(RG_WINDMILL_MAN_SOUL) && logic->HasItem(RG_FAIRY_OCARINA)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -178,14 +182,14 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_BAZAAR] = Region("Kak Bazaar", SCENE_BAZAAR, {}, { //Locations - LOCATION(RC_KAK_BAZAAR_ITEM_1, true), - LOCATION(RC_KAK_BAZAAR_ITEM_2, true), - LOCATION(RC_KAK_BAZAAR_ITEM_3, true), - LOCATION(RC_KAK_BAZAAR_ITEM_4, true), - LOCATION(RC_KAK_BAZAAR_ITEM_5, true), - LOCATION(RC_KAK_BAZAAR_ITEM_6, true), - LOCATION(RC_KAK_BAZAAR_ITEM_7, true), - LOCATION(RC_KAK_BAZAAR_ITEM_8, true), + LOCATION(RC_KAK_BAZAAR_ITEM_1, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_2, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_3, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_4, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_5, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_6, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_7, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_BAZAAR_ITEM_8, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -193,7 +197,7 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_SHOOTING_GALLERY] = Region("Kak Shooting Gallery", SCENE_SHOOTING_GALLERY, {}, { //Locations - LOCATION(RC_KAK_SHOOTING_GALLERY_REWARD, logic->HasItem(RG_CHILD_WALLET) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_KAK_SHOOTING_GALLERY_REWARD, logic->HasItem(RG_CHILD_WALLET) && logic->IsAdult && logic->HasSoul(RG_SHOOTING_SOUL) && logic->CanUse(RG_FAIRY_BOW)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -201,14 +205,14 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_POTION_SHOP_FRONT] = Region("Kak Potion Shop Front", SCENE_POTION_SHOP_KAKARIKO, {}, { //Locations - LOCATION(RC_KAK_POTION_SHOP_ITEM_1, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_2, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_3, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_4, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_5, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_6, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_7, logic->IsAdult), - LOCATION(RC_KAK_POTION_SHOP_ITEM_8, logic->IsAdult), + LOCATION(RC_KAK_POTION_SHOP_ITEM_1, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_2, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_3, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_4, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_5, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_6, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_7, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_KAK_POTION_SHOP_ITEM_8, logic->IsAdult && logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -226,8 +230,8 @@ void RegionTable_Init_Kakariko() { // RANDOTODO blue pot access }, { //Locations - LOCATION(RC_KAK_TRADE_ODD_MUSHROOM, logic->IsAdult && logic->CanUse(RG_ODD_MUSHROOM)), - LOCATION(RC_KAK_GRANNYS_SHOP, logic->IsAdult && (logic->CanUse(RG_ODD_MUSHROOM) || logic->TradeQuestStep(RG_ODD_MUSHROOM))), + LOCATION(RC_KAK_TRADE_ODD_MUSHROOM, logic->IsAdult && logic->HasSoul(RG_GRANNY_SOUL) && logic->CanUse(RG_ODD_MUSHROOM)), + LOCATION(RC_KAK_GRANNYS_SHOP, logic->IsAdult && logic->HasSoul(RG_GRANNY_SOUL) && (logic->CanUse(RG_ODD_MUSHROOM) || logic->TradeQuestStep(RG_ODD_MUSHROOM))), }, { // Exits Entrance(RR_KAK_BACKYARD, []{return true;}), @@ -267,7 +271,7 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_WELL] = Region("Kak Well", SCENE_KAKARIKO_VILLAGE, {}, {}, { //Exits - Entrance(RR_KAKARIKO_VILLAGE, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->DrainWell;}), + Entrance(RR_KAKARIKO_VILLAGE, []{return logic->HasItem(RG_CLIMB) && (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->DrainWell);}), Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild || (logic->DrainWell && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF));}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index 525e222009b..9d202c6d499 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -12,7 +12,7 @@ void RegionTable_Init_KokiriForest() { EventAccess(&logic->ShowedMidoSwordAndShield, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}), }, { //Locations - LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild), + LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->CanUse(RG_CRAWL)), LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && (/*TODO: HasNightStart ||*/ logic->CanLeaveForest() || logic->CanUse(RG_SUNS_SONG)) && logic->CanGetNightTimeGS()), LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()), @@ -27,8 +27,8 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_SOUTH_GRASS_EAST_RUPEE, logic->IsChild), LOCATION(RC_KF_NORTH_GRASS_WEST_RUPEE, logic->IsChild), LOCATION(RC_KF_NORTH_GRASS_EAST_RUPEE, logic->IsChild), - LOCATION(RC_KF_BOULDER_RUPEE_1, logic->IsChild), - LOCATION(RC_KF_BOULDER_RUPEE_2, logic->IsChild), + LOCATION(RC_KF_BOULDER_RUPEE_1, logic->CanUse(RG_CRAWL)), + LOCATION(RC_KF_BOULDER_RUPEE_2, logic->CanUse(RG_CRAWL)), LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), @@ -52,9 +52,9 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_CHILD_GRASS_10, logic->IsChild && logic->CanCutShrubs()), LOCATION(RC_KF_CHILD_GRASS_11, logic->IsChild && logic->CanCutShrubs()), LOCATION(RC_KF_CHILD_GRASS_12, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_MAZE_1, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_MAZE_2, logic->IsChild && logic->CanCutShrubs()), - LOCATION(RC_KF_CHILD_GRASS_MAZE_3, logic->IsChild && logic->CanCutShrubs()), + LOCATION(RC_KF_CHILD_GRASS_MAZE_1, logic->IsChild && logic->CanCutShrubs() && logic->CanUse(RG_CRAWL)), + LOCATION(RC_KF_CHILD_GRASS_MAZE_2, logic->IsChild && logic->CanCutShrubs() && logic->CanUse(RG_CRAWL)), + LOCATION(RC_KF_CHILD_GRASS_MAZE_3, logic->IsChild && logic->CanCutShrubs() && logic->CanUse(RG_CRAWL)), LOCATION(RC_KF_ADULT_GRASS_1, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_2, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_3, logic->IsAdult && logic->CanCutShrubs()), @@ -75,18 +75,30 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_ADULT_GRASS_18, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_19, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_20, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_CIRCLE_ROCK_1, true), + LOCATION(RC_KF_CIRCLE_ROCK_2, true), + LOCATION(RC_KF_CIRCLE_ROCK_3, true), + LOCATION(RC_KF_CIRCLE_ROCK_4, true), + LOCATION(RC_KF_CIRCLE_ROCK_5, true), + LOCATION(RC_KF_CIRCLE_ROCK_6, true), + LOCATION(RC_KF_CIRCLE_ROCK_7, true), + LOCATION(RC_KF_CIRCLE_ROCK_8, true), + LOCATION(RC_KF_ROCK_BY_SARIAS_HOUSE, logic->IsChild), + LOCATION(RC_KF_ROCK_BEHIND_SARIAS_HOUSE, logic->IsChild), + LOCATION(RC_KF_ROCK_BY_MIDOS_HOUSE, logic->IsChild), + LOCATION(RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, logic->IsChild), }, { //Exits - Entrance(RR_KF_LINKS_HOUSE, []{return true;}), + Entrance(RR_KF_LINKS_PORCH, []{return logic->CanUse(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_KF_MIDOS_HOUSE, []{return true;}), Entrance(RR_KF_SARIAS_HOUSE, []{return true;}), Entrance(RR_KF_HOUSE_OF_TWINS, []{return true;}), Entrance(RR_KF_KNOW_IT_ALL_HOUSE, []{return true;}), Entrance(RR_KF_KOKIRI_SHOP, []{return true;}), Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->ShowedMidoSwordAndShield;}), - Entrance(RR_THE_LOST_WOODS, []{return true;}), + // Maybe adult jumping to Mido's Roof is trick, in which case bean can also get adult up here + Entrance(RR_KF_OUTSIDE_LOST_WOODS, []{return logic->CanUse(RG_CLIMB);}), Entrance(RR_LW_BRIDGE_FROM_FOREST, []{return logic->IsAdult || ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || logic->DekuTreeClear;}), - Entrance(RR_KF_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), }); areaTable[RR_KF_OUTSIDE_DEKU_TREE] = Region("KF Outside Deku Tree", SCENE_KOKIRI_FOREST, { @@ -108,13 +120,18 @@ void RegionTable_Init_KokiriForest() { Entrance(RR_KOKIRI_FOREST, []{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->ShowedMidoSwordAndShield;}), }); + areaTable[RR_KF_LINKS_PORCH] = Region("KF Link's Porch", SCENE_KOKIRI_FOREST, {}, {}, { + Entrance(RR_KOKIRI_FOREST, []{return true;}), + Entrance(RR_KF_LINKS_HOUSE, []{return true;}), + }); + areaTable[RR_KF_LINKS_HOUSE] = Region("KF Link's House", SCENE_LINKS_HOUSE, {}, { //Locations LOCATION(RC_KF_LINKS_HOUSE_COW, logic->IsAdult && logic->CanUse(RG_EPONAS_SONG) && logic->LinksCow), LOCATION(RC_KF_LINKS_HOUSE_POT, logic->CanBreakPots()), }, { //Exits - Entrance(RR_KOKIRI_FOREST, []{return true;}) + Entrance(RR_KF_LINKS_PORCH, []{return true;}) }); areaTable[RR_KF_MIDOS_HOUSE] = Region("KF Mido's House", SCENE_MIDOS_HOUSE, {}, { @@ -159,19 +176,25 @@ void RegionTable_Init_KokiriForest() { areaTable[RR_KF_KOKIRI_SHOP] = Region("KF Kokiri Shop", SCENE_KOKIRI_SHOP, {}, { //Locations - LOCATION(RC_KF_SHOP_ITEM_1, true), - LOCATION(RC_KF_SHOP_ITEM_2, true), - LOCATION(RC_KF_SHOP_ITEM_3, true), - LOCATION(RC_KF_SHOP_ITEM_4, true), - LOCATION(RC_KF_SHOP_ITEM_5, true), - LOCATION(RC_KF_SHOP_ITEM_6, true), - LOCATION(RC_KF_SHOP_ITEM_7, true), - LOCATION(RC_KF_SHOP_ITEM_8, true), + LOCATION(RC_KF_SHOP_ITEM_1, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_2, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_3, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_4, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_5, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_6, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_7, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), + LOCATION(RC_KF_SHOP_ITEM_8, logic->HasSoul(RG_KOKIRI_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_KOKIRI_FOREST, []{return true;}), }); + areaTable[RR_KF_OUTSIDE_LOST_WOODS] = Region("KF Outside Lost Woods", SCENE_KOKIRI_FOREST, {}, {}, { + Entrance(RR_KOKIRI_FOREST, []{return true;}), + Entrance(RR_THE_LOST_WOODS, []{return true;}), + Entrance(RR_KF_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), + }); + areaTable[RR_KF_STORMS_GROTTO] = Region("KF Storms Grotto", SCENE_GROTTOS, grottoEvents, { //Locations LOCATION(RC_KF_STORMS_GROTTO_CHEST, true), @@ -187,7 +210,7 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_STORMS_GROTTO_GRASS_4, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_KOKIRI_FOREST, []{return true;}) + Entrance(RR_KF_OUTSIDE_LOST_WOODS, []{return true;}) }); // clang-format on 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 964b781ceeb..93aa8c16633 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -17,7 +17,7 @@ void RegionTable_Init_LakeHylia() { //Locations LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)), LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->WaterTempleClear && logic->HasItem(RG_BRONZE_SCALE)) || logic->CanUse(RG_DISTANT_SCARECROW)) && logic->CanUse(RG_FAIRY_BOW)), - LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA))), + LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)) && logic->HasItem(RG_CLIMB)), LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), LOCATION(RC_LH_GS_LAB_WALL, logic->IsChild && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (ctx->GetTrickOption(RT_LH_LAB_WALL_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) && logic->CanGetNightTimeGS() && logic->HasItem(RG_BRONZE_SCALE)), @@ -83,9 +83,9 @@ void RegionTable_Init_LakeHylia() { LOCATION(RC_LH_WARP_PAD_GRASS_2, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_HYRULE_FIELD, []{return true;}), + Entrance(RR_HF_TO_LAKE_HYLIA, []{return true;}), Entrance(RR_LH_FROM_SHORTCUT, []{return true;}), - Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild;}), + Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild && logic->HasSoul(RG_KAEPORA_SOUL);}), Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->WaterTempleClear) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)));}), Entrance(RR_LH_LAB, []{return logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY);}), Entrance(RR_LH_FROM_WATER_TEMPLE, []{return true;}), @@ -104,7 +104,10 @@ void RegionTable_Init_LakeHylia() { Entrance(RR_WATER_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->HasItem(RG_GOLDEN_SCALE))) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_GOLDEN_SCALE)));}), }); - areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, {}, { + areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, { + //Locations + LOCATION(RC_LA_ROCK, true), + }, { //Exits Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE);}), Entrance(RR_LH_FISHING_POND, []{return logic->CanOpenOverworldDoor(RG_FISHING_HOLE_KEY);}), @@ -117,8 +120,8 @@ void RegionTable_Init_LakeHylia() { areaTable[RR_LH_LAB] = Region("LH Lab", SCENE_LAKESIDE_LABORATORY, {}, { //Locations - LOCATION(RC_LH_LAB_DIVE, logic->HasItem(RG_GOLDEN_SCALE) || (ctx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE))), - LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->CanUse(RG_EYEBALL_FROG)), + LOCATION(RC_LH_LAB_DIVE, logic->HasSoul(RG_SCIENTIST_SOUL) && (logic->HasItem(RG_GOLDEN_SCALE) || (ctx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE)))), + LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->HasSoul(RG_SCIENTIST_SOUL) && logic->CanUse(RG_EYEBALL_FROG)), LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanBreakCrates()), LOCATION(RC_LH_LAB_FRONT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), LOCATION(RC_LH_LAB_LEFT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp index c29a5924eb8..0443b50f764 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp @@ -8,11 +8,11 @@ void RegionTable_Init_LonLonRanch() { areaTable[RR_LON_LON_RANCH] = Region("Lon Lon Ranch", SCENE_LON_LON_RANCH, { //Events EventAccess(&logic->FreedEpona, []{return (logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), - EventAccess(&logic->LinksCow, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), + EventAccess(&logic->LinksCow, []{return logic->HasSoul(RG_MALON_SOUL) && logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), }, { //Locations - LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), - LOCATION(RC_LLR_GS_TREE, logic->IsChild), + LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasSoul(RG_MALON_SOUL) && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), + LOCATION(RC_LLR_GS_TREE, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->CanGetNightTimeGS()), LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), @@ -24,6 +24,7 @@ void RegionTable_Init_LonLonRanch() { LOCATION(RC_LLR_RAIN_SHED_POT_2, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_LLR_RAIN_SHED_POT_3, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_LLR_NEAR_TREE_CRATE, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_LLR_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), @@ -35,7 +36,7 @@ void RegionTable_Init_LonLonRanch() { areaTable[RR_LLR_TALONS_HOUSE] = Region("LLR Talons House", SCENE_LON_LON_BUILDINGS, {}, { //Locations - LOCATION(RC_LLR_TALONS_CHICKENS, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtDay && logic->HasItem(RG_ZELDAS_LETTER)), + LOCATION(RC_LLR_TALONS_CHICKENS, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtDay && logic->HasSoul(RG_TALON_SOUL) && logic->HasItem(RG_ZELDAS_LETTER)), LOCATION(RC_LLR_TALONS_HOUSE_POT_1, logic->CanBreakPots()), LOCATION(RC_LLR_TALONS_HOUSE_POT_2, logic->CanBreakPots()), LOCATION(RC_LLR_TALONS_HOUSE_POT_3, logic->CanBreakPots()), @@ -55,7 +56,7 @@ void RegionTable_Init_LonLonRanch() { areaTable[RR_LLR_TOWER] = Region("LLR Tower", SCENE_LON_LON_BUILDINGS, {}, { //Locations - LOCATION(RC_LLR_FREESTANDING_POH, logic->IsChild), + LOCATION(RC_LLR_FREESTANDING_POH, logic->IsChild && logic->HasItem(RG_CRAWL)), LOCATION(RC_LLR_TOWER_LEFT_COW, logic->CanUse(RG_EPONAS_SONG)), LOCATION(RC_LLR_TOWER_RIGHT_COW, logic->CanUse(RG_EPONAS_SONG)), }, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp index e949a7b1e54..77fcb463848 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -7,7 +7,7 @@ void RegionTable_Init_LostWoods() { // clang-format off areaTable[RR_LW_FOREST_EXIT] = Region("LW Forest Exit", SCENE_LOST_WOODS, {}, {}, { //Exits - Entrance(RR_KOKIRI_FOREST, []{return true;}) + Entrance(RR_KF_OUTSIDE_LOST_WOODS, []{return true;}) }); areaTable[RR_THE_LOST_WOODS] = Region("Lost Woods", SCENE_LOST_WOODS, { @@ -18,9 +18,9 @@ void RegionTable_Init_LostWoods() { }, { //Locations LOCATION(RC_LW_SKULL_KID, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), - LOCATION(RC_LW_TRADE_COJIRO, logic->IsAdult && logic->CanUse(RG_COJIRO)), + LOCATION(RC_LW_TRADE_COJIRO, logic->IsAdult && logic->HasSoul(RG_GROG_SOUL) && logic->CanUse(RG_COJIRO)), //I cannot think of a case where you can use Odd pot but not Cojiro to reset the quadrant should you have both. If one exists, add it to logic - LOCATION(RC_LW_TRADE_ODD_POTION, logic->IsAdult && logic->CanUse(RG_ODD_POTION)), + LOCATION(RC_LW_TRADE_ODD_POTION, logic->IsAdult && logic->HasSoul(RG_FADO_SOUL) && logic->CanUse(RG_ODD_POTION)), //all 5 buttons are logically required for memory game //because the chances of being able to beat it //every time you attempt it are as follows: @@ -48,6 +48,7 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_LW_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LW_SHORTCUT_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BOULDER_BY_GORON_CITY, logic->BlastOrSmash()), LOCATION(RC_LW_GOSSIP_STONE, true), LOCATION(RC_LW_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_2, logic->CanCutShrubs()), @@ -81,6 +82,8 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_GRASS_7, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_8, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, logic->BlastOrSmash()), + LOCATION(RC_LW_RUPEE_BOULDER, logic->BlastOrSmash()), }, { //Exits Entrance(RR_LW_FOREST_EXIT, []{return true;}), @@ -110,8 +113,8 @@ void RegionTable_Init_LostWoods() { areaTable[RR_DEKU_THEATER] = Region("Deku Theater", SCENE_GROTTOS, {}, { //Locations - LOCATION(RC_DEKU_THEATER_SKULL_MASK, logic->IsChild && logic->SkullMask), - LOCATION(RC_DEKU_THEATER_MASK_OF_TRUTH, logic->IsChild && logic->MaskOfTruth), + LOCATION(RC_DEKU_THEATER_SKULL_MASK, logic->CanUse(RG_MASK_SKULL)), + LOCATION(RC_DEKU_THEATER_MASK_OF_TRUTH, logic->CanUse(RG_MASK_TRUTH)), }, { //Exits Entrance(RR_LW_BEYOND_MIDO, []{return true;}), @@ -130,7 +133,7 @@ void RegionTable_Init_LostWoods() { areaTable[RR_LW_BRIDGE_FROM_FOREST] = Region("LW Bridge From Forest", SCENE_LOST_WOODS, {}, { //Locations - LOCATION(RC_LW_GIFT_FROM_SARIA, true), + LOCATION(RC_LW_GIFT_FROM_SARIA, logic->HasSoul(RG_SARIA_SOUL)), }, { //Exits Entrance(RR_LW_BRIDGE, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 7d7655ef08e..3dd626ba9e5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -27,6 +27,7 @@ void RegionTable_Init_Market() { LOCATION(RC_MK_NEAR_BAZAAR_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/), LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_1, logic->IsChild /*&& logic->CanRoll()*/), LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/), + LOCATION(RC_MARKET_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits Entrance(RR_MARKET_ENTRANCE, []{return true;}), @@ -54,7 +55,7 @@ void RegionTable_Init_Market() { EventAccess(&logic->CanEmptyBigPoes, []{return logic->IsAdult;}), }, { //Locations - LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && (logic->BigPoeKill || logic->BigPoes >= ctx->GetOption(RSK_BIG_POE_COUNT).Get())), + LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && logic->HasSoul(RG_POE_COLLECTOR_SOUL) && (logic->BigPoeKill || logic->BigPoes >= ctx->GetOption(RSK_BIG_POE_COUNT).Get())), LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_1, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_2, logic->IsChild && logic->CanBreakPots()), @@ -123,14 +124,14 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_BAZAAR] = Region("Market Bazaar", SCENE_BAZAAR, {}, { //Locations - LOCATION(RC_MARKET_BAZAAR_ITEM_1, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_2, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_3, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_4, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_5, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_6, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_7, true), - LOCATION(RC_MARKET_BAZAAR_ITEM_8, true), + LOCATION(RC_MARKET_BAZAAR_ITEM_1, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_2, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_3, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_4, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_5, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_6, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_7, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BAZAAR_ITEM_8, logic->HasSoul(RG_BAZAAR_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), @@ -138,8 +139,8 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_MASK_SHOP] = Region("Market Mask Shop", SCENE_HAPPY_MASK_SHOP, { //Events - EventAccess(&logic->SkullMask, []{return logic->HasItem(RG_ZELDAS_LETTER) && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE));}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link's pocket - EventAccess(&logic->MaskOfTruth, []{return logic->SkullMask && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || (ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && RegionTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->StoneCount() == 3));}), + EventAccess(&logic->SkullMask, []{return logic->HasItem(RG_ZELDAS_LETTER) && ChildCanAccess(RR_KAKARIKO_VILLAGE);}), + EventAccess(&logic->MaskOfTruth, []{return logic->SkullMask && ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && RegionTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->StoneCount() == 3;}), }, { //Locations LOCATION(RC_MASK_SHOP_HINT, true), @@ -150,7 +151,7 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_SHOOTING_GALLERY] = Region("Market Shooting Gallery", SCENE_SHOOTING_GALLERY, {}, { //Locations - LOCATION(RC_MARKET_SHOOTING_GALLERY_REWARD, logic->IsChild && logic->HasItem(RG_CHILD_WALLET)), + LOCATION(RC_MARKET_SHOOTING_GALLERY_REWARD, logic->IsChild && logic->HasSoul(RG_SHOOTING_SOUL) && logic->HasItem(RG_CHILD_WALLET)), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), @@ -158,7 +159,7 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_BOMBCHU_BOWLING] = Region("Market Bombchu Bowling", SCENE_BOMBCHU_BOWLING_ALLEY, { //Events - EventAccess(&logic->CouldPlayBowling, []{return (logic->HasItem(RG_CHILD_WALLET));}), + EventAccess(&logic->CouldPlayBowling, []{return logic->HasSoul(RG_BOMBCHU_LADY_SOUL) && logic->HasItem(RG_CHILD_WALLET);}), }, { //Locations LOCATION(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, logic->CouldPlayBowling && logic->BombchusEnabled()), @@ -170,14 +171,14 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_POTION_SHOP] = Region("Market Potion Shop", SCENE_POTION_SHOP_MARKET, {}, { //Locations - LOCATION(RC_MARKET_POTION_SHOP_ITEM_1, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_2, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_3, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_4, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_5, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_6, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_7, true), - LOCATION(RC_MARKET_POTION_SHOP_ITEM_8, true), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_1, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_2, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_3, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_4, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_5, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_6, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_7, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_8, logic->HasSoul(RG_POTION_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), @@ -185,18 +186,18 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_TREASURE_CHEST_GAME] = Region("Market Treasure Chest Game", SCENE_TREASURE_BOX_SHOP, {}, { //Locations - LOCATION(RC_GREG_HINT, logic->HasItem(RG_CHILD_WALLET)), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasItem(RG_CHILD_WALLET) && ((logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_GREG_HINT, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET)), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasSoul(RG_TREASURE_MAN_SOUL) && logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), @@ -204,14 +205,14 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_BOMBCHU_SHOP] = Region("Market Bombchu Shop", SCENE_BOMBCHU_SHOP, {}, { //Locations - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_1, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_2, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_3, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_4, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_5, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_6, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_7, true), - LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_8, true), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_1, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_2, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_3, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_4, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_5, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_6, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_7, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_8, logic->HasSoul(RG_BOMBCHU_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_MARKET_BACK_ALLEY, []{return true;}), @@ -219,7 +220,7 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_DOG_LADY_HOUSE] = Region("Market Dog Lady House", SCENE_DOG_LADY_HOUSE, {}, { //Locations - LOCATION(RC_MARKET_LOST_DOG, logic->IsChild && logic->AtNight), + LOCATION(RC_MARKET_LOST_DOG, logic->IsChild && logic->AtNight && logic->HasSoul(RG_DOG_LADY_SOUL)), LOCATION(RC_MK_LOST_DOG_HOUSE_CRATE, logic->CanBreakCrates()), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp index 9d641ac9807..78a077551cf 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp @@ -12,31 +12,49 @@ void RegionTable_Init_SacredForestMeadow() { Entrance(RR_SFM_WOLFOS_GROTTO, []{return logic->CanOpenBombGrotto();}), }); - areaTable[RR_SACRED_FOREST_MEADOW] = Region("Sacred Forest Meadow", SCENE_SACRED_FOREST_MEADOW, { + areaTable[RR_SFM_ABOVE_MAZE] = Region("SFM Maze", SCENE_SACRED_FOREST_MEADOW, { //Events EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}), }, { //Locations - LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER)), - LOCATION(RC_SHEIK_IN_FOREST, logic->IsAdult), LOCATION(RC_SFM_GS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), - LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE, true), LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE, true), + }, { + //Exits + Entrance(RR_SFM_ENTRYWAY, []{return true;}), + Entrance(RR_SFM_OUTSIDE_FAIRY_GROTTO, []{return true;}), + Entrance(RR_SACRED_FOREST_MEADOW, []{return true;}), + }); + + areaTable[RR_SACRED_FOREST_MEADOW] = Region("Sacred Forest Meadow", SCENE_SACRED_FOREST_MEADOW, { + //Events + EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}), + }, { + //Locations + LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasSoul(RG_SARIA_SOUL) && logic->HasItem(RG_ZELDAS_LETTER)), + LOCATION(RC_SHEIK_IN_FOREST, logic->IsAdult && logic->HasSoul(RG_ZELDA_SOUL)), + LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_SFM_SARIA_GOSSIP_STONE, true), }, { //Exits - Entrance(RR_SFM_ENTRYWAY, []{return true;}), Entrance(RR_FOREST_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_SFM_FAIRY_GROTTO, []{return true;}), + Entrance(RR_SFM_ENTRYWAY, []{return true;}), + Entrance(RR_SFM_ABOVE_MAZE, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_SFM_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), }); + areaTable[RR_SFM_OUTSIDE_FAIRY_GROTTO] = Region("SFM Outside Fairy Grotto", SCENE_SACRED_FOREST_MEADOW, {}, {}, { + //Exits + Entrance(RR_SFM_FAIRY_GROTTO, []{return true;}), + Entrance(RR_SFM_ABOVE_MAZE, []{return logic->HasItem(RG_CLIMB) || logic->HasItem(RG_HOOKSHOT);}), + }); + areaTable[RR_SFM_FAIRY_GROTTO] = Region("SFM Fairy Grotto", SCENE_GROTTOS, { //Events EventAccess(&logic->FreeFairies, []{return true;}), @@ -52,7 +70,7 @@ void RegionTable_Init_SacredForestMeadow() { LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_8, true), }, { //Exits - Entrance(RR_SACRED_FOREST_MEADOW, []{return true;}), + Entrance(RR_SFM_OUTSIDE_FAIRY_GROTTO, []{return true;}), }); areaTable[RR_SFM_WOLFOS_GROTTO] = Region("SFM Wolfos Grotto", SCENE_GROTTOS, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp index 07efc4326a5..64c44c7af49 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp @@ -33,7 +33,7 @@ void RegionTable_Init_TempleOfTime() { LOCATION(RC_TOT_LIGHT_ARROWS_CUTSCENE, logic->IsAdult && logic->CanTriggerLACS()), LOCATION(RC_ALTAR_HINT_CHILD, logic->IsChild), LOCATION(RC_ALTAR_HINT_ADULT, logic->IsAdult), - LOCATION(RC_TOT_SHEIK_HINT, logic->IsAdult), + LOCATION(RC_TOT_SHEIK_HINT, logic->IsAdult && logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_TOT_ENTRANCE, []{return true;}), @@ -46,8 +46,8 @@ void RegionTable_Init_TempleOfTime() { }, { //Locations LOCATION(RC_TOT_MASTER_SWORD, logic->IsAdult), - LOCATION(RC_GIFT_FROM_RAURU, logic->IsAdult), - LOCATION(RC_SHEIK_AT_TEMPLE, logic->HasItem(RG_FOREST_MEDALLION) && logic->IsAdult), + LOCATION(RC_GIFT_FROM_RAURU, logic->IsAdult && logic->HasSoul(RG_RAURU_SOUL)), + LOCATION(RC_SHEIK_AT_TEMPLE, logic->HasItem(RG_FOREST_MEDALLION) && logic->IsAdult && logic->HasSoul(RG_ZELDA_SOUL)), }, { //Exits Entrance(RR_TEMPLE_OF_TIME, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp index 0a70e77e84f..3870ff05f79 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp @@ -17,7 +17,7 @@ void RegionTable_Init_ThievesHideout() { LOCATION(RC_TH_1_TORCH_CELL_MID_POT, logic->CanBreakPots()), LOCATION(RC_TH_1_TORCH_CELL_LEFT_POT, logic->CanBreakPots()), LOCATION(RC_TH_1_TORCH_CELL_CRATE, logic->CanBreakCrates()), - LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters), + LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters && logic->HasSoul(RG_ICHIRO_SOUL)), }, { //Exits Entrance(RR_GF_OUTSKIRTS, []{return true;}), @@ -40,7 +40,7 @@ void RegionTable_Init_ThievesHideout() { LOCATION(RC_TH_LEFTMOST_JAILED_POT, logic->CanBreakPots()), LOCATION(RC_TH_DOUBLE_CELL_LEFT_CRATE, logic->CanBreakCrates()), LOCATION(RC_TH_DOUBLE_CELL_RIGHT_CRATE, logic->CanBreakCrates()), - LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters), + LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters && logic->HasSoul(RG_SABOORO_SOUL)), }, { //Exits Entrance(RR_GF_OUTSKIRTS, []{return true;}), @@ -55,7 +55,7 @@ void RegionTable_Init_ThievesHideout() { //Locations LOCATION(RC_TH_DEAD_END_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), LOCATION(RC_TH_DEAD_END_CELL_CRATE, logic->CanBreakCrates()), - LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters), + LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters && logic->HasSoul(RG_JIRO_SOUL)), }, { //Exits Entrance(RR_GF_BELOW_GS, []{return true;}), @@ -70,7 +70,7 @@ void RegionTable_Init_ThievesHideout() { LOCATION(RC_TH_STEEP_SLOPE_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), LOCATION(RC_TH_STEEP_SLOPE_RIGHT_POT, logic->CanBreakPots()), LOCATION(RC_TH_STEEP_SLOPE_LEFT_POT, logic->CanBreakPots()), - LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters), + LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters && logic->HasSoul(RG_SHIRO_SOUL)), }, { //Exits Entrance(RR_GF_ABOVE_GTG, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index 3a626a2f93c..6f1e2d1655c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -15,7 +15,7 @@ void RegionTable_Init_ZorasDomain() { EventAccess(&logic->DeliverLetter, []{return logic->CanUse(RG_RUTOS_LETTER) && logic->IsChild && ctx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN);}), }, { //Locations - LOCATION(RC_ZD_DIVING_MINIGAME, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), + LOCATION(RC_ZD_DIVING_MINIGAME, logic->IsChild && logic->HasSoul(RG_DIVING_SOUL) && logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CHILD_WALLET)), LOCATION(RC_ZD_CHEST, logic->IsChild && logic->CanUse(RG_STICKS)), LOCATION(RC_ZD_KING_ZORA_THAWED, logic->IsAdult && logic->KingZoraThawed), LOCATION(RC_ZD_TRADE_PRESCRIPTION, logic->IsAdult && logic->KingZoraThawed && logic->CanUse(RG_PRESCRIPTION)), @@ -35,6 +35,14 @@ void RegionTable_Init_ZorasDomain() { LOCATION(RC_ZD_NEAR_SHOP_POT_3, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_4, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_5, logic->CanBreakPots()), + LOCATION(RC_ZD_CIRCLE_ROCK_1, true), + LOCATION(RC_ZD_CIRCLE_ROCK_2, true), + LOCATION(RC_ZD_CIRCLE_ROCK_3, true), + LOCATION(RC_ZD_CIRCLE_ROCK_4, true), + LOCATION(RC_ZD_CIRCLE_ROCK_5, true), + LOCATION(RC_ZD_CIRCLE_ROCK_6, true), + LOCATION(RC_ZD_CIRCLE_ROCK_7, true), + LOCATION(RC_ZD_CIRCLE_ROCK_8, true), }, { //Exits Entrance(RR_ZR_BEHIND_WATERFALL, []{return true;}), @@ -64,14 +72,14 @@ void RegionTable_Init_ZorasDomain() { areaTable[RR_ZD_SHOP] = Region("ZD Shop", SCENE_ZORA_SHOP, {}, { //Locations - LOCATION(RC_ZD_SHOP_ITEM_1, true), - LOCATION(RC_ZD_SHOP_ITEM_2, true), - LOCATION(RC_ZD_SHOP_ITEM_3, true), - LOCATION(RC_ZD_SHOP_ITEM_4, true), - LOCATION(RC_ZD_SHOP_ITEM_5, true), - LOCATION(RC_ZD_SHOP_ITEM_6, true), - LOCATION(RC_ZD_SHOP_ITEM_7, true), - LOCATION(RC_ZD_SHOP_ITEM_8, true), + LOCATION(RC_ZD_SHOP_ITEM_1, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_2, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_3, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_4, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_5, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_6, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_7, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), + LOCATION(RC_ZD_SHOP_ITEM_8, logic->HasSoul(RG_ZORA_SHOPKEEPER_SOUL)), }, { //Exits Entrance(RR_ZORAS_DOMAIN, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index cfd2125c1df..c114bcff7aa 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -11,7 +11,7 @@ void RegionTable_Init_ZorasFountain() { EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}), }, { //Locations - LOCATION(RC_ZF_GS_TREE, logic->IsChild), + LOCATION(RC_ZF_GS_TREE, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), @@ -23,6 +23,10 @@ void RegionTable_Init_ZorasFountain() { LOCATION(RC_ZF_NEAR_JABU_POT_2, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_ZF_NEAR_JABU_POT_3, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_ZF_NEAR_JABU_POT_4, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_ZF_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_ZF_UNDERGROUND_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash()), + LOCATION(RC_ZF_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits Entrance(RR_ZD_BEHIND_KING_ZORA, []{return true;}), @@ -89,7 +93,7 @@ void RegionTable_Init_ZorasFountain() { //Exits //There are invisible big skultullas here as adult but they do not block the path and can be "seen" with Z-target //Lens is not currently needed for this either, implying they are not considered blocking, but it's open for discussion long-term - Entrance(RR_ZF_HIDDEN_LEDGE, []{return true;}), + Entrance(RR_ZF_HIDDEN_LEDGE, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}), }); areaTable[RR_ZF_HIDDEN_LEDGE] = Region("ZF Hidden Ledge", SCENE_ZORAS_FOUNTAIN, {}, { @@ -112,7 +116,7 @@ void RegionTable_Init_ZorasFountain() { areaTable[RR_ZF_GREAT_FAIRY_FOUNTAIN] = Region("ZF Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, {}, { //Locations - LOCATION(RC_ZF_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_ZF_GREAT_FAIRY_REWARD, logic->HasSoul(RG_GREAT_FAIRY_SOUL) && logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits Entrance(RR_ZORAS_FOUNTAIN, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 5473ee2caa7..727411395a4 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -7,19 +7,24 @@ void RegionTable_Init_ZoraRiver() { // clang-format off areaTable[RR_ZR_FRONT] = Region("ZR Front", SCENE_ZORAS_RIVER, {}, { //Locations - LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), - LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_4, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_5, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_6, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_7, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_8, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_9, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), + LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_5, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_6, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_7, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_8, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_ZR_BOULDER_1, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_2, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_3, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_4, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits Entrance(RR_ZORAS_RIVER, []{return logic->IsAdult || logic->BlastOrSmash();}), @@ -34,7 +39,7 @@ void RegionTable_Init_ZoraRiver() { EventAccess(&logic->BugShrub, []{return logic->CanCutShrubs();}), }, { //Locations - LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), + LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->HasSoul(RG_BEAN_SALESMAN_SOUL)), LOCATION(RC_ZR_FROGS_OCARINA_GAME, logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanUse(RG_SARIAS_SONG) && logic->CanUse(RG_SUNS_SONG) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_FROGS_IN_THE_RAIN, logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_FROGS_ZELDAS_LULLABY, logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY)), @@ -45,27 +50,35 @@ void RegionTable_Init_ZoraRiver() { LOCATION(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, logic->IsChild || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_ZR_LOWER))), LOCATION(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, logic->IsChild || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_ZR_UPPER))), LOCATION(RC_ZR_GS_LADDER, logic->IsChild && logic->CanAttack() && logic->CanGetNightTimeGS()), - LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->CanGetNightTimeGS()), LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), - LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, true), + LOCATION(RC_ZR_CIRCLE_ROCK_1, true), + LOCATION(RC_ZR_CIRCLE_ROCK_2, true), + LOCATION(RC_ZR_CIRCLE_ROCK_3, true), + LOCATION(RC_ZR_CIRCLE_ROCK_4, true), + LOCATION(RC_ZR_CIRCLE_ROCK_5, true), + LOCATION(RC_ZR_CIRCLE_ROCK_6, true), + LOCATION(RC_ZR_CIRCLE_ROCK_7, true), + LOCATION(RC_ZR_CIRCLE_ROCK_8, true), + LOCATION(RC_ZR_ROCK, true), + LOCATION(RC_ZR_UNDERWATER_ROCK_1, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UNDERWATER_ROCK_2, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UNDERWATER_ROCK_3, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UNDERWATER_ROCK_4, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, true), LOCATION(RC_ZR_NEAR_FREESTANDING_POH_GRASS, logic->CanCutShrubs()), }, { //Exits Entrance(RR_ZR_FRONT, []{return true;}), - Entrance(RR_ZR_OPEN_GROTTO, []{return true;}), - Entrance(RR_ZR_FAIRY_GROTTO, []{return Here(RR_ZORAS_RIVER, []{return logic->BlastOrSmash();});}), + Entrance(RR_ZR_UPPER_GROTTOS, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || CanPlantBean(RR_ZORAS_RIVER);}), Entrance(RR_THE_LOST_WOODS, []{return logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), Entrance(RR_ZR_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), Entrance(RR_ZR_BEHIND_WATERFALL, []{return ctx->GetOption(RSK_SLEEPING_WATERFALL).Is(RO_WATERFALL_OPEN) || Here(RR_ZORAS_RIVER, []{return logic->CanUse(RG_ZELDAS_LULLABY);}) || (logic->IsChild && ctx->GetTrickOption(RT_ZR_CUCCO)) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_ZR_HOVERS));}), @@ -83,6 +96,28 @@ void RegionTable_Init_ZoraRiver() { Entrance(RR_ZORAS_DOMAIN, []{return true;}), }); + areaTable[RR_ZR_UPPER_GROTTOS] = Region("ZR Upper Grottos", SCENE_ZORAS_RIVER, {}, { + //Locations + LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, true), + LOCATION(RC_ZR_UPPER_CIRCLE_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_1, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_2, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_3, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_4, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_5, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_6, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_7, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_8, true), + }, { + //Exits + Entrance(RR_ZORAS_RIVER, []{return true;}), + Entrance(RR_ZR_OPEN_GROTTO, []{return true;}), + Entrance(RR_ZR_FAIRY_GROTTO, []{return Here(RR_ZR_UPPER_GROTTOS, []{return logic->BlastOrSmash();});}), + }); + areaTable[RR_ZR_OPEN_GROTTO] = Region("ZR Open Grotto", SCENE_GROTTOS, grottoEvents, { //Locations LOCATION(RC_ZR_OPEN_GROTTO_CHEST, true), @@ -98,7 +133,7 @@ void RegionTable_Init_ZoraRiver() { LOCATION(RC_ZR_OPEN_GROTTO_GRASS_4, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_ZORAS_RIVER, []{return true;}), + Entrance(RR_ZR_UPPER_GROTTOS, []{return true;}), }); areaTable[RR_ZR_FAIRY_GROTTO] = Region("ZR Fairy Grotto", SCENE_GROTTOS, { @@ -116,7 +151,7 @@ void RegionTable_Init_ZoraRiver() { LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_8, true), }, { //Exits - Entrance(RR_ZORAS_RIVER, []{return true;}), + Entrance(RR_ZR_UPPER_GROTTOS, []{return true;}), }); areaTable[RR_ZR_STORMS_GROTTO] = Region("ZR Storms Grotto", SCENE_GROTTOS, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 2fea752ccb7..3eb7a333d32 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -1,4 +1,5 @@ #include "static_data.h" + #include "z64save.h" #include "context.h" #include "dungeon.h" @@ -748,7 +749,7 @@ void Rando::StaticData::InitLocationTable() { locationTable[RC_GV_GS_PILLAR] = Location::GSToken(RC_GV_GS_PILLAR, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 21252, 0x04, "GS Pillar", RHT_GV_GS_PILLAR, 0x13); locationTable[RC_GV_GS_BEHIND_TENT] = Location::GSToken(RC_GV_GS_BEHIND_TENT, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 21256, 0x08, "GS Behind Tent", RHT_GV_GS_BEHIND_TENT, 0x13); // Gerudo Fortress - locationTable[RC_GF_HBA_RANGE_GS] = Location::GSToken(RC_GF_HBA_RANGE_GS, RCQUEST_BOTH, SCENE_GERUDOS_FORTRESS, 21505, 0x01, "GS Archery Range", RHT_GF_GS_ARCHERY_RANGE, 0x14); + locationTable[RC_GF_HBA_RANGE_GS] = Location::GSToken(RC_GF_HBA_RANGE_GS, RCQUEST_BOTH, SCENE_GERUDOS_FORTRESS, 21505, 0x01, "GS Archery Range", RHT_GF_GS_ARCHERY_RANGE, 0x14); locationTable[RC_GF_GS_TOP_FLOOR] = Location::GSToken(RC_GF_GS_TOP_FLOOR, RCQUEST_BOTH, SCENE_GERUDOS_FORTRESS, 21506, 0x02, "GS Top Floor", RHT_GF_GS_TOP_FLOOR, 0x14); // Wasteland & Desert Colossus locationTable[RC_WASTELAND_GS] = Location::GSToken(RC_WASTELAND_GS, RCQUEST_BOTH, SCENE_HAUNTED_WASTELAND, 13570, 0x02, "GS", RHT_WASTELAND_GS, 0x15); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 442f2b23b38..9a73cb60410 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -123,6 +123,31 @@ bool Logic::HasItem(RandomizerGet itemName) { return CheckQuestItem(RandoGetToQuestItem.at(itemName)); case RG_DOUBLE_DEFENSE: return GetSaveContext()->isDoubleDefenseAcquired; + // Masks + case RG_MASK_SKULL: + switch (ctx->GetOption(RSK_MASK_QUEST).Get()) { + case RO_MASK_QUEST_VANILLA: + return SkullMask; + case RO_MASK_QUEST_COMPLETED: + return HasItem(RG_ZELDAS_LETTER); + case RO_MASK_QUEST_SHUFFLE: + return HasItem(RG_ZELDAS_LETTER) && CheckRandoInf(RAND_INF_CHILD_TRADES_HAS_MASK_SKULL); + default: + assert(false); + return false; + } + case RG_MASK_TRUTH: + switch (ctx->GetOption(RSK_MASK_QUEST).Get()) { + case RO_MASK_QUEST_VANILLA: + return MaskOfTruth; + case RO_MASK_QUEST_COMPLETED: + return HasItem(RG_ZELDAS_LETTER); + case RO_MASK_QUEST_SHUFFLE: + return HasItem(RG_ZELDAS_LETTER) && CheckRandoInf(RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH); + default: + assert(false); + return false; + } case RG_FISHING_POLE: case RG_ZELDAS_LETTER: case RG_WEIRD_EGG: @@ -143,8 +168,57 @@ bool Logic::HasItem(RandomizerGet itemName) { case RG_BONGO_BONGO_SOUL: case RG_TWINROVA_SOUL: case RG_GANON_SOUL: + // NPC Souls + case RG_ANJU_SOUL: + case RG_TALON_SOUL: + case RG_GROG_SOUL: + case RG_GRANNY_SOUL: + case RG_FADO_SOUL: + case RG_LINK_SOUL: + case RG_BIGGORON_SOUL: + case RG_HOT_RODDER_SOUL: + case RG_MEDIGORON_SOUL: + case RG_CARPENTER_BOSS_SOUL: + case RG_ICHIRO_SOUL: + case RG_SABOORO_SOUL: + case RG_JIRO_SOUL: + case RG_SHIRO_SOUL: + case RG_HW_GATEKEEPER_SOUL: + case RG_GTG_GATEKEEPER_SOUL: + case RG_ARCHER_SOUL: + case RG_GREAT_FAIRY_SOUL: + case RG_POE_COLLECTOR_SOUL: + case RG_DAMPE_SOUL: + case RG_WINDMILL_MAN_SOUL: + case RG_MAN_ON_ROOF_SOUL: + case RG_KAKARIKO_GATEKEEPER_SOUL: + case RG_MALON_SOUL: + case RG_BEGGAR_SOUL: + case RG_DOG_LADY_SOUL: + case RG_ARMS_DEALER_SOUL: + case RG_BEAN_SALESMAN_SOUL: + case RG_SHOOTING_SOUL: + case RG_KOKIRI_SHOPKEEPER_SOUL: + case RG_POTION_SHOPKEEPER_SOUL: + case RG_BAZAAR_SHOPKEEPER_SOUL: + case RG_GORON_SHOPKEEPER_SOUL: + case RG_ZORA_SHOPKEEPER_SOUL: + case RG_BOMBCHU_SHOPKEEPER_SOUL: + case RG_MASK_SALESMAN_SOUL: + case RG_TREASURE_MAN_SOUL: + case RG_BOMBCHU_LADY_SOUL: + case RG_DIVING_SOUL: + case RG_SCIENTIST_SOUL: + case RG_KAEPORA_SOUL: + case RG_RAURU_SOUL: + case RG_SARIA_SOUL: + case RG_DARUNIA_SOUL: + case RG_RUTO_SOUL: + case RG_NABOORU_SOUL: + case RG_IMPA_SOUL: + case RG_ZELDA_SOUL: + // Overworld Keys case RG_SKELETON_KEY: - // Overworld Keys case RG_GUARD_HOUSE_KEY: case RG_MARKET_BAZAAR_KEY: case RG_MARKET_POTION_SHOP_KEY: @@ -221,6 +295,10 @@ bool Logic::HasItem(RandomizerGet itemName) { return CurrentUpgrade(UPG_SCALE) >= 1; case RG_GOLDEN_SCALE: return CurrentUpgrade(UPG_SCALE) >= 2; + case RG_CLIMB: + return CheckRandoInf(RAND_INF_CAN_CLIMB); + case RG_CRAWL: + return CheckRandoInf(RAND_INF_CAN_CRAWL); case RG_POCKET_EGG: return CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG); case RG_COJIRO: @@ -340,6 +418,9 @@ bool Logic::CanUse(RandomizerGet itemName) { return IsChild; case RG_MAGIC_BEAN: return IsChild; + case RG_MASK_SKULL: + case RG_MASK_TRUTH: + return IsChild; // Songs case RG_ZELDAS_LULLABY: @@ -374,7 +455,8 @@ bool Logic::CanUse(RandomizerGet itemName) { return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies case RG_EPONA: return IsAdult && CanUse(RG_EPONAS_SONG); - + case RG_CRAWL: + return IsChild; // Bottle Items case RG_BOTTLE_WITH_BUGS: return BugShrub || WanderingBugs || BugRock || GetInLogic(LOGIC_BUGS_ACCESS); @@ -406,10 +488,7 @@ bool Logic::HasProjectile(HasProjectileAge age) { (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW))); } -bool Logic::HasBossSoul(RandomizerGet itemName) { - if (!ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) { - return true; - } +bool Logic::HasSoul(RandomizerGet itemName) { switch (itemName) { case RG_GOHMA_SOUL: case RG_KING_DODONGO_SOUL: @@ -419,15 +498,67 @@ bool Logic::HasBossSoul(RandomizerGet itemName) { case RG_MORPHA_SOUL: case RG_BONGO_BONGO_SOUL: case RG_TWINROVA_SOUL: - return HasItem(itemName); + return !ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS) || HasItem(itemName); case RG_GANON_SOUL: - return ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON) ? HasItem(RG_GANON_SOUL) - : true; + return !ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON) || HasItem(RG_GANON_SOUL); + case RG_ANJU_SOUL: + case RG_TALON_SOUL: + case RG_GROG_SOUL: + case RG_GRANNY_SOUL: + case RG_FADO_SOUL: + case RG_LINK_SOUL: + case RG_BIGGORON_SOUL: + case RG_HOT_RODDER_SOUL: + case RG_MEDIGORON_SOUL: + case RG_CARPENTER_BOSS_SOUL: + case RG_ICHIRO_SOUL: + case RG_SABOORO_SOUL: + case RG_JIRO_SOUL: + case RG_SHIRO_SOUL: + case RG_HW_GATEKEEPER_SOUL: + case RG_GTG_GATEKEEPER_SOUL: + case RG_ARCHER_SOUL: + case RG_GREAT_FAIRY_SOUL: + case RG_POE_COLLECTOR_SOUL: + case RG_DAMPE_SOUL: + case RG_WINDMILL_MAN_SOUL: + case RG_MAN_ON_ROOF_SOUL: + case RG_KAKARIKO_GATEKEEPER_SOUL: + case RG_MALON_SOUL: + case RG_BEGGAR_SOUL: + case RG_DOG_LADY_SOUL: + case RG_ARMS_DEALER_SOUL: + case RG_BEAN_SALESMAN_SOUL: + case RG_SHOOTING_SOUL: + case RG_KOKIRI_SHOPKEEPER_SOUL: + case RG_POTION_SHOPKEEPER_SOUL: + case RG_BAZAAR_SHOPKEEPER_SOUL: + case RG_GORON_SHOPKEEPER_SOUL: + case RG_ZORA_SHOPKEEPER_SOUL: + case RG_BOMBCHU_SHOPKEEPER_SOUL: + case RG_MASK_SALESMAN_SOUL: + case RG_TREASURE_MAN_SOUL: + case RG_BOMBCHU_LADY_SOUL: + case RG_DIVING_SOUL: + case RG_SCIENTIST_SOUL: + case RG_KAEPORA_SOUL: + case RG_RAURU_SOUL: + case RG_SARIA_SOUL: + case RG_DARUNIA_SOUL: + case RG_RUTO_SOUL: + case RG_NABOORU_SOUL: + case RG_IMPA_SOUL: + case RG_ZELDA_SOUL: + return !ctx->GetOption(RSK_SHUFFLE_NPC_SOULS) || HasItem(itemName); default: return false; } } +bool Logic::HasSage(RandomizerGet itemName) { + return !ctx->GetOption(RSK_SHUFFLE_NPC_SOULS).Is(RO_NPC_SOULS_ON_PLUS_SAGES) || HasItem(itemName); +} + // RANDOMISERTODO intergrate into HasItem bool Logic::CanOpenOverworldDoor(RandomizerGet key) { if (!ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) { @@ -735,31 +866,31 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal // without shenanigans anyway. Bunny makes it free return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_STICKS) || CanUse(RG_MASTER_SWORD); case RE_GOHMA: - return HasBossSoul(RG_GOHMA_SOUL) && CanJumpslash() && + return HasSoul(RG_GOHMA_SOUL) && CanJumpslash() && (CanUse(RG_NUTS) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || HookshotOrBoomerang()); case RE_KING_DODONGO: - return HasBossSoul(RG_KING_DODONGO_SOUL) && CanJumpslash() && + return HasSoul(RG_KING_DODONGO_SOUL) && CanJumpslash() && (CanUse(RG_BOMB_BAG) || HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_DC_DODONGO_CHU) && IsAdult && CanUse(RG_BOMBCHU_5))); case RE_BARINADE: - return HasBossSoul(RG_BARINADE_SOUL) && CanUse(RG_BOOMERANG) && CanJumpslashExceptHammer(); + return HasSoul(RG_BARINADE_SOUL) && CanUse(RG_BOOMERANG) && CanJumpslashExceptHammer(); case RE_PHANTOM_GANON: - return HasBossSoul(RG_PHANTOM_GANON_SOUL) && CanUseSword() && + return HasSoul(RG_PHANTOM_GANON_SOUL) && CanUseSword() && (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT)); case RE_VOLVAGIA: - return HasBossSoul(RG_VOLVAGIA_SOUL) && CanUse(RG_MEGATON_HAMMER); + return HasSoul(RG_VOLVAGIA_SOUL) && CanUse(RG_MEGATON_HAMMER); case RE_MORPHA: - return HasBossSoul(RG_MORPHA_SOUL) && + return HasSoul(RG_MORPHA_SOUL) && (CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_WATER_MORPHA_WITHOUT_HOOKSHOT) && HasItem(RG_BRONZE_SCALE))) && (CanUseSword() || CanUse(RG_MEGATON_HAMMER)); case RE_BONGO_BONGO: - return HasBossSoul(RG_BONGO_BONGO_SOUL) && - (CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) && CanUseSword() && + return HasSoul(RG_BONGO_BONGO_SOUL) && (CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) && + CanUseSword() && (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || ctx->GetTrickOption(RT_SHADOW_BONGO)); case RE_TWINROVA: - return HasBossSoul(RG_TWINROVA_SOUL) && CanUse(RG_MIRROR_SHIELD) && + return HasSoul(RG_TWINROVA_SOUL) && CanUse(RG_MIRROR_SHIELD) && (CanUseSword() || CanUse(RG_MEGATON_HAMMER)); case RE_GANONDORF: // RANDOTODO: Trick to use hammer (no jumpslash) or stick (only jumpslash) instead of a sword to reflect the @@ -769,9 +900,9 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal // for killing ganondorf and all of those can reflect the energy ball // This will not be the case once ammo logic in taken into account as // sticks are limited and using a bottle might become a requirement in that case - return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_LIGHT_ARROWS) && CanUseSword(); + return HasSoul(RG_GANON_SOUL) && CanUse(RG_LIGHT_ARROWS) && CanUseSword(); case RE_GANON: - return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_MASTER_SWORD); + return HasSoul(RG_GANON_SOUL) && HasSage(RG_ZELDA_SOUL) && CanUse(RG_MASTER_SWORD); case RE_DARK_LINK: // RANDOTODO Dark link is buggy right now, retest when he is not return CanJumpslash() || CanUse(RG_FAIRY_BOW); @@ -1152,6 +1283,10 @@ bool Logic::CanBreakSmallCrates() { return true; } +bool Logic::CanBonkTrees() { + return true; +} + bool Logic::HasExplosives() { return CanUse(RG_BOMB_BAG) || CanUse(RG_BOMBCHU_5); } @@ -1470,11 +1605,67 @@ std::map Logic::RandoGetToRandInf = { { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, + { RG_ANJU_SOUL, RAND_INF_ANJU_SOUL }, + { RG_TALON_SOUL, RAND_INF_TALON_SOUL }, + { RG_GROG_SOUL, RAND_INF_GROG_SOUL }, + { RG_GRANNY_SOUL, RAND_INF_GRANNY_SOUL }, + { RG_FADO_SOUL, RAND_INF_FADO_SOUL }, + { RG_ICHIRO_SOUL, RAND_INF_ICHIRO_SOUL }, + { RG_SABOORO_SOUL, RAND_INF_SABOORO_SOUL }, + { RG_JIRO_SOUL, RAND_INF_JIRO_SOUL }, + { RG_SHIRO_SOUL, RAND_INF_SHIRO_SOUL }, + { RG_HW_GATEKEEPER_SOUL, RAND_INF_HW_GATEKEEPER_SOUL }, + { RG_GTG_GATEKEEPER_SOUL, RAND_INF_GTG_GATEKEEPER_SOUL }, + { RG_ARCHER_SOUL, RAND_INF_ARCHER_SOUL }, + { RG_LINK_SOUL, RAND_INF_LINK_SOUL }, + { RG_BIGGORON_SOUL, RAND_INF_BIGGORON_SOUL }, + { RG_HOT_RODDER_SOUL, RAND_INF_HOT_RODDER_SOUL }, + { RG_MEDIGORON_SOUL, RAND_INF_MEDIGORON_SOUL }, + { RG_CARPENTER_BOSS_SOUL, RAND_INF_CARPENTER_BOSS_SOUL }, + { RG_GREAT_FAIRY_SOUL, RAND_INF_GREAT_FAIRY_SOUL }, + { RG_POE_COLLECTOR_SOUL, RAND_INF_POE_COLLECTOR_SOUL }, + { RG_DAMPE_SOUL, RAND_INF_DAMPE_SOUL }, + { RG_WINDMILL_MAN_SOUL, RAND_INF_WINDMILL_MAN_SOUL }, + { RG_MAN_ON_ROOF_SOUL, RAND_INF_MAN_ON_ROOF_SOUL }, + { RG_KAKARIKO_GATEKEEPER_SOUL, RAND_INF_KAKARIKO_GATEKEEPER_SOUL }, + { RG_MALON_SOUL, RAND_INF_MALON_SOUL }, + { RG_RAURU_SOUL, RAND_INF_RAURU_SOUL }, + { RG_SARIA_SOUL, RAND_INF_SARIA_SOUL }, + { RG_DARUNIA_SOUL, RAND_INF_DARUNIA_SOUL }, + { RG_RUTO_SOUL, RAND_INF_RUTO_SOUL }, + { RG_NABOORU_SOUL, RAND_INF_NABOORU_SOUL }, + { RG_IMPA_SOUL, RAND_INF_IMPA_SOUL }, + { RG_ZELDA_SOUL, RAND_INF_ZELDA_SOUL }, + { RG_BEGGAR_SOUL, RAND_INF_BEGGAR_SOUL }, + { RG_DOG_LADY_SOUL, RAND_INF_DOG_LADY_SOUL }, + { RG_ARMS_DEALER_SOUL, RAND_INF_ARMS_DEALER_SOUL }, + { RG_BEAN_SALESMAN_SOUL, RAND_INF_BEAN_SALESMAN_SOUL }, + { RG_SHOOTING_SOUL, RAND_INF_SHOOTING_SOUL }, + { RG_KOKIRI_SHOPKEEPER_SOUL, RAND_INF_KOKIRI_SHOPKEEPER_SOUL }, + { RG_POTION_SHOPKEEPER_SOUL, RAND_INF_POTION_SHOPKEEPER_SOUL }, + { RG_BAZAAR_SHOPKEEPER_SOUL, RAND_INF_BAZAAR_SHOPKEEPER_SOUL }, + { RG_GORON_SHOPKEEPER_SOUL, RAND_INF_GORON_SHOPKEEPER_SOUL }, + { RG_ZORA_SHOPKEEPER_SOUL, RAND_INF_ZORA_SHOPKEEPER_SOUL }, + { RG_BOMBCHU_SHOPKEEPER_SOUL, RAND_INF_BOMBCHU_SHOPKEEPER_SOUL }, + { RG_MASK_SALESMAN_SOUL, RAND_INF_MASK_SALESMAN_SOUL }, + { RG_TREASURE_MAN_SOUL, RAND_INF_TREASURE_MAN_SOUL }, + { RG_BOMBCHU_LADY_SOUL, RAND_INF_BOMBCHU_LADY_SOUL }, + { RG_DIVING_SOUL, RAND_INF_DIVING_SOUL }, + { RG_SCIENTIST_SOUL, RAND_INF_SCIENTIST_SOUL }, + { RG_KAEPORA_SOUL, RAND_INF_KAEPORA_SOUL }, { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, + { RG_MASK_KEATON, RAND_INF_CHILD_TRADES_HAS_MASK_KEATON }, + { RG_MASK_SKULL, RAND_INF_CHILD_TRADES_HAS_MASK_SKULL }, + { RG_MASK_SPOOKY, RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY }, + { RG_MASK_BUNNY, RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY }, + { RG_MASK_GORON, RAND_INF_CHILD_TRADES_HAS_MASK_GORON }, + { RG_MASK_ZORA, RAND_INF_CHILD_TRADES_HAS_MASK_ZORA }, + { RG_MASK_GERUDO, RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO }, + { RG_MASK_TRUTH, RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH }, { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, { RG_GREG_RUPEE, RAND_INF_GREG_FOUND }, { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, @@ -1631,6 +1822,12 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_CLAIM_CHECK: SetRandoInf(randoGet - RG_COJIRO + RAND_INF_ADULT_TRADES_HAS_COJIRO, state); break; + case RG_CLIMB: + SetRandoInf(RAND_INF_CAN_CLIMB, state); + break; + case RG_CRAWL: + SetRandoInf(RAND_INF_CAN_CRAWL, state); + break; case RG_PROGRESSIVE_HOOKSHOT: { uint8_t i; for (i = 0; i < 3; i++) { @@ -1836,11 +2033,67 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_BONGO_BONGO_SOUL: case RG_TWINROVA_SOUL: case RG_GANON_SOUL: + case RG_ANJU_SOUL: + case RG_TALON_SOUL: + case RG_GROG_SOUL: + case RG_GRANNY_SOUL: + case RG_FADO_SOUL: + case RG_LINK_SOUL: + case RG_BIGGORON_SOUL: + case RG_HOT_RODDER_SOUL: + case RG_MEDIGORON_SOUL: + case RG_CARPENTER_BOSS_SOUL: + case RG_ICHIRO_SOUL: + case RG_SABOORO_SOUL: + case RG_JIRO_SOUL: + case RG_SHIRO_SOUL: + case RG_HW_GATEKEEPER_SOUL: + case RG_GTG_GATEKEEPER_SOUL: + case RG_ARCHER_SOUL: + case RG_GREAT_FAIRY_SOUL: + case RG_POE_COLLECTOR_SOUL: + case RG_DAMPE_SOUL: + case RG_WINDMILL_MAN_SOUL: + case RG_MAN_ON_ROOF_SOUL: + case RG_KAKARIKO_GATEKEEPER_SOUL: + case RG_MALON_SOUL: + case RG_BEGGAR_SOUL: + case RG_DOG_LADY_SOUL: + case RG_ARMS_DEALER_SOUL: + case RG_BEAN_SALESMAN_SOUL: + case RG_SHOOTING_SOUL: + case RG_KOKIRI_SHOPKEEPER_SOUL: + case RG_POTION_SHOPKEEPER_SOUL: + case RG_BAZAAR_SHOPKEEPER_SOUL: + case RG_GORON_SHOPKEEPER_SOUL: + case RG_ZORA_SHOPKEEPER_SOUL: + case RG_BOMBCHU_SHOPKEEPER_SOUL: + case RG_MASK_SALESMAN_SOUL: + case RG_TREASURE_MAN_SOUL: + case RG_BOMBCHU_LADY_SOUL: + case RG_DIVING_SOUL: + case RG_SCIENTIST_SOUL: + case RG_KAEPORA_SOUL: + case RG_RAURU_SOUL: + case RG_SARIA_SOUL: + case RG_DARUNIA_SOUL: + case RG_RUTO_SOUL: + case RG_NABOORU_SOUL: + case RG_IMPA_SOUL: + case RG_ZELDA_SOUL: case RG_OCARINA_A_BUTTON: case RG_OCARINA_C_UP_BUTTON: case RG_OCARINA_C_DOWN_BUTTON: case RG_OCARINA_C_LEFT_BUTTON: case RG_OCARINA_C_RIGHT_BUTTON: + case RG_MASK_KEATON: + case RG_MASK_SKULL: + case RG_MASK_SPOOKY: + case RG_MASK_BUNNY: + case RG_MASK_GORON: + case RG_MASK_ZORA: + case RG_MASK_GERUDO: + case RG_MASK_TRUTH: case RG_GREG_RUPEE: case RG_FISHING_POLE: case RG_GUARD_HOUSE_KEY: @@ -2351,8 +2604,9 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { // AmmoCanDrop = /*AmmoDrops.IsNot(AMMODROPS_NONE)*/ false; TODO: AmmoDrop setting // Child item logic - SkullMask = false; - MaskOfTruth = false; + // Mask logic only used for vanilla mask quest, avoid computing outside that scenario + SkullMask = ctx->GetOption(RSK_MASK_QUEST).IsNot(RO_MASK_QUEST_VANILLA); + MaskOfTruth = ctx->GetOption(RSK_MASK_QUEST).IsNot(RO_MASK_QUEST_VANILLA); // Adult logic FreedEpona = false; @@ -2397,6 +2651,16 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { SetRandoInf(RAND_INF_CAN_SWIM, true); } + // If we're not shuffling climb, we start with it + if (ctx->GetOption(RSK_SHUFFLE_CLIMB).Is(false)) { + SetRandoInf(RAND_INF_CAN_CLIMB, true); + } + + // If we're not shuffling crawl, we start with it + if (ctx->GetOption(RSK_SHUFFLE_CRAWL).Is(false)) { + SetRandoInf(RAND_INF_CAN_CRAWL, true); + } + // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { SetRandoInf(RAND_INF_HAS_WALLET, true); diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index ba9ab60d0be..d5574e610e7 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -41,6 +41,13 @@ class Logic { bool WakeUpAdultTalon = false; // Dungeon Clears + bool DodongosCavernWin = false; + bool JabuJabusBellyWin = false; + bool ForestTempleWin = false; + bool FireTempleWin = false; + bool WaterTempleWin = false; + bool SpiritTempleWin = false; + bool ShadowTempleWin = false; bool DekuTreeClear = false; bool DodongosCavernClear = false; bool JabuJabusBellyClear = false; @@ -189,7 +196,8 @@ class Logic { bool CanUse(RandomizerGet itemName); bool HasProjectile(HasProjectileAge age); bool HasItem(RandomizerGet itemName); - bool HasBossSoul(RandomizerGet itemName); + bool HasSoul(RandomizerGet itemName); + bool HasSage(RandomizerGet itemName); bool CanOpenOverworldDoor(RandomizerGet itemName); bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount); bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched); @@ -247,6 +255,7 @@ class Logic { bool CanBreakPots(); bool CanBreakCrates(); bool CanBreakSmallCrates(); + bool CanBonkTrees(); bool HasFireSource(); bool HasFireSourceWithTorch(); bool TradeQuestStep(RandomizerGet rg); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 16c89a1c41c..93b7ffaf66d 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -249,6 +249,8 @@ void Settings::CreateOptionDescriptions() { "\n" "If you enter a water entrance without swim you will be respawned on land to prevent infinite death loops.\n" "If you void out in Water Temple you will immediately be kicked out to prevent a softlock."; + mOptionDescriptions[RSK_SHUFFLE_CLIMB] = "Shuffle the ability to climb ladders into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_CRAWL] = "Shuffles the ability to use crawlspaces into the item pool."; mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG] = "Shuffles the Weird Egg from Malon in to the item pool. Enabling " "\"Skip Child Zelda\" disables this feature.\n" "\n" @@ -288,6 +290,10 @@ void Settings::CreateOptionDescriptions() { "Overworld - Only shuffle crates that are outside of dungeons.\n" "\n" "All Crates - Shuffle all crates."; + mOptionDescriptions[RSK_SHUFFLE_TREES] = + "Trees will contain randomized items which are dropped the first time the player rolls into one.\n" + "Trees will have a special appearance when carrying randomized items.\n" + "\nSome trees are dependant on Link's age, such as some trees in Hyrule Field."; mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE] = "Shuffles the fishing pole into the item pool.\n" "\n" "The fishing pole is required to play the fishing pond minigame."; @@ -486,6 +492,8 @@ void Settings::CreateOptionDescriptions() { "Overworld - Only shuffle grass/bushes that are outside of dungeons.\n" "\n" "All Grass/Bushes - Shuffle all grass/bushes."; + mOptionDescriptions[RSK_SHUFFLE_ROCKS] = "Shuffle rock locations."; + mOptionDescriptions[RSK_SHUFFLE_BOULDERS] = "Shuffle boulder locations."; mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS] = "Shuffles the location of Spiritual Stones and medallions.\n" "Vanilla - Spiritual Stones and medallions will be given from their respective boss.\n" @@ -602,8 +610,13 @@ void Settings::CreateOptionDescriptions() { "Start with Zelda's Letter and the item Impa would normally give you and skip the sequence up " "until after meeting Zelda. Disables the ability to shuffle Weird Egg."; mOptionDescriptions[RSK_SKIP_EPONA_RACE] = "Epona can be summoned with Epona's Song without needing to race Ingo."; - mOptionDescriptions[RSK_COMPLETE_MASK_QUEST] = - "Once the Happy Mask Shop is opened, all masks will be available to be borrowed."; + mOptionDescriptions[RSK_MASK_QUEST] = + "How masks are acquired.\n" + "Vanilla - Mask trade quest.\n" + "\n" + "Completed - Once the Happy Mask Shop is opened, all masks will be available to be borrowed.\n" + "\n" + "Shuffle - Happy Mask Shop never opens, masks are shuffled with rest of items."; mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG] = "Start with the ability to summon Pierre the Scarecrow. Pulling out an Ocarina in the usual locations will " "automatically summon him.\n" @@ -758,5 +771,8 @@ void Settings::CreateOptionDescriptions() { "Shuffles 8 boss souls (one for each blue warp dungeon). A boss will not appear until you collect its " "respective soul." "\n\"On + Ganon\" will also hide Ganon and Ganondorf behind a boss soul."; + mOptionDescriptions[RSK_SHUFFLE_NPC_SOULS] = + "Shuffles souls of NPCs. An NPC will not appear until you collect its respective soul." + "\n\"On + Sages\" requires sage souls to receive blue warp reward. Zelda is required to defeat Ganon."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index abfa8f3b632..049681fee6b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -465,6 +465,93 @@ std::unordered_map getItemIdToItemId = { { GI_CLAIM_CHECK, ITEM_CLAIM_CHECK }, }; +// used for items that only set a rand inf when obtained +std::map randomizerGetToRandInf = { + { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, + { RG_BRONZE_SCALE, RAND_INF_CAN_SWIM }, + { RG_CLIMB, RAND_INF_CAN_CLIMB }, + { RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER }, + { RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG }, + { RG_BULLET_BAG_INF, RAND_INF_HAS_INFINITE_BULLET_BAG }, + { RG_STICK_UPGRADE_INF, RAND_INF_HAS_INFINITE_STICK_UPGRADE }, + { RG_NUT_UPGRADE_INF, RAND_INF_HAS_INFINITE_NUT_UPGRADE }, + { RG_MAGIC_INF, RAND_INF_HAS_INFINITE_MAGIC_METER }, + { RG_BOMBCHU_INF, RAND_INF_HAS_INFINITE_BOMBCHUS }, + { RG_WALLET_INF, RAND_INF_HAS_INFINITE_MONEY }, + { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, + { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, + { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, + { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, + { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, + { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, + { RG_MASK_KEATON, RAND_INF_CHILD_TRADES_HAS_MASK_KEATON }, + { RG_MASK_SKULL, RAND_INF_CHILD_TRADES_HAS_MASK_SKULL }, + { RG_MASK_SPOOKY, RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY }, + { RG_MASK_BUNNY, RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY }, + { RG_MASK_GORON, RAND_INF_CHILD_TRADES_HAS_MASK_GORON }, + { RG_MASK_ZORA, RAND_INF_CHILD_TRADES_HAS_MASK_ZORA }, + { RG_MASK_GERUDO, RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO }, + { RG_MASK_TRUTH, RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH }, + { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, + { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, + { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, + { RG_PHANTOM_GANON_SOUL, RAND_INF_PHANTOM_GANON_SOUL }, + { RG_VOLVAGIA_SOUL, RAND_INF_VOLVAGIA_SOUL }, + { RG_MORPHA_SOUL, RAND_INF_MORPHA_SOUL }, + { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, + { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, + { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, + { RG_CRAWL, RAND_INF_CAN_CRAWL }, + { RG_ANJU_SOUL, RAND_INF_ANJU_SOUL }, + { RG_TALON_SOUL, RAND_INF_TALON_SOUL }, + { RG_GROG_SOUL, RAND_INF_GROG_SOUL }, + { RG_GRANNY_SOUL, RAND_INF_GRANNY_SOUL }, + { RG_FADO_SOUL, RAND_INF_FADO_SOUL }, + { RG_LINK_SOUL, RAND_INF_LINK_SOUL }, + { RG_BIGGORON_SOUL, RAND_INF_BIGGORON_SOUL }, + { RG_HOT_RODDER_SOUL, RAND_INF_HOT_RODDER_SOUL }, + { RG_MEDIGORON_SOUL, RAND_INF_MEDIGORON_SOUL }, + { RG_CARPENTER_BOSS_SOUL, RAND_INF_CARPENTER_BOSS_SOUL }, + { RG_ICHIRO_SOUL, RAND_INF_ICHIRO_SOUL }, + { RG_SABOORO_SOUL, RAND_INF_SABOORO_SOUL }, + { RG_JIRO_SOUL, RAND_INF_JIRO_SOUL }, + { RG_SHIRO_SOUL, RAND_INF_SHIRO_SOUL }, + { RG_HW_GATEKEEPER_SOUL, RAND_INF_HW_GATEKEEPER_SOUL }, + { RG_GTG_GATEKEEPER_SOUL, RAND_INF_GTG_GATEKEEPER_SOUL }, + { RG_ARCHER_SOUL, RAND_INF_ARCHER_SOUL }, + { RG_GREAT_FAIRY_SOUL, RAND_INF_GREAT_FAIRY_SOUL }, + { RG_POE_COLLECTOR_SOUL, RAND_INF_POE_COLLECTOR_SOUL }, + { RG_DAMPE_SOUL, RAND_INF_DAMPE_SOUL }, + { RG_WINDMILL_MAN_SOUL, RAND_INF_WINDMILL_MAN_SOUL }, + { RG_MAN_ON_ROOF_SOUL, RAND_INF_MAN_ON_ROOF_SOUL }, + { RG_KAKARIKO_GATEKEEPER_SOUL, RAND_INF_KAKARIKO_GATEKEEPER_SOUL }, + { RG_MALON_SOUL, RAND_INF_MALON_SOUL }, + { RG_RAURU_SOUL, RAND_INF_RAURU_SOUL }, + { RG_SARIA_SOUL, RAND_INF_SARIA_SOUL }, + { RG_DARUNIA_SOUL, RAND_INF_DARUNIA_SOUL }, + { RG_RUTO_SOUL, RAND_INF_RUTO_SOUL }, + { RG_NABOORU_SOUL, RAND_INF_NABOORU_SOUL }, + { RG_IMPA_SOUL, RAND_INF_IMPA_SOUL }, + { RG_ZELDA_SOUL, RAND_INF_ZELDA_SOUL }, + { RG_BEGGAR_SOUL, RAND_INF_BEGGAR_SOUL }, + { RG_DOG_LADY_SOUL, RAND_INF_DOG_LADY_SOUL }, + { RG_ARMS_DEALER_SOUL, RAND_INF_ARMS_DEALER_SOUL }, + { RG_BEAN_SALESMAN_SOUL, RAND_INF_BEAN_SALESMAN_SOUL }, + { RG_SHOOTING_SOUL, RAND_INF_SHOOTING_SOUL }, + { RG_KOKIRI_SHOPKEEPER_SOUL, RAND_INF_KOKIRI_SHOPKEEPER_SOUL }, + { RG_POTION_SHOPKEEPER_SOUL, RAND_INF_POTION_SHOPKEEPER_SOUL }, + { RG_BAZAAR_SHOPKEEPER_SOUL, RAND_INF_BAZAAR_SHOPKEEPER_SOUL }, + { RG_GORON_SHOPKEEPER_SOUL, RAND_INF_GORON_SHOPKEEPER_SOUL }, + { RG_ZORA_SHOPKEEPER_SOUL, RAND_INF_ZORA_SHOPKEEPER_SOUL }, + { RG_BOMBCHU_SHOPKEEPER_SOUL, RAND_INF_BOMBCHU_SHOPKEEPER_SOUL }, + { RG_MASK_SALESMAN_SOUL, RAND_INF_MASK_SALESMAN_SOUL }, + { RG_TREASURE_MAN_SOUL, RAND_INF_TREASURE_MAN_SOUL }, + { RG_BOMBCHU_LADY_SOUL, RAND_INF_BOMBCHU_LADY_SOUL }, + { RG_DIVING_SOUL, RAND_INF_DIVING_SOUL }, + { RG_SCIENTIST_SOUL, RAND_INF_SCIENTIST_SOUL }, + { RG_KAEPORA_SOUL, RAND_INF_KAEPORA_SOUL }, +}; + #ifdef _MSC_VER #pragma optimize("", off) #else @@ -728,7 +815,10 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerCheck(Randomizer } ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGet randoGet) { - + if (randomizerGetToRandInf.find(randoGet) != randomizerGetToRandInf.end()) { + return Flags_GetRandomizerInf(randomizerGetToRandInf.find(randoGet)->second) ? CANT_OBTAIN_ALREADY_HAVE + : CAN_OBTAIN; + } // This is needed since Plentiful item pool also adds a third progressive wallet // but we should not get Tycoon's Wallet from it if it is off. bool tycoonWallet = GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET); @@ -1098,18 +1188,6 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe case RG_LIGHT_MEDALLION: return !CHECK_QUEST_ITEM(QUEST_MEDALLION_LIGHT) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; - // Ocarina Buttons - case RG_OCARINA_A_BUTTON: - return Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN; - case RG_OCARINA_C_LEFT_BUTTON: - return Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN; - case RG_OCARINA_C_RIGHT_BUTTON: - return Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN; - case RG_OCARINA_C_UP_BUTTON: - return Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN; - case RG_OCARINA_C_DOWN_BUTTON: - return Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN; - case RG_RECOVERY_HEART: case RG_GREEN_RUPEE: case RG_GREG_RUPEE: @@ -3258,6 +3336,349 @@ std::map rcToRandomizerInf = { RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, }, + { RC_KF_CIRCLE_ROCK_1, RAND_INF_KF_CIRCLE_ROCK_1 }, + { RC_KF_CIRCLE_ROCK_2, RAND_INF_KF_CIRCLE_ROCK_2 }, + { RC_KF_CIRCLE_ROCK_3, RAND_INF_KF_CIRCLE_ROCK_3 }, + { RC_KF_CIRCLE_ROCK_4, RAND_INF_KF_CIRCLE_ROCK_4 }, + { RC_KF_CIRCLE_ROCK_5, RAND_INF_KF_CIRCLE_ROCK_5 }, + { RC_KF_CIRCLE_ROCK_6, RAND_INF_KF_CIRCLE_ROCK_6 }, + { RC_KF_CIRCLE_ROCK_7, RAND_INF_KF_CIRCLE_ROCK_7 }, + { RC_KF_CIRCLE_ROCK_8, RAND_INF_KF_CIRCLE_ROCK_8 }, + { RC_KF_ROCK_BY_SARIAS_HOUSE, RAND_INF_KF_ROCK_BY_SARIAS_HOUSE }, + { RC_KF_ROCK_BEHIND_SARIAS_HOUSE, RAND_INF_KF_ROCK_BEHIND_SARIAS_HOUSE }, + { RC_KF_ROCK_BY_MIDOS_HOUSE, RAND_INF_KF_ROCK_BY_MIDOS_HOUSE }, + { RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, RAND_INF_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE }, + { RC_LW_BOULDER_BY_GORON_CITY, RAND_INF_LW_BOULDER_BY_GORON_CITY }, + { RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, RAND_INF_LW_BOULDER_BY_SACRED_FOREST_MEADOW }, + { RC_LW_RUPEE_BOULDER, RAND_INF_LW_RUPEE_BOULDER }, + { RC_HC_ROCK_1, RAND_INF_HC_ROCK_1 }, + { RC_HC_ROCK_2, RAND_INF_HC_ROCK_2 }, + { RC_HC_ROCK_3, RAND_INF_HC_ROCK_3 }, + { RC_HC_BOULDER, RAND_INF_HC_BOULDER }, + { RC_OGC_BRONZE_BOULDER_1, RAND_INF_OGC_BRONZE_BOULDER_1 }, + { RC_OGC_BRONZE_BOULDER_2, RAND_INF_OGC_BRONZE_BOULDER_2 }, + { RC_OGC_BRONZE_BOULDER_3, RAND_INF_OGC_BRONZE_BOULDER_3 }, + { RC_OGC_SILVER_BOULDER_1, RAND_INF_OGC_SILVER_BOULDER_1 }, + { RC_OGC_SILVER_BOULDER_2, RAND_INF_OGC_SILVER_BOULDER_2 }, + { RC_OGC_SILVER_BOULDER_3, RAND_INF_OGC_SILVER_BOULDER_3 }, + { RC_OGC_SILVER_BOULDER_4, RAND_INF_OGC_SILVER_BOULDER_4 }, + { RC_DMC_CIRCLE_ROCK_1, RAND_INF_DMC_CIRCLE_ROCK_1 }, + { RC_DMC_CIRCLE_ROCK_2, RAND_INF_DMC_CIRCLE_ROCK_2 }, + { RC_DMC_CIRCLE_ROCK_3, RAND_INF_DMC_CIRCLE_ROCK_3 }, + { RC_DMC_CIRCLE_ROCK_4, RAND_INF_DMC_CIRCLE_ROCK_4 }, + { RC_DMC_CIRCLE_ROCK_5, RAND_INF_DMC_CIRCLE_ROCK_5 }, + { RC_DMC_CIRCLE_ROCK_6, RAND_INF_DMC_CIRCLE_ROCK_6 }, + { RC_DMC_CIRCLE_ROCK_7, RAND_INF_DMC_CIRCLE_ROCK_7 }, + { RC_DMC_CIRCLE_ROCK_8, RAND_INF_DMC_CIRCLE_ROCK_8 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_1, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_1 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_2, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_2 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_3, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_3 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_4, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_4 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_5, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_5 }, + { RC_DMC_GOSSIP_ROCK_1, RAND_INF_DMC_GOSSIP_ROCK_1 }, + { RC_DMC_GOSSIP_ROCK_2, RAND_INF_DMC_GOSSIP_ROCK_2 }, + { RC_DMC_BOULDER_1, RAND_INF_DMC_BOULDER_1 }, + { RC_DMC_BOULDER_2, RAND_INF_DMC_BOULDER_2 }, + { RC_DMC_BOULDER_3, RAND_INF_DMC_BOULDER_3 }, + { RC_DMC_BRONZE_BOULDER_1, RAND_INF_DMC_BRONZE_BOULDER_1 }, + { RC_DMC_BRONZE_BOULDER_2, RAND_INF_DMC_BRONZE_BOULDER_2 }, + { RC_DMC_BRONZE_BOULDER_3, RAND_INF_DMC_BRONZE_BOULDER_3 }, + { RC_DMC_BRONZE_BOULDER_4, RAND_INF_DMC_BRONZE_BOULDER_4 }, + { RC_GV_SILVER_BOULDER, RAND_INF_GV_SILVER_BOULDER }, + { RC_GV_ROCK_1, RAND_INF_GV_ROCK_1 }, + { RC_GV_ROCK_2, RAND_INF_GV_ROCK_2 }, + { RC_GV_ROCK_3, RAND_INF_GV_ROCK_3 }, + { RC_GV_UNDERWATER_ROCK_1, RAND_INF_GV_UNDERWATER_ROCK_1 }, + { RC_GV_UNDERWATER_ROCK_2, RAND_INF_GV_UNDERWATER_ROCK_2 }, + { RC_GV_UNDERWATER_ROCK_3, RAND_INF_GV_UNDERWATER_ROCK_3 }, + { RC_GV_ROCK_ACROSS_BRIDGE_1, RAND_INF_GV_ROCK_ACROSS_BRIDGE_1 }, + { RC_GV_ROCK_ACROSS_BRIDGE_2, RAND_INF_GV_ROCK_ACROSS_BRIDGE_2 }, + { RC_GV_ROCK_ACROSS_BRIDGE_3, RAND_INF_GV_ROCK_ACROSS_BRIDGE_3 }, + { RC_GV_ROCK_ACROSS_BRIDGE_4, RAND_INF_GV_ROCK_ACROSS_BRIDGE_4 }, + { RC_GV_BOULDER_1, RAND_INF_GV_BOULDER_1 }, + { RC_GV_BOULDER_2, RAND_INF_GV_BOULDER_2 }, + { RC_GV_BOULDER_ACROSS_BRIDGE, RAND_INF_GV_BOULDER_ACROSS_BRIDGE }, + { RC_GV_BRONZE_BOULDER_1, RAND_INF_GV_BRONZE_BOULDER_1 }, + { RC_GV_BRONZE_BOULDER_2, RAND_INF_GV_BRONZE_BOULDER_2 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6 }, + { RC_HF_SILVER_BOULDER, RAND_INF_HF_SILVER_BOULDER }, + { RC_HF_ROCK_1, RAND_INF_HF_ROCK_1 }, + { RC_HF_ROCK_2, RAND_INF_HF_ROCK_2 }, + { RC_HF_ROCK_3, RAND_INF_HF_ROCK_3 }, + { RC_HF_ROCK_4, RAND_INF_HF_ROCK_4 }, + { RC_HF_ROCK_5, RAND_INF_HF_ROCK_5 }, + { RC_HF_ROCK_6, RAND_INF_HF_ROCK_6 }, + { RC_HF_ROCK_7, RAND_INF_HF_ROCK_7 }, + { RC_HF_ROCK_8, RAND_INF_HF_ROCK_8 }, + { RC_HF_BOULDER_NORTH, RAND_INF_HF_BOULDER_NORTH }, + { RC_HF_BOULDER_BY_MARKET, RAND_INF_HF_BOULDER_BY_MARKET }, + { RC_HF_BOULDER_SOUTH, RAND_INF_HF_BOULDER_SOUTH }, + { RC_HF_BRONZE_BOULDER_1, RAND_INF_HF_BRONZE_BOULDER_1 }, + { RC_HF_BRONZE_BOULDER_2, RAND_INF_HF_BRONZE_BOULDER_2 }, + { RC_HF_BRONZE_BOULDER_3, RAND_INF_HF_BRONZE_BOULDER_3 }, + { RC_HF_BRONZE_BOULDER_4, RAND_INF_HF_BRONZE_BOULDER_4 }, + { RC_KAK_SILVER_BOULDER, RAND_INF_KAK_SILVER_BOULDER }, + { RC_KAK_ROCK_1, RAND_INF_KAK_ROCK_1 }, + { RC_KAK_ROCK_2, RAND_INF_KAK_ROCK_2 }, + { RC_GY_ROCK, RAND_INF_GY_ROCK }, + { RC_LA_ROCK, RAND_INF_LA_ROCK }, + { RC_ZD_CIRCLE_ROCK_1, RAND_INF_ZD_CIRCLE_ROCK_1 }, + { RC_ZD_CIRCLE_ROCK_2, RAND_INF_ZD_CIRCLE_ROCK_2 }, + { RC_ZD_CIRCLE_ROCK_3, RAND_INF_ZD_CIRCLE_ROCK_3 }, + { RC_ZD_CIRCLE_ROCK_4, RAND_INF_ZD_CIRCLE_ROCK_4 }, + { RC_ZD_CIRCLE_ROCK_5, RAND_INF_ZD_CIRCLE_ROCK_5 }, + { RC_ZD_CIRCLE_ROCK_6, RAND_INF_ZD_CIRCLE_ROCK_6 }, + { RC_ZD_CIRCLE_ROCK_7, RAND_INF_ZD_CIRCLE_ROCK_7 }, + { RC_ZD_CIRCLE_ROCK_8, RAND_INF_ZD_CIRCLE_ROCK_8 }, + { RC_ZF_BOULDER, RAND_INF_ZF_BOULDER }, + { RC_ZF_SILVER_BOULDER, RAND_INF_ZF_SILVER_BOULDER }, + { RC_ZF_UNDERGROUND_BOULDER, RAND_INF_ZF_UNDERGROUND_BOULDER }, + { RC_ZR_BOULDER_1, RAND_INF_ZR_BOULDER_1 }, + { RC_ZR_BOULDER_2, RAND_INF_ZR_BOULDER_2 }, + { RC_ZR_BOULDER_3, RAND_INF_ZR_BOULDER_3 }, + { RC_ZR_BOULDER_4, RAND_INF_ZR_BOULDER_4 }, + { RC_ZR_CIRCLE_ROCK_1, RAND_INF_ZR_CIRCLE_ROCK_1 }, + { RC_ZR_CIRCLE_ROCK_2, RAND_INF_ZR_CIRCLE_ROCK_2 }, + { RC_ZR_CIRCLE_ROCK_3, RAND_INF_ZR_CIRCLE_ROCK_3 }, + { RC_ZR_CIRCLE_ROCK_4, RAND_INF_ZR_CIRCLE_ROCK_4 }, + { RC_ZR_CIRCLE_ROCK_5, RAND_INF_ZR_CIRCLE_ROCK_5 }, + { RC_ZR_CIRCLE_ROCK_6, RAND_INF_ZR_CIRCLE_ROCK_6 }, + { RC_ZR_CIRCLE_ROCK_7, RAND_INF_ZR_CIRCLE_ROCK_7 }, + { RC_ZR_CIRCLE_ROCK_8, RAND_INF_ZR_CIRCLE_ROCK_8 }, + { RC_ZR_UPPER_CIRCLE_BOULDER, RAND_INF_ZR_UPPER_CIRCLE_BOULDER }, + { RC_ZR_UPPER_CIRCLE_ROCK_1, RAND_INF_ZR_UPPER_CIRCLE_ROCK_1 }, + { RC_ZR_UPPER_CIRCLE_ROCK_2, RAND_INF_ZR_UPPER_CIRCLE_ROCK_2 }, + { RC_ZR_UPPER_CIRCLE_ROCK_3, RAND_INF_ZR_UPPER_CIRCLE_ROCK_3 }, + { RC_ZR_UPPER_CIRCLE_ROCK_4, RAND_INF_ZR_UPPER_CIRCLE_ROCK_4 }, + { RC_ZR_UPPER_CIRCLE_ROCK_5, RAND_INF_ZR_UPPER_CIRCLE_ROCK_5 }, + { RC_ZR_UPPER_CIRCLE_ROCK_6, RAND_INF_ZR_UPPER_CIRCLE_ROCK_6 }, + { RC_ZR_UPPER_CIRCLE_ROCK_7, RAND_INF_ZR_UPPER_CIRCLE_ROCK_7 }, + { RC_ZR_UPPER_CIRCLE_ROCK_8, RAND_INF_ZR_UPPER_CIRCLE_ROCK_8 }, + { RC_ZR_ROCK, RAND_INF_ZR_ROCK }, + { RC_ZR_UNDERWATER_ROCK_1, RAND_INF_ZR_UNDERWATER_ROCK_1 }, + { RC_ZR_UNDERWATER_ROCK_2, RAND_INF_ZR_UNDERWATER_ROCK_2 }, + { RC_ZR_UNDERWATER_ROCK_3, RAND_INF_ZR_UNDERWATER_ROCK_3 }, + { RC_ZR_UNDERWATER_ROCK_4, RAND_INF_ZR_UNDERWATER_ROCK_4 }, + { RC_DMT_ROCK_1, RAND_INF_DMT_ROCK_1 }, + { RC_DMT_ROCK_2, RAND_INF_DMT_ROCK_2 }, + { RC_DMT_ROCK_3, RAND_INF_DMT_ROCK_3 }, + { RC_DMT_ROCK_4, RAND_INF_DMT_ROCK_4 }, + { RC_DMT_ROCK_5, RAND_INF_DMT_ROCK_5 }, + { RC_DMT_SUMMIT_ROCK, RAND_INF_DMT_SUMMIT_ROCK }, + { RC_DMT_CIRCLE_ROCK_1, RAND_INF_DMT_CIRCLE_ROCK_1 }, + { RC_DMT_CIRCLE_ROCK_2, RAND_INF_DMT_CIRCLE_ROCK_2 }, + { RC_DMT_CIRCLE_ROCK_3, RAND_INF_DMT_CIRCLE_ROCK_3 }, + { RC_DMT_CIRCLE_ROCK_4, RAND_INF_DMT_CIRCLE_ROCK_4 }, + { RC_DMT_CIRCLE_ROCK_5, RAND_INF_DMT_CIRCLE_ROCK_5 }, + { RC_DMT_CIRCLE_ROCK_6, RAND_INF_DMT_CIRCLE_ROCK_6 }, + { RC_DMT_CIRCLE_ROCK_7, RAND_INF_DMT_CIRCLE_ROCK_7 }, + { RC_DMT_CIRCLE_ROCK_8, RAND_INF_DMT_CIRCLE_ROCK_8 }, + { RC_DMT_BOULDER_1, RAND_INF_DMT_BOULDER_1 }, + { RC_DMT_BOULDER_2, RAND_INF_DMT_BOULDER_2 }, + { RC_DMT_BOULDER_3, RAND_INF_DMT_BOULDER_3 }, + { RC_DMT_COW_BOULDER, RAND_INF_DMT_COW_BOULDER }, + { RC_DMT_BRONZE_BOULDER_1, RAND_INF_DMT_BRONZE_BOULDER_1 }, + { RC_DMT_BRONZE_BOULDER_2, RAND_INF_DMT_BRONZE_BOULDER_2 }, + { RC_DMT_BRONZE_BOULDER_3, RAND_INF_DMT_BRONZE_BOULDER_3 }, + { RC_DMT_BRONZE_BOULDER_4, RAND_INF_DMT_BRONZE_BOULDER_4 }, + { RC_DMT_BRONZE_BOULDER_5, RAND_INF_DMT_BRONZE_BOULDER_5 }, + { RC_DMT_BRONZE_BOULDER_6, RAND_INF_DMT_BRONZE_BOULDER_6 }, + { RC_DMT_BRONZE_BOULDER_7, RAND_INF_DMT_BRONZE_BOULDER_7 }, + { RC_DMT_BRONZE_BOULDER_8, RAND_INF_DMT_BRONZE_BOULDER_8 }, + { RC_DMT_BRONZE_BOULDER_9, RAND_INF_DMT_BRONZE_BOULDER_9 }, + { RC_DMT_BRONZE_BOULDER_10, RAND_INF_DMT_BRONZE_BOULDER_10 }, + { RC_DMT_BRONZE_BOULDER_11, RAND_INF_DMT_BRONZE_BOULDER_11 }, + { RC_GC_LW_BOULDER_1, RAND_INF_GC_LW_BOULDER_1 }, + { RC_GC_LW_BOULDER_2, RAND_INF_GC_LW_BOULDER_2 }, + { RC_GC_LW_BOULDER_3, RAND_INF_GC_LW_BOULDER_3 }, + { RC_GC_ENTRANCE_BOULDER_1, RAND_INF_GC_ENTRANCE_BOULDER_1 }, + { RC_GC_ENTRANCE_BOULDER_2, RAND_INF_GC_ENTRANCE_BOULDER_2 }, + { RC_GC_ENTRANCE_BOULDER_3, RAND_INF_GC_ENTRANCE_BOULDER_3 }, + { RC_GC_MAZE_SILVER_BOULDER_1, RAND_INF_GC_MAZE_SILVER_BOULDER_1 }, + { RC_GC_MAZE_SILVER_BOULDER_2, RAND_INF_GC_MAZE_SILVER_BOULDER_2 }, + { RC_GC_MAZE_SILVER_BOULDER_3, RAND_INF_GC_MAZE_SILVER_BOULDER_3 }, + { RC_GC_MAZE_SILVER_BOULDER_4, RAND_INF_GC_MAZE_SILVER_BOULDER_4 }, + { RC_GC_MAZE_SILVER_BOULDER_5, RAND_INF_GC_MAZE_SILVER_BOULDER_5 }, + { RC_GC_MAZE_SILVER_BOULDER_6, RAND_INF_GC_MAZE_SILVER_BOULDER_6 }, + { RC_GC_MAZE_SILVER_BOULDER_7, RAND_INF_GC_MAZE_SILVER_BOULDER_7 }, + { RC_GC_MAZE_SILVER_BOULDER_8, RAND_INF_GC_MAZE_SILVER_BOULDER_8 }, + { RC_GC_MAZE_SILVER_BOULDER_9, RAND_INF_GC_MAZE_SILVER_BOULDER_9 }, + { RC_GC_MAZE_SILVER_BOULDER_10, RAND_INF_GC_MAZE_SILVER_BOULDER_10 }, + { RC_GC_MAZE_SILVER_BOULDER_11, RAND_INF_GC_MAZE_SILVER_BOULDER_11 }, + { RC_GC_MAZE_SILVER_BOULDER_12, RAND_INF_GC_MAZE_SILVER_BOULDER_12 }, + { RC_GC_MAZE_SILVER_BOULDER_13, RAND_INF_GC_MAZE_SILVER_BOULDER_13 }, + { RC_GC_MAZE_SILVER_BOULDER_14, RAND_INF_GC_MAZE_SILVER_BOULDER_14 }, + { RC_GC_MAZE_SILVER_BOULDER_15, RAND_INF_GC_MAZE_SILVER_BOULDER_15 }, + { RC_GC_MAZE_SILVER_BOULDER_16, RAND_INF_GC_MAZE_SILVER_BOULDER_16 }, + { RC_GC_MAZE_SILVER_BOULDER_17, RAND_INF_GC_MAZE_SILVER_BOULDER_17 }, + { RC_GC_MAZE_SILVER_BOULDER_18, RAND_INF_GC_MAZE_SILVER_BOULDER_18 }, + { RC_GC_MAZE_SILVER_BOULDER_19, RAND_INF_GC_MAZE_SILVER_BOULDER_19 }, + { RC_GC_MAZE_SILVER_BOULDER_20, RAND_INF_GC_MAZE_SILVER_BOULDER_20 }, + { RC_GC_MAZE_SILVER_BOULDER_21, RAND_INF_GC_MAZE_SILVER_BOULDER_21 }, + { RC_GC_MAZE_SILVER_BOULDER_22, RAND_INF_GC_MAZE_SILVER_BOULDER_22 }, + { RC_GC_MAZE_SILVER_BOULDER_23, RAND_INF_GC_MAZE_SILVER_BOULDER_23 }, + { RC_GC_MAZE_SILVER_BOULDER_24, RAND_INF_GC_MAZE_SILVER_BOULDER_24 }, + { RC_GC_MAZE_SILVER_BOULDER_25, RAND_INF_GC_MAZE_SILVER_BOULDER_25 }, + { RC_GC_MAZE_SILVER_BOULDER_26, RAND_INF_GC_MAZE_SILVER_BOULDER_26 }, + { RC_GC_MAZE_SILVER_BOULDER_27, RAND_INF_GC_MAZE_SILVER_BOULDER_27 }, + { RC_GC_MAZE_SILVER_BOULDER_28, RAND_INF_GC_MAZE_SILVER_BOULDER_28 }, + { RC_GC_MAZE_SILVER_BOULDER_29, RAND_INF_GC_MAZE_SILVER_BOULDER_29 }, + { RC_GC_MAZE_BOULDER_1, RAND_INF_GC_MAZE_BOULDER_1 }, + { RC_GC_MAZE_BOULDER_2, RAND_INF_GC_MAZE_BOULDER_2 }, + { RC_GC_MAZE_BOULDER_3, RAND_INF_GC_MAZE_BOULDER_3 }, + { RC_GC_MAZE_BOULDER_4, RAND_INF_GC_MAZE_BOULDER_4 }, + { RC_GC_MAZE_BOULDER_5, RAND_INF_GC_MAZE_BOULDER_5 }, + { RC_GC_MAZE_BOULDER_6, RAND_INF_GC_MAZE_BOULDER_6 }, + { RC_GC_MAZE_BOULDER_7, RAND_INF_GC_MAZE_BOULDER_7 }, + { RC_GC_MAZE_BOULDER_8, RAND_INF_GC_MAZE_BOULDER_8 }, + { RC_GC_MAZE_BOULDER_9, RAND_INF_GC_MAZE_BOULDER_9 }, + { RC_GC_MAZE_BOULDER_10, RAND_INF_GC_MAZE_BOULDER_10 }, + { RC_GC_MAZE_BRONZE_BOULDER_1, RAND_INF_GC_MAZE_BRONZE_BOULDER_1 }, + { RC_GC_MAZE_BRONZE_BOULDER_2, RAND_INF_GC_MAZE_BRONZE_BOULDER_2 }, + { RC_GC_MAZE_BRONZE_BOULDER_3, RAND_INF_GC_MAZE_BRONZE_BOULDER_3 }, + { RC_GC_MAZE_BRONZE_BOULDER_4, RAND_INF_GC_MAZE_BRONZE_BOULDER_4 }, + { RC_GC_MAZE_BRONZE_BOULDER_5, RAND_INF_GC_MAZE_BRONZE_BOULDER_5 }, + { RC_GC_MAZE_ROCK, RAND_INF_GC_MAZE_ROCK }, + { RC_COLOSSUS_SILVER_BOULDER, RAND_INF_COLOSSUS_SILVER_BOULDER }, + { RC_COLOSSUS_ROCK, RAND_INF_COLOSSUS_ROCK }, + { RC_COLOSSUS_CIRCLE_1_ROCK_1, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_1 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_2, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_2 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_3, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_3 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_4, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_4 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_5, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_5 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_6, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_6 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_7, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_7 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_8, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_8 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_1, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_1 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_2, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_2 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_3, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_3 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_4, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_4 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_5, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_5 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_6, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_6 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_7, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_7 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_8, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_8 }, + { RC_HC_STORMS_GROTTO_ROCK_1, RAND_INF_HC_STORMS_GROTTO_ROCK_1 }, + { RC_HC_STORMS_GROTTO_ROCK_2, RAND_INF_HC_STORMS_GROTTO_ROCK_2 }, + { RC_HC_STORMS_GROTTO_ROCK_3, RAND_INF_HC_STORMS_GROTTO_ROCK_3 }, + { RC_HC_STORMS_GROTTO_ROCK_4, RAND_INF_HC_STORMS_GROTTO_ROCK_4 }, + { RC_HC_STORMS_GROTTO_ROCK_5, RAND_INF_HC_STORMS_GROTTO_ROCK_5 }, + { RC_HC_STORMS_GROTTO_ROCK_6, RAND_INF_HC_STORMS_GROTTO_ROCK_6 }, + { RC_HC_STORMS_GROTTO_ROCK_7, RAND_INF_HC_STORMS_GROTTO_ROCK_7 }, + { RC_HC_STORMS_GROTTO_ROCK_8, RAND_INF_HC_STORMS_GROTTO_ROCK_8 }, + { RC_BOTW_BOULDER_1, RAND_INF_BOTW_BOULDER_1 }, + { RC_BOTW_BOULDER_2, RAND_INF_BOTW_BOULDER_2 }, + { RC_BOTW_BOULDER_3, RAND_INF_BOTW_BOULDER_3 }, + { RC_BOTW_BOULDER_4, RAND_INF_BOTW_BOULDER_4 }, + { RC_BOTW_BOULDER_5, RAND_INF_BOTW_BOULDER_5 }, + { RC_BOTW_BOULDER_6, RAND_INF_BOTW_BOULDER_6 }, + { RC_DEKU_TREE_MQ_BOULDER_1, RAND_INF_DEKU_TREE_MQ_BOULDER_1 }, + { RC_DEKU_TREE_MQ_BOULDER_2, RAND_INF_DEKU_TREE_MQ_BOULDER_2 }, + { RC_DEKU_TREE_MQ_BOULDER_3, RAND_INF_DEKU_TREE_MQ_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12 }, + { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3 }, + { RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER }, + { RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER }, + { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER }, + { RC_BOTW_MQ_BOULDER_1, RAND_INF_BOTW_MQ_BOULDER_1 }, + { RC_BOTW_MQ_BOULDER_2, RAND_INF_BOTW_MQ_BOULDER_2 }, + { RC_BOTW_MQ_BOULDER_3, RAND_INF_BOTW_MQ_BOULDER_3 }, + { RC_MARKET_TREE, RAND_INF_MARKET_TREE }, + { RC_HC_NEAR_GUARDS_TREE_1, RAND_INF_HC_NEAR_GUARDS_TREE_1 }, + { RC_HC_NEAR_GUARDS_TREE_2, RAND_INF_HC_NEAR_GUARDS_TREE_2 }, + { RC_HC_NEAR_GUARDS_TREE_3, RAND_INF_HC_NEAR_GUARDS_TREE_3 }, + { RC_HC_NEAR_GUARDS_TREE_4, RAND_INF_HC_NEAR_GUARDS_TREE_4 }, + { RC_HC_NEAR_GUARDS_TREE_5, RAND_INF_HC_NEAR_GUARDS_TREE_5 }, + { RC_HC_NEAR_GUARDS_TREE_6, RAND_INF_HC_NEAR_GUARDS_TREE_6 }, + { RC_HC_SKULLTULA_TREE, RAND_INF_HC_SKULLTULA_TREE }, + { RC_HC_GROTTO_TREE, RAND_INF_HC_GROTTO_TREE }, + { RC_HC_NL_TREE_1, RAND_INF_HC_NL_TREE_1 }, + { RC_HC_NL_TREE_2, RAND_INF_HC_NL_TREE_2 }, + { RC_HF_NEAR_KAK_TREE, RAND_INF_HF_NEAR_KAK_TREE }, + { RC_HF_NEAR_KAK_SMALL_TREE, RAND_INF_HF_NEAR_KAK_SMALL_TREE }, + { RC_HF_NEAR_MARKET_TREE_1, RAND_INF_HF_NEAR_MARKET_TREE_1 }, + { RC_HF_NEAR_MARKET_TREE_2, RAND_INF_HF_NEAR_MARKET_TREE_2 }, + { RC_HF_NEAR_MARKET_TREE_3, RAND_INF_HF_NEAR_MARKET_TREE_3 }, + { RC_HF_NEAR_LLR_TREE, RAND_INF_HF_NEAR_LLR_TREE }, + { RC_HF_NEAR_LH_TREE, RAND_INF_HF_NEAR_LH_TREE }, + { RC_HF_CHILD_NEAR_GV_TREE, RAND_INF_HF_CHILD_NEAR_GV_TREE }, + { RC_HF_ADULT_NEAR_GV_TREE, RAND_INF_HF_ADULT_NEAR_GV_TREE }, + { RC_HF_NEAR_ZR_TREE, RAND_INF_HF_NEAR_ZR_TREE }, + { RC_HF_NORTHWEST_TREE_1, RAND_INF_HF_NORTHWEST_TREE_1 }, + { RC_HF_NORTHWEST_TREE_2, RAND_INF_HF_NORTHWEST_TREE_2 }, + { RC_HF_NORTHWEST_TREE_3, RAND_INF_HF_NORTHWEST_TREE_3 }, + { RC_HF_NORTHWEST_TREE_4, RAND_INF_HF_NORTHWEST_TREE_4 }, + { RC_HF_NORTHWEST_TREE_5, RAND_INF_HF_NORTHWEST_TREE_5 }, + { RC_HF_NORTHWEST_TREE_6, RAND_INF_HF_NORTHWEST_TREE_6 }, + { RC_HF_EAST_TREE_1, RAND_INF_HF_EAST_TREE_1 }, + { RC_HF_EAST_TREE_2, RAND_INF_HF_EAST_TREE_2 }, + { RC_HF_EAST_TREE_3, RAND_INF_HF_EAST_TREE_3 }, + { RC_HF_EAST_TREE_4, RAND_INF_HF_EAST_TREE_4 }, + { RC_HF_EAST_TREE_5, RAND_INF_HF_EAST_TREE_5 }, + { RC_HF_EAST_TREE_6, RAND_INF_HF_EAST_TREE_6 }, + { RC_HF_SOUTHEAST_TREE_1, RAND_INF_HF_SOUTHEAST_TREE_1 }, + { RC_HF_SOUTHEAST_TREE_2, RAND_INF_HF_SOUTHEAST_TREE_2 }, + { RC_HF_SOUTHEAST_TREE_3, RAND_INF_HF_SOUTHEAST_TREE_3 }, + { RC_HF_SOUTHEAST_TREE_4, RAND_INF_HF_SOUTHEAST_TREE_4 }, + { RC_HF_SOUTHEAST_TREE_5, RAND_INF_HF_SOUTHEAST_TREE_5 }, + { RC_HF_SOUTHEAST_TREE_6, RAND_INF_HF_SOUTHEAST_TREE_6 }, + { RC_HF_SOUTHEAST_TREE_7, RAND_INF_HF_SOUTHEAST_TREE_7 }, + { RC_HF_SOUTHEAST_TREE_8, RAND_INF_HF_SOUTHEAST_TREE_8 }, + { RC_HF_SOUTHEAST_TREE_9, RAND_INF_HF_SOUTHEAST_TREE_9 }, + { RC_HF_SOUTHEAST_TREE_10, RAND_INF_HF_SOUTHEAST_TREE_10 }, + { RC_HF_SOUTHEAST_TREE_11, RAND_INF_HF_SOUTHEAST_TREE_11 }, + { RC_HF_SOUTHEAST_TREE_12, RAND_INF_HF_SOUTHEAST_TREE_12 }, + { RC_HF_SOUTHEAST_TREE_13, RAND_INF_HF_SOUTHEAST_TREE_13 }, + { RC_HF_SOUTHEAST_TREE_14, RAND_INF_HF_SOUTHEAST_TREE_14 }, + { RC_HF_SOUTHEAST_TREE_15, RAND_INF_HF_SOUTHEAST_TREE_15 }, + { RC_HF_SOUTHEAST_TREE_16, RAND_INF_HF_SOUTHEAST_TREE_16 }, + { RC_HF_SOUTHEAST_TREE_17, RAND_INF_HF_SOUTHEAST_TREE_17 }, + { RC_HF_SOUTHEAST_TREE_18, RAND_INF_HF_SOUTHEAST_TREE_18 }, + { RC_HF_SOUTHEAST_TREE_19, RAND_INF_HF_SOUTHEAST_TREE_19 }, + { RC_HF_CHILD_SOUTHEAST_TREE_1, RAND_INF_HF_CHILD_SOUTHEAST_TREE_1 }, + { RC_HF_CHILD_SOUTHEAST_TREE_2, RAND_INF_HF_CHILD_SOUTHEAST_TREE_2 }, + { RC_HF_CHILD_SOUTHEAST_TREE_3, RAND_INF_HF_CHILD_SOUTHEAST_TREE_3 }, + { RC_HF_CHILD_SOUTHEAST_TREE_4, RAND_INF_HF_CHILD_SOUTHEAST_TREE_4 }, + { RC_HF_CHILD_SOUTHEAST_TREE_5, RAND_INF_HF_CHILD_SOUTHEAST_TREE_5 }, + { RC_HF_CHILD_SOUTHEAST_TREE_6, RAND_INF_HF_CHILD_SOUTHEAST_TREE_6 }, + { RC_HF_TEKTITE_GROTTO_TREE, RAND_INF_HF_TEKTITE_GROTTO_TREE }, + { RC_ZF_TREE, RAND_INF_ZF_TREE }, + { RC_ZR_TREE, RAND_INF_ZR_TREE }, + { RC_KAK_TREE, RAND_INF_KAK_TREE }, + { RC_LLR_TREE, RAND_INF_LLR_TREE }, }; BeehiveIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) { @@ -3283,7 +3704,6 @@ BeehiveIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 res } Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, s32 actorParams = 0x00) { - auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); RandomizerCheck specialRc = RC_UNKNOWN_CHECK; // TODO: Migrate these special cases into table, or at least document why they are special switch (sceneNum) { @@ -3679,6 +4099,43 @@ SmallCrateIdentity Randomizer::IdentifySmallCrate(s32 sceneNum, s32 posX, s32 po return smallCrateIdentity; } +RockIdentity Randomizer::IdentifyRock(s32 sceneNum, s32 posX, s32 posZ) { + struct RockIdentity rockIdentity; + + rockIdentity.randomizerInf = RAND_INF_MAX; + rockIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_ISHI, sceneNum, TWO_ACTOR_PARAMS(posX, posZ)); + + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + rockIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + rockIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return rockIdentity; +} + +TreeIdentity Randomizer::IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) { + struct TreeIdentity treeIdentity; + + if (sceneNum == SCENE_MARKET_NIGHT) { + sceneNum = SCENE_MARKET_DAY; + } + + s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_WOOD02, sceneNum, actorParams); + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK && + (location->GetRCType() != RCTYPE_NLTREE || GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) { + treeIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + treeIdentity.randomizerCheck = location->GetRandomizerCheck(); + return treeIdentity; + } + + treeIdentity.randomizerInf = RAND_INF_MAX; + treeIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + return treeIdentity; +} + u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { return Rando::Context::GetInstance()->GetOption(randoSettingKey).Get(); } @@ -5343,7 +5800,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) { void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). - const std::array getItemMessages = { { + const std::array getItemMessages = { { GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn&wirklich gefunden!", "Félicitation! Vous avez trouvé %gGreg%w!"), GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, "You found the %gMaster Sword%w!", @@ -5638,6 +6095,106 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_GANON_SOUL, ITEM_BIG_POE, "You found the soul for %cGanon%w!", "Du hast die Seele von&%cGanon%w gefunden!", "Vous obtenez l'âme de %cGanon%w!"), + GIMESSAGE_NO_GERMAN(RG_ANJU_SOUL, ITEM_BIG_POE, "You found the soul for %bAnju%w!", + "Vous obtenez l'âme de %bAnju%w!"), + GIMESSAGE_NO_GERMAN(RG_TALON_SOUL, ITEM_BIG_POE, "You found the soul for %bTalon%w!", + "Vous obtenez l'âme de %bTalon%w!"), + GIMESSAGE_NO_GERMAN(RG_GROG_SOUL, ITEM_BIG_POE, "You found the soul for %bGrog%w!", + "Vous obtenez l'âme de %bGrog%w!"), + GIMESSAGE_NO_GERMAN(RG_GRANNY_SOUL, ITEM_BIG_POE, "You found the soul for %bGranny%w!", + "Vous obtenez l'âme de %bGranny%w!"), + GIMESSAGE_NO_GERMAN(RG_FADO_SOUL, ITEM_BIG_POE, "You found the soul for %bFado%w!", + "Vous obtenez l'âme de %bFado%w!"), + GIMESSAGE_NO_GERMAN(RG_LINK_SOUL, ITEM_BIG_POE, "You found the soul for %bDarunia's Son%w!", + "Vous obtenez l'âme de %ble fils de Darunia%w!"), + GIMESSAGE_NO_GERMAN(RG_BIGGORON_SOUL, ITEM_BIG_POE, "You found the soul for %bBiggoron%w!", + "Vous obtenez l'âme de %bBiggoron%w!"), + GIMESSAGE_NO_GERMAN(RG_HOT_RODDER_SOUL, ITEM_BIG_POE, "You found the soul for %bHot Rodder%w!", + "Vous obtenez l'âme de %bHot Rodder%w!"), + GIMESSAGE_NO_GERMAN(RG_MEDIGORON_SOUL, ITEM_BIG_POE, "You found the soul for %bMedigoron%w!", + "Vous obtenez l'âme de %bMedigoron%w!"), + GIMESSAGE_NO_GERMAN(RG_CARPENTER_BOSS_SOUL, ITEM_BIG_POE, "You found the soul for %bCarpenter Boss%w!", + "Vous obtenez l'âme de %bCarpenter Boss%w!"), + GIMESSAGE_NO_GERMAN(RG_ICHIRO_SOUL, ITEM_BIG_POE, "You found the soul for %bIchiro%w!", + "Vous obtenez l'âme de %bIchiro%w!"), + GIMESSAGE_NO_GERMAN(RG_SABOORO_SOUL, ITEM_BIG_POE, "You found the soul for %bSabooro%w!", + "Vous obtenez l'âme de %bSabooro%w!"), + GIMESSAGE_NO_GERMAN(RG_JIRO_SOUL, ITEM_BIG_POE, "You found the soul for %bJiro%w!", + "Vous obtenez l'âme de %bJiro%w!"), + GIMESSAGE_NO_GERMAN(RG_SHIRO_SOUL, ITEM_BIG_POE, "You found the soul for %bShiro%w!", + "Vous obtenez l'âme de %bShiro%w!"), + GIMESSAGE_NO_GERMAN(RG_HW_GATEKEEPER_SOUL, ITEM_BIG_POE, + "You found the soul for %bHaunted Wasteland Gate Operator%w!", + "Vous obtenez l'âme de %bHaunted Wasteland Gate Operator%w!"), + GIMESSAGE_NO_GERMAN(RG_GTG_GATEKEEPER_SOUL, ITEM_BIG_POE, + "You found the soul for %bTraining Ground Gate Operator%w!", + "Vous obtenez l'âme de %bTraining Ground Gate Operator%w!"), + GIMESSAGE_NO_GERMAN(RG_ARCHER_SOUL, ITEM_BIG_POE, "You found the soul for %bHorseback Archer%w!", + "Vous obtenez l'âme de %bHorseback Archer%w!"), + GIMESSAGE_NO_GERMAN(RG_GREAT_FAIRY_SOUL, ITEM_BIG_POE, "You found the soul for %bGreat Fairy%w!", + "Vous obtenez l'âme de %bGreat Fairy%w!"), + GIMESSAGE_NO_GERMAN(RG_POE_COLLECTOR_SOUL, ITEM_BIG_POE, "You found the soul for %bPoe Collector%w!", + "Vous obtenez l'âme de %bPoe Collector%w!"), + GIMESSAGE_NO_GERMAN(RG_DAMPE_SOUL, ITEM_BIG_POE, "You found the soul for %bDampe%w!", + "Vous obtenez l'âme de %bDampe%w!"), + GIMESSAGE_NO_GERMAN(RG_WINDMILL_MAN_SOUL, ITEM_BIG_POE, "You found the soul for %bWindmill Man%w!", + "Vous obtenez l'âme de %bWindmill Man%w!"), + GIMESSAGE_NO_GERMAN(RG_MAN_ON_ROOF_SOUL, ITEM_BIG_POE, "You found the soul for %bMan on Roof%w!", + "Vous obtenez l'âme de %bMan on Roof%w!"), + GIMESSAGE_NO_GERMAN(RG_KAKARIKO_GATEKEEPER_SOUL, ITEM_BIG_POE, + "You found the soul for %bKakariko Gatekeeper%w!", + "Vous obtenez l'âme de %bKakariko Gatekeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_MALON_SOUL, ITEM_BIG_POE, "You found the soul for %bMalon%w!", + "Vous obtenez l'âme de %bMalon%w!"), + GIMESSAGE_NO_GERMAN(RG_BEGGAR_SOUL, ITEM_BIG_POE, "You found the soul for %bBeggar%w!", + "Vous obtenez l'âme de %bBeggar%w!"), + GIMESSAGE_NO_GERMAN(RG_DOG_LADY_SOUL, ITEM_BIG_POE, "You found the soul for %bDog Lady%w!", + "Vous obtenez l'âme de %bDog Lady%w!"), + GIMESSAGE_NO_GERMAN(RG_ARMS_DEALER_SOUL, ITEM_BIG_POE, "You found the soul for %bArms Dealer%w!", + "Vous obtenez l'âme de %bArms Dealer%w!"), + GIMESSAGE_NO_GERMAN(RG_BEAN_SALESMAN_SOUL, ITEM_BIG_POE, "You found the soul for %bBean Salesman%w!", + "Vous obtenez l'âme de %bBean Salesman%w!"), + GIMESSAGE_NO_GERMAN(RG_SHOOTING_SOUL, ITEM_BIG_POE, "You found the soul for %bShooter%w!", + "Vous obtenez l'âme de %bShooter%w!"), + GIMESSAGE_NO_GERMAN(RG_KOKIRI_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bKokiri Shopkeeper%w!", + "Vous obtenez l'âme de %bKokiri Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_POTION_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bPotion Shopkeeper%w!", + "Vous obtenez l'âme de %bPotion Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_BAZAAR_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bBazaar Shopkeeper%w!", + "Vous obtenez l'âme de %bBazaar Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_GORON_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bGoron Shopkeeper%w!", + "Vous obtenez l'âme de %bGoron Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_ZORA_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bZora Shopkeeper%w!", + "Vous obtenez l'âme de %bZora Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_BOMBCHU_SHOPKEEPER_SOUL, ITEM_BIG_POE, "You found the soul for %bBombchu Shopkeeper%w!", + "Vous obtenez l'âme de %bBombchu Shopkeeper%w!"), + GIMESSAGE_NO_GERMAN(RG_MASK_SALESMAN_SOUL, ITEM_BIG_POE, "You found the soul for %bMask Salesman%w!", + "Vous obtenez l'âme de %bMask Salesman%w!"), + GIMESSAGE_NO_GERMAN(RG_TREASURE_MAN_SOUL, ITEM_BIG_POE, "You found the soul for %bTreasure Man%w!", + "Vous obtenez l'âme de %bTreasure Man%w!"), + GIMESSAGE_NO_GERMAN(RG_BOMBCHU_LADY_SOUL, ITEM_BIG_POE, "You found the soul for %bBombchu Lady%w!", + "Vous obtenez l'âme de %bBombchu Lady%w!"), + GIMESSAGE_NO_GERMAN(RG_DIVING_SOUL, ITEM_BIG_POE, "You found the soul for %bDiver%w!", + "Vous obtenez l'âme de %bDiver%w!"), + GIMESSAGE_NO_GERMAN(RG_SCIENTIST_SOUL, ITEM_BIG_POE, "You found the soul for %bScientist%w!", + "Vous obtenez l'âme de %bScientifique%w!"), + GIMESSAGE_NO_GERMAN(RG_KAEPORA_SOUL, ITEM_BIG_POE, "You found the soul for %bKaepora%w!", + "Vous obtenez l'âme de %bKaepora%w!"), + GIMESSAGE_NO_GERMAN(RG_RAURU_SOUL, ITEM_BIG_POE, "You found the soul for %bRauru%w!", + "Vous obtenez l'âme de %bRauru%w!"), + GIMESSAGE_NO_GERMAN(RG_SARIA_SOUL, ITEM_BIG_POE, "You found the soul for %bSaria%w!", + "Vous obtenez l'âme de %bSaria%w!"), + GIMESSAGE_NO_GERMAN(RG_DARUNIA_SOUL, ITEM_BIG_POE, "You found the soul for %bDarunia%w!", + "Vous obtenez l'âme de %bDarunia%w!"), + GIMESSAGE_NO_GERMAN(RG_RUTO_SOUL, ITEM_BIG_POE, "You found the soul for %bRuto%w!", + "Vous obtenez l'âme de %bRuto%w!"), + GIMESSAGE_NO_GERMAN(RG_NABOORU_SOUL, ITEM_BIG_POE, "You found the soul for %bNabooru%w!", + "Vous obtenez l'âme de %bNabooru%w!"), + GIMESSAGE_NO_GERMAN(RG_IMPA_SOUL, ITEM_BIG_POE, "You found the soul for %bImpa%w!", + "Vous obtenez l'âme de %bImpa%w!"), + GIMESSAGE_NO_GERMAN(RG_ZELDA_SOUL, ITEM_BIG_POE, "You found the soul for %bZelda%w!", + "Vous obtenez l'âme de %bZelda%w!"), + GIMESSAGE(RG_OCARINA_A_BUTTON, ITEM_OCARINA_TIME, "You got the %b\x9f%r button for the&Ocarina%w! You can now use it&while playing songs!", "Der %b\x9f%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", @@ -5664,9 +6221,22 @@ void Randomizer::CreateCustomMessages() { "Vous obtenez la %rtouche %y\xa6%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en " "jouez!"), + GIMESSAGE(RG_MASK_KEATON, ITEM_MASK_KEATON, "!!!", "!!!", "!!!"), + GIMESSAGE(RG_MASK_SKULL, ITEM_MASK_SKULL, "!!!", "!!!", "!!!"), + GIMESSAGE(RG_MASK_SPOOKY, ITEM_MASK_SPOOKY, "!!!", "!!!", "!!!"), + GIMESSAGE(RG_MASK_BUNNY, ITEM_MASK_BUNNY, "!!!", "!!!", "!!!"), + GIMESSAGE(RG_MASK_GORON, ITEM_MASK_GORON, "!!!", "!!!", "!!!"), + GIMESSAGE(RG_MASK_ZORA, ITEM_MASK_ZORA, "!!!", "!!!", "!!!"), + GIMESSAGE(RG_MASK_GERUDO, ITEM_MASK_GERUDO, "!!!", "!!!", "!!!"), + GIMESSAGE(RG_MASK_TRUTH, ITEM_MASK_TRUTH, "!!!", "!!!", "!!!"), + GIMESSAGE(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!", "Du hast die %rBronzene Schuppe%w&erhalten! Die Fähigkeit zu&Schwimmen ist nun dein!", "Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"), + GIMESSAGE_NO_GERMAN(RG_CLIMB, ITEM_SCALE_SILVER, "You got the %rAbility to Climb Ladders%w!&", "!!!"), + GIMESSAGE_NO_GERMAN(RG_CRAWL, ITEM_SCALE_SILVER, + "You got the %rAbility to Crawl%w!&The power of kneecaps is yours!", + "Vous obtenez la %rCapacité à Ramper%w!"), GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!", "Du hast eine verlorene %rAngelrute%w&gefunden!&Zeit, im Teich&zu angeln!", "Vous obtenez une %rCanne à pêche%w&perdue!&Il est temps d'aller à %gl'étang%w!"), @@ -5775,35 +6345,6 @@ void Randomizer_GameplayStats_SetTimestamp(uint16_t item) { extern "C" u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem); -// used for items that only set a rand inf when obtained -std::map randomizerGetToRandInf = { - { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, - { RG_BRONZE_SCALE, RAND_INF_CAN_SWIM }, - { RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER }, - { RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG }, - { RG_BULLET_BAG_INF, RAND_INF_HAS_INFINITE_BULLET_BAG }, - { RG_STICK_UPGRADE_INF, RAND_INF_HAS_INFINITE_STICK_UPGRADE }, - { RG_NUT_UPGRADE_INF, RAND_INF_HAS_INFINITE_NUT_UPGRADE }, - { RG_MAGIC_INF, RAND_INF_HAS_INFINITE_MAGIC_METER }, - { RG_BOMBCHU_INF, RAND_INF_HAS_INFINITE_BOMBCHUS }, - { RG_WALLET_INF, RAND_INF_HAS_INFINITE_MONEY }, - { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, - { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, - { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, - { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, - { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, - { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, - { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, - { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, - { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, - { RG_PHANTOM_GANON_SOUL, RAND_INF_PHANTOM_GANON_SOUL }, - { RG_VOLVAGIA_SOUL, RAND_INF_VOLVAGIA_SOUL }, - { RG_MORPHA_SOUL, RAND_INF_MORPHA_SOUL }, - { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, - { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, - { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, -}; - extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { if (giEntry.modIndex != MOD_RANDOMIZER) { LUSLOG_WARN( diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 78f48b01c92..0cff0130acd 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -57,6 +57,8 @@ class Randomizer { GrassIdentity IdentifyGrass(s32 sceneNum, s32 posX, s32 posZ, s32 respawnData, s32 linkAge); CrateIdentity IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ); SmallCrateIdentity IdentifySmallCrate(s32 sceneNum, s32 posX, s32 posZ); + RockIdentity IdentifyRock(s32 sceneNum, s32 posX, s32 posZ); + TreeIdentity IdentifyTree(s32 sceneNum, s32 posX, s32 posZ); GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability = true); GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 8295eb6cda5..dafbd877f8e 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -203,6 +203,54 @@ typedef enum { LOGIC_CAN_SUMMON_BONGOBONGO, LOGIC_CAN_SUMMON_TWINROVA, LOGIC_CAN_SUMMON_GANON, + LOGIC_CAN_SUMMON_ANJU, + LOGIC_CAN_SUMMON_TALON, + LOGIC_CAN_SUMMON_GROG, + LOGIC_CAN_SUMMON_GRANNY, + LOGIC_CAN_SUMMON_FADO, + LOGIC_CAN_SUMMON_LINK, + LOGIC_CAN_SUMMON_BIGGORON, + LOGIC_CAN_SUMMON_HOT_RODDER, + LOGIC_CAN_SUMMON_MEDIGORON, + LOGIC_CAN_SUMMON_CARPENTER_BOSS, + LOGIC_CAN_SUMMON_ICHIRO, + LOGIC_CAN_SUMMON_SABOORO, + LOGIC_CAN_SUMMON_JIRO, + LOGIC_CAN_SUMMON_SHIRO, + LOGIC_CAN_SUMMON_HW_GATEKEEPER, + LOGIC_CAN_SUMMON_GTG_GATEKEEPER, + LOGIC_CAN_SUMMON_ARCHER, + LOGIC_CAN_SUMMON_GREAT_FAIRY, + LOGIC_CAN_SUMMON_POE_COLLECTOR, + LOGIC_CAN_SUMMON_DAMPE, + LOGIC_CAN_SUMMON_WINDMILL_MAN, + LOGIC_CAN_SUMMON_MAN_ON_ROOF, + LOGIC_CAN_SUMMON_KAKARIKO_GATEKEEPER, + LOGIC_CAN_SUMMON_MALON, + LOGIC_CAN_SUMMON_BEGGAR, + LOGIC_CAN_SUMMON_DOG_LADY, + LOGIC_CAN_SUMMON_ARMS_DEALER, + LOGIC_CAN_SUMMON_BEAN_SALESMAN, + LOGIC_CAN_SUMMON_SHOOTING, + LOGIC_CAN_SUMMON_KOKIRI_SHOPKEEPER, + LOGIC_CAN_SUMMON_POTION_SHOPKEEPER, + LOGIC_CAN_SUMMON_BAZAAR_SHOPKEEPER, + LOGIC_CAN_SUMMON_GORON_SHOPKEEPER, + LOGIC_CAN_SUMMON_ZORA_SHOPKEEPER, + LOGIC_CAN_SUMMON_BOMBCHU_SHOPKEEPER, + LOGIC_CAN_SUMMON_MASK_SALESMAN, + LOGIC_CAN_SUMMON_TREASURE_MAN, + LOGIC_CAN_SUMMON_BOMBCHU_LADY, + LOGIC_CAN_SUMMON_DIVING, + LOGIC_CAN_SUMMON_SCIENTIST, + LOGIC_CAN_SUMMON_KAEPORA, + LOGIC_CAN_SUMMON_RAURU, + LOGIC_CAN_SUMMON_SARIA, + LOGIC_CAN_SUMMON_DARUNIA, + LOGIC_CAN_SUMMON_RUTO, + LOGIC_CAN_SUMMON_NABOORU, + LOGIC_CAN_SUMMON_IMPA, + LOGIC_CAN_SUMMON_ZELDA, LOGIC_FISHING_POLE, LOGIC_OCARINA_A_BUTTON, LOGIC_OCARINA_C_UP_BUTTON, @@ -299,6 +347,8 @@ typedef enum { RCTYPE_CRATE, // Crates RCTYPE_NLCRATE, // NL Crates RCTYPE_SMALL_CRATE, // Small crates + RCTYPE_TREE, // Trees + RCTYPE_NLTREE, // NL Trees RCTYPE_DUNGEON_REWARD, // Dungeon rewards (blue warps) RCTYPE_OCARINA, // Ocarina locations RCTYPE_BEEHIVE, // Beehives @@ -306,6 +356,8 @@ typedef enum { RCTYPE_FREESTANDING, // Freestanding rupees and hearts RCTYPE_FAIRY, // Fairies RCTYPE_GRASS, // Grass + RCTYPE_ROCK, // Rocks + RCTYPE_BOULDER, // Boulders } RandomizerCheckType; typedef enum { RCQUEST_VANILLA, RCQUEST_MQ, RCQUEST_BOTH } RandomizerCheckQuest; @@ -370,6 +422,7 @@ typedef enum { RR_NOCTURNE_OF_SHADOW_WARP, RR_PRELUDE_OF_LIGHT_WARP, RR_KOKIRI_FOREST, + RR_KF_LINKS_PORCH, RR_KF_LINKS_HOUSE, RR_KF_MIDOS_HOUSE, RR_KF_SARIAS_HOUSE, @@ -377,6 +430,7 @@ typedef enum { RR_KF_KNOW_IT_ALL_HOUSE, RR_KF_KOKIRI_SHOP, RR_KF_OUTSIDE_DEKU_TREE, + RR_KF_OUTSIDE_LOST_WOODS, RR_KF_STORMS_GROTTO, RR_THE_LOST_WOODS, RR_LW_BRIDGE_FROM_FOREST, @@ -387,11 +441,15 @@ typedef enum { RR_DEKU_THEATER, RR_LW_SCRUBS_GROTTO, RR_SFM_ENTRYWAY, + RR_SFM_MAZE, + RR_SFM_ABOVE_MAZE, + RR_SFM_OUTSIDE_FAIRY_GROTTO, RR_SACRED_FOREST_MEADOW, RR_SFM_WOLFOS_GROTTO, RR_SFM_FAIRY_GROTTO, RR_SFM_STORMS_GROTTO, RR_HYRULE_FIELD, + RR_HF_TO_LAKE_HYLIA, RR_HF_SOUTHEAST_GROTTO, RR_HF_OPEN_GROTTO, RR_HF_INSIDE_FENCE_GROTTO, @@ -472,8 +530,10 @@ typedef enum { RR_TOT_BEYOND_DOOR_OF_TIME, RR_CASTLE_GROUNDS, RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE, + RR_HC_GATE, RR_HYRULE_CASTLE_GROUNDS, RR_HC_GARDEN, + RR_HC_MOAT, RR_HC_GREAT_FAIRY_FOUNTAIN, RR_HC_STORMS_GROTTO, RR_HC_STORMS_GROTTO_BEHIND_WALLS, @@ -509,6 +569,7 @@ typedef enum { RR_GRAVEYARD_HEART_PIECE_GRAVE, RR_GRAVEYARD_WARP_PAD_REGION, RR_DEATH_MOUNTAIN_TRAIL, + RR_DEATH_MOUNTAIN_AVALANCHE, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMT_OWL_FLIGHT, RR_DMT_GREAT_FAIRY_FOUNTAIN, @@ -532,10 +593,12 @@ typedef enum { RR_DMC_HAMMER_GROTTO, RR_DMC_GREAT_FAIRY_FOUNTAIN, RR_DMC_DISTANT_PLATFORM, + RR_DMC_OUTSIDE_FIRE_TEMPLE, RR_ZR_FRONT, RR_ZORAS_RIVER, RR_ZR_FROM_SHORTCUT, RR_ZR_BEHIND_WATERFALL, + RR_ZR_UPPER_GROTTOS, RR_ZR_OPEN_GROTTO, RR_ZR_FAIRY_GROTTO, RR_ZR_STORMS_GROTTO, @@ -572,6 +635,8 @@ typedef enum { RR_GANONS_CASTLE_ENTRYWAY, RR_DEKU_TREE_LOBBY, + RR_DEKU_TREE_LOBBY_2F, + RR_DEKU_TREE_LOBBY_3F, RR_DEKU_TREE_2F_MIDDLE_ROOM, RR_DEKU_TREE_SLINGSHOT_ROOM, RR_DEKU_TREE_COMPASS_ROOM, @@ -2645,6 +2710,72 @@ typedef enum { RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, // End Crates + // Start Trees + RC_MARKET_TREE, + RC_HC_NEAR_GUARDS_TREE_1, + RC_HC_NEAR_GUARDS_TREE_2, + RC_HC_NEAR_GUARDS_TREE_3, + RC_HC_NEAR_GUARDS_TREE_4, + RC_HC_NEAR_GUARDS_TREE_5, + RC_HC_NEAR_GUARDS_TREE_6, + RC_HC_SKULLTULA_TREE, + RC_HC_GROTTO_TREE, + RC_HC_NL_TREE_1, + RC_HC_NL_TREE_2, + RC_HF_NEAR_LLR_TREE, + RC_HF_NEAR_LH_TREE, + RC_HF_CHILD_NEAR_GV_TREE, + RC_HF_ADULT_NEAR_GV_TREE, + RC_HF_NEAR_ZR_TREE, + RC_HF_NEAR_KAK_TREE, + RC_HF_NEAR_KAK_SMALL_TREE, + RC_HF_NEAR_MARKET_TREE_1, + RC_HF_NEAR_MARKET_TREE_2, + RC_HF_NEAR_MARKET_TREE_3, + RC_HF_NORTHWEST_TREE_1, + RC_HF_NORTHWEST_TREE_2, + RC_HF_NORTHWEST_TREE_3, + RC_HF_NORTHWEST_TREE_4, + RC_HF_NORTHWEST_TREE_5, + RC_HF_NORTHWEST_TREE_6, + RC_HF_EAST_TREE_1, + RC_HF_EAST_TREE_2, + RC_HF_EAST_TREE_3, + RC_HF_EAST_TREE_4, + RC_HF_EAST_TREE_5, + RC_HF_EAST_TREE_6, + RC_HF_SOUTHEAST_TREE_1, + RC_HF_SOUTHEAST_TREE_2, + RC_HF_SOUTHEAST_TREE_3, + RC_HF_SOUTHEAST_TREE_4, + RC_HF_SOUTHEAST_TREE_5, + RC_HF_SOUTHEAST_TREE_6, + RC_HF_SOUTHEAST_TREE_7, + RC_HF_SOUTHEAST_TREE_8, + RC_HF_SOUTHEAST_TREE_9, + RC_HF_SOUTHEAST_TREE_10, + RC_HF_SOUTHEAST_TREE_11, + RC_HF_SOUTHEAST_TREE_12, + RC_HF_SOUTHEAST_TREE_13, + RC_HF_SOUTHEAST_TREE_14, + RC_HF_SOUTHEAST_TREE_15, + RC_HF_SOUTHEAST_TREE_16, + RC_HF_SOUTHEAST_TREE_17, + RC_HF_SOUTHEAST_TREE_18, + RC_HF_SOUTHEAST_TREE_19, + RC_HF_CHILD_SOUTHEAST_TREE_1, + RC_HF_CHILD_SOUTHEAST_TREE_2, + RC_HF_CHILD_SOUTHEAST_TREE_3, + RC_HF_CHILD_SOUTHEAST_TREE_4, + RC_HF_CHILD_SOUTHEAST_TREE_5, + RC_HF_CHILD_SOUTHEAST_TREE_6, + RC_HF_TEKTITE_GROTTO_TREE, + RC_ZF_TREE, + RC_ZR_TREE, + RC_KAK_TREE, + RC_LLR_TREE, + // End Trees + RC_PIERRE, RC_DELIVER_RUTOS_LETTER, RC_MASTER_SWORD_PEDESTAL, @@ -3512,6 +3643,287 @@ typedef enum { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_8, // End Grass + RC_KF_CIRCLE_ROCK_1, + RC_KF_CIRCLE_ROCK_2, + RC_KF_CIRCLE_ROCK_3, + RC_KF_CIRCLE_ROCK_4, + RC_KF_CIRCLE_ROCK_5, + RC_KF_CIRCLE_ROCK_6, + RC_KF_CIRCLE_ROCK_7, + RC_KF_CIRCLE_ROCK_8, + RC_KF_ROCK_BY_SARIAS_HOUSE, + RC_KF_ROCK_BEHIND_SARIAS_HOUSE, + RC_KF_ROCK_BY_MIDOS_HOUSE, + RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, + RC_LW_BOULDER_BY_GORON_CITY, + RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, + RC_LW_RUPEE_BOULDER, + RC_HC_ROCK_1, + RC_HC_ROCK_2, + RC_HC_ROCK_3, + RC_HC_BOULDER, + RC_OGC_BRONZE_BOULDER_1, + RC_OGC_BRONZE_BOULDER_2, + RC_OGC_BRONZE_BOULDER_3, + RC_OGC_SILVER_BOULDER_1, + RC_OGC_SILVER_BOULDER_2, + RC_OGC_SILVER_BOULDER_3, + RC_OGC_SILVER_BOULDER_4, + RC_DMC_CIRCLE_ROCK_1, + RC_DMC_CIRCLE_ROCK_2, + RC_DMC_CIRCLE_ROCK_3, + RC_DMC_CIRCLE_ROCK_4, + RC_DMC_CIRCLE_ROCK_5, + RC_DMC_CIRCLE_ROCK_6, + RC_DMC_CIRCLE_ROCK_7, + RC_DMC_CIRCLE_ROCK_8, + RC_DMC_ROCK_BY_FIRE_TEMPLE_1, + RC_DMC_ROCK_BY_FIRE_TEMPLE_2, + RC_DMC_ROCK_BY_FIRE_TEMPLE_3, + RC_DMC_ROCK_BY_FIRE_TEMPLE_4, + RC_DMC_ROCK_BY_FIRE_TEMPLE_5, + RC_DMC_GOSSIP_ROCK_1, + RC_DMC_GOSSIP_ROCK_2, + RC_DMC_BOULDER_1, + RC_DMC_BOULDER_2, + RC_DMC_BOULDER_3, + RC_DMC_BRONZE_BOULDER_1, + RC_DMC_BRONZE_BOULDER_2, + RC_DMC_BRONZE_BOULDER_3, + RC_DMC_BRONZE_BOULDER_4, + RC_GV_SILVER_BOULDER, + RC_GV_ROCK_1, + RC_GV_ROCK_2, + RC_GV_ROCK_3, + RC_GV_UNDERWATER_ROCK_1, + RC_GV_UNDERWATER_ROCK_2, + RC_GV_UNDERWATER_ROCK_3, + RC_GV_ROCK_ACROSS_BRIDGE_1, + RC_GV_ROCK_ACROSS_BRIDGE_2, + RC_GV_ROCK_ACROSS_BRIDGE_3, + RC_GV_ROCK_ACROSS_BRIDGE_4, + RC_GV_BOULDER_1, + RC_GV_BOULDER_2, + RC_GV_BOULDER_ACROSS_BRIDGE, + RC_GV_BRONZE_BOULDER_1, + RC_GV_BRONZE_BOULDER_2, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, + RC_HF_SILVER_BOULDER, + RC_HF_ROCK_1, + RC_HF_ROCK_2, + RC_HF_ROCK_3, + RC_HF_ROCK_4, + RC_HF_ROCK_5, + RC_HF_ROCK_6, + RC_HF_ROCK_7, + RC_HF_ROCK_8, + RC_HF_BOULDER_NORTH, + RC_HF_BOULDER_BY_MARKET, + RC_HF_BOULDER_SOUTH, + RC_HF_BRONZE_BOULDER_1, + RC_HF_BRONZE_BOULDER_2, + RC_HF_BRONZE_BOULDER_3, + RC_HF_BRONZE_BOULDER_4, + RC_KAK_SILVER_BOULDER, + RC_KAK_ROCK_1, + RC_KAK_ROCK_2, + RC_GY_ROCK, + RC_LA_ROCK, + RC_ZD_CIRCLE_ROCK_1, + RC_ZD_CIRCLE_ROCK_2, + RC_ZD_CIRCLE_ROCK_3, + RC_ZD_CIRCLE_ROCK_4, + RC_ZD_CIRCLE_ROCK_5, + RC_ZD_CIRCLE_ROCK_6, + RC_ZD_CIRCLE_ROCK_7, + RC_ZD_CIRCLE_ROCK_8, + RC_ZF_BOULDER, + RC_ZF_SILVER_BOULDER, + RC_ZF_UNDERGROUND_BOULDER, + RC_ZR_BOULDER_1, + RC_ZR_BOULDER_2, + RC_ZR_BOULDER_3, + RC_ZR_BOULDER_4, + RC_ZR_CIRCLE_ROCK_1, + RC_ZR_CIRCLE_ROCK_2, + RC_ZR_CIRCLE_ROCK_3, + RC_ZR_CIRCLE_ROCK_4, + RC_ZR_CIRCLE_ROCK_5, + RC_ZR_CIRCLE_ROCK_6, + RC_ZR_CIRCLE_ROCK_7, + RC_ZR_CIRCLE_ROCK_8, + RC_ZR_UPPER_CIRCLE_BOULDER, + RC_ZR_UPPER_CIRCLE_ROCK_1, + RC_ZR_UPPER_CIRCLE_ROCK_2, + RC_ZR_UPPER_CIRCLE_ROCK_3, + RC_ZR_UPPER_CIRCLE_ROCK_4, + RC_ZR_UPPER_CIRCLE_ROCK_5, + RC_ZR_UPPER_CIRCLE_ROCK_6, + RC_ZR_UPPER_CIRCLE_ROCK_7, + RC_ZR_UPPER_CIRCLE_ROCK_8, + RC_ZR_ROCK, + RC_ZR_UNDERWATER_ROCK_1, + RC_ZR_UNDERWATER_ROCK_2, + RC_ZR_UNDERWATER_ROCK_3, + RC_ZR_UNDERWATER_ROCK_4, + RC_DMT_ROCK_1, + RC_DMT_ROCK_2, + RC_DMT_ROCK_3, + RC_DMT_ROCK_4, + RC_DMT_ROCK_5, + RC_DMT_SUMMIT_ROCK, + RC_DMT_CIRCLE_ROCK_1, + RC_DMT_CIRCLE_ROCK_2, + RC_DMT_CIRCLE_ROCK_3, + RC_DMT_CIRCLE_ROCK_4, + RC_DMT_CIRCLE_ROCK_5, + RC_DMT_CIRCLE_ROCK_6, + RC_DMT_CIRCLE_ROCK_7, + RC_DMT_CIRCLE_ROCK_8, + RC_DMT_BOULDER_1, + RC_DMT_BOULDER_2, + RC_DMT_BOULDER_3, + RC_DMT_COW_BOULDER, + RC_DMT_BRONZE_BOULDER_1, + RC_DMT_BRONZE_BOULDER_2, + RC_DMT_BRONZE_BOULDER_3, + RC_DMT_BRONZE_BOULDER_4, + RC_DMT_BRONZE_BOULDER_5, + RC_DMT_BRONZE_BOULDER_6, + RC_DMT_BRONZE_BOULDER_7, + RC_DMT_BRONZE_BOULDER_8, + RC_DMT_BRONZE_BOULDER_9, + RC_DMT_BRONZE_BOULDER_10, + RC_DMT_BRONZE_BOULDER_11, + RC_GC_LW_BOULDER_1, + RC_GC_LW_BOULDER_2, + RC_GC_LW_BOULDER_3, + RC_GC_ENTRANCE_BOULDER_1, + RC_GC_ENTRANCE_BOULDER_2, + RC_GC_ENTRANCE_BOULDER_3, + RC_GC_MAZE_SILVER_BOULDER_1, + RC_GC_MAZE_SILVER_BOULDER_2, + RC_GC_MAZE_SILVER_BOULDER_3, + RC_GC_MAZE_SILVER_BOULDER_4, + RC_GC_MAZE_SILVER_BOULDER_5, + RC_GC_MAZE_SILVER_BOULDER_6, + RC_GC_MAZE_SILVER_BOULDER_7, + RC_GC_MAZE_SILVER_BOULDER_8, + RC_GC_MAZE_SILVER_BOULDER_9, + RC_GC_MAZE_SILVER_BOULDER_10, + RC_GC_MAZE_SILVER_BOULDER_11, + RC_GC_MAZE_SILVER_BOULDER_12, + RC_GC_MAZE_SILVER_BOULDER_13, + RC_GC_MAZE_SILVER_BOULDER_14, + RC_GC_MAZE_SILVER_BOULDER_15, + RC_GC_MAZE_SILVER_BOULDER_16, + RC_GC_MAZE_SILVER_BOULDER_17, + RC_GC_MAZE_SILVER_BOULDER_18, + RC_GC_MAZE_SILVER_BOULDER_19, + RC_GC_MAZE_SILVER_BOULDER_20, + RC_GC_MAZE_SILVER_BOULDER_21, + RC_GC_MAZE_SILVER_BOULDER_22, + RC_GC_MAZE_SILVER_BOULDER_23, + RC_GC_MAZE_SILVER_BOULDER_24, + RC_GC_MAZE_SILVER_BOULDER_25, + RC_GC_MAZE_SILVER_BOULDER_26, + RC_GC_MAZE_SILVER_BOULDER_27, + RC_GC_MAZE_SILVER_BOULDER_28, + RC_GC_MAZE_SILVER_BOULDER_29, + RC_GC_MAZE_BOULDER_1, + RC_GC_MAZE_BOULDER_2, + RC_GC_MAZE_BOULDER_3, + RC_GC_MAZE_BOULDER_4, + RC_GC_MAZE_BOULDER_5, + RC_GC_MAZE_BOULDER_6, + RC_GC_MAZE_BOULDER_7, + RC_GC_MAZE_BOULDER_8, + RC_GC_MAZE_BOULDER_9, + RC_GC_MAZE_BOULDER_10, + RC_GC_MAZE_BRONZE_BOULDER_1, + RC_GC_MAZE_BRONZE_BOULDER_2, + RC_GC_MAZE_BRONZE_BOULDER_3, + RC_GC_MAZE_BRONZE_BOULDER_4, + RC_GC_MAZE_BRONZE_BOULDER_5, + RC_GC_MAZE_ROCK, + RC_COLOSSUS_SILVER_BOULDER, + RC_COLOSSUS_ROCK, + RC_COLOSSUS_CIRCLE_1_ROCK_1, + RC_COLOSSUS_CIRCLE_1_ROCK_2, + RC_COLOSSUS_CIRCLE_1_ROCK_3, + RC_COLOSSUS_CIRCLE_1_ROCK_4, + RC_COLOSSUS_CIRCLE_1_ROCK_5, + RC_COLOSSUS_CIRCLE_1_ROCK_6, + RC_COLOSSUS_CIRCLE_1_ROCK_7, + RC_COLOSSUS_CIRCLE_1_ROCK_8, + RC_COLOSSUS_CIRCLE_2_ROCK_1, + RC_COLOSSUS_CIRCLE_2_ROCK_2, + RC_COLOSSUS_CIRCLE_2_ROCK_3, + RC_COLOSSUS_CIRCLE_2_ROCK_4, + RC_COLOSSUS_CIRCLE_2_ROCK_5, + RC_COLOSSUS_CIRCLE_2_ROCK_6, + RC_COLOSSUS_CIRCLE_2_ROCK_7, + RC_COLOSSUS_CIRCLE_2_ROCK_8, + RC_HC_STORMS_GROTTO_ROCK_1, + RC_HC_STORMS_GROTTO_ROCK_2, + RC_HC_STORMS_GROTTO_ROCK_3, + RC_HC_STORMS_GROTTO_ROCK_4, + RC_HC_STORMS_GROTTO_ROCK_5, + RC_HC_STORMS_GROTTO_ROCK_6, + RC_HC_STORMS_GROTTO_ROCK_7, + RC_HC_STORMS_GROTTO_ROCK_8, + RC_BOTW_BOULDER_1, + RC_BOTW_BOULDER_2, + RC_BOTW_BOULDER_3, + RC_BOTW_BOULDER_4, + RC_BOTW_BOULDER_5, + RC_BOTW_BOULDER_6, + RC_DEKU_TREE_MQ_BOULDER_1, + RC_DEKU_TREE_MQ_BOULDER_2, + RC_DEKU_TREE_MQ_BOULDER_3, + RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, + RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, + RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, + RC_BOTW_MQ_BOULDER_1, + RC_BOTW_MQ_BOULDER_2, + RC_BOTW_MQ_BOULDER_3, + RC_MAX } RandomizerCheck; @@ -3993,6 +4405,54 @@ typedef enum { RG_BONGO_BONGO_SOUL, RG_TWINROVA_SOUL, RG_GANON_SOUL, + RG_ANJU_SOUL, // used by loop, must be first NPC soul + RG_TALON_SOUL, + RG_GROG_SOUL, + RG_GRANNY_SOUL, + RG_FADO_SOUL, + RG_LINK_SOUL, + RG_BIGGORON_SOUL, + RG_HOT_RODDER_SOUL, + RG_MEDIGORON_SOUL, + RG_CARPENTER_BOSS_SOUL, + RG_ICHIRO_SOUL, + RG_SABOORO_SOUL, + RG_JIRO_SOUL, + RG_SHIRO_SOUL, + RG_HW_GATEKEEPER_SOUL, + RG_GTG_GATEKEEPER_SOUL, + RG_ARCHER_SOUL, + RG_GREAT_FAIRY_SOUL, + RG_POE_COLLECTOR_SOUL, + RG_DAMPE_SOUL, + RG_WINDMILL_MAN_SOUL, + RG_MAN_ON_ROOF_SOUL, + RG_KAKARIKO_GATEKEEPER_SOUL, + RG_MALON_SOUL, + RG_BEGGAR_SOUL, + RG_DOG_LADY_SOUL, + RG_ARMS_DEALER_SOUL, + RG_BEAN_SALESMAN_SOUL, + RG_SHOOTING_SOUL, + RG_KOKIRI_SHOPKEEPER_SOUL, + RG_POTION_SHOPKEEPER_SOUL, + RG_BAZAAR_SHOPKEEPER_SOUL, + RG_GORON_SHOPKEEPER_SOUL, + RG_ZORA_SHOPKEEPER_SOUL, + RG_BOMBCHU_SHOPKEEPER_SOUL, + RG_MASK_SALESMAN_SOUL, + RG_TREASURE_MAN_SOUL, + RG_BOMBCHU_LADY_SOUL, + RG_DIVING_SOUL, + RG_SCIENTIST_SOUL, + RG_KAEPORA_SOUL, + RG_RAURU_SOUL, + RG_SARIA_SOUL, + RG_DARUNIA_SOUL, + RG_RUTO_SOUL, + RG_NABOORU_SOUL, + RG_IMPA_SOUL, + RG_ZELDA_SOUL, // used by loop, must be last NPC soul RG_OCARINA_A_BUTTON, RG_OCARINA_C_UP_BUTTON, RG_OCARINA_C_DOWN_BUTTON, @@ -4005,6 +4465,8 @@ typedef enum { RG_HINT, RG_TYCOON_WALLET, RG_BRONZE_SCALE, + RG_CLIMB, + RG_CRAWL, RG_CHILD_WALLET, RG_BOMBCHU_BAG, RG_QUIVER_INF, @@ -4040,6 +4502,14 @@ typedef enum { RG_HOOKSHOT, RG_LONGSHOT, RG_SCARECROW, + RG_MASK_KEATON, + RG_MASK_SKULL, + RG_MASK_SPOOKY, + RG_MASK_BUNNY, + RG_MASK_GORON, + RG_MASK_ZORA, + RG_MASK_GERUDO, + RG_MASK_TRUTH, // Overworld keys RG_GUARD_HOUSE_KEY, @@ -4066,6 +4536,7 @@ typedef enum { RG_BACK_TOWER_KEY, RG_HYLIA_LAB_KEY, RG_FISHING_HOLE_KEY, + // Logic Only RG_DISTANT_SCARECROW, RG_STICKS, @@ -5196,12 +5667,70 @@ typedef enum { RHT_BONGO_BONGO_SOUL, RHT_TWINROVA_SOUL, RHT_GANON_SOUL, + RHT_ANJU_SOUL, + RHT_TALON_SOUL, + RHT_GROG_SOUL, + RHT_GRANNY_SOUL, + RHT_FADO_SOUL, + RHT_LINK_SOUL, + RHT_BIGGORON_SOUL, + RHT_HOT_RODDER_SOUL, + RHT_MEDIGORON_SOUL, + RHT_CARPENTER_BOSS_SOUL, + RHT_ICHIRO_SOUL, + RHT_SABOORO_SOUL, + RHT_JIRO_SOUL, + RHT_SHIRO_SOUL, + RHT_HW_GATEKEEPER_SOUL, + RHT_GTG_GATEKEEPER_SOUL, + RHT_ARCHER_SOUL, + RHT_GREAT_FAIRY_SOUL, + RHT_POE_COLLECTOR_SOUL, + RHT_DAMPE_SOUL, + RHT_WINDMILL_MAN_SOUL, + RHT_MAN_ON_ROOF_SOUL, + RHT_KAKARIKO_GATEKEEPER_SOUL, + RHT_MALON_SOUL, + RHT_BEGGAR_SOUL, + RHT_DOG_LADY_SOUL, + RHT_ARMS_DEALER_SOUL, + RHT_BEAN_SALESMAN_SOUL, + RHT_SHOOTING_SOUL, + RHT_KOKIRI_SHOPKEEPER_SOUL, + RHT_POTION_SHOPKEEPER_SOUL, + RHT_BAZAAR_SHOPKEEPER_SOUL, + RHT_GORON_SHOPKEEPER_SOUL, + RHT_ZORA_SHOPKEEPER_SOUL, + RHT_BOMBCHU_SHOPKEEPER_SOUL, + RHT_MASK_SALESMAN_SOUL, + RHT_TREASURE_MAN_SOUL, + RHT_BOMBCHU_LADY_SOUL, + RHT_DIVING_SOUL, + RHT_SCIENTIST_SOUL, + RHT_KAEPORA_SOUL, + RHT_RAURU_SOUL, + RHT_SARIA_SOUL, + RHT_DARUNIA_SOUL, + RHT_RUTO_SOUL, + RHT_NABOORU_SOUL, + RHT_IMPA_SOUL, + RHT_ZELDA_SOUL, RHT_OCARINA_A_BUTTON, RHT_OCARINA_C_UP_BUTTON, RHT_OCARINA_C_DOWN_BUTTON, RHT_OCARINA_C_LEFT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, + RHT_MASK_KEATON, + RHT_MASK_SKULL, + RHT_MASK_SPOOKY, + RHT_MASK_BUNNY, + RHT_MASK_GORON, + RHT_MASK_ZORA, + RHT_MASK_GERUDO, + RHT_MASK_TRUTH, RHT_BRONZE_SCALE, + RHT_CLIMB, + RHT_CRAWL, RHT_FISHING_POLE, RHT_SKELETON_KEY, RHT_EPONA, @@ -5477,6 +6006,14 @@ typedef enum { RHT_CRATE_SPIRIT_TEMPLE, RHT_CRATE_SHADOW_TEMPLE, RHT_CRATE_GERUDO_TRAINING_GROUND, + // Shuffle Trees + RHT_TREE_HYRULE_FIELD, + RHT_TREE_MARKET, + RHT_TREE_HYRULE_CASTLE, + RHT_TREE_ZORAS_FOUNTAIN, + RHT_TREE_ZORAS_RIVER, + RHT_TREE_LON_LON_RANCH, + RHT_TREE_KAKARIKO, // Ganon Line RHT_GANON_JOKE01, RHT_GANON_JOKE02, @@ -5656,6 +6193,48 @@ typedef enum { RHT_DODONGOS_CAVERN_GRASS, RHT_BOTTOM_OF_THE_WELL_GRASS, RHT_JABU_JABUS_BELLY_GRASS, + + RHT_KF_ROCK, + RHT_LW_BOULDER, + RHT_HC_ROCK, + RHT_HC_BOULDER, + RHT_OGC_BRONZE_BOULDER, + RHT_OGC_SILVER_BOULDER, + RHT_DMC_ROCK, + RHT_DMC_BOULDER, + RHT_DMC_BRONZE_BOULDER, + RHT_GV_SILVER_BOULDER, + RHT_GV_ROCK, + RHT_GV_BOULDER, + RHT_GV_BRONZE_BOULDER, + RHT_HF_SILVER_BOULDER, + RHT_HF_ROCK, + RHT_HF_BOULDER, + RHT_HF_BRONZE_BOULDER, + RHT_KAK_SILVER_BOULDER, + RHT_KAK_ROCK, + RHT_GY_ROCK, + RHT_LA_ROCK, + RHT_ZD_ROCK, + RHT_ZF_BOULDER, + RHT_ZF_SILVER_BOULDER, + RHT_ZR_BOULDER, + RHT_ZR_ROCK, + RHT_DMT_ROCK, + RHT_DMT_BOULDER, + RHT_DMT_BRONZE_BOULDER, + RHT_GC_BOULDER, + RHT_GC_SILVER_BOULDER, + RHT_GC_BRONZE_BOULDER, + RHT_GC_ROCK, + RHT_COLOSSUS_SILVER_BOULDER, + RHT_COLOSSUS_ROCK, + RHT_HC_STORMS_GROTTO_ROCK, + RHT_BOTW_BOULDER, + RHT_DEKU_BOULDER, + RHT_DODONGOS_BOULDER, + RHT_JABU_BOULDER, + RHT_SPIRIT_TEMPLE_BOULDER, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -5764,6 +6343,8 @@ typedef enum { RSK_SHUFFLE_OCARINA, RSK_SHUFFLE_OCARINA_BUTTONS, RSK_SHUFFLE_SWIM, + RSK_SHUFFLE_CLIMB, + RSK_SHUFFLE_CRAWL, RSK_STARTING_DEKU_SHIELD, RSK_STARTING_KOKIRI_SWORD, RSK_STARTING_MASTER_SWORD, @@ -5815,6 +6396,7 @@ typedef enum { RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, RSK_SHUFFLE_POTS, RSK_SHUFFLE_CRATES, + RSK_SHUFFLE_TREES, RSK_SHUFFLE_FROG_SONG_RUPEES, RSK_ITEM_POOL, RSK_ICE_TRAPS, @@ -5859,7 +6441,7 @@ typedef enum { RSK_SHUFFLE_CHEST_MINIGAME, RSK_BIG_POE_COUNT, RSK_SKIP_EPONA_RACE, - RSK_COMPLETE_MASK_QUEST, + RSK_MASK_QUEST, RSK_SKIP_SCARECROWS_SONG, RSK_SKULLS_SUNS_SONG, RSK_SHUFFLE_ADULT_TRADE, @@ -5948,6 +6530,9 @@ typedef enum { RSK_SHUFFLE_FAIRIES, RSK_LOCK_OVERWORLD_DOORS, RSK_SHUFFLE_GRASS, + RSK_SHUFFLE_ROCKS, + RSK_SHUFFLE_BOULDERS, + RSK_SHUFFLE_NPC_SOULS, RSK_MAX } RandomizerSettingKey; @@ -6086,6 +6671,12 @@ typedef enum { RO_BOSS_SOULS_ON_PLUS_GANON, } RandoOptionBossSouls; +typedef enum { + RO_NPC_SOULS_OFF, + RO_NPC_SOULS_ON, + RO_NPC_SOULS_ON_PLUS_SAGES, +} RandoOptionNpcSouls; + // Fishsanity settings (off, loach only, pond only, grottos only, both) typedef enum { RO_FISHSANITY_OFF, @@ -6221,6 +6812,13 @@ typedef enum { RO_STARTING_OCARINA_TIME, } RandoOptionStartingOcarina; +// Mask Quest Settings (vanilla, completed, shuffle) +typedef enum { + RO_MASK_QUEST_VANILLA, + RO_MASK_QUEST_COMPLETED, + RO_MASK_QUEST_SHUFFLE, +} RandoOptionMaskQuest; + // Item Pool Settings typedef enum { RO_ITEM_POOL_PLENTIFUL, @@ -6311,6 +6909,14 @@ typedef enum { RO_SHUFFLE_CRATES_ALL, } RandoOptionShuffleCrates; +// Shuffle Boulder settings (off, dungeons, overworld, all) +typedef enum { + RO_SHUFFLE_BOULDERS_OFF, + RO_SHUFFLE_BOULDERS_DUNGEONS, + RO_SHUFFLE_BOULDERS_OVERWORLD, + RO_SHUFFLE_BOULDERS_ALL, +} RandoOptionShuffleBoulders; + // Link's Pocket Settings (dungeon reward, advancement, anything, nothing) typedef enum { RO_LINKS_POCKET_DUNGEON_REWARD, @@ -6426,6 +7032,16 @@ typedef struct SmallCrateIdentity { RandomizerCheck randomizerCheck; } SmallCrateIdentity; +typedef struct RockIdentity { + RandomizerInf randomizerInf; + RandomizerCheck randomizerCheck; +} RockIdentity; + +typedef struct TreeIdentity { + RandomizerInf randomizerInf; + RandomizerCheck randomizerCheck; +} TreeIdentity; + typedef enum { TRACKER_WINDOW_FLOATING, TRACKER_WINDOW_WINDOW, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index da05ee50816..f8a73ddd2e1 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -189,6 +189,10 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_SMALL_CRATE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_TREE || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTrees"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_NLTREE || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTrees"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_FISH || ctx->GetFishsanity()->GetFishLocationIncluded(&location, FSO_SOURCE_CVARS)) && (location.GetRCType() != RCTYPE_ADULT_TRADE || diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index d460c6daf63..6518eae5a68 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -68,6 +68,10 @@ bool showOverworldGrass; bool showDungeonGrass; bool showOverworldCrates; bool showDungeonCrates; +bool showRocks; +bool showOverworldBoulders; +bool showDungeonBoulders; +bool showTrees; bool showFrogSongRupees; bool showFairies; bool showStartingMapsCompasses; @@ -176,6 +180,7 @@ bool hideSeen = false; bool hideSkipped = false; bool hideSaved = false; bool hideCollected = false; +bool hideJunk = false; bool showHidden = true; bool mystery = false; bool showLogicTooltip = false; @@ -283,6 +288,9 @@ uint16_t GetTotalChecksGotten() { } bool IsCheckHidden(RandomizerCheck rc) { + if (showHidden) { + return false; + } Rando::ItemLocation* itemLocation = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); RandomizerCheckStatus status = itemLocation->GetCheckStatus(); bool available = itemLocation->IsAvailable(); @@ -291,9 +299,11 @@ bool IsCheckHidden(RandomizerCheck rc) { bool seen = status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED; bool scummed = status == RCSHOW_SCUMMED; bool unchecked = status == RCSHOW_UNCHECKED; + bool isJunk = itemLocation->GetPlacedItem().GetGIEntry()->getItemCategory == ITEM_CATEGORY_JUNK; + bool knownJunk = (seen || scummed) && isJunk; - return !showHidden && - ((skipped && hideSkipped) || (seen && hideSeen) || (scummed && hideScummed) || (unchecked && hideUnchecked)); + return (skipped && hideSkipped) || (seen && hideSeen) || (scummed && hideScummed) || (unchecked && hideUnchecked) || + (knownJunk && hideJunk); } void RecalculateAreaTotals(RandomizerCheckArea rcArea) { @@ -619,16 +629,46 @@ void CheckTrackerTransition(uint32_t sceneNum) { doAreaScroll = true; previousArea = currentArea; currentArea = GetCheckArea(); - switch (sceneNum) { - case SCENE_KOKIRI_SHOP: - case SCENE_BAZAAR: - case SCENE_POTION_SHOP_MARKET: - case SCENE_BOMBCHU_SHOP: - case SCENE_POTION_SHOP_KAKARIKO: - case SCENE_GORON_SHOP: - case SCENE_ZORA_SHOP: - SetShopSeen(sceneNum, false); - break; + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_NPC_SOULS) == RO_NPC_SOULS_OFF) { + SetShopSeen(sceneNum, false); + } else { + switch (sceneNum) { + case SCENE_KOKIRI_SHOP: + if (Flags_GetRandomizerInf(RAND_INF_KOKIRI_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_BAZAAR: + if (Flags_GetRandomizerInf(RAND_INF_BAZAAR_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_POTION_SHOP_MARKET: + if (Flags_GetRandomizerInf(RAND_INF_POTION_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_BOMBCHU_SHOP: + if (Flags_GetRandomizerInf(RAND_INF_BOMBCHU_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_POTION_SHOP_KAKARIKO: + if (Flags_GetRandomizerInf(RAND_INF_POTION_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_GORON_SHOP: + if (Flags_GetRandomizerInf(RAND_INF_GORON_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + case SCENE_ZORA_SHOP: + if (Flags_GetRandomizerInf(RAND_INF_ZORA_SHOPKEEPER_SOUL)) { + SetShopSeen(sceneNum, false); + } + break; + } } if (!IsAreaSpoiled(currentArea) && (RandomizerCheckObjects::AreaIsOverworld(currentArea) || std::find(spoilingEntrances.begin(), spoilingEntrances.end(), @@ -962,6 +1002,7 @@ void CheckTrackerWindow::DrawElement() { hideSkipped = CVarGetInteger(CVAR_TRACKER_CHECK("Skipped.Hide"), 0); hideSaved = CVarGetInteger(CVAR_TRACKER_CHECK("Saved.Hide"), 0); hideCollected = CVarGetInteger(CVAR_TRACKER_CHECK("Collected.Hide"), 0); + hideJunk = CVarGetInteger(CVAR_TRACKER_CHECK("Junk.Hide"), 0); showHidden = CVarGetInteger(CVAR_TRACKER_CHECK("ShowHidden"), 0); mystery = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0); showLogicTooltip = CVarGetInteger(CVAR_TRACKER_CHECK("ShowLogic"), 0); @@ -1238,7 +1279,14 @@ bool UpdateFilters() { } bool ShouldShowCheck(RandomizerCheck check) { - auto itemLoc = Rando::Context::GetInstance()->GetItemLocation(check); + Rando::ItemLocation* itemLoc = Rando::Context::GetInstance()->GetItemLocation(check); + RandomizerCheckStatus status = itemLoc->GetCheckStatus(); + + if (hideJunk && (status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED || status == RCSHOW_SCUMMED) && + itemLoc->GetPlacedItem().GetGIEntry()->getItemCategory == ITEM_CATEGORY_JUNK) { + return false; + } + std::string search = (Rando::StaticData::GetLocation(check)->GetShortName() + " " + Rando::StaticData::GetLocation(check)->GetName() + " " + RandomizerCheckObjects::GetRCAreaName(Rando::StaticData::GetLocation(check)->GetArea())); @@ -1448,6 +1496,29 @@ void LoadSettings() { showDungeonCrates = false; break; } + + showRocks = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ROCKS); + + switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOULDERS)) { + case RO_SHUFFLE_BOULDERS_ALL: + showOverworldBoulders = true; + showDungeonBoulders = true; + break; + case RO_SHUFFLE_BOULDERS_OVERWORLD: + showOverworldBoulders = true; + showDungeonBoulders = false; + break; + case RO_SHUFFLE_BOULDERS_DUNGEONS: + showOverworldBoulders = false; + showDungeonBoulders = true; + break; + default: + showOverworldBoulders = false; + showDungeonBoulders = false; + break; + } + + showTrees = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TREES); } else { // Vanilla showOverworldTokens = true; showDungeonTokens = true; @@ -1457,6 +1528,10 @@ void LoadSettings() { showDungeonGrass = false; showOverworldCrates = false; showDungeonCrates = false; + showRocks = false; + showOverworldBoulders = false; + showDungeonBoulders = false; + showTrees = false; } fortressFast = false; @@ -1526,16 +1601,13 @@ void LoadSettings() { bool IsCheckShuffled(RandomizerCheck rc) { Rando::Location* loc = Rando::StaticData::GetLocation(rc); - if (loc->GetRCType() == RCTYPE_SHOP) { - auto identity = OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1); - } if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) != RO_LOGIC_VANILLA) { return (loc->GetArea() != RCAREA_INVALID) && // don't show Invalid locations (loc->GetRCType() != RCTYPE_GOSSIP_STONE) && // TODO: Don't show hints until tracker supports them (loc->GetRCType() != RCTYPE_STATIC_HINT) && // TODO: Don't show hints until tracker supports them - (loc->GetRCType() != - RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we support shuffling them - (rc != RC_HC_ZELDAS_LETTER) && // don't show zeldas letter until we support shuffling it + (loc->GetRCType() != RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we + // support shuffling them + (rc != RC_HC_ZELDAS_LETTER) && // don't show zeldas letter until we support shuffling it (rc != RC_LINKS_POCKET || showLinksPocket) && OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) && (loc->GetRCType() != RCTYPE_SHOP || @@ -1562,6 +1634,10 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_CRATE || (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_TREE || showTrees) && + (loc->GetRCType() != RCTYPE_NLTREE || + (showTrees && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) && (loc->GetRCType() != RCTYPE_NLCRATE || (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea()) && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC) || @@ -1569,6 +1645,10 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_SMALL_CRATE || (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_ROCK || showRocks) && + (loc->GetRCType() != RCTYPE_BOULDER || + (showOverworldBoulders && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonBoulders && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && (loc->GetRCType() != RCTYPE_COW || showCows) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && @@ -1601,7 +1681,15 @@ bool IsCheckShuffled(RandomizerCheck rc) { } bool IsVisibleInCheckTracker(RandomizerCheck rc) { - auto loc = Rando::StaticData::GetLocation(rc); + Rando::Location* loc = Rando::StaticData::GetLocation(rc); + Rando::ItemLocation* itemLoc = Rando::Context::GetInstance()->GetItemLocation(rc); + RandomizerCheckStatus status = itemLoc->GetCheckStatus(); + + if (hideJunk && (status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED || status == RCSHOW_SCUMMED) && + itemLoc->GetPlacedItem().GetGIEntry()->getItemCategory == ITEM_CATEGORY_JUNK) { + return false; + } + if (IS_RANDO) { return IsCheckShuffled(rc) || (alwaysShowGS && loc->GetRCType() == RCTYPE_SKULL_TOKEN && @@ -1719,6 +1807,11 @@ void DrawLocation(RandomizerCheck rc) { return; } + if (!showHidden && hideJunk && (status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED || status == RCSHOW_SCUMMED) && + itemLoc->GetPlacedItem().GetGIEntry()->getItemCategory == ITEM_CATEGORY_JUNK) { + return; + } + if (status == RCSHOW_COLLECTED) { if (!showHidden && hideCollected) { return; @@ -2149,6 +2242,10 @@ void CheckTrackerSettingsWindow::DrawElement() { UIWidgets::CheckboxOptions() .Tooltip("If enabled, will show a check's logic when hovering over it.") .Color(THEME_COLOR)); + UIWidgets::CVarCheckbox("Hide Junk", CVAR_TRACKER_CHECK("Junk.Hide"), + UIWidgets::CheckboxOptions() + .Tooltip("If enabled, checks that are known to be junk will be hidden.") + .Color(THEME_COLOR)); ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); if (UIWidgets::CVarCheckbox("Enable Available Checks", CVAR_TRACKER_CHECK("EnableAvailableChecks"), UIWidgets::CheckboxOptions() diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 1a635f58e84..719758b03b9 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp @@ -739,7 +739,7 @@ void EntranceTrackerSettingsWindow::DrawElement() { ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); UIWidgets::CVarCheckbox( "Show Source", CVAR_TRACKER_ENTRANCE("ShowFrom"), - UIWidgets::CheckboxOptions().Tooltip("Reveal the sourcefor undiscovered entrances").Color(THEME_COLOR)); + UIWidgets::CheckboxOptions().Tooltip("Reveal the source for undiscovered entrances").Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Show Destination", CVAR_TRACKER_ENTRANCE("ShowTo"), UIWidgets::CheckboxOptions() .Tooltip("Reveal the destination for undiscovered entrances") @@ -836,7 +836,7 @@ void EntranceTrackerWindow::DrawElement() { ImGui::BeginChild("ChildEntranceTrackerLocations", ImVec2(0, -8)); bool showTo = CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowTo"), 0); bool showFrom = CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowFrom"), 0); - bool collapsUndiscovered = CVarGetInteger(CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), 0); + bool collapseUndiscovered = CVarGetInteger(CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), 0); bool highlightPrevious = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightPrevious"), 0); bool highlightAvailable = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightAvailable"), 0); bool hideReverse = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HideReverseEntrances"), 1); @@ -892,7 +892,7 @@ void EntranceTrackerWindow::DrawElement() { const char* rplcDstName = showOverride ? override->destination.c_str() : ""; // Filter for entrances by group name, type, source/destination names, and meta tags - if ((!locationSearch.IsActive() && (showOriginal || showOverride || !collapsUndiscovered)) || + if ((!locationSearch.IsActive() && (showOriginal || showOverride || !collapseUndiscovered)) || ((showOriginal && (locationSearch.PassFilter(origSrcName) || locationSearch.PassFilter(origSrcAreaName) || locationSearch.PassFilter(origTypeName) || locationSearch.PassFilter(original->metaTag.c_str()))) || diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index cf2f83d3ad5..231d6f2ba8b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -997,10 +997,75 @@ DEFINE_RAND_INF(RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3) DEFINE_RAND_INF(RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4) DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE) DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE) +DEFINE_RAND_INF(RAND_INF_MARKET_TREE) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_1) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_2) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_3) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_4) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_5) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_6) +DEFINE_RAND_INF(RAND_INF_HC_SKULLTULA_TREE) +DEFINE_RAND_INF(RAND_INF_HC_GROTTO_TREE) +DEFINE_RAND_INF(RAND_INF_HC_NL_TREE_1) +DEFINE_RAND_INF(RAND_INF_HC_NL_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_LLR_TREE) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_LH_TREE) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NEAR_GV_TREE) +DEFINE_RAND_INF(RAND_INF_HF_ADULT_NEAR_GV_TREE) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_ZR_TREE) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_KAK_TREE) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_KAK_SMALL_TREE) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_MARKET_TREE_1) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_MARKET_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_MARKET_TREE_3) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_1) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_3) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_4) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_5) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_6) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_1) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_3) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_4) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_5) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_6) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_1) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_3) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_4) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_5) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_6) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_7) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_8) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_9) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_10) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_11) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_12) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_13) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_14) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_15) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_16) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_17) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_18) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_19) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_1) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_3) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_4) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_5) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_6) +DEFINE_RAND_INF(RAND_INF_HF_TEKTITE_GROTTO_TREE) +DEFINE_RAND_INF(RAND_INF_ZF_TREE) +DEFINE_RAND_INF(RAND_INF_ZR_TREE) +DEFINE_RAND_INF(RAND_INF_KAK_TREE) +DEFINE_RAND_INF(RAND_INF_LLR_TREE) DEFINE_RAND_INF(RAND_INF_CAUGHT_LOACH) DEFINE_RAND_INF(RAND_INF_CAN_SWIM) +DEFINE_RAND_INF(RAND_INF_CAN_CLIMB) +DEFINE_RAND_INF(RAND_INF_CAN_CRAWL) DEFINE_RAND_INF(RAND_INF_HAS_WALLET) @@ -1951,4 +2016,333 @@ DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_6) DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7) DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8) // End Grass -DEFINE_RAND_INF(RAND_INF_OBTAINED_RUTOS_LETTER) \ No newline at end of file +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_SARIAS_HOUSE) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BEHIND_SARIAS_HOUSE) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_MIDOS_HOUSE) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE) +DEFINE_RAND_INF(RAND_INF_LW_BOULDER_BY_GORON_CITY) +DEFINE_RAND_INF(RAND_INF_LW_BOULDER_BY_SACRED_FOREST_MEADOW) +DEFINE_RAND_INF(RAND_INF_LW_RUPEE_BOULDER) +DEFINE_RAND_INF(RAND_INF_HC_ROCK_1) +DEFINE_RAND_INF(RAND_INF_HC_ROCK_2) +DEFINE_RAND_INF(RAND_INF_HC_ROCK_3) +DEFINE_RAND_INF(RAND_INF_HC_BOULDER) +DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_1) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_2) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_3) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_4) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_5) +DEFINE_RAND_INF(RAND_INF_DMC_GOSSIP_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMC_GOSSIP_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GV_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_1) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_2) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_3) +DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_1) +DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_2) +DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_3) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_1) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_2) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_3) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_4) +DEFINE_RAND_INF(RAND_INF_GV_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GV_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GV_BOULDER_ACROSS_BRIDGE) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6) +DEFINE_RAND_INF(RAND_INF_HF_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_1) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_2) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_3) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_4) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_5) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_6) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_7) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_8) +DEFINE_RAND_INF(RAND_INF_HF_BOULDER_NORTH) +DEFINE_RAND_INF(RAND_INF_HF_BOULDER_BY_MARKET) +DEFINE_RAND_INF(RAND_INF_HF_BOULDER_SOUTH) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_KAK_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_KAK_ROCK_1) +DEFINE_RAND_INF(RAND_INF_KAK_ROCK_2) +DEFINE_RAND_INF(RAND_INF_GY_ROCK) +DEFINE_RAND_INF(RAND_INF_LA_ROCK) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_ZF_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZF_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZF_UNDERGROUND_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_ZR_ROCK) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_3) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_5) +DEFINE_RAND_INF(RAND_INF_DMT_SUMMIT_ROCK) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMT_COW_BOULDER) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_11) +DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_11) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_12) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_13) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_14) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_15) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_16) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_17) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_18) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_19) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_20) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_21) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_22) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_23) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_24) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_25) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_26) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_27) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_28) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_29) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_ROCK) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_ROCK) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_1) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_2) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_3) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_4) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_5) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_6) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_7) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_8) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_1) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_2) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_3) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_4) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_5) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_6) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_7) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_8) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_1) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_2) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_3) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_4) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_5) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_6) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_7) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_8) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER) +DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_3) + +DEFINE_RAND_INF(RAND_INF_OBTAINED_RUTOS_LETTER) +DEFINE_RAND_INF(RAND_INF_ANJU_SOUL) // used by loop, must be first NPC soul +DEFINE_RAND_INF(RAND_INF_TALON_SOUL) +DEFINE_RAND_INF(RAND_INF_GROG_SOUL) +DEFINE_RAND_INF(RAND_INF_GRANNY_SOUL) +DEFINE_RAND_INF(RAND_INF_FADO_SOUL) +DEFINE_RAND_INF(RAND_INF_LINK_SOUL) +DEFINE_RAND_INF(RAND_INF_BIGGORON_SOUL) +DEFINE_RAND_INF(RAND_INF_HOT_RODDER_SOUL) +DEFINE_RAND_INF(RAND_INF_MEDIGORON_SOUL) +DEFINE_RAND_INF(RAND_INF_CARPENTER_BOSS_SOUL) +DEFINE_RAND_INF(RAND_INF_ICHIRO_SOUL) +DEFINE_RAND_INF(RAND_INF_SABOORO_SOUL) +DEFINE_RAND_INF(RAND_INF_JIRO_SOUL) +DEFINE_RAND_INF(RAND_INF_SHIRO_SOUL) +DEFINE_RAND_INF(RAND_INF_HW_GATEKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_GTG_GATEKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_ARCHER_SOUL) +DEFINE_RAND_INF(RAND_INF_GREAT_FAIRY_SOUL) +DEFINE_RAND_INF(RAND_INF_POE_COLLECTOR_SOUL) +DEFINE_RAND_INF(RAND_INF_DAMPE_SOUL) +DEFINE_RAND_INF(RAND_INF_WINDMILL_MAN_SOUL) +DEFINE_RAND_INF(RAND_INF_MAN_ON_ROOF_SOUL) +DEFINE_RAND_INF(RAND_INF_KAKARIKO_GATEKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_MALON_SOUL) +DEFINE_RAND_INF(RAND_INF_BEGGAR_SOUL) +DEFINE_RAND_INF(RAND_INF_DOG_LADY_SOUL) +DEFINE_RAND_INF(RAND_INF_ARMS_DEALER_SOUL) +DEFINE_RAND_INF(RAND_INF_BEAN_SALESMAN_SOUL) +DEFINE_RAND_INF(RAND_INF_SHOOTING_SOUL) +DEFINE_RAND_INF(RAND_INF_KOKIRI_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_POTION_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_BAZAAR_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_GORON_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_ZORA_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_BOMBCHU_SHOPKEEPER_SOUL) +DEFINE_RAND_INF(RAND_INF_MASK_SALESMAN_SOUL) +DEFINE_RAND_INF(RAND_INF_BOMBCHU_LADY_SOUL) +DEFINE_RAND_INF(RAND_INF_TREASURE_MAN_SOUL) +DEFINE_RAND_INF(RAND_INF_DIVING_SOUL) +DEFINE_RAND_INF(RAND_INF_SCIENTIST_SOUL) +DEFINE_RAND_INF(RAND_INF_KAEPORA_SOUL) +DEFINE_RAND_INF(RAND_INF_RAURU_SOUL) +DEFINE_RAND_INF(RAND_INF_SARIA_SOUL) +DEFINE_RAND_INF(RAND_INF_DARUNIA_SOUL) +DEFINE_RAND_INF(RAND_INF_RUTO_SOUL) +DEFINE_RAND_INF(RAND_INF_NABOORU_SOUL) +DEFINE_RAND_INF(RAND_INF_IMPA_SOUL) +DEFINE_RAND_INF(RAND_INF_ZELDA_SOUL) // used by loop, must be last NPC soul diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 05a10a2b351..8b3bfdb917b 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -258,6 +258,14 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetRandomizerInf(RAND_INF_CAN_SWIM); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CLIMB) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_CLIMB); + } + + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CRAWL) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_CRAWL); + } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_WALLET) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); } @@ -413,7 +421,7 @@ extern "C" void Randomizer_InitSaveFile() { } // complete mask quest - if (Randomizer_GetSettingValue(RSK_COMPLETE_MASK_QUEST)) { + if (Randomizer_GetSettingValue(RSK_MASK_QUEST) == RO_MASK_QUEST_COMPLETED) { Flags_SetInfTable(INFTABLE_GATE_GUARD_PUT_ON_KEATON_MASK); Flags_SetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE); diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 52add036e94..e3c6f97971f 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -211,11 +211,16 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_OCARINA, "Shuffle Ocarinas", CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), mOptionDescriptions[RSK_SHUFFLE_OCARINA]); OPT_BOOL(RSK_SHUFFLE_OCARINA_BUTTONS, "Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]); OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]); + OPT_BOOL(RSK_SHUFFLE_CLIMB, "Shuffle Climb", CVAR_RANDOMIZER_SETTING("ShuffleClimb"), mOptionDescriptions[RSK_SHUFFLE_CLIMB]); + OPT_BOOL(RSK_SHUFFLE_CRAWL, "Shuffle Crawl", CVAR_RANDOMIZER_SETTING("ShuffleCrawl"), mOptionDescriptions[RSK_SHUFFLE_CRAWL]); OPT_BOOL(RSK_SHUFFLE_WEIRD_EGG, "Shuffle Weird Egg", CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG]); OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, "Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]); OPT_U8(RSK_SHUFFLE_POTS, "Shuffle Pots", {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), mOptionDescriptions[RSK_SHUFFLE_POTS], WidgetType::Combobox, RO_SHUFFLE_POTS_OFF); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); + OPT_BOOL(RSK_SHUFFLE_ROCKS, "Shuffle Rocks", CVAR_RANDOMIZER_SETTING("ShuffleRocks"), mOptionDescriptions[RSK_SHUFFLE_ROCKS]); + OPT_U8(RSK_SHUFFLE_BOULDERS, "Shuffle Boulders", {"Off", "Dungeons", "Overworld", "All Boulders"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBoulders"), mOptionDescriptions[RSK_SHUFFLE_BOULDERS], WidgetType::Combobox, RO_SHUFFLE_BOULDERS_OFF); + OPT_BOOL(RSK_SHUFFLE_TREES, "Shuffle Trees", CVAR_RANDOMIZER_SETTING("ShuffleTrees"), mOptionDescriptions[RSK_SHUFFLE_TREES]); OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, "Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]); OPT_U8(RSK_SHUFFLE_MERCHANTS, "Shuffle Merchants", {"Off", "Bean Merchant Only", "All But Beans", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), mOptionDescriptions[RSK_SHUFFLE_MERCHANTS], WidgetType::Combobox, RO_SHUFFLE_MERCHANTS_OFF, IMFLAG_NONE); OPT_U8(RSK_MERCHANT_PRICES, "Merchant Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPrices"), mOptionDescriptions[RSK_MERCHANT_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); @@ -233,6 +238,7 @@ void Settings::CreateOptions() { OPT_U8(RSK_SHUFFLE_CHEST_MINIGAME, "Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}); OPT_BOOL(RSK_SHUFFLE_100_GS_REWARD, "Shuffle 100 GS Reward", CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), mOptionDescriptions[RSK_SHUFFLE_100_GS_REWARD], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); OPT_U8(RSK_SHUFFLE_BOSS_SOULS, "Shuffle Boss Souls", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WidgetType::Combobox); + OPT_U8(RSK_SHUFFLE_NPC_SOULS, "Shuffle NPC Souls", {"Off", "On", "On + Sages"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleNpcSouls"), mOptionDescriptions[RSK_SHUFFLE_NPC_SOULS], WidgetType::Combobox); OPT_BOOL(RSK_SHUFFLE_DEKU_STICK_BAG, "Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); OPT_BOOL(RSK_SHUFFLE_DEKU_NUT_BAG, "Shuffle Deku Nut Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); OPT_U8(RSK_SHUFFLE_FREESTANDING, "Shuffle Freestanding Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), mOptionDescriptions[RSK_SHUFFLE_FREESTANDING], WidgetType::Combobox, RO_SHUFFLE_FREESTANDING_OFF); @@ -269,7 +275,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SKIP_EPONA_RACE, "Skip Epona Race", {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipEponaRace"), mOptionDescriptions[RSK_SKIP_EPONA_RACE], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); OPT_BOOL(RSK_SKIP_SCARECROWS_SONG, "Skip Scarecrow's Song", CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG]); OPT_U8(RSK_BIG_POE_COUNT, "Big Poe Target Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), mOptionDescriptions[RSK_BIG_POE_COUNT], WidgetType::Slider, 10); - OPT_BOOL(RSK_COMPLETE_MASK_QUEST, "Complete Mask Quest", CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), mOptionDescriptions[RSK_COMPLETE_MASK_QUEST]); + OPT_U8(RSK_MASK_QUEST, "Mask Quest", {"Vanilla", "Completed", "Shuffle"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), mOptionDescriptions[RSK_MASK_QUEST], WidgetType::Combobox, 0); OPT_U8(RSK_GOSSIP_STONE_HINTS, "Gossip Stone Hints", {"No Hints", "Need Nothing", "Mask of Truth", "Stone of Agony"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GossipStoneHints"), mOptionDescriptions[RSK_GOSSIP_STONE_HINTS], WidgetType::Combobox, RO_GOSSIP_STONES_NEED_NOTHING, false, IMFLAG_NONE); OPT_U8(RSK_HINT_CLARITY, "Hint Clarity", {"Obscure", "Ambiguous", "Clear"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("HintClarity"), mOptionDescriptions[RSK_HINT_CLARITY], WidgetType::Combobox, RO_HINT_CLARITY_CLEAR, true, IMFLAG_INDENT); OPT_U8(RSK_HINT_DISTRIBUTION, "Hint Distribution", {"Useless", "Balanced", "Strong", "Very Strong"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("HintDistribution"), mOptionDescriptions[RSK_HINT_DISTRIBUTION], WidgetType::Combobox, RO_HINT_DIST_BALANCED, true, IMFLAG_UNINDENT); @@ -1236,12 +1242,15 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_CLIMB], + &mOptions[RSK_SHUFFLE_CRAWL], &mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], &mOptions[RSK_SHUFFLE_FISHING_POLE], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_FREESTANDING], + &mOptions[RSK_MASK_QUEST], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = @@ -1277,6 +1286,9 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_ROCKS], + &mOptions[RSK_SHUFFLE_BOULDERS], + &mOptions[RSK_SHUFFLE_TREES], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_MERCHANT_PRICES], &mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE], @@ -1292,6 +1304,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BOSS_SOULS], + &mOptions[RSK_SHUFFLE_NPC_SOULS], &mOptions[RSK_SHUFFLE_FAIRIES], &mOptions[RSK_SHUFFLE_GRASS], }, @@ -1331,11 +1344,11 @@ void Settings::CreateOptions() { &mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI], }, WidgetContainerType::TABLE); - mOptionGroups[RSG_TIMESAVERS_IMGUI] = OptionGroup::SubGroup( - "Timesavers", - { &mOptions[RSK_BIG_POE_COUNT], &mOptions[RSK_SKIP_CHILD_ZELDA], &mOptions[RSK_SKIP_EPONA_RACE], - &mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG] }, - WidgetContainerType::COLUMN); + mOptionGroups[RSG_TIMESAVERS_IMGUI] = + OptionGroup::SubGroup("Timesavers", + { &mOptions[RSK_BIG_POE_COUNT], &mOptions[RSK_SKIP_CHILD_ZELDA], + &mOptions[RSK_SKIP_EPONA_RACE], &mOptions[RSK_SKIP_SCARECROWS_SONG] }, + WidgetContainerType::COLUMN); mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI] = OptionGroup::SubGroup("", { &mOptions[RSK_ITEM_POOL], @@ -1509,10 +1522,13 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_TREES], &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_CLIMB], + &mOptions[RSK_SHUFFLE_CRAWL], &mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], &mOptions[RSK_SHUFFLE_MERCHANTS], @@ -1531,6 +1547,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_CHEST_MINIGAME], &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BOSS_SOULS], + &mOptions[RSK_SHUFFLE_NPC_SOULS], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_FREESTANDING], @@ -1599,7 +1616,6 @@ void Settings::CreateOptions() { &mOptions[RSK_SKIP_EPONA_RACE], &mOptions[RSK_SKIP_SCARECROWS_SONG], &mOptions[RSK_BIG_POE_COUNT], - &mOptions[RSK_COMPLETE_MASK_QUEST], }); mOptionGroups[RSG_MISC] = OptionGroup("Miscellaneous Settings", { diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index 7bdec17c117..7a3757a13ed 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -58,6 +58,8 @@ class StaticData { static void RegisterFreestandingLocations(); static void RegisterGrassLocations(); static void RegisterCrateLocations(); + static void RegisterRockLocations(); + static void RegisterTreeLocations(); static void InitHashMaps(); static std::array, 17> randomizerFishingPondFish; static std::unordered_map randomizerGrottoFishMap; diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index dd8185c1d05..8d1f9cd6909 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -463,9 +463,12 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL); Flags_SetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER); Flags_SetEventChkInf(EVENTCHKINF_SHEIK_SPAWNED_AT_MASTER_SWORD_PEDESTAL); - Flags_SetEventChkInf(EVENTCHKINF_TIME_TRAVELED_TO_ADULT); - if (GameInteractor_Should(VB_GIVE_ITEM_LIGHT_MEDALLION, true)) { - Item_Give(gPlayState, ITEM_MEDALLION_LIGHT); + if (!IS_RANDO || !RAND_GET_OPTION(RSK_SHUFFLE_NPC_SOULS) || + Flags_GetRandomizerInf(RAND_INF_RAURU_SOUL)) { + Flags_SetEventChkInf(EVENTCHKINF_TIME_TRAVELED_TO_ADULT); + if (GameInteractor_Should(VB_GIVE_ITEM_LIGHT_MEDALLION, true)) { + Item_Give(gPlayState, ITEM_MEDALLION_LIGHT); + } } } *should = false; diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index d6342255121..498eb7acc78 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -26,6 +26,8 @@ #include "Enhancements/audio/AudioCollection.h" #include "Enhancements/enhancementTypes.h" #include "Enhancements/debugconsole.h" +#include "Enhancements/randomizer/entrance.h" +#include "Enhancements/randomizer/location_access.h" #include "Enhancements/randomizer/randomizer.h" #include "Enhancements/randomizer/randomizer_entrance_tracker.h" #include "Enhancements/randomizer/randomizer_item_tracker.h" @@ -261,10 +263,6 @@ const char* constCameraStrings[] = { }; OTRGlobals::OTRGlobals() { - context = Ship::Context::CreateUninitializedInstance("Ship of Harkinian", appShortName, "shipofharkinian.json"); -} - -void OTRGlobals::Initialize() { std::vector OTRFiles; std::string mqPath = Ship::Context::LocateFileAcrossAppDirs("oot-mq.o2r", appShortName); if (std::filesystem::exists(mqPath)) { @@ -306,6 +304,8 @@ void OTRGlobals::Initialize() { OOT_NTSC_JP_GC, OOT_NTSC_US_GC, OOT_PAL_GC, OOT_PAL_GC_DBG1, OOT_PAL_GC_DBG2, }; + context = Ship::Context::CreateUninitializedInstance("Ship of Harkinian", appShortName, "shipofharkinian.json"); + context->InitLogging(); context->InitGfxDebugger(); context->InitConfiguration(); @@ -1104,7 +1104,7 @@ void CheckAndCreateModFolder() { } extern "C" void InitOTR() { - OTRGlobals::Instance = new OTRGlobals(); + #ifdef __SWITCH__ Ship::Switch::Init(Ship::PreInitPhase); #elif defined(__WIIU__) @@ -1211,7 +1211,7 @@ extern "C" void InitOTR() { DetectOTRVersion("oot.o2r", false); DetectOTRVersion("oot-mq.o2r", true); - OTRGlobals::Instance->Initialize(); + OTRGlobals::Instance = new OTRGlobals(); CustomMessageManager::Instance = new CustomMessageManager(); ItemTableManager::Instance = new ItemTableManager(); GameInteractor::Instance = new GameInteractor(); @@ -2224,6 +2224,137 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { s16 actorParams = 0; if (IS_RANDO) { auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) { + s16 entrance = -1; + switch (textId) { + case TEXT_WATERFALL: + entrance = ENTR_ZORAS_DOMAIN_ENTRANCE; + break; + case TEXT_OUTSIDE_FISHING_POND: + entrance = ENTR_FISHING_POND_0; + break; + case TEXT_HF_SIGN: + if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE) { + entrance = ENTR_HYRULE_FIELD_STAIRS_EXIT; + } else if (gPlayState->sceneNum == SCENE_GERUDO_VALLEY) { + entrance = ENTR_HYRULE_FIELD_ROCKY_PATH; + } else if (gPlayState->sceneNum == SCENE_LAKE_HYLIA) { + entrance = ENTR_HYRULE_FIELD_FENCE_EXIT; + } + break; + case TEXT_HC_GF: + entrance = ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC; + break; + case TEXT_KAK_SIGN: + if (gPlayState->sceneNum == SCENE_HYRULE_FIELD) { + entrance = ENTR_KAKARIKO_VILLAGE_FRONT_GATE; + } else { + entrance = ENTR_KAKARIKO_VILLAGE_GUARD_GATE; + } + break; + case TEXT_KAK_GY: + entrance = ENTR_GRAVEYARD_ENTRANCE; + break; + case TEXT_KAK_WELL: + entrance = ENTR_BOTTOM_OF_THE_WELL_ENTRANCE; + break; + case TEXT_KAK_DMT: + entrance = ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT; + break; + case TEXT_DMT_DC: + entrance = ENTR_DEATH_MOUNTAIN_TRAIL_OUTSIDE_DODONGOS_CAVERN; + break; + case TEXT_GC_SIGN: + if (gPlayState->sceneNum == SCENE_DEATH_MOUNTAIN_TRAIL) { + entrance = ENTR_GORON_CITY_UPPER_EXIT; + } else { + entrance = ENTR_GORON_CITY_DARUNIA_ROOM_EXIT; + } + break; + case TEXT_HF_ZR: + entrance = ENTR_ZORAS_RIVER_WEST_EXIT; + break; + case TEXT_KF_SHOP_SIGN: + entrance = ENTR_KOKIRI_SHOP_0; + break; + case TEXT_LINKS_HOUSE_SIGN: + entrance = ENTR_LINKS_HOUSE_1; + break; + case TEXT_KOKIRI_EXIT_SIGN: + entrance = ENTR_LOST_WOODS_BRIDGE_WEST_EXIT; + break; + case TEXT_ZD_SIGN: + if (gPlayState->sceneNum == SCENE_ZORAS_DOMAIN) { + entrance = ENTR_ZORAS_RIVER_WATERFALL_EXIT; + } else { + entrance = ENTR_ZORAS_DOMAIN_KING_ZORA_EXIT; + } + break; + case TEXT_ZF_JABU_SIGN: + entrance = ENTR_JABU_JABU_ENTRANCE; + break; + case TEXT_KF_LW: + entrance = ENTR_LOST_WOODS_SOUTH_EXIT; + break; + case TEXT_HF_LON_LON: + entrance = ENTR_LON_LON_RANCH_ENTRANCE; + break; + case TEXT_LA_SIGN: + entrance = ENTR_LAKE_HYLIA_NORTH_EXIT; + break; + case TEXT_LA_LAB: + entrance = ENTR_LAKESIDE_LABORATORY_0; + break; + case TEXT_GV_SIGN: + if (gPlayState->sceneNum == SCENE_HYRULE_FIELD) { + entrance = ENTR_GERUDO_VALLEY_EAST_EXIT; + } else { + entrance = ENTR_GERUDO_VALLEY_WEST_EXIT; + } + break; + case TEXT_ZD_SHOP_SIGN: + entrance = ENTR_ZORA_SHOP_0; + break; + case TEXT_OUTSIDE_KOKIRI_SIGN: + entrance = ENTR_MARKET_ENTRANCE_OUTSIDE_GUARD_HOUSE; + break; + case TEXT_OUTSIDE_MARKET_SIGN: + entrance = ENTR_LON_LON_RANCH_ENTRANCE; + break; + case TEXT_MIDO_HOUSE_SIGN: + entrance = ENTR_MIDOS_HOUSE_0; + break; + case TEXT_KNOW_IT_ALL_HOUSE: + entrance = ENTR_KNOW_IT_ALL_BROS_HOUSE_0; + break; + case TEXT_TWINS_HOUSE_SIGN: + entrance = ENTR_TWINS_HOUSE_0; + break; + case TEXT_SARIAS_HOUSE_SIGN: + entrance = ENTR_SARIAS_HOUSE_0; + break; + case TEXT_NO_DIVING_SIGN: + entrance = ENTR_LAKE_HYLIA_RIVER_EXIT; + break; + } + if (entrance != -1) { + auto entranceCtx = ctx->GetEntranceShuffler(); + for (size_t i = 0; i < ENTRANCE_OVERRIDES_MAX_COUNT; i++) { + if (Entrance_EntranceIsNull(&entranceCtx->entranceOverrides[i])) { + break; + } + if (entranceCtx->entranceOverrides[i].index == entrance) { + s16 overrideIndex = entranceCtx->entranceOverrides[i].override; + Entrance_SetEntranceDiscovered(entrance, false); + auto data = GetEntranceData(overrideIndex); + font->charTexBuf[0] = (TEXTBOX_TYPE_WOODEN << 4) | TEXTBOX_POS_BOTTOM; + return msgCtx->msgLength = font->msgLength = SohUtils::CopyStringToCharBuffer( + buffer, data->source + CustomMessage::MESSAGE_END(), maxBufferSize); + } + } + } + } + bool nonBeanMerchants = ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL); Player* player = GET_PLAYER(play); @@ -2299,7 +2430,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { } else { messageEntry = ctx->GetHint(stoneHint)->GetHintMessage(MF_AUTO_FORMAT); } - } else if ((textId == TEXT_ALTAR_CHILD || textId == TEXT_ALTAR_ADULT)) { + } else if (textId == TEXT_ALTAR_CHILD || textId == TEXT_ALTAR_ADULT) { // rando hints at altar messageEntry = (LINK_IS_ADULT) ? ctx->GetHint(RH_ALTAR_ADULT)->GetHintMessage() : ctx->GetHint(RH_ALTAR_CHILD)->GetHintMessage(MF_AUTO_FORMAT); diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 9e7815523c5..3e6f1a34d35 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -71,7 +71,7 @@ class OTRGlobals { ~OTRGlobals(); void ScaleImGui(); - void Initialize(); + bool HasMasterQuest(); bool HasOriginal(); uint32_t GetInterpolationFPS(); diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index fc63f96c8a5..6c357c612fb 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -2782,7 +2782,6 @@ void Message_OpenText(PlayState* play, u16 textId) { gSaveContext.eventInf[0] = gSaveContext.eventInf[1] = gSaveContext.eventInf[2] = gSaveContext.eventInf[3] = 0; } - // RANDOTODO: Use this for ice trap messages if (CustomMessage_RetrieveIfExists(play)) { osSyncPrintf("Found custom message"); if (gSaveContext.language == LANGUAGE_JPN) { diff --git a/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c b/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c index a3a46ed36f3..9ae66bbe394 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c @@ -8,6 +8,7 @@ #include "objects/object_spot00_objects/object_spot00_objects.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED @@ -214,9 +215,11 @@ void BgSpot00Hanebasi_Update(Actor* thisx, PlayState* play) { if (this->dyna.actor.params == DT_DRAWBRIDGE) { if (play->sceneNum == SCENE_HYRULE_FIELD) { - if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY) && - CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) && !Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE) && - LINK_IS_CHILD) { + if (GameInteractor_Should(VB_BE_ELIGIBLE_FOR_OCARINA_OF_TIME, + CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY) && + CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) && + !Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE) && + LINK_IS_CHILD)) { Player* player = GET_PLAYER(play); if ((player->actor.world.pos.x > -450.0f) && (player->actor.world.pos.x < 450.0f) && diff --git a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c index 37dc1fa9db7..fccc1a0d222 100644 --- a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -8,6 +8,7 @@ #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "vt.h" @@ -251,6 +252,10 @@ void EnIshi_SpawnDustLarge(EnIshi* this, PlayState* play) { void EnIshi_DropCollectible(EnIshi* this, PlayState* play) { s16 dropParams; + if (!GameInteractor_Should(VB_ROCK_DROP_ITEM, true, this)) { + return; + } + if ((this->actor.params & 1) == ROCK_SMALL) { dropParams = (this->actor.params >> 8) & 0xF; diff --git a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h index 254ea0987b9..e52ca095460 100644 --- a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h +++ b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h @@ -19,6 +19,7 @@ typedef struct EnIshi { /* 0x0000 */ Actor actor; /* 0x014C */ EnIshiActionFunc actionFunc; /* 0x0150 */ ColliderCylinder collider; + /* */ RockIdentity rockIdentity; } EnIshi; // size = 0x019C #endif diff --git a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c index 2fe2445a6f5..4e0f540d9c5 100644 --- a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c +++ b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c @@ -357,16 +357,18 @@ void EnWood02_Update(Actor* thisx, PlayState* play2) { dropsSpawnPt = this->actor.world.pos; dropsSpawnPt.y += 200.0f; - if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) { - if (GameInteractor_Should(VB_TREE_DROP_COLLECTIBLE, true, this)) { - Item_DropCollectibleRandom(play, &this->actor, &dropsSpawnPt, this->unk_14C << 4); + if (GameInteractor_Should(VB_TREE_DROP_ITEM, true, this)) { + if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) { + if (GameInteractor_Should(VB_TREE_DROP_COLLECTIBLE, true, this)) { + Item_DropCollectibleRandom(play, &this->actor, &dropsSpawnPt, this->unk_14C << 4); + } + } else if (this->actor.home.rot.z != 0) { + this->actor.home.rot.z &= 0x1FFF; + this->actor.home.rot.z |= 0xE000; + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y, dropsSpawnPt.z, 0, + this->actor.world.rot.y, 0, this->actor.home.rot.z, true); + this->actor.home.rot.z = 0; } - } else if (this->actor.home.rot.z != 0) { - this->actor.home.rot.z &= 0x1FFF; - this->actor.home.rot.z |= 0xE000; - Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y, dropsSpawnPt.z, 0, - this->actor.world.rot.y, 0, this->actor.home.rot.z, true); - this->actor.home.rot.z = 0; } // Spawn falling leaves @@ -458,11 +460,13 @@ void EnWood02_Draw(Actor* thisx, PlayState* play) { Gfx_SetupDL_25Xlu(gfxCtx); - if ((this->actor.params == WOOD_LEAF_GREEN) || (this->actor.params == WOOD_LEAF_YELLOW)) { + if (GameInteractor_Should(VB_TREE_SETUP_DRAW, + (this->actor.params == WOOD_LEAF_GREEN) || (this->actor.params == WOOD_LEAF_YELLOW), + this)) { Gfx_SetupDL_25Opa(gfxCtx); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, 127); Gfx_DrawDListOpa(play, object_wood02_DL_000700); - } else if (D_80B3BF70[this->drawType & 0xF] != NULL) { + } else if (GameInteractor_Should(VB_TREE_SETUP_DRAW, D_80B3BF70[this->drawType & 0xF] != NULL, this)) { Gfx_DrawDListOpa(play, D_80B3BF54[this->drawType & 0xF]); gDPSetEnvColor(POLY_XLU_DISP++, red, green, blue, 0); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h index 96746c0afc5..6cc2cdae1da 100644 --- a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h +++ b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h @@ -13,6 +13,7 @@ typedef struct EnWood02 { /* 0x0153 */ u8 spawnType; /* 0x0154 */ u8 drawType; /* 0x0158 */ ColliderCylinder collider; + /* */ TreeIdentity treeId; } EnWood02; // size = 0x01A4 // Types with SPAWNED in the name are those that can be managed by a spawner, however the actor allows you to spawn them diff --git a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c index 602236816e0..019a09320c1 100644 --- a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c +++ b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c @@ -7,6 +7,7 @@ #include "z_obj_bombiwa.h" #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/object_bombiwa/object_bombiwa.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -75,7 +76,7 @@ void ObjBombiwa_InitCollision(Actor* thisx, PlayState* play) { void ObjBombiwa_Init(Actor* thisx, PlayState* play) { Actor_ProcessInitChain(thisx, sInitChain); ObjBombiwa_InitCollision(thisx, play); - if ((Flags_GetSwitch(play, thisx->params & 0x3F) != 0)) { + if (GameInteractor_Should(VB_BOULDER_BREAK_FLAG, Flags_GetSwitch(play, thisx->params & 0x3F), thisx)) { Actor_Kill(thisx); } else { CollisionCheck_SetInfo(&thisx->colChkInfo, NULL, &sColChkInfoInit); diff --git a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h index d6208298888..d5af33cfb0d 100644 --- a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h +++ b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h @@ -9,6 +9,7 @@ struct ObjBombiwa; typedef struct ObjBombiwa { /* 0x0000 */ Actor actor; /* 0x014C */ ColliderCylinder collider; + /* */ RockIdentity rockIdentity; } ObjBombiwa; // size = 0x0198 #endif diff --git a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c index d4d952cc0bc..c609992d72b 100644 --- a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c +++ b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c @@ -6,6 +6,7 @@ #include "z_obj_hamishi.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -150,7 +151,7 @@ void ObjHamishi_Init(Actor* thisx, PlayState* play) { ObjHamishi_InitCollision(&this->actor, play); CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); - if (Flags_GetSwitch(play, this->actor.params & 0x3F)) { + if (GameInteractor_Should(VB_BOULDER_BREAK_FLAG, Flags_GetSwitch(play, this->actor.params & 0x3F), this)) { Actor_Kill(&this->actor); return; } diff --git a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h index 13e5b1483e6..5201eeaccdf 100644 --- a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h +++ b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h @@ -15,6 +15,7 @@ typedef struct ObjHamishi { /* 0x01A2 */ s16 shakePosPhase; /* 0x01A4 */ s16 shakeRotPhase; /* 0x01A6 */ s16 hitCount; + /* */ RockIdentity rockIdentity; } ObjHamishi; // size = 0x01A8 #endif diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 4ae6fb7448f..58fdd737c48 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -7635,6 +7635,10 @@ s32 Player_TryEnteringCrawlspace(Player* this, PlayState* play, u32 interactWall s32 i; if (!LINK_IS_ADULT && !(this->stateFlags1 & PLAYER_STATE1_IN_WATER) && (interactWallFlags & 0x30)) { + if (!GameInteractor_Should(VB_CRAWL, true)) { + return false; + } + wallPoly = this->actor.wallPoly; CollisionPoly_GetVerticesByBgId(wallPoly, this->actor.wallBgId, &play->colCtx, wallVertices); @@ -13376,6 +13380,13 @@ void Player_Action_8084BF1C(Player* this, PlayState* play) { this->fallStartHeight = this->actor.world.pos.y; this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS; + if (!GameInteractor_Should(VB_CLIMB, true)) { + sp80 = 0; + if (sp84 > 0) { + sp84 = 0; + } + } + if ((this->av1.actionVar1 != 0) && (ABS(sp84) < ABS(sp80))) { phi_f0 = ABS(sp80) * 0.0325f; sp84 = 0;