summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Dubé <159546+serprex@users.noreply.github.com>2026-07-23 23:35:41 +0000
committerGitHub <noreply@github.com>2026-07-23 23:35:41 +0000
commitda4e6dc3321bda48a313b162261156580bc376f4 (patch)
tree0ced64e72909cd21e26e246a3eda252fe4fe1212
parentcca66cdc5de2b0247ca2474080c2c760e8cb785a (diff)
Progressive Shuffle Open Chest (#6971)
-rw-r--r--soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h2
-rw-r--r--soh/soh/Enhancements/kaleido.cpp5
-rw-r--r--soh/soh/Enhancements/randomizer/3drando/item_pool.cpp4
-rw-r--r--soh/soh/Enhancements/randomizer/Messages/ItemMessages.cpp14
-rw-r--r--soh/soh/Enhancements/randomizer/hook_handlers.cpp9
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp12
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp12
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp12
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp16
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp16
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp6
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp4
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp12
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp12
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp16
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp22
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp18
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp2
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp4
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp2
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp22
-rw-r--r--soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp2
-rw-r--r--soh/soh/Enhancements/randomizer/logic.cpp17
-rw-r--r--soh/soh/Enhancements/randomizer/logic.h1
-rw-r--r--soh/soh/Enhancements/randomizer/option_descriptions.cpp5
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer.cpp12
-rw-r--r--soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h2
-rw-r--r--soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h7
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp27
-rw-r--r--soh/soh/Enhancements/randomizer/savefile.cpp3
-rw-r--r--soh/soh/Enhancements/randomizer/settings.cpp2
-rw-r--r--soh/src/overlays/actors/ovl_player_actor/z_player.c2
32 files changed, 196 insertions, 106 deletions
diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
index dad1e863b..9d2c1fed1 100644
--- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
+++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
@@ -1688,7 +1688,7 @@ typedef enum {
// this->getItemId != GI_NONE
// ```
// #### `args`
- // - `None`
+ // - `*EnBox`
VB_OPEN_CHEST,
// #### `result`
diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp
index 3c8e6b73d..9e9763c38 100644
--- a/soh/soh/Enhancements/kaleido.cpp
+++ b/soh/soh/Enhancements/kaleido.cpp
@@ -215,6 +215,11 @@ Kaleido::Kaleido() {
mEntries.push_back(std::make_shared<KaleidoEntryIconFlag>(
gMapChestIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 8, Color_RGBA8{ 255, 255, 255, 255 },
FlagType::FLAG_RANDOMIZER_INF, RAND_INF_CAN_OPEN_CHEST, "Open Chests"));
+ if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST).Is(RO_OPEN_CHEST_PROGRESSIVE)) {
+ mEntries.push_back(std::make_shared<KaleidoEntryIconFlag>(
+ gMapChestIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 8, Color_RGBA8{ 255, 255, 255, 255 },
+ FlagType::FLAG_RANDOMIZER_INF, RAND_INF_CAN_OPEN_LARGE_CHEST, "Open Large Chests"));
+ }
}
if (ctx->GetOption(RSK_SHUFFLE_SWIM)) {
mEntries.push_back(std::make_shared<KaleidoEntryIconFlag>(
diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp
index ff4d3beeb..1b01143b5 100644
--- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp
+++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp
@@ -436,7 +436,9 @@ void GenerateItemPool() {
if (ctx->GetOption(RSK_SHUFFLE_CRAWL)) {
AddItemToPool(RG_CRAWL, 2, 1, 1, 1);
}
- if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST)) {
+ if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST).Is(RO_OPEN_CHEST_PROGRESSIVE)) {
+ AddItemToPool(RG_OPEN_CHEST, 3, 2, 2, 2);
+ } else if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST)) {
AddItemToPool(RG_OPEN_CHEST, 2, 1, 1, 1);
}
diff --git a/soh/soh/Enhancements/randomizer/Messages/ItemMessages.cpp b/soh/soh/Enhancements/randomizer/Messages/ItemMessages.cpp
index 3624448e8..c48184dac 100644
--- a/soh/soh/Enhancements/randomizer/Messages/ItemMessages.cpp
+++ b/soh/soh/Enhancements/randomizer/Messages/ItemMessages.cpp
@@ -18,8 +18,9 @@
#include <algorithm>
extern "C" {
-#include <variables.h>
-#include <macros.h>
+#include "variables.h"
+#include "macros.h"
+#include "functions.h"
#include "z64item.h"
extern PlayState* gPlayState;
}
@@ -145,6 +146,15 @@ void BuildCustomItemMessage(Player* player, CustomMessage& msg) {
}
CustomMessage name =
CustomMessage(Rando::StaticData::RetrieveItem(static_cast<RandomizerGet>(rgid)).GetName(), TEXTBOX_TYPE_BLUE);
+ if (rgid == RG_OPEN_CHEST &&
+ OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_OPEN_CHEST).Is(RO_OPEN_CHEST_PROGRESSIVE)) {
+ // message is built before the item is given, so the flags still say which copy this is
+ name = Flags_GetRandomizerInf(RAND_INF_CAN_OPEN_CHEST)
+ ? CustomMessage("Open Big Chests", "Große Truhen öffnen", "Ouvrir les grands coffres",
+ TEXTBOX_TYPE_BLUE)
+ : CustomMessage("Open Small Chests", "Kleine Truhen öffnen", "Ouvrir les petits coffres",
+ TEXTBOX_TYPE_BLUE);
+ }
CustomMessage article = CustomMessage(
Rando::StaticData::RetrieveItem(static_cast<RandomizerGet>(rgid)).GetArticle(), TEXTBOX_TYPE_BLUE);
msg.Replace("[[article]]", article);
diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp
index b856cecdf..c9b8de0fe 100644
--- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp
+++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp
@@ -1131,9 +1131,16 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
case VB_MIDO_CONSIDER_DEKU_TREE_DEAD:
*should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD);
break;
- case VB_OPEN_CHEST:
+ case VB_OPEN_CHEST: {
+ EnBox* chest = va_arg(args, EnBox*);
*should = *should && Flags_GetRandomizerInf(RAND_INF_CAN_OPEN_CHEST);
+ if (*should && RAND_GET_OPTION(RSK_SHUFFLE_OPEN_CHEST).Is(RO_OPEN_CHEST_PROGRESSIVE) &&
+ chest->type != ENBOX_TYPE_SMALL && chest->type != ENBOX_TYPE_6 &&
+ chest->type != ENBOX_TYPE_ROOM_CLEAR_SMALL && chest->type != ENBOX_TYPE_SWITCH_FLAG_FALL_SMALL) {
+ *should = Flags_GetRandomizerInf(RAND_INF_CAN_OPEN_LARGE_CHEST);
+ }
break;
+ }
case VB_OPEN_KOKIRI_FOREST:
*should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD) ||
RAND_GET_OPTION(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON);
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 2b0256dda..e264c9d31 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
@@ -112,7 +112,7 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTW_PIT_CAGE] = Region("Bottom of the Well Pit Cage", SCENE_BOTTOM_OF_THE_WELL, {}, {
//Locations
- LOCATION(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_BOTW_PERIMETER, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)),
@@ -178,7 +178,7 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTW_DEAD_HAND_ROOM] = Region("Bottom of the Well Dead Hand Room", SCENE_BOTTOM_OF_THE_WELL, {}, {
//Locations
- LOCATION(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->CanOpenLargeChest()),
LOCATION(RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)),
}, {
//Exits
@@ -253,7 +253,7 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTW_B3_CHEST_AREA] = Region("Bottom of the Well B3 Chest Area", SCENE_BOTTOM_OF_THE_WELL, {}, {
//Locations
- LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_BOTW_B3_OOZE, AnyAgeTime([]{return logic->BlastOrSmash();})),
@@ -325,7 +325,7 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTW_MQ_MIDDLE] = Region("Bottom of the Well MQ Middle", SCENE_BOTTOM_OF_THE_WELL, {}, {
//Locations
- LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, logic->CanOpenLargeChest()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, logic->CanBreakPots()),
@@ -443,7 +443,7 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTW_MQ_DEAD_HAND_ROOM] = Region("Bottom of the Well MQ Dead Hand Room", SCENE_BOTTOM_OF_THE_WELL, {}, {
//Locations
- LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->CanOpenLargeChest()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, logic->HasExplosives() || (ctx->GetTrickOption(RT_BOTW_MQ_DEADHAND_KEY) && logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_2, logic->CanCutShrubs()),
@@ -470,7 +470,7 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTW_MQ_B3_PLATFORM] = Region("Bottom of the Well MQ B3 Platform", SCENE_BOTTOM_OF_THE_WELL, {}, {
//Locations
//Assumes RR_BOTW_MQ_B3 access
- LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, logic->CanPassEnemy(RE_REDEAD) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, logic->CanPassEnemy(RE_REDEAD) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_BOTW_MQ_B3, true),
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 7e7cb56e4..f336d200e 100644
--- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp
@@ -38,7 +38,7 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_LOBBY_2F] = Region("Deku Tree Lobby 2F", SCENE_DEKU_TREE, {}, {
//Locations
- LOCATION(RC_DEKU_TREE_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_DEKU_TREE_MAP_CHEST, logic->CanOpenLargeChest()),
LOCATION(RC_DEKU_TREE_LOBBY_LOWER_HEART, true),
LOCATION(RC_DEKU_TREE_2F_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_2F_GRASS_2, logic->CanCutShrubs()),
@@ -69,7 +69,7 @@ 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, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_DEKU_TREE_SLINGSHOT_CHEST, logic->CanOpenLargeChest()),
LOCATION(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_2, logic->CanCutShrubs()),
@@ -86,7 +86,7 @@ void RegionTable_Init_DekuTree() {
EVENT_ACCESS(LOGIC_NUT_ACCESS, logic->CanGetDekuBabaNuts()),
}, {
//Locations
- LOCATION(RC_DEKU_TREE_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_DEKU_TREE_COMPASS_CHEST, logic->CanOpenLargeChest()),
LOCATION(RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_DEKU_TREE_GS_COMPASS_ROOM, logic->CanAttack()),
LOCATION(RC_DEKU_TREE_COMPASS_GRASS_1, logic->CanCutShrubs()),
@@ -247,7 +247,7 @@ void RegionTable_Init_DekuTree() {
EVENT_ACCESS(LOGIC_DEKU_TREE_MQ_2F_BURNED_WEB, logic->HasFireSource()),
}, {
//Locations
- LOCATION(RC_DEKU_TREE_MQ_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_DEKU_TREE_MQ_MAP_CHEST, logic->CanOpenLargeChest()),
LOCATION(RC_DEKU_TREE_MQ_GS_LOBBY, (logic->CanBreakCrates() || ctx->GetTrickOption(RT_VISIBLE_COLLISION)) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
LOCATION(RC_DEKU_TREE_MQ_LOBBY_HEART, true),
LOCATION(RC_DEKU_TREE_MQ_2F_GRASS_1, logic->CanCutShrubs()),
@@ -281,7 +281,7 @@ void RegionTable_Init_DekuTree() {
}, {
//Locations
//Implies CanKillEnemy(RE_GOHMA_LARVA)
- LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, logic->CanKillEnemy(RE_DEKU_BABA) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, logic->CanKillEnemy(RE_DEKU_BABA) && logic->CanOpenLargeChest()),
LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, (logic->HasFireSourceWithTorch() || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW))) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, true),
LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_1, logic->CanCutShrubs()),
@@ -313,7 +313,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, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_DEKU_TREE_MQ_COMPASS_CHEST, logic->CanOpenLargeChest()),
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()),
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 ca228e934..51c26b6c5 100644
--- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp
@@ -28,7 +28,7 @@ void RegionTable_Init_DodongosCavern() {
EVENT_ACCESS(LOGIC_DC_EYES_LIT, ctx->GetTrickOption(RT_DC_EYES_CHU) && logic->CanUse(RG_BOMBCHU_5)),
}, {
//Locations
- LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->HasItem(RG_OPEN_CHEST);),
+ LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->CanOpenLargeChest();),
LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, (logic->CanStunDeku() || logic->HasItem(RG_GORONS_BRACELET)) && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()),
LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, AnyAgeTime([]{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET); }) && logic->CallGossipFairy()),
LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, AnyAgeTime([]{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET); }) && logic->CanUse(RG_SONG_OF_STORMS)),
@@ -149,7 +149,7 @@ void RegionTable_Init_DodongosCavern() {
areaTable[RR_DODONGOS_CAVERN_COMPASS_ROOM] = Region("Dodongos Cavern Compass Room", SCENE_DODONGOS_CAVERN, {}, {
//Locations
- LOCATION(RC_DODONGOS_CAVERN_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_DODONGOS_CAVERN_COMPASS_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_DODONGOS_CAVERN_STAIRS_LOWER, logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)),
@@ -227,7 +227,7 @@ void RegionTable_Init_DodongosCavern() {
areaTable[RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER] = Region("Dodongos Cavern Bomb Room Upper", SCENE_DODONGOS_CAVERN, {}, {
//Locations
- LOCATION(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, logic->CanOpenLargeChest()),
LOCATION(RC_DODONGOS_CAVERN_BLADE_POT_1, logic->CanBreakPots()),
LOCATION(RC_DODONGOS_CAVERN_BLADE_POT_2, logic->CanBreakPots()),
}, {
@@ -291,7 +291,7 @@ void RegionTable_Init_DodongosCavern() {
EVENT_ACCESS(LOGIC_DC_EYES_LIT, ctx->GetTrickOption(RT_DC_EYES_CHU) && logic->CanUse(RG_BOMBCHU_5)),
}, {
//Locations
- LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->CanOpenLargeChest()),
LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku() && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()),
LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku() && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()),
LOCATION(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)),
@@ -322,7 +322,7 @@ void RegionTable_Init_DodongosCavern() {
areaTable[RR_DODONGOS_CAVERN_MQ_OUTSIDE_POES_ROOM] = Region("Dodongos Cavern MQ Outside Poes Room", SCENE_DODONGOS_CAVERN, {}, {
//Locations
- LOCATION(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, logic->CanOpenLargeChest()),
}, {
//Events
ENTRANCE(RR_DODONGOS_CAVERN_MQ_LOBBY, true),
@@ -402,7 +402,7 @@ void RegionTable_Init_DodongosCavern() {
areaTable[RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM] = Region("Dodongos Cavern MQ Dodongo Room", SCENE_DODONGOS_CAVERN, {}, {
//Locations
- LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, (logic->CanKillEnemy(RE_DODONGO) || (logic->HasItem(RG_GORONS_BRACELET) && logic->CanClimbLadder())) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, (logic->CanKillEnemy(RE_DODONGO) || (logic->HasItem(RG_GORONS_BRACELET) && logic->CanClimbLadder())) && logic->CanOpenLargeChest()),
LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_2, logic->CanCutShrubs()),
LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_3, logic->CanCutShrubs()),
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 a9c662c5b..2935d5349 100644
--- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp
@@ -86,7 +86,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_LOOP_GORON_CAGE] = Region("Fire Temple Loop Goron Cage", SCENE_FIRE_TEMPLE, {}, {
//Locations
- LOCATION(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_LOOP_CAGE_SWITCH, logic->Get(LOGIC_FIRE_LOOP_SWITCH)),
@@ -240,7 +240,7 @@ void RegionTable_Init_FireTemple() {
//firetimer for entering this area from RR_FIRE_TEMPLE_FIRE_WALL_CHASE is handled there
areaTable[RR_FIRE_TEMPLE_FIRE_WALL_CAGE] = Region("Fire Temple Fire Wall Cage", SCENE_FIRE_TEMPLE, {}, {
//Locations
- LOCATION(RC_FIRE_TEMPLE_MAP_CHEST, logic->FireTimer() >= 8 && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FIRE_TEMPLE_MAP_CHEST, logic->FireTimer() >= 8 && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_NARROW_PATH_ROOM, true),
@@ -321,7 +321,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_CAGELESS_CHEST_ROOM] = Region("Fire Temple Cageless Chest Room", SCENE_FIRE_TEMPLE, {}, {
//Locations
- LOCATION(RC_FIRE_TEMPLE_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FIRE_TEMPLE_COMPASS_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_FIRE_MAZE_MAIN, true),
@@ -393,7 +393,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_NARROW_STAIRS] = Region("Fire Temple Narrow Stairs", SCENE_FIRE_TEMPLE, {}, {
//Locations
- LOCATION(RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_SOT_CAGE_UPPER_DOOR, logic->TakeDamage()),
@@ -506,7 +506,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_MQ_LOOP_FLARE_DANCER] = Region("Fire Temple MQ Loop Flare Dancer", SCENE_FIRE_TEMPLE, {}, {
//Locations
- LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, (logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || logic->CanGroundJump()) && AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);}) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, (logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || logic->CanGroundJump()) && AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);}) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_MQ_LOOP_5_TILE_ROOM, true),
@@ -524,7 +524,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_MQ_LOOP_GORON_CAGE] = Region("Fire Temple MQ Loop Goron Cage", SCENE_FIRE_TEMPLE, {}, {
//Locations
- LOCATION(RC_FIRE_TEMPLE_MQ_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FIRE_TEMPLE_MQ_MAP_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_MQ_LOOP_CAGE_SWITCH, logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE)),
@@ -626,7 +626,7 @@ void RegionTable_Init_FireTemple() {
EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanUse(RG_HOOKSHOT)),
}, {
//Locations
- LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanOpenLargeChest()),
LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, logic->HookshotOrBoomerang()),
LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, logic->HookshotOrBoomerang()),
LOCATION(RC_FIRE_TEMPLE_MQ_WONDER_BOSS_KEY_ROOM_HOOKSHOT, logic->CanUse(RG_HOOKSHOT)),
@@ -797,7 +797,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_CAGE] = Region("Fire Temple MQ Shortcut Cage", SCENE_FIRE_TEMPLE, {}, {
//Locations
- LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_MQ_SHORTCUT_CLIMB, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT)),
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 f60a0c2b8..5ad8dcd3b 100644
--- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp
@@ -191,7 +191,7 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_MAP_ROOM] = Region("Forest Temple Map Room", SCENE_FOREST_TEMPLE, {}, {
//Locations
- LOCATION(RC_FOREST_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_BLUE_BUBBLE) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FOREST_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_BLUE_BUBBLE) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_FOREST_TEMPLE_NW_COURTYARD_UPPER_ALCOVE, AnyAgeTime([]{return logic->CanKillEnemy(RE_BLUE_BUBBLE);})),
@@ -296,7 +296,7 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_NW_HALLWAY_STRAIGHTENED] = Region("Forest Temple NW Hallway Straightened", SCENE_FOREST_TEMPLE, {}, {
//Locations
- LOCATION(RC_FOREST_TEMPLE_BOSS_KEY_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FOREST_TEMPLE_BOSS_KEY_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, true),
@@ -321,7 +321,7 @@ void RegionTable_Init_ForestTemple() {
EVENT_ACCESS(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)),
}, {
//Locations
- LOCATION(RC_FOREST_TEMPLE_BOW_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FOREST_TEMPLE_BOW_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3) && logic->CanOpenLargeChest()),
LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, logic->CanBreakPots()),
LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, logic->CanBreakPots()),
LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, logic->CanBreakPots()),
@@ -337,7 +337,7 @@ void RegionTable_Init_ForestTemple() {
EVENT_ACCESS(LOGIC_FOREST_BETH, logic->CanUse(RG_FAIRY_BOW)),
}, {
//Locations
- LOCATION(RC_FOREST_TEMPLE_BLUE_POE_CHEST, logic->Get(LOGIC_FOREST_BETH) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FOREST_TEMPLE_BLUE_POE_CHEST, logic->Get(LOGIC_FOREST_BETH) && logic->CanOpenLargeChest()),
LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_1, logic->CanBreakPots()),
LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_2, logic->CanBreakPots()),
LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_3, logic->CanBreakPots()),
@@ -562,7 +562,7 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_MQ_STRAIGHT_HALLWAY] = Region("Forest Temple MQ Straight Hallway", SCENE_FOREST_TEMPLE, {}, {
//Locations
- LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(SCENE_FOREST_TEMPLE, 3) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(SCENE_FOREST_TEMPLE, 3) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_FOREST_TEMPLE_MQ_FLOORMASTER_ROOM, true),
@@ -719,7 +719,7 @@ void RegionTable_Init_ForestTemple() {
EVENT_ACCESS(LOGIC_FOREST_JOELLE, logic->CanUse(RG_FAIRY_BOW)),
}, {
//Locations
- LOCATION(RC_FOREST_TEMPLE_MQ_MAP_CHEST, logic->Get(LOGIC_FOREST_JOELLE) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FOREST_TEMPLE_MQ_MAP_CHEST, logic->Get(LOGIC_FOREST_JOELLE) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, logic->SmallKeys(SCENE_FOREST_TEMPLE, 4)),
@@ -732,7 +732,7 @@ void RegionTable_Init_ForestTemple() {
EVENT_ACCESS(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH, logic->CanKillEnemy(RE_WOLFOS)),
}, {
//Locations
- LOCATION(RC_FOREST_TEMPLE_MQ_BOW_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FOREST_TEMPLE_MQ_BOW_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3) && logic->CanOpenLargeChest()),
LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, logic->CanBreakPots()),
LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, logic->CanBreakPots()),
LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, logic->CanBreakPots()),
@@ -748,7 +748,7 @@ void RegionTable_Init_ForestTemple() {
EVENT_ACCESS(LOGIC_FOREST_BETH, logic->CanUse(RG_FAIRY_BOW)),
}, {
//Locations
- LOCATION(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_FOREST_BETH) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_FOREST_BETH) && logic->CanOpenLargeChest()),
LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, logic->CanBreakPots()),
LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, logic->CanBreakPots()),
LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, logic->CanBreakPots()),
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 2124dcd93..8fa1c73ef 100644
--- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp
@@ -255,7 +255,7 @@ void RegionTable_Init_GanonsCastle() {
EVENT_ACCESS(LOGIC_SHADOW_TRIAL_RUSTED_SWITCH, (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_MEGATON_HAMMER)),
}, {
//Locations
- LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->Get(LOGIC_SHADOW_TRIAL_LOWER_SWITCH) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->Get(LOGIC_SHADOW_TRIAL_LOWER_SWITCH) && logic->CanOpenLargeChest()),
LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG)),
@@ -701,7 +701,7 @@ void RegionTable_Init_GanonsCastle() {
//better names for these would be nice.
LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasItem(RG_OPEN_CHEST)),
- LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->CanOpenLargeChest()),
LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasItem(RG_OPEN_CHEST)),
}, {
//Exits
@@ -806,7 +806,7 @@ void RegionTable_Init_GanonsCastle() {
areaTable[RR_GANONS_TOWER_FLOOR_2] = Region("Ganon's Tower Floor 2", SCENE_GANONS_TOWER, {}, {
//Locations
- LOCATION(RC_GANONS_TOWER_BOSS_KEY_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_GANONS_TOWER_BOSS_KEY_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_GANONS_TOWER_STAIRS_2, AnyAgeTime([]{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);})),
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 d4760f276..37becd5ff 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
@@ -49,7 +49,7 @@ void RegionTable_Init_GerudoTrainingGround() {
LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 4) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 6) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 7) && logic->HasItem(RG_OPEN_CHEST)),
- LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 9) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 9) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_GERUDO_TRAINING_GROUND_LOBBY, true),
@@ -316,7 +316,7 @@ void RegionTable_Init_GerudoTrainingGround() {
areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM] = Region("Gerudo Training Ground MQ Magenta Fire Room", SCENE_GERUDO_TRAINING_GROUND, {}, {
//Locations
- LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, logic->Get(LOGIC_GTG_MQ_MAZE_SWITCH) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, logic->Get(LOGIC_GTG_MQ_MAZE_SWITCH) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, true),
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 3e477361d..e9725caab 100644
--- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp
@@ -71,7 +71,7 @@ void RegionTable_Init_IceCavern() {
EVENT_ACCESS(LOGIC_BLUE_FIRE_ACCESS, true),
}, {
//Locations
- LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->CanOpenLargeChest()),
// Bow extension is possible, but very precise: X = 403, Z = 2062-3, Rot = -11475, needs a setup and is its own trick
LOCATION(RC_ICE_CAVERN_FROZEN_POT_1, (logic->CanBreakPots() && logic->BlueFire()) || logic->HasExplosives() ||
(ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->CanJumpslash()) ||
@@ -99,7 +99,7 @@ void RegionTable_Init_IceCavern() {
EVENT_ACCESS(LOGIC_BLUE_FIRE_ACCESS, true),
}, {
//Locations
- LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, (logic->IsChild || logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, (logic->IsChild || logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire() && logic->CanOpenLargeChest()),
LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, (logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire()), // can skip blue fire with rang trick
LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->HookshotOrBoomerang()),
LOCATION(RC_ICE_CAVERN_HEART_PIECE_ROOM_CENTER_STALACTITE_1, true),
@@ -202,7 +202,7 @@ void RegionTable_Init_IceCavern() {
areaTable[RR_ICE_CAVERN_FINAL_ROOM] = Region("Ice Cavern Final Room", SCENE_ICE_CAVERN, {}, {
//Locations
- LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_WOLFOS);}) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_WOLFOS);}) && logic->CanOpenLargeChest()),
LOCATION(RC_SHEIK_IN_ICE_CAVERN, AnyAgeTime([]{return logic->CanKillEnemy(RE_WOLFOS);}) && logic->HasItem(RG_OPEN_CHEST)), // rando enables this for child
}, {
//Exits
@@ -281,7 +281,7 @@ void RegionTable_Init_IceCavern() {
EVENT_ACCESS(LOGIC_BLUE_FIRE_ACCESS, logic->IsChild || logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)),
}, {
//Locations
- LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && AnyAgeTime([]{return logic->CanHitSwitch();}) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && AnyAgeTime([]{return logic->CanHitSwitch();}) && logic->CanOpenLargeChest()),
LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_1, logic->CanClearStalagmite()),
LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_LEFT_STALAGMITE_2, logic->CanClearStalagmite()),
LOCATION(RC_ICE_CAVERN_MQ_MAP_ROOM_CENTER_STALAGMITE_1, logic->CanClearStalagmite()),
@@ -335,7 +335,7 @@ void RegionTable_Init_IceCavern() {
EVENT_ACCESS(LOGIC_BLUE_FIRE_ACCESS, true),
}, {
//Locations
- LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, logic->CanOpenLargeChest()),
//It is possible for child with master, BGS or sticks, or adult with BGS, to hit this switch through the ice with a crouchstab, but it's precise and unintuitive for a trick
LOCATION(RC_ICE_CAVERN_MQ_FREESTANDING_POH, logic->HasExplosives()), // can get with rang trick
//doing RT_ICE_MQ_RED_ICE_GS as child is untested, as I could not perform the trick reliably even as adult
@@ -353,7 +353,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) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, logic->CanKillEnemy(RE_STALFOS) && logic->CanOpenLargeChest()),
LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_STALFOS) && logic->HasItem(RG_OPEN_CHEST)), // rando enables this for child
}, {
//Exits
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 0c96824ab..597686955 100644
--- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp
@@ -135,7 +135,7 @@ void RegionTable_Init_JabuJabusBelly() {
EVENT_ACCESS(LOGIC_JABU_WEST_TENTACLE, logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG)),
}, {
//Locations
- LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->Get(LOGIC_JABU_WEST_TENTACLE) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->Get(LOGIC_JABU_WEST_TENTACLE) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, true),
@@ -151,7 +151,7 @@ void RegionTable_Init_JabuJabusBelly() {
areaTable[RR_JABU_JABUS_BELLY_FORK_NORTH_WEST] = Region("Jabu Jabus Belly Fork North West", SCENE_JABU_JABU, {}, {
//Locations
//ruto could theoretically clear this room, but it's hard because of the timer and she doesn't appear with you when you respawn after failing, which would force a savewarp
- LOCATION(RC_JABU_JABUS_BELLY_COMPASS_CHEST, logic->CanKillEnemy(RE_SHABOM, ED_CLOSE, false, 9) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_JABU_JABUS_BELLY_COMPASS_CHEST, logic->CanKillEnemy(RE_SHABOM, ED_CLOSE, false, 9) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_JABU_JABUS_BELLY_TO_FORK_NORTH_WEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_SHABOM, ED_CLOSE, false, 9);})),
@@ -191,7 +191,7 @@ void RegionTable_Init_JabuJabusBelly() {
areaTable[RR_JABU_JABUS_BELLY_FORK_EAST] = Region("Jabu Jabus Belly Fork East", SCENE_JABU_JABU, {}, {
//Locations
//We can kill the Stingers with ruto
- LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, (logic->Get(LOGIC_JABU_RUTO_IN_1F) || logic->CanKillEnemy(RE_STINGER, ED_CLOSE, true, 4)) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, (logic->Get(LOGIC_JABU_RUTO_IN_1F) || logic->CanKillEnemy(RE_STINGER, ED_CLOSE, true, 4)) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, true),
@@ -266,7 +266,7 @@ void RegionTable_Init_JabuJabusBelly() {
EVENT_ACCESS(LOGIC_NUT_ACCESS, logic->CanBreakPots()),
}, {
//Locations
- LOCATION(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, logic->BlastOrSmash() && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, logic->BlastOrSmash() && logic->CanOpenLargeChest()),
LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, logic->CanBreakPots()),
LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, logic->CanBreakPots()),
@@ -307,7 +307,7 @@ void RegionTable_Init_JabuJabusBelly() {
EVENT_ACCESS(LOGIC_JABU_MQ_HOLES_ROOM_DOOR, true),
}, {
//Locations
- LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, (logic->CanHitSwitch(ED_HOOKSHOT, true) || (ctx->GetTrickOption(RT_JABU_MQ_RANG_JUMP) && logic->CanUse(RG_BOOMERANG) && logic->HasItem(RG_BRONZE_SCALE))) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, (logic->CanHitSwitch(ED_HOOKSHOT, true) || (ctx->GetTrickOption(RT_JABU_MQ_RANG_JUMP) && logic->CanUse(RG_BOOMERANG) && logic->HasItem(RG_BRONZE_SCALE))) && logic->CanOpenLargeChest()),
LOCATION(RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, logic->CanBreakPots()),
LOCATION(RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, logic->CanBreakPots()),
//Getting the ones closest to the ledge with rang may be a trick due to the awkward angle without blind shooting through the flesh
@@ -375,7 +375,7 @@ void RegionTable_Init_JabuJabusBelly() {
}, {
//Locations
LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, logic->HasItem(RG_OPEN_CHEST)),
- LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, (logic->IsAdult || logic->HasItem(RG_CLIMB)) && logic->CanKillEnemy(RE_LIZALFOS) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, (logic->IsAdult || logic->HasItem(RG_CLIMB)) && logic->CanKillEnemy(RE_LIZALFOS) && logic->CanOpenLargeChest()),
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()),
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 3b273588d..ce7e5db94 100644
--- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp
@@ -68,7 +68,7 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE_ROOM] = Region("Shadow Temple Whispering Walls Side Room", SCENE_SHADOW_TEMPLE, {}, {
//Locations
- LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_REDEAD) && logic->CanKillEnemy(RE_KEESE) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_REDEAD) && logic->CanKillEnemy(RE_KEESE) && logic->CanOpenLargeChest()),
LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, logic->CanBreakPots()),
}, {
@@ -78,7 +78,7 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_DEAD_HAND] = Region("Shadow Temple Dead Hand", SCENE_SHADOW_TEMPLE, {}, {
//Locations
- LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_SHADOW_TEMPLE_WHISPERING_WALLS_END, AnyAgeTime([]{return logic->CanKillEnemy(RE_DEAD_HAND);})),
@@ -97,7 +97,7 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_COMPASS_ROOM] = Region("Shadow Temple Compass Room", SCENE_SHADOW_TEMPLE, {}, {
//Locations
- LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanKillEnemy(RE_GIBDO) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanKillEnemy(RE_GIBDO) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_SHADOW_TEMPLE_FIRST_BEAMOS, AnyAgeTime([]{return logic->CanKillEnemy(RE_GIBDO);})),
@@ -354,7 +354,7 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_WOODEN_SPIKES] = Region("Shadow Temple Wooden Spikes", SCENE_SHADOW_TEMPLE, {}, {
//Locations
LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->HasItem(RG_OPEN_CHEST)),
- LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->CanOpenLargeChest()),
LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, logic->CanBreakPots()),
}, {
//Exits
@@ -431,7 +431,7 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE_ROOM] = Region("Shadow Temple MQ Whispering Walls Side Room", SCENE_SHADOW_TEMPLE, {}, {
//Locations
- LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_REDEAD) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_REDEAD) && logic->CanOpenLargeChest()),
LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, logic->CanBreakPots()),
}, {
@@ -441,7 +441,7 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND] = Region("Shadow Temple MQ Whispering Walls Dead Hand", SCENE_SHADOW_TEMPLE, {}, {
//Locations
- LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_END, AnyAgeTime([]{return logic->CanKillEnemy(RE_DEAD_HAND);})),
@@ -469,7 +469,7 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM] = Region("Shadow Temple MQ B2 Spinning Blade Room", SCENE_SHADOW_TEMPLE, {}, {
//Locations
- LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump()))) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump()))) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, AnyAgeTime([]{return logic->CanKillEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));})),
@@ -756,7 +756,7 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM] = Region("Shadow Temple MQ Spike Walls Room", SCENE_SHADOW_TEMPLE, {}, {
//Locations
LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->HasItem(RG_OPEN_CHEST)),
- LOCATION(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->CanOpenLargeChest()),
LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, logic->CanBreakPots()),
}, {
//Exits
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 53e05c633..a5b5f5ce5 100644
--- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp
@@ -152,7 +152,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_SAND_PIT] = Region("Spirit Temple Sand Pit", SCENE_SPIRIT_TEMPLE, {}, {
//Locations
- LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_MEGATON_HAMMER))) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_MEGATON_HAMMER))) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_SPIRIT_TEMPLE_ADULT_SIDE_HUB, true),
@@ -208,7 +208,7 @@ void RegionTable_Init_SpiritTemple() {
//Locations
//Assumes RR_SPIRIT_TEMPLE_STATUE_ROOM access
LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW));}, false,
- RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasFireSource();}) && logic->HasItem(RG_OPEN_CHEST)),
+ RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasFireSource();}) && logic->CanOpenLargeChest()),
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT);}, false,
RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE) ? ED_BOOMERANG : ED_HOOKSHOT);},
RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA);})),
@@ -256,7 +256,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM] = Region("Spirit Temple Statue Room", SCENE_SPIRIT_TEMPLE, {}, {
//Locations
LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasFireSource();}, false,
- RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW));}) && logic->HasItem(RG_OPEN_CHEST)),
+ RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW));}) && logic->CanOpenLargeChest()),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})),
@@ -341,7 +341,7 @@ void RegionTable_Init_SpiritTemple() {
EVENT_ACCESS(LOGIC_SPIRIT_NABOORU_KIDNAPPED, SpiritShared(RR_SPIRIT_TEMPLE_OUTER_RIGHT_HAND, []{return logic->HasItem(RG_OPEN_CHEST);})),
}, {
//Locations
- LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_OUTER_RIGHT_HAND, []{return logic->HasItem(RG_OPEN_CHEST);})),
+ LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_OUTER_RIGHT_HAND, []{return logic->CanOpenLargeChest();})),
}, {
//Exits
ENTRANCE(RR_SPIRIT_TEMPLE_RIGHT_HAND_EXIT, true),
@@ -450,7 +450,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_OUTER_LEFT_HAND] = Region("Spirit Temple Outer Left Hand", SCENE_SPIRIT_TEMPLE, {}, {
//Locations
- LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_SPIRIT_TEMPLE_LEFT_HAND_EXIT, true),
@@ -487,7 +487,7 @@ void RegionTable_Init_SpiritTemple() {
//Locations
LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, ((logic->TakeDamage() && ctx->GetTrickOption(RT_FIRE_RINGS)) ||
(AnyAgeTime([]{return logic->CanHitEyeTargets() && logic->CanAvoidEnemy(RE_TORCH_SLUG, true, 4);})
- && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_OPEN_CHEST)),
+ && logic->CanUse(RG_HOOKSHOT))) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_SPIRIT_TEMPLE_4F_CENTRAL, true),
@@ -672,7 +672,7 @@ void RegionTable_Init_SpiritTemple() {
EVENT_ACCESS(LOGIC_SPIRIT_MQ_MAP_ROOM_ENEMIES, logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE, ED_BOOMERANG)),
}, {
//Locations
- LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
//The bridge is a temp flag, so not a way to cross south to north in logic
@@ -778,7 +778,7 @@ void RegionTable_Init_SpiritTemple() {
EVENT_ACCESS(LOGIC_SPIRIT_MQ_STATUE_ROOM_TORCHES, logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE))),
}, {
//Locations
- LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST);})),
+ LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets() && logic->CanOpenLargeChest();})),
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})),
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})),
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})),
@@ -840,7 +840,7 @@ void RegionTable_Init_SpiritTemple() {
EVENT_ACCESS(LOGIC_SPIRIT_NABOORU_KIDNAPPED, SpiritShared(RR_SPIRIT_TEMPLE_OUTER_RIGHT_HAND, []{return logic->HasItem(RG_OPEN_CHEST);})),
}, {
//Locations
- LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_OUTER_RIGHT_HAND, []{return logic->HasItem(RG_OPEN_CHEST);})),
+ LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_OUTER_RIGHT_HAND, []{return logic->CanOpenLargeChest();})),
}, {
//Exits
//If it is ever relevent for 1 age to spawn the mirror shield chest for the other can longshot across, it needs an eventAccess
@@ -1028,7 +1028,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_MQ_OUTER_LEFT_HAND] = Region("Spirit Temple MQ Outer Left Hand", SCENE_SPIRIT_TEMPLE, {}, {
//Locations
- LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_SPIRIT_TEMPLE_MQ_OUTER_RIGHT_HAND, logic->CanUse(RG_LONGSHOT)),
@@ -1038,7 +1038,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM] = Region("Spirit Temple MQ 3F Gibdo Room", SCENE_SPIRIT_TEMPLE, {}, {
//Locations
- LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, true),
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 44f7b9445..bd2a21997 100644
--- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp
@@ -172,7 +172,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_4_SPIKES_ROOM] = Region("Water Temple 4 Spikes Room", SCENE_WATER_TEMPLE, {}, {
//Locations
- LOCATION(RC_WATER_TEMPLE_MAP_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 4);}) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_WATER_TEMPLE_MAP_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 4);}) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_WATER_TEMPLE_LOW_EMBLEM, AnyAgeTime([]{return logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 4);})),
@@ -180,7 +180,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_CRACKED_WALL] = Region("Water Temple Cracked Wall", SCENE_WATER_TEMPLE, {}, {
//Locations
- LOCATION(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, (logic->WaterLevel(WL_LOW_OR_MID) && logic->HasItem(RG_OPEN_CHEST)) || logic->CanOpenUnderwaterChest()),
+ LOCATION(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, (logic->WaterLevel(WL_LOW_OR_MID) || logic->CanOpenUnderwaterChest()) && logic->HasItem(RG_OPEN_CHEST)),
}, {
//Exits
ENTRANCE(RR_WATER_TEMPLE_SIDE_TOWER_2F, true),
@@ -322,7 +322,7 @@ void RegionTable_Init_WaterTemple() {
EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanBreakPots()),
}, {
//Locations
- LOCATION(RC_WATER_TEMPLE_BOSS_KEY_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_WATER_TEMPLE_BOSS_KEY_CHEST, logic->CanOpenLargeChest()),
LOCATION(RC_WATER_TEMPLE_BOSS_KEY_POT_1, logic->CanBreakPots()),
LOCATION(RC_WATER_TEMPLE_BOSS_KEY_POT_2, logic->CanBreakPots()),
}, {
@@ -427,7 +427,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_JET_CHEST_ROOM] = Region("Water Temple Jet Chest Room", SCENE_WATER_TEMPLE, {}, {
//Locations
- LOCATION(RC_WATER_TEMPLE_COMPASS_CHEST, logic->CanUseProjectile() && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_WATER_TEMPLE_COMPASS_CHEST, logic->CanUseProjectile() && logic->CanOpenLargeChest()),
LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, logic->CanBreakPots()),
LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, logic->CanBreakPots()),
LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, logic->CanBreakPots()),
@@ -564,7 +564,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_SOT_PIT_ROOM] = Region("Water Temple Song Of Time Pit Room", SCENE_WATER_TEMPLE, {}, {
//Locations
- LOCATION(RC_WATER_TEMPLE_LONGSHOT_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_WATER_TEMPLE_LONGSHOT_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_WATER_TEMPLE_DARK_LINK_ROOM, true),
@@ -801,7 +801,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_MQ_SIDE_TOWER_2F] = Region("Water Temple MQ Side Tower 2F", SCENE_WATER_TEMPLE, {}, {
//Locations
- LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, logic->CanUse(RG_HOOKSHOT) && ((logic->WaterLevel(WL_MID) && logic->HasItem(RG_OPEN_CHEST)) || logic->CanOpenUnderwaterChest())),
+ LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, logic->CanUse(RG_HOOKSHOT) && (logic->WaterLevel(WL_MID) || logic->CanOpenUnderwaterChest()) && logic->CanOpenLargeChest()),
LOCATION(RC_WATER_TEMPLE_MQ_WONDER_LONGSHOT_ROOM, logic->CanUse(RG_HOOKSHOT) && (logic->WaterLevel(WL_MID) || logic->CanUse(RG_IRON_BOOTS))),
}, {
//Exits
@@ -823,7 +823,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_MQ_3_STALFOS_ROOM] = Region("Water Temple MQ 3 Stalfos Room", SCENE_WATER_TEMPLE, {}, {
//Locations
- LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanOpenLargeChest()),
LOCATION(RC_WATER_TEMPLE_MQ_WONDER_STALFOS_ROOM, logic->CanUse(RG_HOOKSHOT)),
}, {
//Exits
@@ -835,7 +835,7 @@ void RegionTable_Init_WaterTemple() {
EVENT_ACCESS(LOGIC_WATER_MQ_SIDE_TOWER_TARGETS, logic->CanKillEnemy(RE_LIZALFOS) && logic->CanKillEnemy(RE_SPIKE)),
}, {
//Locations
- LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_WATER_MQ_SIDE_TOWER_TARGETS) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_WATER_MQ_SIDE_TOWER_TARGETS) && logic->CanOpenLargeChest()),
LOCATION(RC_WATER_TEMPLE_MQ_WONDER_LIZALFOS_ROOM, logic->CanUse(RG_HOOKSHOT)),
}, {
//Exits
@@ -1240,7 +1240,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST] = Region("Water Temple MQ Boss Key Room Chest", SCENE_WATER_TEMPLE, {}, {
//Locations
- LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, logic->CanHitSwitch(ED_BOMB_THROW) || logic->CanUse(RG_HOVER_BOOTS)),
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 e092d9ce7..bddb3617a 100644
--- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp
@@ -155,7 +155,7 @@ void RegionTable_Init_GerudoFortress() {
areaTable[RR_GF_NEAR_CHEST] = Region("GF Near Chest", SCENE_GERUDOS_FORTRESS, {}, {
//Locations
- LOCATION(RC_GF_CHEST, logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_GF_CHEST, logic->CanOpenLargeChest()),
LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) && logic->CanGetNightTimeGS()),
}, {
//Exits
diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp
index feeca7bd3..f1b56d4ec 100644
--- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp
@@ -76,7 +76,7 @@ void RegionTable_Init_Graveyard() {
areaTable[RR_GRAVEYARD_HEART_PIECE_GRAVE] = Region("Graveyard Heart Piece Grave", SCENE_REDEAD_GRAVE, {}, {
//Locations
- LOCATION(RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, logic->CanUse(RG_SUNS_SONG) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, logic->CanUse(RG_SUNS_SONG) && logic->CanOpenLargeChest()),
}, {
//Exits
ENTRANCE(RR_THE_GRAVEYARD, true),
@@ -97,7 +97,7 @@ void RegionTable_Init_Graveyard() {
EVENT_ACCESS(LOGIC_NUT_ACCESS, logic->CanBreakPots()),
}, {
//Locations
- LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest()),
LOCATION(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, (logic->IsAdult || ctx->GetTrickOption(RT_GY_CHILD_DAMPE_RACE_POH)) && logic->HasItem(RG_SPEAK_HYLIAN)),
LOCATION(RC_GY_DAMPES_GRAVE_POT_1, logic->CanBreakPots()),
LOCATION(RC_GY_DAMPES_GRAVE_POT_2, logic->CanBreakPots()),
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 180c4ae9e..3ba6b4567 100644
--- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp
@@ -154,7 +154,7 @@ void RegionTable_Init_KokiriForest() {
areaTable[RR_KF_BOULDER_LOOP] = Region("KF Boulder Loop", SCENE_KOKIRI_FOREST, {}, {
//Locations
- LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild && logic->CanOpenLargeChest()),
LOCATION(RC_KF_BOULDER_RUPEE_1, logic->IsChild),
LOCATION(RC_KF_BOULDER_RUPEE_2, logic->IsChild),
LOCATION(RC_KF_CHILD_GRASS_MAZE_1, logic->IsChild && logic->CanCutShrubs()),
diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp
index 58d683bbb..460c5c232 100644
--- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp
@@ -205,17 +205,17 @@ 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) && logic->HasItem(RG_SPEAK_HYLIAN)),
- LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST) && ((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(SCENE_TREASURE_BOX_SHOP, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)))),
- LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))),
+ LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest() && ((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(SCENE_TREASURE_BOX_SHOP, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)))),
+ LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest() && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest() && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest() && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest() && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest() && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest() && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest() && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest() && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest() && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 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) && logic->HasItem(RG_SPEAK_HYLIAN) && logic->CanOpenLargeChest() && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))),
}, {
//Exits
ENTRANCE(RR_THE_MARKET, 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 0649f5f3d..5f528b531 100644
--- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp
+++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp
@@ -16,7 +16,7 @@ void RegionTable_Init_ZorasDomain() {
}, {
//Locations
LOCATION(RC_ZD_DIVING_MINIGAME, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_ZORA) && logic->IsChild),
- LOCATION(RC_ZD_CHEST, logic->IsChild && logic->CanUse(RG_STICKS) && logic->HasItem(RG_OPEN_CHEST)),
+ LOCATION(RC_ZD_CHEST, logic->IsChild && logic->CanUse(RG_STICKS) && logic->CanOpenLargeChest()),
LOCATION(RC_ZD_KING_ZORA_THAWED, logic->IsAdult && logic->Get(LOGIC_KING_ZORA_THAWED) && logic->HasItem(RG_SPEAK_ZORA)),
LOCATION(RC_ZD_TRADE_PRESCRIPTION, logic->IsAdult && logic->Get(LOGIC_KING_ZORA_THAWED) && logic->CanUse(RG_PRESCRIPTION)),
LOCATION(RC_ZD_GS_FROZEN_WATERFALL, logic->IsAdult && (logic->HookshotOrBoomerang() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || (logic->CanUse(RG_MAGIC_SINGLE) && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))) || (ctx->GetTrickOption(RT_ZD_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()),
diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp
index c00b4aac5..7c199b43a 100644
--- a/soh/soh/Enhancements/randomizer/logic.cpp
+++ b/soh/soh/Enhancements/randomizer/logic.cpp
@@ -677,6 +677,10 @@ bool Logic::CanOpenUnderwaterChest() {
HasItem(RG_OPEN_CHEST);
}
+bool Logic::CanOpenLargeChest() {
+ return CheckRandoInf(RAND_INF_CAN_OPEN_LARGE_CHEST);
+}
+
uint8_t GetDifficultyValueFromString(Rando::Option& glitchOption) {
return 0;
}
@@ -2085,7 +2089,17 @@ void Logic::ApplyItemEffect(Item& item, bool state) {
SetRandoInf(RAND_INF_CAN_CRAWL, state);
break;
case RG_OPEN_CHEST:
- SetRandoInf(RAND_INF_CAN_OPEN_CHEST, state);
+ if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST).Is(RO_OPEN_CHEST_PROGRESSIVE)) {
+ if (state ? CheckRandoInf(RAND_INF_CAN_OPEN_CHEST)
+ : CheckRandoInf(RAND_INF_CAN_OPEN_LARGE_CHEST)) {
+ SetRandoInf(RAND_INF_CAN_OPEN_LARGE_CHEST, state);
+ } else {
+ SetRandoInf(RAND_INF_CAN_OPEN_CHEST, state);
+ }
+ } else {
+ SetRandoInf(RAND_INF_CAN_OPEN_CHEST, state);
+ SetRandoInf(RAND_INF_CAN_OPEN_LARGE_CHEST, state);
+ }
break;
case RG_PROGRESSIVE_HOOKSHOT: {
uint8_t i;
@@ -2941,6 +2955,7 @@ void Logic::Reset(bool resetSaveContext /*= true*/) {
if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST).Is(false)) {
SetRandoInf(RAND_INF_CAN_OPEN_CHEST, true);
+ SetRandoInf(RAND_INF_CAN_OPEN_LARGE_CHEST, true);
}
if (ctx->GetOption(RSK_SHUFFLE_SPEAK).Is(false)) {
diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h
index 22e9dbd6d..6f5d3f6d7 100644
--- a/soh/soh/Enhancements/randomizer/logic.h
+++ b/soh/soh/Enhancements/randomizer/logic.h
@@ -47,6 +47,7 @@ class Logic {
bool CanGroundJumpslash(bool hasBombflower = false);
bool CanMiddairGroundJump(bool hasBombflower = false);
bool CanOpenUnderwaterChest();
+ bool CanOpenLargeChest();
bool CanDoGlitch(GlitchType glitch);
bool CanEquipSwap(RandomizerGet itemName);
bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true,
diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp
index 653038610..26c8d945d 100644
--- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp
+++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp
@@ -268,7 +268,10 @@ void Settings::CreateOptionDescriptions() {
mOptionDescriptions[RSK_SHUFFLE_SPEAK] =
"Shuffle ability to speak to NPCs. 6 jabbernuts will be shuffled:\nDeku, Gerudo, Goron, Hylian, Kokiri, "
"Zora\nKaepora Gaebora speaks any language.";
- mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST] = "Shuffles the ability to open chests into the item pool.";
+ mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST] =
+ "Shuffles the ability to open chests into the item pool.\n"
+ "\n"
+ "Progressive shuffles two copies: first only opens small chests, second also opens big chests.";
mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG] =
"Vanilla: Malon gives the Weird Egg at Hyrule Castle.\n"
"\n"
diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp
index bf2fe2ecd..cb72c0aff 100644
--- a/soh/soh/Enhancements/randomizer/randomizer.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer.cpp
@@ -242,6 +242,11 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerCheck(Randomizer
}
ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGet randoGet) {
+ // progressive open chest has a second copy that unlocks large chests
+ if (randoGet == RG_OPEN_CHEST && GetRandoSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_OPEN_CHEST_PROGRESSIVE) {
+ return Flags_GetRandomizerInf(RAND_INF_CAN_OPEN_LARGE_CHEST) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN;
+ }
+
if (Rando::StaticData::RandoGetToRandInf.find(randoGet) != Rando::StaticData::RandoGetToRandInf.end()) {
return Flags_GetRandomizerInf((RandomizerInf)Rando::StaticData::RandoGetToRandInf.find(randoGet)->second)
? CANT_OBTAIN_ALREADY_HAVE
@@ -1133,6 +1138,13 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
// Gameplay stats: Update the time the item was obtained
Randomizer_GameplayStats_SetTimestamp(item);
+ // open chest: not progressive gives both flags at once, progressive gives large only as the second copy
+ if (item == RG_OPEN_CHEST &&
+ (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_OPEN_CHEST) != RO_OPEN_CHEST_PROGRESSIVE ||
+ Flags_GetRandomizerInf(RAND_INF_CAN_OPEN_CHEST))) {
+ Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_LARGE_CHEST);
+ }
+
// if it's an item that just sets a randomizerInf, set it
if (Rando::StaticData::RandoGetToRandInf.find(item) != Rando::StaticData::RandoGetToRandInf.end()) {
Flags_SetRandomizerInf((RandomizerInf)Rando::StaticData::RandoGetToRandInf.find(item)->second);
diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h
index 28a58f16e..ce6e94a2c 100644
--- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h
+++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h
@@ -1445,6 +1445,7 @@ RANDO_ENUM_ITEM(RAND_INF_CAN_CLIMB)
RANDO_ENUM_ITEM(RAND_INF_CAN_CRAWL)
RANDO_ENUM_ITEM(RAND_INF_CAN_GRAB)
RANDO_ENUM_ITEM(RAND_INF_CAN_OPEN_CHEST)
+RANDO_ENUM_ITEM(RAND_INF_CAN_OPEN_LARGE_CHEST)
RANDO_ENUM_ITEM(RAND_INF_CAN_SPEAK_DEKU)
RANDO_ENUM_ITEM(RAND_INF_CAN_SPEAK_GERUDO)
RANDO_ENUM_ITEM(RAND_INF_CAN_SPEAK_GORON)
@@ -2929,7 +2930,6 @@ RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_2)
RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3)
RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4)
RANDO_ENUM_ITEM(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5)
-
// Set when a non-shop shield/tunic is found, gating the matching shop copy behind it
// (RSK_SHOP_SHIELDS_AND_TUNICS_ONLY_REFILL).
RANDO_ENUM_ITEM(RAND_INF_HAS_FOUND_DEKU_SHIELD)
diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h
index ea255d0c4..bb3c95e00 100644
--- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h
+++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerOptions.h
@@ -314,6 +314,13 @@ RANDO_ENUM_ITEM(RO_WEIRD_EGG_SHUFFLED)
RANDO_ENUM_ITEM(RO_WEIRD_EGG_SKIP_TALON)
RANDO_ENUM_END(RandoOptionShuffleWeirdEgg)
+// Shuffle Open Chest Settings (off, on, progressive)
+RANDO_ENUM_BEGIN(RandoOptionShuffleOpenChest)
+RANDO_ENUM_ITEM(RO_OPEN_CHEST_OFF)
+RANDO_ENUM_ITEM(RO_OPEN_CHEST_ON)
+RANDO_ENUM_ITEM(RO_OPEN_CHEST_PROGRESSIVE)
+RANDO_ENUM_END(RandoOptionShuffleOpenChest)
+
// Starting Ocarina Settings (off, fairy, oot)
RANDO_ENUM_BEGIN(RandoOptionStartingOcarina)
RANDO_ENUM_ITEM(RO_STARTING_OCARINA_OFF)
diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
index f4c363706..5224974af 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
@@ -62,6 +62,7 @@ static WidgetInfo overworldKeysTracking;
static WidgetInfo fishingPoleTracking;
static WidgetInfo personalNotesWiget;
static WidgetInfo hookshotIdentWidget;
+static WidgetInfo openChestIdentWidget;
namespace SohGui {
extern std::shared_ptr<SohMenu> mSohMenu;
@@ -670,6 +671,23 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) {
}
}
+ // progressive open chest: 'S' for small chests only, 'B' once big chests can be opened too
+ if (item.id == RG_OPEN_CHEST && CVarGetInteger(CVAR_TRACKER_ITEM("OpenChestIdentifier"), 0) && IS_RANDO &&
+ RAND_GET_OPTION(RSK_SHUFFLE_OPEN_CHEST).Is(RO_OPEN_CHEST_PROGRESSIVE) &&
+ Flags_GetRandomizerInf(RAND_INF_CAN_OPEN_CHEST)) {
+ const char* ident = Flags_GetRandomizerInf(RAND_INF_CAN_OPEN_LARGE_CHEST) ? "B" : "S";
+
+ ImVec2 textPos = ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(ident).x * textScalingFactor / 2) +
+ 8 * textScalingFactor,
+ p.y - 22 * textScalingFactor);
+
+ ImGui::SetCursorScreenPos(textPos);
+ ImGui::SetWindowFontScale(textScalingFactor);
+
+ ImGui::Text("%s", ident);
+ ImGui::SetWindowFontScale(1.0f);
+ }
+
ImGui::SetWindowFontScale(textSize / 13.0f);
if (item.id == ITEM_KEY_SMALL && IsValidSaveFile()) {
@@ -2200,6 +2218,7 @@ void ItemTrackerSettingsWindow::DrawElement() {
SohGui::mSohMenu->MenuDrawItem(personalNotesWiget, 250, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(hookshotIdentWidget, 250, THEME_COLOR);
+ SohGui::mSohMenu->MenuDrawItem(openChestIdentWidget, 250, THEME_COLOR);
ImGui::PopStyleVar(1);
ImGui::EndTable();
@@ -2404,6 +2423,14 @@ void RegisterItemTrackerWidgets() {
.Color(THEME_COLOR)
.Tooltip("Shows an 'H' or an 'L' to more easily distinguish between Hookshot and Longshot."));
SohGui::mSohMenu->AddSearchWidget({ hookshotIdentWidget, "Randomizer", "Item Tracker", "General Settings" });
+
+ openChestIdentWidget = { .name = "Show Open Chest Identifiers", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
+ openChestIdentWidget.CVar(CVAR_TRACKER_ITEM("OpenChestIdentifier"))
+ .Options(CheckboxOptions()
+ .Color(THEME_COLOR)
+ .Tooltip("With progressive Shuffle Open Chest, shows an 'S' when only small chests can be "
+ "opened and a 'B' once big chests can be opened too."));
+ SohGui::mSohMenu->AddSearchWidget({ openChestIdentWidget, "Randomizer", "Item Tracker", "General Settings" });
}
void RegisterItemTracker() {
diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp
index a54a31c5b..392f69ff1 100644
--- a/soh/soh/Enhancements/randomizer/savefile.cpp
+++ b/soh/soh/Enhancements/randomizer/savefile.cpp
@@ -521,8 +521,9 @@ extern "C" void Randomizer_InitSaveFile() {
Flags_SetRandomizerInf(RAND_INF_CAN_SPEAK_ZORA);
}
- if (Randomizer_GetSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_GENERIC_OFF) {
+ if (Randomizer_GetSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_OPEN_CHEST_OFF) {
Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_CHEST);
+ Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_LARGE_CHEST);
}
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_WALLET) == RO_GENERIC_OFF) {
diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp
index 17a6930ed..9122e3098 100644
--- a/soh/soh/Enhancements/randomizer/settings.cpp
+++ b/soh/soh/Enhancements/randomizer/settings.cpp
@@ -851,7 +851,7 @@ void Settings::CreateOptions() {
}
});
OPT_BOOL(RSK_SHUFFLE_SPEAK, "Shuffle Jabber Nuts", CVAR_RANDOMIZER_SETTING("ShuffleSpeak"), mOptionDescriptions[RSK_SHUFFLE_SPEAK]);
- OPT_BOOL(RSK_SHUFFLE_OPEN_CHEST, "Shuffle Open Chest", CVAR_RANDOMIZER_SETTING("ShuffleOpenChest"), mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST]);
+ OPT_U8(RSK_SHUFFLE_OPEN_CHEST, "Shuffle Open Chest", {"Off", "On", "Progressive"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleOpenChest"), mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST], WIDGET_CVAR_COMBOBOX, RO_OPEN_CHEST_OFF);
OPT_U8(RSK_SHUFFLE_WEIRD_EGG, "Shuffle Weird Egg", {"Vanilla", "Shuffled", "Skip Waking Talon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG], WIDGET_CVAR_COMBOBOX, RO_WEIRD_EGG_VANILLA);
OPT_BOOL(RSK_SHUFFLE_ZELDAS_LETTER, "Shuffle Zelda's Letter", CVAR_RANDOMIZER_SETTING("ShuffleZeldasLetter"), mOptionDescriptions[RSK_SHUFFLE_ZELDAS_LETTER]);
OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, "Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]);
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 0dcaed486..542ce8789 100644
--- a/soh/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c
@@ -7368,7 +7368,7 @@ s32 Player_ActionHandler_2(Player* this, PlayState* play) {
!(this->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) &&
!(this->stateFlags2 & PLAYER_STATE2_UNDERWATER)) {
if (this->getItemId != GI_NONE) {
- if (GameInteractor_Should(VB_OPEN_CHEST, true)) {
+ if (GameInteractor_Should(VB_OPEN_CHEST, true, interactedActor)) {
GetItemEntry giEntry;
if (this->getItemEntry.objectId == OBJECT_INVALID) {
giEntry = ItemTable_Retrieve(-this->getItemId);