From 885e8f73609488ea92393def836cdc64e1e8b2d6 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:10:37 -0500 Subject: [PATCH 01/12] collision viewer "apply as decal" default on (#4727) --- soh/soh/Enhancements/debugger/colViewer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/debugger/colViewer.cpp b/soh/soh/Enhancements/debugger/colViewer.cpp index 57df9a4a2..2cba03f5b 100644 --- a/soh/soh/Enhancements/debugger/colViewer.cpp +++ b/soh/soh/Enhancements/debugger/colViewer.cpp @@ -62,7 +62,7 @@ void ColViewerWindow::DrawElement() { UIWidgets::LabeledRightAlignedEnhancementCombobox("Col Check", CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), ColRenderSettingNames, COLVIEW_DISABLED); UIWidgets::LabeledRightAlignedEnhancementCombobox("Waterbox", CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), ColRenderSettingNames, COLVIEW_DISABLED); - UIWidgets::EnhancementCheckbox("Apply as decal", CVAR_DEVELOPER_TOOLS("ColViewer.Decal")); + UIWidgets::EnhancementCheckbox("Apply as decal", CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), false, "", UIWidgets::CheckboxGraphics::Cross, true); UIWidgets::InsertHelpHoverText("Applies the collision as a decal display. This can be useful if there is z-fighting occuring " "with the scene geometry, but can cause other artifacts."); UIWidgets::EnhancementCheckbox("Shaded", CVAR_DEVELOPER_TOOLS("ColViewer.Shaded")); @@ -299,7 +299,7 @@ void InitGfx(std::vector& gfx, ColRenderSetting setting) { alpha = 0xFF; } - if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), 0) != 0) { + if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), 1) != 0) { rm |= ZMODE_DEC; } else if (setting == ColRenderSetting::Transparent) { rm |= ZMODE_XLU; From 6daa680a6187b1b0047bccac486b0a265df548d3 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Thu, 19 Dec 2024 23:27:55 +0000 Subject: [PATCH 02/12] Fix Closed forest tooltip (#4733) * Fix Closed forest tooltip * forgot to save --- .../Enhancements/randomizer/option_descriptions.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 534cb451e..a23489f5d 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -2,12 +2,14 @@ namespace Rando { void Settings::CreateOptionDescriptions() { - mOptionDescriptions[RSK_FOREST] = "Closed - Kokiri Sword & Deku Shield are required to access " - "the Deku Tree, and completing the Deku Tree is required to " - "access the Hyrule Field exit.\n" + mOptionDescriptions[RSK_FOREST] = "Determines if Kokiri forest can be left for the Lost Woods bridge or the Deku Tree.\n" "\n" - "Closed Deku - Kokiri boy no longer blocks the path to Hyrule " - "Field but Mido still requires the Kokiri Sword and Deku Shield " + "Closed - Kokiri Sword & Deku Shield are required to access " + "the Deku Tree, and completing the Deku Tree is required to " + "access the Lost Woods Bridge Exit.\n" + "\n" + "Closed Deku - Kokiri boy no longer blocks the path to the Bridge " + "but Mido still requires the Kokiri Sword and Deku Shield " "to access the tree.\n" "\n" "Open - Mido no longer blocks the path to the Deku Tree. Kokiri " From e7e5b1190a971401402fff847168b65972dfc98b Mon Sep 17 00:00:00 2001 From: Jordan Longstaff Date: Thu, 19 Dec 2024 18:28:23 -0500 Subject: [PATCH 03/12] Skip playing cutscenes of Pierre spawning (#4736) --- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 171620af6..48527f802 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -323,6 +323,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li case ACTOR_BG_MIZU_SHUTTER: case ACTOR_SHOT_SUN: case ACTOR_BG_HAKA_GATE: + case ACTOR_EN_KAKASI2: *should = false; RateLimitedSuccessChime(); break; From 1edd41e807325522fd618d75b997846257a5bc3a Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Fri, 20 Dec 2024 19:56:36 +0000 Subject: [PATCH 04/12] Fix freeing gorons cutscene leaving link in cutscene state until the goron actor is killed (#4712) * Fix goron cutscene * Update soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c --- soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index 950a62964..82abfca31 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -1923,8 +1923,8 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { if (GameInteractor_Should(VB_PLAY_GORON_FREE_CS, true)) { EnGo2_GoronFireCamera(this, play); + play->msgCtx.msgMode = MSGMODE_PAUSED; } - play->msgCtx.msgMode = MSGMODE_PAUSED; Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_2); this->waypoint = 1; this->skelAnime.playSpeed = 2.0f; From c17b55b465ca122cff68e2c125940f41affa9bde Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Fri, 20 Dec 2024 22:44:35 +0000 Subject: [PATCH 05/12] Improve KZ hook (#4732) * improve KZ hook * Adjust KZ hooks to permit early eyeball frog in rando * Update soh/soh/Enhancements/randomizer/hook_handlers.cpp Co-authored-by: Archez * Update soh/soh/Enhancements/game-interactor/GameInteractor.h Co-authored-by: Archez --------- Co-authored-by: Archez --- .../game-interactor/GameInteractor.h | 10 ++-- .../Enhancements/randomizer/hook_handlers.cpp | 46 ++++++++++++------- soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c | 38 ++++++--------- soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h | 1 - 4 files changed, 47 insertions(+), 48 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 44d0ef1fc..754b77cc1 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -196,6 +196,9 @@ typedef enum { // Opt: *EnKz // Vanilla condition: Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED) VB_KING_ZORA_BE_MOVED, + // Opt: *EnKz, + // Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) + VB_KING_ZORA_TUNIC_CHECK, // Vanilla condition: gSaveState.bgsFlag VB_BIGGORON_CONSIDER_TRADE_COMPLETE, // Vanilla condition: gSaveState.bgsFlag @@ -395,9 +398,6 @@ typedef enum { VB_GIVE_ITEM_FROM_ANJU_AS_CHILD, // Opt: *EnNiwLady VB_GIVE_ITEM_FROM_ANJU_AS_ADULT, - // Opt: *EnKz - // Vanilla condition: !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) - VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, // Opt: *EnGo2 VB_GIVE_ITEM_FROM_GORON, // Opt: *EnGb @@ -479,13 +479,13 @@ typedef enum { // Opt: *EnToryo VB_TRADE_SAW, // Opt: *EnKz, - VB_TRADE_PRESCRIPTION, + VB_ADULT_KING_ZORA_ITEM_GIVE, // Opt: *EnMk VB_TRADE_FROG, VB_TRADE_TIMER_ODD_MUSHROOM, - VB_TRADE_TIMER_EYEDROPS, VB_TRADE_TIMER_FROG, + VB_TRADE_TIMER_EYEDROPS, // Opt: *EnNiwLady VB_ANJU_SET_OBTAINED_TRADE_ITEM, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 0a99dfb86..93213afb8 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -946,6 +946,12 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } break; } + case VB_KING_ZORA_TUNIC_CHECK: { + if (!Flags_GetRandomizerInf(RAND_INF_KING_ZORA_THAWED)) { + *should = false; + } + break; + } case VB_BIGGORON_CONSIDER_SWORD_COLLECTED: { *should = Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK); break; @@ -1054,17 +1060,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = false; break; } - case VB_GIVE_ITEM_FROM_THAWING_KING_ZORA: { - EnKz* enKz = va_arg(args, EnKz*); - // If we aren't setting up the item offer, then we're just checking if it should be possible. - if (enKz->actionFunc != (EnKzActionFunc)EnKz_SetupGetItem) { - // Always give the reward in rando - *should = true; - break; - } - *should = false; - break; - } case VB_GIVE_ITEM_FROM_ANJU_AS_CHILD: { Flags_SetItemGetInf(ITEMGETINF_0C); *should = false; @@ -1195,14 +1190,31 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = false; break; } - case VB_TRADE_PRESCRIPTION: { + case VB_ADULT_KING_ZORA_ITEM_GIVE: { EnKz* enKz = va_arg(args, EnKz*); - // If we aren't setting up the item offer, then we're just checking if it should be possible. - if (enKz->actionFunc != (EnKzActionFunc)EnKz_SetupGetItem) { - *should = !Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); - break; + Input input = gPlayState->state.input[0]; + + if (CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + // For early eyeball frog hook override, simulate collection delay behavior by just checking for the R + // button being held while wearing a shield, and a trade item lower than frog in inventory + bool hasShieldHoldingR = (CHECK_BTN_ANY(input.cur.button, BTN_R) && + CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) > EQUIP_VALUE_SHIELD_NONE); + + if (func_8002F368(gPlayState) == EXCH_ITEM_PRESCRIPTION || + (hasShieldHoldingR && INV_CONTENT(ITEM_TRADE_ADULT) < ITEM_FROG)) { + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_PRESCRIPTION); + } else { + Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); + } + } else { + if (enKz->isTrading){ + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_PRESCRIPTION); + } else { + Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); + } } - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_PRESCRIPTION); *should = false; break; } diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index e6ad9e997..22e0fa413 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -94,9 +94,8 @@ u16 EnKz_GetTextNoMaskAdult(PlayState* play, EnKz* this) { // this works because both ITEM_NONE and later trade items are > ITEM_FROG if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_FROG) { if (!Flags_GetInfTable(INFTABLE_139)) { - if (!GameInteractor_Should(VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, ( - !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) - ), this)) { + if (GameInteractor_Should(VB_KING_ZORA_TUNIC_CHECK, + CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA), this)) { return 0x401F; } else { return 0x4012; @@ -148,7 +147,7 @@ s16 func_80A9C6C0(PlayState* play, Actor* thisx) { case 0x401F: Flags_SetInfTable(INFTABLE_139); break; - } + } } break; case TEXT_STATE_CLOSING: @@ -306,15 +305,13 @@ void func_80A9CB18(EnKz* this, PlayState* play) { if (LINK_IS_ADULT) { if ((INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_PRESCRIPTION) && (func_8002F368(play) == EXCH_ITEM_PRESCRIPTION)) { - if (GameInteractor_Should(VB_TRADE_PRESCRIPTION, true, this)) { - this->actor.textId = 0x4014; - this->sfxPlayed = false; - player->actor.textId = this->actor.textId; - if (!CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { - this->isTrading = true; - } - return; + this->actor.textId = 0x4014; + this->sfxPlayed = false; + player->actor.textId = this->actor.textId; + if (!CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + this->isTrading = true; } + return; } if (!CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { this->isTrading = false; @@ -324,11 +321,10 @@ void func_80A9CB18(EnKz* this, PlayState* play) { player->actor.textId = this->actor.textId; } else { this->actor.textId = - !GameInteractor_Should(VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, - (!CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA)), this) + GameInteractor_Should(VB_KING_ZORA_TUNIC_CHECK, + CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA), this) ? 0x401F : 0x4012; - player->actor.textId = this->actor.textId; } } @@ -511,18 +507,10 @@ void EnKz_SetupGetItem(EnKz* this, PlayState* play) { f32 xzRange; f32 yRange; - if (Actor_HasParent(&this->actor, play) || ( - (this->isTrading && !GameInteractor_Should(VB_TRADE_PRESCRIPTION, true, this)) || - (!this->isTrading && !GameInteractor_Should(VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, true, this)) - )) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_ADULT_KING_ZORA_ITEM_GIVE, true, this)) { this->actor.parent = NULL; this->interactInfo.talkState = NPC_TALK_STATE_TALKING; this->actionFunc = EnKz_StartTimer; - if (!this->isTrading) { - Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); - } else { - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); - } } else { if (CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { getItemId = func_8002F368(play) == EXCH_ITEM_PRESCRIPTION ? GI_FROG : GI_TUNIC_ZORA; @@ -537,7 +525,7 @@ void EnKz_SetupGetItem(EnKz* this, PlayState* play) { void EnKz_StartTimer(EnKz* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { - if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_FROG && GameInteractor_Should(VB_TRADE_TIMER_FROG, true)) { + if (GameInteractor_Should(VB_TRADE_TIMER_FROG, INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_FROG)) { func_80088AA0(180); // start timer2 with 3 minutes gSaveContext.eventInf[1] &= ~1; } diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h index c97732356..0b48ff202 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h @@ -28,6 +28,5 @@ typedef struct EnKz { /* 0x02BE */ s16 unk_2BE[12]; } EnKz; // size = 0x02D8 -void EnKz_SetupGetItem(EnKz* enKz, PlayState* play); #endif From 35e0a7ce10ce6ad2406b0306d74e045df99237d8 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Fri, 20 Dec 2024 23:09:59 +0000 Subject: [PATCH 06/12] Remove excess magic from the MQ GTG pots (#4710) * remove excess magic * change rupees to hearts --- soh/soh/Enhancements/randomizer/location_list.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 1b707648a..86ac2832c 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -1594,10 +1594,10 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2] = Location::Pot(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-1150, -3031), "MQ Storage Room B Pot 2", "Water Temple MQ Storage Room B Pot 2", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2)); locationTable[RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1] = Location::Pot(RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(28, -3817), "MQ Mini Dodongo Pot 1", "Water Temple MQ Mini Dodongo Pot 1", RHT_POT_WATER_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1)); locationTable[RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2] = Location::Pot(RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-28, -3817), "MQ Mini Dodongo Pot 2", "Water Temple MQ Mini Dodongo Pot 2", RHT_POT_WATER_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2)); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-324, -72), "MQ Lobby Left Pot 1", "Gerudo Training Ground MQ Lobby Left Pot 1", RHT_POT_GERUDO_TRAINING_GROUND, RG_MAGIC_SINGLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1)); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-324, -177), "MQ Lobby Left Pot 2", "Gerudo Training Ground MQ Lobby Left Pot 2", RHT_POT_GERUDO_TRAINING_GROUND, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2)); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(199, -79), "MQ Lobby Right Pot 1", "Gerudo Training Ground MQ Lobby Right Pot 1", RHT_POT_GERUDO_TRAINING_GROUND, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1)); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(197, -179), "MQ Lobby Right Pot 2", "Gerudo Training Ground MQ Lobby Right Pot 2", RHT_POT_GERUDO_TRAINING_GROUND, RG_MAGIC_DOUBLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-324, -72), "MQ Lobby Left Pot 1", "Gerudo Training Ground MQ Lobby Left Pot 1", RHT_POT_GERUDO_TRAINING_GROUND, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-324, -177), "MQ Lobby Left Pot 2", "Gerudo Training Ground MQ Lobby Left Pot 2", RHT_POT_GERUDO_TRAINING_GROUND, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(199, -79), "MQ Lobby Right Pot 1", "Gerudo Training Ground MQ Lobby Right Pot 1", RHT_POT_GERUDO_TRAINING_GROUND, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(197, -179), "MQ Lobby Right Pot 2", "Gerudo Training Ground MQ Lobby Right Pot 2", RHT_POT_GERUDO_TRAINING_GROUND, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2)); // Gossip Stones From dd11751b43894fc51772393825f6971eaa38b773 Mon Sep 17 00:00:00 2001 From: Jordan Longstaff Date: Fri, 20 Dec 2024 18:26:42 -0500 Subject: [PATCH 07/12] Rename `code_80043480.c` from decomp (#4731) --- soh/include/functions.h | 18 +++---- soh/include/z64actor.h | 11 ++++- soh/src/code/code_800430A0.c | 8 ++-- soh/src/code/{code_80043480.c => z_bg_item.c} | 48 +++++++++---------- soh/src/code/z_bgcheck.c | 2 +- soh/src/code/z_en_a_keep.c | 6 +-- .../ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c | 8 ++-- .../ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c | 10 ++-- .../ovl_Bg_Gnd_Firemeiro/z_bg_gnd_firemeiro.c | 6 +-- .../actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c | 2 +- .../ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c | 8 ++-- .../ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c | 2 +- .../ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c | 10 ++-- .../ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c | 4 +- .../ovl_Bg_Hidan_Syoku/z_bg_hidan_syoku.c | 6 +-- .../ovl_Bg_Jya_1flift/z_bg_jya_1flift.c | 2 +- .../actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c | 7 +-- .../z_bg_menkuri_kaiten.c | 2 +- .../ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c | 2 +- .../ovl_Bg_Mori_Elevator/z_bg_mori_elevator.c | 5 +- .../z_bg_spot08_iceblock.c | 4 +- .../actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.c | 6 +-- .../actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c | 2 +- .../overlays/actors/ovl_En_Brob/z_en_brob.c | 2 +- .../actors/ovl_En_Lightbox/z_en_lightbox.c | 4 +- .../actors/ovl_En_Pu_box/z_en_pu_box.c | 4 +- .../actors/ovl_En_Siofuki/z_en_siofuki.c | 2 +- .../overlays/actors/ovl_Obj_Bean/z_obj_bean.c | 10 ++-- .../actors/ovl_Obj_Elevator/z_obj_elevator.c | 4 +- .../overlays/actors/ovl_Obj_Lift/z_obj_lift.c | 2 +- .../actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c | 10 ++-- .../actors/ovl_Obj_Switch/z_obj_switch.c | 16 ++++--- .../ovl_Obj_Timeblock/z_obj_timeblock.c | 2 +- .../ovl_Obj_Warp2block/z_obj_warp2block.c | 2 +- .../actors/ovl_player_actor/z_player.c | 4 +- 35 files changed, 126 insertions(+), 115 deletions(-) rename soh/src/code/{code_80043480.c => z_bg_item.c} (57%) diff --git a/soh/include/functions.h b/soh/include/functions.h index d4b47b60c..64d7026e1 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -717,15 +717,15 @@ void BgCheck_DrawStaticCollision(PlayState*, CollisionContext*); void func_80043334(CollisionContext* colCtx, Actor* actor, s32 bgId); s32 func_800433A4(CollisionContext* colCtx, s32 bgId, Actor* actor); void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 flags); -void func_800434A0(DynaPolyActor* dynaActor); -void func_800434A8(DynaPolyActor* dynaActor); -void func_800434C8(CollisionContext* colCtx, s32 floorBgId); -void func_80043508(CollisionContext* colCtx, s32 floorBgId); -void func_80043538(DynaPolyActor* dynaActor); -s32 func_80043548(DynaPolyActor* dynaActor); -s32 func_8004356C(DynaPolyActor* dynaActor); -s32 func_80043590(DynaPolyActor* dynaActor); -s32 func_800435B4(DynaPolyActor* dynaActor); +void DynaPolyActor_UnsetAllInteractFlags(DynaPolyActor* dynaActor); +void DynaPolyActor_SetActorOnTop(DynaPolyActor* dynaActor); +void DynaPoly_SetPlayerOnTop(CollisionContext* colCtx, s32 floorBgId); +void DynaPoly_SetPlayerAbove(CollisionContext* colCtx, s32 floorBgId); +void DynaPolyActor_SetSwitchPressed(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsActorOnTop(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsPlayerOnTop(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsPlayerAbove(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsSwitchPressed(DynaPolyActor* dynaActor); s32 func_800435D8(PlayState* play, DynaPolyActor* dynaActor, s16 arg2, s16 arg3, s16 arg4); void Camera_Init(Camera* camera, View* view, CollisionContext* colCtx, PlayState* play); void Camera_InitPlayerSettings(Camera* camera, Player* player); diff --git a/soh/include/z64actor.h b/soh/include/z64actor.h index 156f1d679..5d6bfc26b 100644 --- a/soh/include/z64actor.h +++ b/soh/include/z64actor.h @@ -214,6 +214,13 @@ if neither of the above are set : blue 0x2000 : translucent, else opaque */ +#define DYNA_INTERACT_ACTOR_ON_TOP (1 << 0) // There is an actor standing on the collision of the dynapoly actor +#define DYNA_INTERACT_PLAYER_ON_TOP (1 << 1) // The player actor is standing on the collision of the dynapoly actor +#define DYNA_INTERACT_PLAYER_ABOVE \ + (1 << 2) // The player is directly above the collision of the dynapoly actor (any distance above) +#define DYNA_INTERACT_ACTOR_SWITCH_PRESSED \ + (1 << 3) // An actor that is capable of pressing switches is on top of the dynapoly actor + typedef struct DynaPolyActor { /* 0x000 */ struct Actor actor; /* 0x14C */ s32 bgId; @@ -221,8 +228,8 @@ typedef struct DynaPolyActor { /* 0x154 */ f32 unk_154; /* 0x158 */ s16 unk_158; // y rotation? /* 0x15A */ u16 unk_15A; - /* 0x15C */ u32 unk_15C; - /* 0x160 */ u8 unk_160; + /* 0x15C */ u32 transformFlags; + /* 0x160 */ u8 interactFlags; /* 0x162 */ s16 unk_162; } DynaPolyActor; // size = 0x164 diff --git a/soh/src/code/code_800430A0.c b/soh/src/code/code_800430A0.c index 379f4a3e6..6047b2fc0 100644 --- a/soh/src/code/code_800430A0.c +++ b/soh/src/code/code_800430A0.c @@ -60,10 +60,10 @@ void func_80043334(CollisionContext* colCtx, Actor* actor, s32 bgId) { if (DynaPoly_IsBgIdBgActor(bgId)) { DynaPolyActor* dynaActor = DynaPoly_GetActor(colCtx, bgId); if (dynaActor != NULL) { - func_800434A8(dynaActor); + DynaPolyActor_SetActorOnTop(dynaActor); if (CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_CAN_PRESS_SWITCH)) { - func_80043538(dynaActor); + DynaPolyActor_SetSwitchPressed(dynaActor); } } } @@ -91,12 +91,12 @@ s32 func_800433A4(CollisionContext* colCtx, s32 bgId, Actor* actor) { return false; } - if (dynaActor->unk_15C & 1) { + if (dynaActor->transformFlags & 1) { func_800430A0(colCtx, bgId, actor); result = true; } - if (dynaActor->unk_15C & 2) { + if (dynaActor->transformFlags & 2) { func_800432A0(colCtx, bgId, actor); result = true; } diff --git a/soh/src/code/code_80043480.c b/soh/src/code/z_bg_item.c similarity index 57% rename from soh/src/code/code_80043480.c rename to soh/src/code/z_bg_item.c index 3ba733e26..d36374b59 100644 --- a/soh/src/code/code_80043480.c +++ b/soh/src/code/z_bg_item.c @@ -2,74 +2,74 @@ void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 flags) { dynaActor->bgId = -1; - dynaActor->unk_15C = flags; - dynaActor->unk_160 = 0; + dynaActor->transformFlags = flags; + dynaActor->interactFlags = 0; dynaActor->unk_150 = 0.0f; dynaActor->unk_154 = 0.0f; } -void func_800434A0(DynaPolyActor* dynaActor) { - dynaActor->unk_160 = 0; +void DynaPolyActor_UnsetAllInteractFlags(DynaPolyActor* dynaActor) { + dynaActor->interactFlags = 0; } -void func_800434A8(DynaPolyActor* dynaActor) { - dynaActor->unk_160 |= 1; +void DynaPolyActor_SetActorOnTop(DynaPolyActor* dynaActor) { + dynaActor->interactFlags |= DYNA_INTERACT_ACTOR_ON_TOP; } -void func_800434B8(DynaPolyActor* dynaActor) { - dynaActor->unk_160 |= 2; +void DynaPolyActor_SetPlayerOnTop(DynaPolyActor* dynaActor) { + dynaActor->interactFlags |= DYNA_INTERACT_PLAYER_ON_TOP; } -void func_800434C8(CollisionContext* colCtx, s32 floorBgId) { +void DynaPoly_SetPlayerOnTop(CollisionContext* colCtx, s32 floorBgId) { DynaPolyActor* dynaActor = DynaPoly_GetActor(colCtx, floorBgId); if (dynaActor != NULL) { - func_800434B8(dynaActor); + DynaPolyActor_SetPlayerOnTop(dynaActor); } } -void func_800434F8(DynaPolyActor* dynaActor) { - dynaActor->unk_160 |= 4; +void DynaPolyActor_SetPlayerAbove(DynaPolyActor* dynaActor) { + dynaActor->interactFlags |= DYNA_INTERACT_PLAYER_ABOVE; } -void func_80043508(CollisionContext* colCtx, s32 floorBgId) { +void DynaPoly_SetPlayerAbove(CollisionContext* colCtx, s32 floorBgId) { DynaPolyActor* dynaActor = DynaPoly_GetActor(colCtx, floorBgId); if (dynaActor != NULL) { - func_800434F8(dynaActor); + DynaPolyActor_SetPlayerAbove(dynaActor); } } -void func_80043538(DynaPolyActor* dynaActor) { - dynaActor->unk_160 |= 8; +void DynaPolyActor_SetSwitchPressed(DynaPolyActor* dynaActor) { + dynaActor->interactFlags |= DYNA_INTERACT_ACTOR_SWITCH_PRESSED; } -s32 func_80043548(DynaPolyActor* dynaActor) { - if (dynaActor->unk_160 & 1) { +s32 DynaPolyActor_IsActorOnTop(DynaPolyActor* dynaActor) { + if (dynaActor->interactFlags & DYNA_INTERACT_ACTOR_ON_TOP) { return true; } else { return false; } } -s32 func_8004356C(DynaPolyActor* dynaActor) { - if (dynaActor->unk_160 & 2) { +s32 DynaPolyActor_IsPlayerOnTop(DynaPolyActor* dynaActor) { + if (dynaActor->interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) { return true; } else { return false; } } -s32 func_80043590(DynaPolyActor* dynaActor) { - if (dynaActor->unk_160 & 4) { +s32 DynaPolyActor_IsPlayerAbove(DynaPolyActor* dynaActor) { + if (dynaActor->interactFlags & DYNA_INTERACT_PLAYER_ABOVE) { return true; } else { return false; } } -s32 func_800435B4(DynaPolyActor* dynaActor) { - if (dynaActor->unk_160 & 8) { +s32 DynaPolyActor_IsSwitchPressed(DynaPolyActor* dynaActor) { + if (dynaActor->interactFlags & DYNA_INTERACT_ACTOR_SWITCH_PRESSED) { return true; } else { return false; diff --git a/soh/src/code/z_bgcheck.c b/soh/src/code/z_bgcheck.c index df7dd0600..20deee679 100644 --- a/soh/src/code/z_bgcheck.c +++ b/soh/src/code/z_bgcheck.c @@ -2954,7 +2954,7 @@ void func_8003F8EC(PlayState* play, DynaCollisionContext* dyna, Actor* actor) { if ((dyna->bgActorFlags[i] & 1)) { dynaActor = DynaPoly_GetActor(&play->colCtx, i); if (dynaActor != NULL && &dynaActor->actor == actor) { - func_800434A0((DynaPolyActor*)actor); + DynaPolyActor_UnsetAllInteractFlags((DynaPolyActor*)actor); return; } } diff --git a/soh/src/code/z_en_a_keep.c b/soh/src/code/z_en_a_keep.c index 307ecf048..9b29b666e 100644 --- a/soh/src/code/z_en_a_keep.c +++ b/soh/src/code/z_en_a_keep.c @@ -122,8 +122,8 @@ void EnAObj_Init(Actor* thisx, PlayState* play) { thisx->focus.pos = thisx->world.pos; this->dyna.bgId = BGACTOR_NEG_ONE; - this->dyna.unk_160 = 0; - this->dyna.unk_15C = DPM_UNK; + this->dyna.interactFlags = 0; + this->dyna.transformFlags = DPM_UNK; thisx->uncullZoneDownward = 1200.0f; thisx->uncullZoneScale = 200.0f; @@ -234,7 +234,7 @@ void EnAObj_SetupBlockRot(EnAObj* this, s16 type) { void EnAObj_BlockRot(EnAObj* this, PlayState* play) { if (this->rotateState == 0) { - if (this->dyna.unk_160 != 0) { + if (this->dyna.interactFlags != 0) { this->rotateState++; this->rotateForTimer = 20; diff --git a/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c b/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c index 489a50cfa..e46758bd0 100644 --- a/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c @@ -326,7 +326,7 @@ void func_8086C6EC(BgBdanObjects* this, PlayState* play) { } void func_8086C76C(BgBdanObjects* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->dyna.actor.xzDistToPlayer < 120.0f) { this->actionFunc = func_8086C7D0; OnePointCutscene_Init(play, 3090, -99, &this->dyna.actor, MAIN_CAM); @@ -352,7 +352,7 @@ void func_8086C874(BgBdanObjects* this, PlayState* play) { this->timer--; } if (this->switchFlag == 0) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->cameraSetting = play->cameraPtrs[MAIN_CAM]->setting; Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_NORMAL2); func_8005AD1C(play->cameraPtrs[MAIN_CAM], 4); @@ -360,7 +360,7 @@ void func_8086C874(BgBdanObjects* this, PlayState* play) { } } else { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_NORMAL2); - if (!func_8004356C(&this->dyna)) { + if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->switchFlag != 0) { this->switchFlag--; } @@ -411,7 +411,7 @@ void func_8086CABC(BgBdanObjects* this, PlayState* play) { } void func_8086CB10(BgBdanObjects* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { Flags_SetSwitch(play, this->switchFlag); this->timer = 50; this->actionFunc = func_8086CB8C; diff --git a/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c b/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c index 7e0781067..13ecc51bb 100644 --- a/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c +++ b/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c @@ -254,13 +254,13 @@ void func_8086D5C4(BgBdanSwitch* this) { void func_8086D5E0(BgBdanSwitch* this, PlayState* play) { switch (this->dyna.actor.params & 0xFF) { case BLUE: - if (func_800435B4(&this->dyna)) { + if (DynaPolyActor_IsSwitchPressed(&this->dyna)) { func_8086D67C(this); func_8086D4B4(this, play); } break; case YELLOW: - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { func_8086D67C(this); func_8086D4B4(this, play); } @@ -293,7 +293,7 @@ void func_8086D730(BgBdanSwitch* this) { void func_8086D754(BgBdanSwitch* this, PlayState* play) { switch (this->dyna.actor.params & 0xFF) { case BLUE: - if (!func_800435B4(&this->dyna)) { + if (!DynaPolyActor_IsSwitchPressed(&this->dyna)) { if (this->unk_1D8 <= 0) { func_8086D7FC(this); func_8086D548(this, play); @@ -328,7 +328,7 @@ void func_8086D86C(BgBdanSwitch* this) { } void func_8086D888(BgBdanSwitch* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { func_8086D8BC(this); } } @@ -371,7 +371,7 @@ void func_8086D9F8(BgBdanSwitch* this) { void func_8086DA1C(BgBdanSwitch* this, PlayState* play) { Actor* heldActor = GET_PLAYER(play)->heldActor; - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (heldActor != NULL && heldActor->id == ACTOR_EN_RU1) { if (this->unk_1D8 <= 0) { func_8086D944(this); diff --git a/soh/src/overlays/actors/ovl_Bg_Gnd_Firemeiro/z_bg_gnd_firemeiro.c b/soh/src/overlays/actors/ovl_Bg_Gnd_Firemeiro/z_bg_gnd_firemeiro.c index fa66b29aa..e838191ae 100644 --- a/soh/src/overlays/actors/ovl_Bg_Gnd_Firemeiro/z_bg_gnd_firemeiro.c +++ b/soh/src/overlays/actors/ovl_Bg_Gnd_Firemeiro/z_bg_gnd_firemeiro.c @@ -60,7 +60,7 @@ void BgGndFiremeiro_Destroy(Actor* thisx, PlayState* play2) { void BgGndFiremeiro_Sink(BgGndFiremeiro* this, PlayState* play) { f32 sunkHeight = this->initPos.y - 150.0f; - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->timer = 10; } @@ -85,7 +85,7 @@ void BgGndFiremeiro_Shake(BgGndFiremeiro* this, PlayState* play) { s32 pad; f32 randSign; - if (func_8004356C(&this->dyna)) { // Player standing on it + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { // Player standing on it if (this->timer > 0) { this->timer--; @@ -114,7 +114,7 @@ void BgGndFiremeiro_Rise(BgGndFiremeiro* this, PlayState* play) { Player* player = GET_PLAYER(play); Actor* thisx = &this->dyna.actor; - if ((player->currentBoots != PLAYER_BOOTS_HOVER) && func_8004356C(&this->dyna)) { // Player standing on it + if ((player->currentBoots != PLAYER_BOOTS_HOVER) && DynaPolyActor_IsPlayerOnTop(&this->dyna)) { // Player standing on it if (thisx->world.pos.y < this->initPos.y) { this->actionFunc = BgGndFiremeiro_Sink; this->timer = 20; diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c b/soh/src/overlays/actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c index cec9f68e4..b47a85590 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c @@ -179,7 +179,7 @@ void BgHakaShip_CrashFall(BgHakaShip* this, PlayState* play) { } } else { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCKSINK - SFX_FLAG); - if ((this->dyna.actor.home.pos.y - this->dyna.actor.world.pos.y > 500.0f) && func_8004356C(&this->dyna)) { + if ((this->dyna.actor.home.pos.y - this->dyna.actor.world.pos.y > 500.0f) && DynaPolyActor_IsPlayerOnTop(&this->dyna)) { Play_TriggerVoidOut(play); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c index e7151be7d..9ff062dd7 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c @@ -90,7 +90,7 @@ void func_80886FCC(BgHidanFslift* this, PlayState* play) { if ((this->dyna.actor.world.pos.y - this->dyna.actor.home.pos.y) < 0.5f) { heightBool = true; } - if (func_80043590(&this->dyna) && (heightBool)) { + if (DynaPolyActor_IsPlayerAbove(&this->dyna) && (heightBool)) { this->actionFunc = func_808870D8; } else if (!heightBool) { this->actionFunc = func_8088706C; @@ -109,7 +109,7 @@ void func_8088706C(BgHidanFslift* this, PlayState* play) { } void func_808870D8(BgHidanFslift* this, PlayState* play) { - if (func_80043590(&this->dyna)) { + if (DynaPolyActor_IsPlayerAbove(&this->dyna)) { if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 790.0f, 4.0f)) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); func_80886FB4(this); @@ -126,12 +126,12 @@ void BgHidanFslift_Update(Actor* thisx, PlayState* play) { BgHidanFslift* this = (BgHidanFslift*)thisx; this->actionFunc(this, play); - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_16A == 0) { this->unk_16A = 3; } Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_FIRE_PLATFORM); - } else if (!func_8004356C(&this->dyna)) { + } else if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_16A != 0) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c index ea49fbd4f..fecd9451a 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c @@ -216,7 +216,7 @@ void func_808896B8(BgHidanHrock* this, PlayState* play) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); } - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y - 5.0f, 1.0f); } else { Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 1.0f); diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c index 15f8a6586..108378185 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c @@ -212,7 +212,7 @@ void func_8088B5F4(BgHidanRock* this, PlayState* play) { } void func_8088B634(BgHidanRock* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->timer = 20; this->dyna.actor.world.rot.y = Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x4000; this->actionFunc = func_8088B69C; @@ -263,12 +263,12 @@ void func_8088B79C(BgHidanRock* this, PlayState* play) { this->unk_16C = CLAMP_MIN(this->unk_16C, 0.0f); if (this->type == 0) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_169 == 0) { this->unk_169 = 3; } Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_FIRE_PLATFORM); - } else if (!func_8004356C(&this->dyna)) { + } else if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_169 != 0) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } @@ -316,12 +316,12 @@ void func_8088B990(BgHidanRock* this, PlayState* play) { this->unk_16C = (this->dyna.actor.world.pos.y + 50.0f - this->dyna.actor.home.pos.y + 40.0f) / 80.0f; if (this->type == 0) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_169 == 0) { this->unk_169 = 3; } Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_FIRE_PLATFORM); - } else if (!func_8004356C(&this->dyna)) { + } else if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_169 != 0) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c index 03615e480..2b9331ab8 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c @@ -118,7 +118,7 @@ void func_8088E518(BgHidanSima* this, PlayState* play) { Player* player = GET_PLAYER(play); Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 3.4f); - if (func_8004356C(&this->dyna) && !(player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE))) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna) && !(player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE))) { this->timer = 20; this->dyna.actor.world.rot.y = Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x4000; if (this->dyna.actor.home.pos.y <= this->dyna.actor.world.pos.y) { @@ -150,7 +150,7 @@ void func_8088E5D0(BgHidanSima* this, PlayState* play) { } void func_8088E6D0(BgHidanSima* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->timer = 20; } else if (this->timer != 0) { this->timer--; diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Syoku/z_bg_hidan_syoku.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Syoku/z_bg_hidan_syoku.c index 44c1cc5e5..ae8e5b530 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Syoku/z_bg_hidan_syoku.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Syoku/z_bg_hidan_syoku.c @@ -61,7 +61,7 @@ void func_8088F47C(BgHidanSyoku* this) { } void func_8088F4B8(BgHidanSyoku* this, PlayState* play) { - if (Flags_GetClear(play, this->dyna.actor.room) && func_8004356C(&this->dyna)) { + if (Flags_GetClear(play, this->dyna.actor.room) && DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->timer = 140; this->actionFunc = func_8088F514; } @@ -109,12 +109,12 @@ void BgHidanSyoku_Update(Actor* thisx, PlayState* play) { BgHidanSyoku* this = (BgHidanSyoku*)thisx; this->actionFunc(this, play); - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_168 == 0) { this->unk_168 = 3; } Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_FIRE_PLATFORM); - } else if (!func_8004356C(&this->dyna)) { + } else if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_168 != 0) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } diff --git a/soh/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c b/soh/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c index 35cbc3f49..270bcd9ff 100644 --- a/soh/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c +++ b/soh/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c @@ -187,7 +187,7 @@ void BgJya1flift_Update(Actor* thisx, PlayState* play2) { // Room 0 is the first room and 6 is the room that the lift starts on if (play->roomCtx.curRoom.num == 6 || play->roomCtx.curRoom.num == 0) { this->actionFunc(this, play); - tempIsRiding = func_8004356C(&this->dyna) ? true : false; + tempIsRiding = DynaPolyActor_IsPlayerOnTop(&this->dyna) ? true : false; if ((this->actionFunc == BgJya1flift_Move) || (this->actionFunc == BgJya1flift_DelayMove)) { if (tempIsRiding) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_FIRE_PLATFORM); diff --git a/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c b/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c index f8dea0c01..bc7b756d8 100644 --- a/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c +++ b/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c @@ -146,13 +146,14 @@ void BgJyaLift_Update(Actor* thisx, PlayState* play2) { if (this->actionFunc != NULL) { this->actionFunc(this, play); } - if ((this->dyna.unk_160 & 4) && ((this->unk_16B & 4) == 0)) { + if ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ABOVE) && + ((this->unk_16B & DYNA_INTERACT_PLAYER_ABOVE) == 0)) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DIRECTED_YAW); - } else if (((this->dyna.unk_160) & 4) == 0 && ((this->unk_16B & 4)) && + } else if (((this->dyna.interactFlags) & 4) == 0 && ((this->unk_16B & 4)) && (play->cameraPtrs[MAIN_CAM]->setting == CAM_SET_DIRECTED_YAW)) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } - this->unk_16B = this->dyna.unk_160; + this->unk_16B = this->dyna.interactFlags; // Spirit Temple room 5 is the main room with the statue room 25 is directly above room 5 if ((play->roomCtx.curRoom.num != 5) && (play->roomCtx.curRoom.num != 25)) { diff --git a/soh/src/overlays/actors/ovl_Bg_Menkuri_Kaiten/z_bg_menkuri_kaiten.c b/soh/src/overlays/actors/ovl_Bg_Menkuri_Kaiten/z_bg_menkuri_kaiten.c index f209fa291..90a3cbee1 100644 --- a/soh/src/overlays/actors/ovl_Bg_Menkuri_Kaiten/z_bg_menkuri_kaiten.c +++ b/soh/src/overlays/actors/ovl_Bg_Menkuri_Kaiten/z_bg_menkuri_kaiten.c @@ -51,7 +51,7 @@ void BgMenkuriKaiten_Destroy(Actor* thisx, PlayState* play) { void BgMenkuriKaiten_Update(Actor* thisx, PlayState* play) { BgMenkuriKaiten* this = (BgMenkuriKaiten*)thisx; - if (!Flags_GetSwitch(play, this->dyna.actor.params) && func_80043590(&this->dyna)) { + if (!Flags_GetSwitch(play, this->dyna.actor.params) && DynaPolyActor_IsPlayerAbove(&this->dyna)) { func_8002F974(&this->dyna.actor, NA_SE_EV_ELEVATOR_MOVE - SFX_FLAG); this->dyna.actor.shape.rot.y += 0x80; } diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c b/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c index 611a892cf..c95fe6fd8 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c @@ -241,7 +241,7 @@ void BgMoriBigst_Update(Actor* thisx, PlayState* play) { if (this->waitTimer > 0) { this->waitTimer--; } - if (func_80043590(&this->dyna)) { + if (DynaPolyActor_IsPlayerAbove(&this->dyna)) { func_80074CE8(play, 6); } if (this->actionFunc != NULL) { diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Elevator/z_bg_mori_elevator.c b/soh/src/overlays/actors/ovl_Bg_Mori_Elevator/z_bg_mori_elevator.c index e5e84af5a..f0ca8d96c 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Elevator/z_bg_mori_elevator.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Elevator/z_bg_mori_elevator.c @@ -125,7 +125,8 @@ void BgMoriElevator_Destroy(Actor* thisx, PlayState* play) { } s32 BgMoriElevator_IsPlayerRiding(BgMoriElevator* this, PlayState* play) { - return ((this->dyna.unk_160 & 2) && !(this->unk_170 & 2) && + return ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) && + !(this->unk_170 & DYNA_INTERACT_PLAYER_ON_TOP) && ((GET_PLAYER(play)->actor.world.pos.y - this->dyna.actor.world.pos.y) < 80.0f)); } @@ -244,7 +245,7 @@ void BgMoriElevator_Update(Actor* thisx, PlayState* play) { BgMoriElevator* this = (BgMoriElevator*)thisx; this->actionFunc(this, play); - this->unk_170 = this->dyna.unk_160; + this->unk_170 = this->dyna.interactFlags; this->unk_16C = Flags_GetSwitch(play, (thisx->params & 0x3F)); } diff --git a/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c b/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c index d7b45c9b6..2eb0bef7e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c @@ -101,7 +101,7 @@ void BgSpot08Iceblock_SinkUnderPlayer(BgSpot08Iceblock* this) { } // Sink under Player's weight if standing on it - target = (func_80043548(&this->dyna) ? -4.0f : 0.0f); + target = (DynaPolyActor_IsActorOnTop(&this->dyna) ? -4.0f : 0.0f); Math_StepToF(&this->sinkOffset, target, step); } @@ -200,7 +200,7 @@ void BgSpot08Iceblock_Roll(BgSpot08Iceblock* this, PlayState* play) { surfaceNormalHorizontal.z = this->surfaceNormal.z; // If player is standing on it or holding the edge - if (func_8004356C(&this->dyna) && (playerCentroidDist > 3.0f)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna) && (playerCentroidDist > 3.0f)) { Math_Vec3f_Diff(&playerCentroidDiff, &surfaceNormalHorizontal, &playerMoment); BgSpot08Iceblock_MultVectorScalar(&playerMoment, &playerMoment, (sInertias[rollDataIndex] * playerCentroidDist) / this->dyna.actor.scale.x); diff --git a/soh/src/overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.c b/soh/src/overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.c index af63fdcd2..bf4d7c934 100644 --- a/soh/src/overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.c +++ b/soh/src/overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.c @@ -62,13 +62,13 @@ void BgSstFloor_Update(BgSstFloor* thisx, PlayState* play) { colHeader->vtxList = SEGMENTED_TO_VIRTUAL(colHeader->vtxList); - if (func_80043590(&this->dyna) && (this->dyna.actor.yDistToPlayer < 1000.0f)) { + if (DynaPolyActor_IsPlayerAbove(&this->dyna) && (this->dyna.actor.yDistToPlayer < 1000.0f)) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_BOSS_BONGO); } else { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } - if (func_8004356C(&this->dyna) && (player->fallDistance > 1000.0f)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna) && (player->fallDistance > 1000.0f)) { this->dyna.actor.params = 1; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EN_SHADEST_TAIKO_HIGH); } @@ -82,7 +82,7 @@ void BgSstFloor_Update(BgSstFloor* thisx, PlayState* play) { this->dyna.actor.params = BONGOFLOOR_REST; this->drumPhase = 28; - if (func_8004356C(&this->dyna) && !(player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE))) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna) && !(player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE))) { distFromRim = 600.0f - this->dyna.actor.xzDistToPlayer; if (distFromRim > 0.0f) { if (distFromRim > 350.0f) { diff --git a/soh/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c b/soh/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c index 59402d658..1307971c7 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c +++ b/soh/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c @@ -292,7 +292,7 @@ void BgYdanSp_FloorWebIdle(BgYdanSp* this, PlayState* play) { BgYdanSp_BurnWeb(this, play); return; } - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { sqrtFallDistance = sqrtf(CLAMP_MIN(player->fallDistance, 0.0f)); if (player->fallDistance > 750.0f) { if (this->dyna.actor.xzDistToPlayer < 80.0f) { diff --git a/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c b/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c index 4d7243455..fbedc59bd 100644 --- a/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c +++ b/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c @@ -154,7 +154,7 @@ void func_809CB054(EnBrob* this, PlayState* play) { this->timer--; } if (this->timer == 0) { - if (func_8004356C(&this->dyna) != 0) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna) != 0) { func_8002F71C(play, &this->dyna.actor, 5.0f, this->dyna.actor.yawTowardsPlayer, 1.0f); func_809CAE44(this, play); } else if (this->dyna.actor.xzDistToPlayer < 300.0f) { diff --git a/soh/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c b/soh/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c index 61a411371..5f7aae79a 100644 --- a/soh/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c +++ b/soh/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c @@ -52,8 +52,8 @@ void EnLightbox_Init(Actor* thisx, PlayState* play) { thisx->colChkInfo.cylRadius = 30; thisx->colChkInfo.cylHeight = 50; ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 6.0f); - this->dyna.unk_160 = 0; - this->dyna.unk_15C = 0; + this->dyna.interactFlags = 0; + this->dyna.transformFlags = 0; thisx->targetMode = 0; thisx->gravity = -2.0f; CollisionHeader_GetVirtual(&object_lightbox_Col_001F10, &colHeader); diff --git a/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c b/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c index 140ebd478..536032a8d 100644 --- a/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c +++ b/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c @@ -52,8 +52,8 @@ void EnPubox_Init(Actor* thisx, PlayState* play) { thisx->uncullZoneDownward = 1200.0f; thisx->uncullZoneScale = 720.0f; ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 6.0f); - this->dyna.unk_160 = 0; - this->dyna.unk_15C = DPM_UNK; + this->dyna.interactFlags = 0; + this->dyna.transformFlags = DPM_UNK; thisx->targetMode = 1; thisx->gravity = -2.0f; CollisionHeader_GetVirtual(&gBlockMediumCol, &colHeader); diff --git a/soh/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c b/soh/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c index e577a3d45..8e4596ff3 100644 --- a/soh/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c +++ b/soh/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c @@ -128,7 +128,7 @@ void func_80AFBE8C(EnSiofuki* this, PlayState* play) { if ((dX > (this->dyna.actor.scale.x * -346.0f)) && (dX < (this->dyna.actor.scale.x * 346.0f)) && (dZ > (this->dyna.actor.scale.z * -400.0f)) && (dZ < (this->dyna.actor.scale.z * 400.0f)) && (dY < 0.0f)) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->splashTimer <= 0) { EffectSsGSplash_Spawn(play, &player->actor.world.pos, NULL, NULL, 1, 1); this->splashTimer = 10; diff --git a/soh/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c b/soh/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c index e1dd79b39..20d7fa71a 100644 --- a/soh/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c +++ b/soh/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c @@ -752,7 +752,7 @@ void ObjBean_SetupWaitForPlayer(ObjBean* this) { } void ObjBean_WaitForPlayer(ObjBean* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { // Player is standing on + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { // Player is standing on ObjBean_SetupFly(this); if (play->sceneNum == SCENE_LOST_WOODS) { // Lost woods Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_BEAN_LOST_WOODS); @@ -786,7 +786,7 @@ void ObjBean_Fly(ObjBean* this, PlayState* play) { Camera_ChangeSetting(camera, CAM_SET_NORMAL0); } - } else if (func_8004356C(&this->dyna) != 0) { // Player is on top + } else if (DynaPolyActor_IsPlayerOnTop(&this->dyna) != 0) { // Player is on top func_8002F974(&this->dyna.actor, NA_SE_PL_PLANT_MOVE - SFX_FLAG); @@ -812,7 +812,7 @@ void ObjBean_SetupWaitForStepOff(ObjBean* this) { } void ObjBean_WaitForStepOff(ObjBean* this, PlayState* play) { - if (!func_80043590(&this->dyna)) { + if (!DynaPolyActor_IsPlayerAbove(&this->dyna)) { ObjBean_SetupWaitForPlayer(this); } ObjBean_UpdatePosition(this); @@ -824,7 +824,7 @@ void func_80B908EC(ObjBean* this) { } void func_80B90918(ObjBean* this, PlayState* play) { - if (!func_8004356C(&this->dyna)) { + if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { ObjBean_SetupPathCount(this, play); ObjBean_SetupPath(this, play); ObjBean_Move(this); @@ -904,7 +904,7 @@ void ObjBean_Update(Actor* thisx, PlayState* play) { } Actor_SetFocus(&this->dyna.actor, 6.0f); if (this->stateFlags & BEAN_STATE_DYNAPOLY_SET) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->stateFlags |= BEAN_STATE_PLAYER_ON_TOP; } else { this->stateFlags &= ~BEAN_STATE_PLAYER_ON_TOP; diff --git a/soh/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c b/soh/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c index 694644a80..f62956014 100644 --- a/soh/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c +++ b/soh/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c @@ -86,7 +86,7 @@ void func_80B92C80(ObjElevator* this, PlayState* play) { f32 sub; Actor* thisx = &this->dyna.actor; - if ((this->dyna.unk_160 & 2) && !(this->unk_170 & 2)) { + if ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) && !(this->unk_170 & DYNA_INTERACT_PLAYER_ON_TOP)) { sub = thisx->world.pos.y - thisx->home.pos.y; if (fabsf(sub) < 0.1f) { this->unk_168 = thisx->home.pos.y + ((thisx->params >> 0xC) & 0xF) * 80.0f; @@ -118,7 +118,7 @@ void ObjElevator_Update(Actor* thisx, PlayState* play) { if (this->actionFunc) { this->actionFunc(this, play); } - this->unk_170 = this->dyna.unk_160; + this->unk_170 = this->dyna.interactFlags; } void ObjElevator_Draw(Actor* thisx, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c b/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c index f916bf0fe..166dd4c36 100644 --- a/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c +++ b/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c @@ -138,7 +138,7 @@ void func_80B96560(ObjLift* this, PlayState* play) { s32 pad; s32 quakeIndex; - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->timer <= 0) { if (((this->dyna.actor.params >> 8) & 7) == 7) { func_80B967C0(this); diff --git a/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c b/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c index b1b8cc166..c69417461 100644 --- a/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c +++ b/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c @@ -509,8 +509,8 @@ void ObjOshihiki_OnActor(ObjOshihiki* this, PlayState* play) { } else { dynaPolyActor = DynaPoly_GetActor(&play->colCtx, bgId); if (dynaPolyActor != NULL) { - func_800434A8(dynaPolyActor); - func_80043538(dynaPolyActor); + DynaPolyActor_SetActorOnTop(dynaPolyActor); + DynaPolyActor_SetSwitchPressed(dynaPolyActor); if ((this->timer <= 0) && (fabsf(this->dyna.unk_150) > 0.001f)) { if (ObjOshihiki_StrongEnough(this) && ObjOshihiki_NoSwitchPress(this, dynaPolyActor, play) && @@ -537,9 +537,9 @@ void ObjOshihiki_OnActor(ObjOshihiki* this, PlayState* play) { } else { dynaPolyActor = DynaPoly_GetActor(&play->colCtx, bgId); - if ((dynaPolyActor != NULL) && (dynaPolyActor->unk_15C & 1)) { - func_800434A8(dynaPolyActor); - func_80043538(dynaPolyActor); + if ((dynaPolyActor != NULL) && (dynaPolyActor->transformFlags & 1)) { + DynaPolyActor_SetActorOnTop(dynaPolyActor); + DynaPolyActor_SetSwitchPressed(dynaPolyActor); this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight; } else { ObjOshihiki_SetupFall(this, play); diff --git a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c index e08291480..05e3577c0 100644 --- a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c +++ b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c @@ -390,25 +390,26 @@ void ObjSwitch_FloorUp(ObjSwitch* this, PlayState* play) { } else { switch ((this->dyna.actor.params >> 4 & 7)) { case OBJSWITCH_SUBTYPE_FLOOR_0: - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { ObjSwitch_FloorPressInit(this); ObjSwitch_SetOn(this, play); } break; case OBJSWITCH_SUBTYPE_FLOOR_1: - if ((this->dyna.unk_160 & 2) && !(this->unk_17F & 2)) { + if ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) && + !(this->unk_17F & DYNA_INTERACT_PLAYER_ON_TOP)) { ObjSwitch_FloorPressInit(this); ObjSwitch_SetOn(this, play); } break; case OBJSWITCH_SUBTYPE_FLOOR_2: - if (func_800435B4(&this->dyna)) { + if (DynaPolyActor_IsSwitchPressed(&this->dyna)) { ObjSwitch_FloorPressInit(this); ObjSwitch_SetOn(this, play); } break; case OBJSWITCH_SUBTYPE_FLOOR_3: - if (func_800435B4(&this->dyna)) { + if (DynaPolyActor_IsSwitchPressed(&this->dyna)) { ObjSwitch_FloorPressInit(this); ObjSwitch_SetOff(this, play); } @@ -448,14 +449,15 @@ void ObjSwitch_FloorDown(ObjSwitch* this, PlayState* play) { } break; case OBJSWITCH_SUBTYPE_FLOOR_1: - if ((this->dyna.unk_160 & 2) && !(this->unk_17F & 2)) { + if ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) && + !(this->unk_17F & DYNA_INTERACT_PLAYER_ON_TOP)) { ObjSwitch_FloorReleaseInit(this); ObjSwitch_SetOff(this, play); } break; case OBJSWITCH_SUBTYPE_FLOOR_2: case OBJSWITCH_SUBTYPE_FLOOR_3: - if (!func_800435B4(&this->dyna) && !Player_InCsMode(play)) { + if (!DynaPolyActor_IsSwitchPressed(&this->dyna) && !Player_InCsMode(play)) { if (this->releaseTimer <= 0) { ObjSwitch_FloorReleaseInit(this); if ((this->dyna.actor.params >> 4 & 7) == OBJSWITCH_SUBTYPE_FLOOR_2) { @@ -695,7 +697,7 @@ void ObjSwitch_Update(Actor* thisx, PlayState* play) { switch ((this->dyna.actor.params & 7)) { case OBJSWITCH_TYPE_FLOOR: case OBJSWITCH_TYPE_FLOOR_RUSTY: - this->unk_17F = this->dyna.unk_160; + this->unk_17F = this->dyna.interactFlags; break; case OBJSWITCH_TYPE_EYE: this->unk_17F = this->tris.col.base.acFlags; diff --git a/soh/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c b/soh/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c index dfcf9605d..1701eb60d 100644 --- a/soh/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c +++ b/soh/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c @@ -148,7 +148,7 @@ void ObjTimeblock_Destroy(Actor* thisx, PlayState* play) { } u8 ObjTimeblock_PlayerIsInRange(ObjTimeblock* this, PlayState* play) { - if (this->isVisible && func_80043590(&this->dyna)) { + if (this->isVisible && DynaPolyActor_IsPlayerAbove(&this->dyna)) { return false; } diff --git a/soh/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c b/soh/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c index 8315d42fc..f4c77c73f 100644 --- a/soh/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c +++ b/soh/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c @@ -82,7 +82,7 @@ s32 func_80BA1ECC(ObjWarp2block* this, PlayState* play) { Vec3f sp20; f32 temp_f2; - if (func_80043590(&this->dyna)) { + if (DynaPolyActor_IsPlayerAbove(&this->dyna)) { return 0; } 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 d51e33e8b..cda6356f5 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -11236,7 +11236,7 @@ void Player_ProcessSceneCollision(PlayState* play, Player* this) { func_80074CE8(play, SurfaceType_GetLightSettingIndex(&play->colCtx, floorPoly, this->actor.floorBgId)); } else { - func_80043508(&play->colCtx, this->actor.floorBgId); + DynaPoly_SetPlayerAbove(&play->colCtx, this->actor.floorBgId); } } @@ -11438,7 +11438,7 @@ void Player_ProcessSceneCollision(PlayState* play, Player* this) { s32 pad3; if (this->actor.floorBgId != BGCHECK_SCENE) { - func_800434C8(&play->colCtx, this->actor.floorBgId); + DynaPoly_SetPlayerOnTop(&play->colCtx, this->actor.floorBgId); } floorPolyNormalX = COLPOLY_GET_NORMAL(floorPoly->normal.x); From c5923fafcfcd87425bdf737be85cb201f68ead95 Mon Sep 17 00:00:00 2001 From: Jordan Longstaff Date: Sat, 21 Dec 2024 09:47:37 -0500 Subject: [PATCH 08/12] Fix Door of Time collision when skipping cutscene (#4734) --- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 48527f802..cf93ae27d 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -551,6 +551,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li case VB_PLAY_DOOR_OF_TIME_CS: { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { *should = false; + Flags_SetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME); Flags_SetEnv(gPlayState, 2); Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } From 845e37936e1b8dc73a12f60dce3783c7434499ed Mon Sep 17 00:00:00 2001 From: Jordan Longstaff Date: Sat, 21 Dec 2024 09:52:34 -0500 Subject: [PATCH 09/12] Skip water level change cutscenes in Water Temple (#4726) * Skip water level change cutscenes in Water Temple * Fix disappearing HUD issue --- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index cf93ae27d..76cd25c04 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -215,11 +215,13 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li s16* csId = va_arg(args, s16*); BgSpot03Taki* taki = NULL; switch (*csId) { + case 3120: case 3150: case 4180: case 4100: *should = false; RateLimitedSuccessChime(); + Message_CloseTextbox(gPlayState); taki = (BgSpot03Taki*)Actor_FindNearby(gPlayState, &GET_PLAYER(gPlayState)->actor, ACTOR_BG_SPOT03_TAKI, ACTORCAT_BG, 999.0f); if (taki != NULL) { From 6fb974bfebc11bcfdb4827e7239c63f9ee2d7bcc Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Sat, 21 Dec 2024 16:08:40 +0100 Subject: [PATCH 10/12] Rando Cleanup (#4741) * Delete empty files * Small Cleanup * Remove some now useless comments * Re-add log --- .../randomizer/3drando/category.hpp | 6 ----- .../randomizer/3drando/entrance.cpp | 0 .../randomizer/3drando/item_location.cpp | 0 .../randomizer/3drando/item_pool.cpp | 27 +++++++++---------- .../Enhancements/randomizer/3drando/keys.hpp | 0 .../randomizer/3drando/location_access.cpp | 7 ----- .../Enhancements/randomizer/3drando/menu.cpp | 1 - .../Enhancements/randomizer/3drando/menu.hpp | 12 --------- .../randomizer/3drando/playthrough.cpp | 2 +- .../randomizer/3drando/rando_main.cpp | 4 --- .../randomizer/3drando/randomizer.hpp | 4 --- .../randomizer/3drando/settings.cpp | 0 .../randomizer/3drando/settings.hpp | 0 .../randomizer/3drando/spoiler_log.cpp | 7 ++++- .../Enhancements/randomizer/3drando/utils.cpp | 7 ----- .../Enhancements/randomizer/3drando/utils.hpp | 6 ----- 16 files changed, 20 insertions(+), 63 deletions(-) delete mode 100644 soh/soh/Enhancements/randomizer/3drando/category.hpp delete mode 100644 soh/soh/Enhancements/randomizer/3drando/entrance.cpp delete mode 100644 soh/soh/Enhancements/randomizer/3drando/item_location.cpp delete mode 100644 soh/soh/Enhancements/randomizer/3drando/keys.hpp delete mode 100644 soh/soh/Enhancements/randomizer/3drando/randomizer.hpp delete mode 100644 soh/soh/Enhancements/randomizer/3drando/settings.cpp delete mode 100644 soh/soh/Enhancements/randomizer/3drando/settings.hpp delete mode 100644 soh/soh/Enhancements/randomizer/3drando/utils.cpp delete mode 100644 soh/soh/Enhancements/randomizer/3drando/utils.hpp diff --git a/soh/soh/Enhancements/randomizer/3drando/category.hpp b/soh/soh/Enhancements/randomizer/3drando/category.hpp deleted file mode 100644 index fc230b435..000000000 --- a/soh/soh/Enhancements/randomizer/3drando/category.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -enum class OptionCategory { - Setting, - Toggle, -}; \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/entrance.cpp b/soh/soh/Enhancements/randomizer/3drando/entrance.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 43ebabe6e..3505cf640 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -679,16 +679,16 @@ void GenerateItemPool() { RG_FIRE_ARROWS, RG_ICE_ARROWS, RG_LIGHT_ARROWS, - RG_DOUBLE_DEFENSE, //Double defense + RG_DOUBLE_DEFENSE, RG_CLAIM_CHECK, - RG_PROGRESSIVE_HOOKSHOT, //Progressive hookshot - RG_PROGRESSIVE_STRENGTH, //Progressive strength - RG_PROGRESSIVE_BOMB_BAG, //Progressive bomb bag - RG_PROGRESSIVE_BOW, //Progressive bow - RG_PROGRESSIVE_SLINGSHOT, //Progressive slingshot - RG_PROGRESSIVE_WALLET, //Progressive wallet - RG_PROGRESSIVE_SCALE, //Progressive scale - RG_PROGRESSIVE_MAGIC_METER, //Progressive magic + RG_PROGRESSIVE_HOOKSHOT, + RG_PROGRESSIVE_STRENGTH, + RG_PROGRESSIVE_BOMB_BAG, + RG_PROGRESSIVE_BOW, + RG_PROGRESSIVE_SLINGSHOT, + RG_PROGRESSIVE_WALLET, + RG_PROGRESSIVE_SCALE, + RG_PROGRESSIVE_MAGIC_METER, }; //Check song shuffle and dungeon reward shuffle just for ice traps if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_ANYWHERE)) { @@ -742,7 +742,7 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD)) { AddItemToMainPool(RG_MASTER_SWORD); - ctx->possibleIceTrapModels.push_back(RG_MASTER_SWORD); //Master Sword without the GI enum + ctx->possibleIceTrapModels.push_back(RG_MASTER_SWORD); } else { if (!ctx->GetOption(RSK_STARTING_MASTER_SWORD)) { ctx->PlaceItemInLocation(RC_TOT_MASTER_SWORD, RG_MASTER_SWORD, false, true); @@ -761,7 +761,7 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { AddItemToPool(PendingJunkPool, RG_PROGRESSIVE_OCARINA); } - ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_OCARINA); //Progressive ocarina + ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_OCARINA); } else { if (ctx->GetOption(RSK_STARTING_OCARINA).Is(RO_STARTING_OCARINA_OFF)) { ctx->PlaceItemInLocation(RC_LW_GIFT_FROM_SARIA, RG_PROGRESSIVE_OCARINA, false, true); @@ -780,7 +780,6 @@ void GenerateItemPool() { AddItemToMainPool(RG_OCARINA_C_LEFT_BUTTON); AddItemToMainPool(RG_OCARINA_C_RIGHT_BUTTON); - //TODO: Re-add when custom models work with ice traps ctx->possibleIceTrapModels.push_back(RG_OCARINA_A_BUTTON); ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_UP_BUTTON); ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_DOWN_BUTTON); @@ -911,7 +910,7 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { AddItemToPool(PendingJunkPool, RG_MAGIC_BEAN_PACK); } - ctx->possibleIceTrapModels.push_back(RG_MAGIC_BEAN_PACK); //Magic bean pack + ctx->possibleIceTrapModels.push_back(RG_MAGIC_BEAN_PACK); } else { ctx->PlaceItemInLocation(RC_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, false, true); } @@ -1410,7 +1409,7 @@ void GenerateItemPool() { if (/*ProgressiveGoronSword TODO: Implement Setting*/false) { ReplaceMaxItem(RG_BIGGORON_SWORD, 0); AddItemToMainPool(RG_PROGRESSIVE_GORONSWORD, 2); - ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_GORONSWORD); // Progressive Goron Sword + ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_GORONSWORD); } else { ctx->possibleIceTrapModels.push_back(RG_BIGGORON_SWORD); } diff --git a/soh/soh/Enhancements/randomizer/3drando/keys.hpp b/soh/soh/Enhancements/randomizer/3drando/keys.hpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp index aa384e665..c1535ed97 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp @@ -353,13 +353,6 @@ void RegionTable_Init() { exit.GetConnectedRegion()->entrances.push_front(&exit); } } - /* - //Events -}, { - //Locations -}, { - //Exits -*/ } void ReplaceFirstInString(std::string& s, std::string const& toReplace, std::string const& replaceWith) { diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index ab064bfe0..b15bfd552 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -7,7 +7,6 @@ #include "menu.hpp" #include "playthrough.hpp" -#include "randomizer.hpp" #include "spoiler_log.hpp" #include "location_access.hpp" #include "soh/Enhancements/debugger/performanceTimer.h" diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.hpp b/soh/soh/Enhancements/randomizer/3drando/menu.hpp index f9393d90e..e0e6e4210 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.hpp @@ -13,16 +13,4 @@ #define DELETE_PRESET 6 #define RESET_TO_DEFAULTS 8 -// #define RESET "\x1b[0m" -// #define DIM "\x1b[2m" - -// #define BLACK "\x1b[30m" -// #define RED "\x1b[31m" -// #define GREEN "\x1b[32m" -// #define YELLOW "\x1b[33m" -// #define BLUE "\x1b[34m" -// #define MEGANTA "\x1b[35m" -// #define CYAN "\x1b[36m" -// #define WHITE "\x1b[37m" - bool GenerateRandomizer(std::set excludedLocations, std::set enabledTricks, std::string seedInput); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp index 53b02e036..23503638d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp @@ -97,7 +97,7 @@ int Playthrough_Repeat(std::set excludedLocations, std::setGetSettings()->SetSeedString(std::to_string(rand() % 0xFFFFFFFF)); repeatedSeed = boost::hash_32{}(ctx->GetSettings()->GetSeedString()); ctx->GetSettings()->SetSeed(repeatedSeed % 0xFFFFFFFF); - //CitraPrint("testing seed: " + std::to_string(Settings::seed)); + SPDLOG_DEBUG("testing seed: %d", repeatedSeed); ClearProgress(); Playthrough_Init(ctx->GetSettings()->GetSeed(), excludedLocations, enabledTricks); SPDLOG_INFO("Seeds Generated: {}", i + 1); diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp index 9a0ba20b4..7a396aa6b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp @@ -4,7 +4,6 @@ #include "location_access.hpp" #include "rando_main.hpp" #include "../context.h" -// #include #include #include #include @@ -14,9 +13,6 @@ void RandoMain::GenerateRando(std::set excludedLocations, std::set enabledTricks, std::string seedString) { - // std::string settingsFileName = "./randomizer/latest_settings.json"; - // CVarSetString(CVAR_RANDOMIZER_SETTING("LoadedPreset"), settingsFileName.c_str()); - Rando::Context::GetInstance()->SetSeedGenerated(GenerateRandomizer(excludedLocations, enabledTricks, seedString)); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); diff --git a/soh/soh/Enhancements/randomizer/3drando/randomizer.hpp b/soh/soh/Enhancements/randomizer/3drando/randomizer.hpp deleted file mode 100644 index 1b02c9037..000000000 --- a/soh/soh/Enhancements/randomizer/3drando/randomizer.hpp +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -#define RANDOMIZER_VERSION "v3.1" -#define COMMIT_NUMBER "develop" diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.hpp b/soh/soh/Enhancements/randomizer/3drando/settings.hpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 58409d0ec..bed532e9b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -6,7 +6,6 @@ #include "../entrance.h" #include "random.hpp" #include "../trial.h" -#include "utils.hpp" #include "hints.hpp" #include "pool_functions.hpp" #include "soh/Enhancements/randomizer/randomizer_check_objects.h" @@ -147,6 +146,12 @@ static void WriteSettings() { } } +// Removes any line breaks from s. +std::string RemoveLineBreaks(std::string s) { + s.erase(std::remove(s.begin(), s.end(), '\n'), s.end()); + return s; +} + // Writes the excluded locations to the spoiler log, if there are any. static void WriteExcludedLocations() { auto ctx = Rando::Context::GetInstance(); diff --git a/soh/soh/Enhancements/randomizer/3drando/utils.cpp b/soh/soh/Enhancements/randomizer/3drando/utils.cpp deleted file mode 100644 index 1cbe8c072..000000000 --- a/soh/soh/Enhancements/randomizer/3drando/utils.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "utils.hpp" - -// Removes any line breaks from s. -std::string RemoveLineBreaks(std::string s) { - s.erase(std::remove(s.begin(), s.end(), '\n'), s.end()); - return s; -} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/utils.hpp b/soh/soh/Enhancements/randomizer/3drando/utils.hpp deleted file mode 100644 index 3f5f69882..000000000 --- a/soh/soh/Enhancements/randomizer/3drando/utils.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include -#include - -std::string RemoveLineBreaks(std::string s); From ff2458128126fa8bb4b4c028c8b3fe627e35c33d Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Sat, 21 Dec 2024 10:08:48 -0500 Subject: [PATCH 11/12] Fix actor inits happening too early (#4742) * fix dogs not running * clean up kak gs fix * clean up scrub leader fix --- soh/src/code/z_scene.c | 12 ++++++++++++ .../actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c | 3 --- soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c | 18 ------------------ 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/soh/src/code/z_scene.c b/soh/src/code/z_scene.c index 207a7b7d0..2ce88cc04 100644 --- a/soh/src/code/z_scene.c +++ b/soh/src/code/z_scene.c @@ -33,6 +33,10 @@ s32 Object_Spawn(ObjectContext* objectCtx, s16 objectId) { return objectCtx->num - 1; } + +// SOH [Port] Track when objects are first loaded for a scene +static u8 sObjectFirstUpdateSkippedForScene = false; + void Object_InitBank(PlayState* play, ObjectContext* objectCtx) { PlayState* play2 = play; // Needs to be a new variable to match (possibly a sub struct?) size_t spaceSize; @@ -75,6 +79,8 @@ void Object_InitBank(PlayState* play, ObjectContext* objectCtx) { objectCtx->mainKeepIndex = Object_Spawn(objectCtx, OBJECT_GAMEPLAY_KEEP); gSegments[4] = VIRTUAL_TO_PHYSICAL(objectCtx->status[objectCtx->mainKeepIndex].segment); + + sObjectFirstUpdateSkippedForScene = false; } void Object_UpdateBank(ObjectContext* objectCtx) { @@ -83,6 +89,12 @@ void Object_UpdateBank(ObjectContext* objectCtx) { RomFile* objectFile; size_t size; + // SOH [Port] Skip the first object load after scene init so that actors have their init delayed by one frame + // This seems to mostly if not nearly resolve actors that depend on console DMA requests ending later + if (!sObjectFirstUpdateSkippedForScene) { + sObjectFirstUpdateSkippedForScene = true; + return; + } for (i = 0; i < objectCtx->num; i++) { if (status->id < 0) { diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c b/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c index a0cc83cb6..85ebef2d0 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c @@ -102,9 +102,6 @@ void EnDntJiji_Destroy(Actor* thisx, PlayState* play) { } void EnDntJiji_SetFlower(EnDntJiji* this, PlayState* play) { - // SOH: Due to removed object dependencies, parent was still NULL when Init was called. In order to properly set - // stage, redo it here now that we are a frame later. - this->stage = (EnDntDemo*)this->actor.parent; if (this->actor.bgCheckFlags & 1) { this->flowerPos = this->actor.world.pos; this->actionFunc = EnDntJiji_SetupWait; diff --git a/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c b/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c index 93dd9c9d3..c0bc087bd 100644 --- a/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c +++ b/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c @@ -215,16 +215,6 @@ s32 func_80B0C0CC(EnSw* this, PlayState* play, s32 arg2) { return sp64; } -// Presumably, due to the removal of object dependency, there is a race condition where -// the GS on the Kak construction site spawns to early and fails to detect the -// construction site dyna poly. This custom action func rechecks moving the GS -// to the nearest poly one frame after init. Further explanation available: -// https://github.com/HarbourMasters/Shipwright/issues/2310#issuecomment-1492829517 -void EnSw_MoveGoldLater(EnSw* this, PlayState* play) { - func_80B0C0CC(this, play, 1); - this->actionFunc = func_80B0D590; -} - void EnSw_Init(Actor* thisx, PlayState* play) { EnSw* this = (EnSw*)thisx; s32 phi_v0; @@ -316,14 +306,6 @@ void EnSw_Init(Actor* thisx, PlayState* play) { } else { this->actionFunc = func_80B0D590; } - - // If a normal GS failed to get attached to a poly during init - // try once more on the next frame via a custom action func - if ((((thisx->params & 0xE000) >> 0xD) == 1 || - ((thisx->params & 0xE000) >> 0xD) == 2) && - this->actor.floorPoly == NULL) { - this->actionFunc = EnSw_MoveGoldLater; - } } void EnSw_Destroy(Actor* thisx, PlayState* play) { From 9ea9100787d470139a30a14ca52a566a9b68cd6c Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Sun, 22 Dec 2024 18:16:00 +0000 Subject: [PATCH 12/12] Freestanding Rupees/Hearts Shuffle (#4686) * Enable freestanding items other than heart pieces and keys * Add option to disable freestanding rupee & heart shuffle * Add items to pool * Actually add shuffle setting * Define overworld locations * Add logic for overworld freestanding checks * Add freestanding items for child dungeons. * Add checks for Ice Cavern and Bottom of the Well * Add checks for Forest Temple and Gerudo Training Grounds * Add checks for Fire Temple and Water Temple * Add Shadow Temple checks This does not include the spinning pots rupees, even though they're included with freestanding rupees in the N64 randomizer as they would require dedicated overrides for the code for the pots in question. * Define Spirit Temple and Ganon's Castle hearts * Add remaining checks to dungeon definitions * Fix missing logic * Add freestanding checks to Save Flags Editor * Fix flags for Zora Fountain underwater rupees * Add option to enable freestanding shuffle for either dungeons or overworld * Add missing MQ checks and fix mac & windows compile error * Improve description and add hint text * Update logic for Bombchu fixes * Add missing Spirit Temple MQ hearts * Add missing settings entries * Actually add Forest Temple trick to the tricks menu. * Re-add Ice Cavern lobby rupee * go over MQ logic * review logic on non-MQ checks * convert all freestandings to location based * add option enum and fix jabu exit logic * fix mislocated freestandings * fix mislocted freestandings * Fix some mislocationed checks --------- Co-authored-by: Angel Bulfone --- soh/include/z64actor.h | 1 - .../Enhancements/debugger/debugSaveEditor.h | 175 +++++++++++++ .../hint_list/hint_list_exclude_dungeon.cpp | 66 +++++ .../hint_list/hint_list_exclude_overworld.cpp | 60 +++++ .../randomizer/3drando/item_pool.cpp | 26 ++ .../locacc_bottom_of_the_well.cpp | 28 +- .../location_access/locacc_castle_town.cpp | 2 +- .../location_access/locacc_death_mountain.cpp | 41 ++- .../location_access/locacc_deku_tree.cpp | 34 ++- .../locacc_dodongos_cavern.cpp | 44 ++-- .../location_access/locacc_fire_temple.cpp | 46 +++- .../location_access/locacc_forest_temple.cpp | 41 ++- .../location_access/locacc_ganons_castle.cpp | 10 +- .../locacc_gerudo_training_ground.cpp | 2 + .../location_access/locacc_gerudo_valley.cpp | 56 ++-- .../location_access/locacc_hyrule_field.cpp | 12 +- .../location_access/locacc_ice_cavern.cpp | 7 + .../locacc_jabujabus_belly.cpp | 11 +- .../location_access/locacc_kakariko.cpp | 8 + .../location_access/locacc_lost_woods.cpp | 46 +++- .../location_access/locacc_shadow_temple.cpp | 48 ++-- .../location_access/locacc_spirit_temple.cpp | 8 +- .../location_access/locacc_water_temple.cpp | 12 +- .../location_access/locacc_zoras_domain.cpp | 80 ++++-- soh/soh/Enhancements/randomizer/dungeon.cpp | 98 +++++++ .../Enhancements/randomizer/hook_handlers.cpp | 21 +- .../Enhancements/randomizer/location_list.cpp | 234 ++++++++++++++++- soh/soh/Enhancements/randomizer/logic.cpp | 1 + .../randomizer/option_descriptions.cpp | 10 + .../Enhancements/randomizer/randomizerTypes.h | 247 +++++++++++++++++- .../randomizer/randomizer_check_tracker.cpp | 30 +++ .../Enhancements/randomizer/randomizer_inf.h | 182 +++++++++++++ soh/soh/Enhancements/randomizer/settings.cpp | 6 + soh/src/code/z_en_item00.c | 8 - 34 files changed, 1545 insertions(+), 156 deletions(-) diff --git a/soh/include/z64actor.h b/soh/include/z64actor.h index 5d6bfc26b..272237d21 100644 --- a/soh/include/z64actor.h +++ b/soh/include/z64actor.h @@ -297,7 +297,6 @@ typedef struct EnItem00 { /* 0x15C */ f32 scale; /* 0x160 */ ColliderCylinder collider; // #region SOH [Randomizer] - GetItemEntry randoGiEntry; RandomizerCheck randoCheck; RandomizerInf randoInf; /* */ s16 ogParams; diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index ea693ab17..3855f02c4 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -1163,6 +1163,181 @@ const std::vector flagTables = { { RAND_INF_ZF_GREAT_FAIRY_REWARD, "RAND_INF_ZF_GREAT_FAIRY_REWARD" }, { RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD, "RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD" }, { RAND_INF_OGC_GREAT_FAIRY_REWARD, "RAND_INF_OGC_GREAT_FAIRY_REWARD" }, + + { RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE, "RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE" }, + { RAND_INF_KF_NORTH_GRASS_WEST_RUPEE, "RAND_INF_KF_NORTH_GRASS_WEST_RUPEE" }, + { RAND_INF_KF_NORTH_GRASS_EAST_RUPEE, "RAND_INF_KF_NORTH_GRASS_EAST_RUPEE" }, + { RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE, "RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE" }, + { RAND_INF_KF_SARIAS_TOP_LEFT_HEART, "RAND_INF_KF_SARIAS_TOP_LEFT_HEART" }, + { RAND_INF_KF_SARIAS_TOP_RIGHT_HEART, "RAND_INF_KF_SARIAS_TOP_RIGHT_HEART" }, + { RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART, "RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART" }, + { RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART, "RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART" }, + { RAND_INF_KF_BEAN_RUPEE_1, "RAND_INF_KF_BEAN_RUPEE_1" }, + { RAND_INF_KF_BEAN_RUPEE_2, "RAND_INF_KF_BEAN_RUPEE_2" }, + { RAND_INF_KF_BEAN_RUPEE_3, "RAND_INF_KF_BEAN_RUPEE_3" }, + { RAND_INF_KF_BEAN_RUPEE_4, "RAND_INF_KF_BEAN_RUPEE_4" }, + { RAND_INF_KF_BEAN_RUPEE_5, "RAND_INF_KF_BEAN_RUPEE_5" }, + { RAND_INF_KF_BEAN_RUPEE_6, "RAND_INF_KF_BEAN_RUPEE_6" }, + { RAND_INF_KF_BEAN_RED_RUPEE, "RAND_INF_KF_BEAN_RED_RUPEE" }, + { RAND_INF_LW_SHORTCUT_RUPEE_1, "RAND_INF_LW_SHORTCUT_RUPEE_1" }, + { RAND_INF_LW_SHORTCUT_RUPEE_2, "RAND_INF_LW_SHORTCUT_RUPEE_2" }, + { RAND_INF_LW_SHORTCUT_RUPEE_3, "RAND_INF_LW_SHORTCUT_RUPEE_3" }, + { RAND_INF_LW_SHORTCUT_RUPEE_4, "RAND_INF_LW_SHORTCUT_RUPEE_4" }, + { RAND_INF_LW_SHORTCUT_RUPEE_5, "RAND_INF_LW_SHORTCUT_RUPEE_5" }, + { RAND_INF_LW_SHORTCUT_RUPEE_6, "RAND_INF_LW_SHORTCUT_RUPEE_6" }, + { RAND_INF_LW_SHORTCUT_RUPEE_7, "RAND_INF_LW_SHORTCUT_RUPEE_7" }, + { RAND_INF_LW_SHORTCUT_RUPEE_8, "RAND_INF_LW_SHORTCUT_RUPEE_8" }, + { RAND_INF_LH_FRONT_RUPEE, "RAND_INF_LH_FRONT_RUPEE" }, + { RAND_INF_LH_MIDDLE_RUPEE, "RAND_INF_LH_MIDDLE_RUPEE" }, + { RAND_INF_LH_BACK_RUPEE, "RAND_INF_LH_BACK_RUPEE" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE" }, + { RAND_INF_DMT_BLUE_RUPEE, "RAND_INF_DMT_BLUE_RUPEE" }, + { RAND_INF_DMT_COW_GROTTO_LEFT_HEART, "RAND_INF_DMT_COW_GROTTO_LEFT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, "RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, "RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_RIGHT_HEART, "RAND_INF_DMT_COW_GROTTO_RIGHT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_1, "RAND_INF_DMT_COW_GROTTO_RUPEE_1" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_2, "RAND_INF_DMT_COW_GROTTO_RUPEE_2" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_3, "RAND_INF_DMT_COW_GROTTO_RUPEE_3" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_4, "RAND_INF_DMT_COW_GROTTO_RUPEE_4" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_5, "RAND_INF_DMT_COW_GROTTO_RUPEE_5" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_6, "RAND_INF_DMT_COW_GROTTO_RUPEE_6" }, + { RAND_INF_DMT_COW_GROTTO_RED_RUPEE, "RAND_INF_DMT_COW_GROTTO_RED_RUPEE" }, + { RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE, "RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE, "RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE, "RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE" }, + { RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART, "RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART" }, + { RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART, "RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART" }, + { RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART" }, + { RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART" }, + { RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART" }, + { RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART, "RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART" }, + { RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, "RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART" }, + { RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, "RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART" }, + { RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, "RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART" }, + { RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART, "RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART" }, + { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART" }, + { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART" }, + { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_1, "RAND_INF_WATER_TEMPLE_RIVER_HEART_1" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_2, "RAND_INF_WATER_TEMPLE_RIVER_HEART_2" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_3, "RAND_INF_WATER_TEMPLE_RIVER_HEART_3" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_4, "RAND_INF_WATER_TEMPLE_RIVER_HEART_4" }, + { RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, "RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, "RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART" }, + { RAND_INF_ICE_CAVERN_LOBBY_RUPEE, "RAND_INF_ICE_CAVERN_LOBBY_RUPEE" }, + { RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART" }, + { RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART" }, + { RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART" }, + { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1" }, + { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2" }, + { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3" }, + { RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART" }, + { RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, "RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART" }, + { RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, "RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3" }, + { RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART" }, + { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART" }, + { RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART, "RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART" }, + { RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART, "RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART" }, + { RAND_INF_DEKU_TREE_MQ_LOBBY_HEART, "RAND_INF_DEKU_TREE_MQ_LOBBY_HEART" }, + { RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, "RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART" }, + { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART" }, + { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART" }, + { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART" }, + { RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, "RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, "RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, "RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART" }, + { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART" }, + { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART" }, + { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART" }, + { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART" }, + { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART" }, } }, }; 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 e06d0e236..3a7eeef74 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 @@ -117,6 +117,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*french*/ "Selon moi, la #peste Mojo dans l'Arbre Mojo# vend #[[1]]#.", {QM_RED, QM_GREEN})); // /*spanish*/ Según dicen, un #deku del Gran Árbol Deku# vende #[[1]]#. + hintTextTable[RHT_DEKU_TREE_HEART] = HintText(CustomMessage("They say that a #heart in the Deku Tree# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | DODONGOS CAVERN | ---------------------------*/ @@ -279,6 +283,10 @@ hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("The /*german*/ "", /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DODONGOS_CAVERN_HEART] = HintText(CustomMessage("They say that a #heart in Dodongo's Cavern# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | JABU JABUS BELLY | ---------------------------*/ @@ -430,6 +438,15 @@ hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("The /*german*/ "", /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_JABU_JABU_RUPEE] = HintText(CustomMessage("They say that #underwater in Jabu-Jabu's Belly# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_JABU_JABU_HEART] = HintText(CustomMessage("They say that near a #central lift in Jabu-Jabu's Belly# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | FOREST TEMPLE | ---------------------------*/ @@ -657,6 +674,10 @@ hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("The /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_FOREST_TEMPLE_HEART] = HintText(CustomMessage("They say that a #heart in the Forest Temple# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | FIRE TEMPLE | ---------------------------*/ @@ -849,6 +870,10 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa /*german*/ "", /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_FIRE_TEMPLE_HEART] = HintText(CustomMessage("They say that a #heart in the Fire Temple# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | WATER TEMPLE | ---------------------------*/ @@ -980,6 +1005,10 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa /*german*/ "", /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_WATER_TEMPLE_HEART] = HintText(CustomMessage("They say that in a #river in the Water Temple# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | SPIRIT TEMPLE | ---------------------------*/ @@ -1217,6 +1246,14 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa /*german*/ "", /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_SPIRIT_TEMPLE_HEART] = HintText(CustomMessage("They say that on a #small platform# in the Spirit Temple lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_HEART] = HintText(CustomMessage("They say that guarded by a #ring of flame# in the Spirit Temple is #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | SHADOW TEMPLE | ---------------------------*/ @@ -1464,6 +1501,10 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*german*/ "", /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_SHADOW_TEMPLE_HEART] = HintText(CustomMessage("They say that a #heart in the Shadow Temple# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | BOTTOM OF THE WELL | ---------------------------*/ @@ -1586,6 +1627,14 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*german*/ "", /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_BOTTOM_OF_THE_WELL_HEART] = HintText(CustomMessage("They say that a #heart within the well# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_RUPEE] = HintText(CustomMessage("They say that a #hidden path through the floor# the well# leads to #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | ICE CAVERN | ---------------------------*/ @@ -1663,6 +1712,14 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*german*/ "", /*french*/ "", { QM_RED, QM_GREEN })); + hintTextTable[RHT_ICE_CAVERN_HEART] = HintText(CustomMessage("They say that atop on a #frozen pillar# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ICE_CAVERN_RUPEE] = HintText(CustomMessage("They say that a #rupee in a frozen cavern# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | Gerudo Training Ground | ---------------------------*/ @@ -1841,6 +1898,10 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*french*/ "Selon moi, #derrière un bloc argent# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); // /*spanish*/ Según dicen, una #hazaña de fuerza# premia a las bandidas con #[[1]]#. + hintTextTable[RHT_GERUDO_TRAINING_GROUNDS_HEART] = HintText(CustomMessage("They say that a watching a #trial with Dinalfos# is #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | GANONS CASTLE | ---------------------------*/ @@ -2037,5 +2098,10 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th hintTextTable[RHT_POT_GANONS_CASTLE] = HintText(CustomMessage("They say that a #pot in Ganon's Castle# contains #[[1]]#.", /*german*/ "", /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GANONS_CASTLE_HEART] = HintText(CustomMessage("They say that a #heart in Ganon's Castle# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + } } 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 cf980d484..1d989d371 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 @@ -1542,5 +1542,65 @@ void StaticData::HintTable_Init_Exclude_Overworld() { hintTextTable[RHT_POT_HYRULE_CASTLE] = HintText(CustomMessage("They say that a #pot in Hyrule Castle# contains #[[1]]#.", /*german*/ "", /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_KOKIRI_FOREST_RUPEE] = HintText(CustomMessage("They say that a rupee in a #tranquil forest# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_KOKIRI_FOREST_HEART] = HintText(CustomMessage("They say that a heart in a #tranquil forest# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_SARIAS_HOUSE_HEART] = HintText(CustomMessage("They say that a heart in a #dear friend's home# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_LOST_WOODS_RUPEE] = HintText(CustomMessage("They say that under a #boulder in the woods# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_LOST_WOODS_SHORTCUT_RUPEE] = HintText(CustomMessage("They say that in a #pool of water in the woods# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_LAKE_HYLIA_RUPEE] = HintText(CustomMessage("They say that just off the #coast of a lake# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_LABORATORY_RUPEE] = HintText(CustomMessage("They say that at the #bottom of a tank# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_DAMPES_GRAVE_RUPEE] = HintText(CustomMessage("They say that within a #quick-footed spirit's grave# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_GERUDO_VALLEY_GROTTO_RUPEE] = HintText(CustomMessage("They say that an Octarok in an #underground spring# guards #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_DEATH_MOUNTAIN_TRAIL_RUPEE] = HintText(CustomMessage("They say that beneath a boulder on a #mountain's cliffside# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART] = HintText(CustomMessage("They say that accompanying a #cow in a small cave# is #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE] = HintText(CustomMessage("They say that accompanying a #cow in a small cave# is #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_DEATH_MOUNTAIN_CRATER_RUPEE] = HintText(CustomMessage("They say that on a #small platform suspended above lava# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_ZORAS_RIVER_WATERFALL_RUPEE] = HintText(CustomMessage("They say that beneath a #waterfall feeding a narrow river# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_ZORAS_FOUNTAIN_RUPEE] = HintText(CustomMessage("They say that at the bottom of a #partially-frozen spring# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ } } diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 3505cf640..a2562c99e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -624,6 +624,30 @@ static void PlaceVanillaOverworldFish() { } } +static void PlaceFreestandingItems() { + auto ctx = Rando::Context::GetInstance(); + auto option = ctx->GetOption(RSK_SHUFFLE_FREESTANDING); + for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_FREESTANDING)) { + RandomizerGet vanillaItem = Rando::StaticData::GetLocation(loc)->GetVanillaItem(); + if (option.Is(RO_FREESTANDING_OVERWORLD) || option.Is(RO_FREESTANDING_ALL)) { + AddItemToMainPool(vanillaItem); + } else { + ctx->PlaceItemInLocation(loc, vanillaItem, false, true); + } + } + + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + for (RandomizerCheck loc : ctx->GetLocations(dungeon->GetDungeonLocations(), RCTYPE_FREESTANDING)) { + RandomizerGet vanillaItem = Rando::StaticData::GetLocation(loc)->GetVanillaItem(); + if (option.Is(RO_FREESTANDING_DUNGEONS) || option.Is(RO_FREESTANDING_ALL)) { + AddItemToMainPool(vanillaItem); + } else { + ctx->PlaceItemInLocation(loc, vanillaItem, false, true); + } + } + } +} + static void SetScarceItemPool() { ReplaceMaxItem(RG_PROGRESSIVE_BOMBCHUS, 3); ReplaceMaxItem(RG_BOMBCHU_5, 1); @@ -1255,6 +1279,8 @@ void GenerateItemPool() { PlaceVanillaDekuScrubItems(ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF)); } + PlaceFreestandingItems(); + AddItemsToPool(ItemPool, alwaysItems); AddItemsToPool(ItemPool, dungeonRewards); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_bottom_of_the_well.cpp index 9e8d008d0..0dd135ede 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_bottom_of_the_well.cpp @@ -65,7 +65,7 @@ void RegionTable_Init_BottomOfTheWell() { Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM, {[]{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}}), }); -//this area has pots and can be reached without lens in logic from basement, but that could require silver rupees if they are shuffled. +//this area can be reached without lens in logic from basement, but that could require silver rupees if they are shuffled. areaTable[RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM] = Region("Bottom of the Well Southwest Room", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, logic->CanBreakPots()), @@ -114,7 +114,9 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM] = Region("Bottom of the Well Coffin Room", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + 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);}}), @@ -162,8 +164,14 @@ void RegionTable_Init_BottomOfTheWell() { Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, {[]{return logic->CanDetonateUprightBombFlower();}}), }); -//Relevant when freestanding shuffle is added - areaTable[RR_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM] = Region("Bottom of the Well Basement Platform", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM] = Region("Bottom of the Well Basement Platform", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, true), + }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, {[]{return true;}}), }); @@ -185,6 +193,9 @@ void RegionTable_Init_BottomOfTheWell() { //Locations //Implies CanBreakPots() 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()), + }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return logic->IsChild;}}), @@ -208,7 +219,9 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM] = Region("Bottom of the Well MQ Coffin Room", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + 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);}}), @@ -261,7 +274,10 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT] = Region("Bottom of the Well MQ Basement", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations //behind invisible big skulltulas, but with navi spotting it's easy to avoid them, or at worst, tank your way through as they do not block the path - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, true), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp index 99a091c70..f403d1dff 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp @@ -301,7 +301,7 @@ void RegionTable_Init_CastleTown() { areaTable[RR_MARKET_TREASURE_CHEST_GAME] = Region("Market Treasure Chest Game", "Market Treasure Chest Game", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GREG_HINT, true), + 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)))), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp index 392df0555..119b802a1 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp @@ -14,6 +14,8 @@ void RegionTable_Init_DeathMountain() { 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_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()), }, { //Exits Entrance(RR_KAK_BEHIND_GATE, {[]{return true;}}), @@ -50,8 +52,19 @@ void RegionTable_Init_DeathMountain() { areaTable[RR_DMT_COW_GROTTO] = Region("DMT Cow Grotto", "DMT Cow Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DMT_COW_GROTTO_COW, logic->CanUse(RG_EPONAS_SONG)), - LOCATION(RC_DMT_COW_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMT_COW_GROTTO_COW, logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_DMT_COW_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMT_COW_GROTTO_LEFT_HEART, true), + LOCATION(RC_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, true), + LOCATION(RC_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, true), + LOCATION(RC_DMT_COW_GROTTO_RIGHT_HEART, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_1, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_2, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_3, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_4, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_5, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_6, true), + LOCATION(RC_DMT_COW_GROTTO_RED_RUPEE, true), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_SUMMIT, {[]{return true;}}), @@ -193,6 +206,7 @@ void RegionTable_Init_DeathMountain() { Entrance(RR_DMC_LADDER_AREA_NEARBY, {[]{return logic->FireTimer() >= 16 || logic->Hearts() >= 3;}}), Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_DISTANT_SCARECROW) && ((logic->EffectiveHealth() > 2) || (logic->CanUse(RG_BOTTLE_WITH_FAIRY) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || logic->CanUse(RG_NAYRUS_LOVE));}}), Entrance(RR_DMC_LOWER_NEARBY, {[]{return false;}}), + Entrance(RR_DMC_DISTANT_PLATFORM, {[]{return (logic->FireTimer() >= 48 && logic->Hearts() >= 2) || logic->Hearts() >= 3;}}), }); areaTable[RR_DMC_LADDER_AREA_NEARBY] = Region("DMC Ladder Region Nearby", "Death Mountain Crater", {RA_DEATH_MOUNTAIN_CRATER}, NO_DAY_NIGHT_CYCLE, {}, { @@ -241,12 +255,21 @@ void RegionTable_Init_DeathMountain() { }, { //Locations LOCATION(RC_DMC_GS_BEAN_PATCH, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_DMC_NEAR_PLATFORM_RED_RUPEE, logic->IsChild), + LOCATION(RC_DMC_MIDDLE_PLATFORM_RED_RUPEE, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), }, { //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);}}), }); areaTable[RR_DMC_GREAT_FAIRY_FOUNTAIN] = Region("DMC Great Fairy Fountain", "DMC Great Fairy Fountain", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -279,4 +302,18 @@ void RegionTable_Init_DeathMountain() { //Exits Entrance(RR_DMC_LOWER_LOCAL, {[]{return true;}}), }); + + areaTable[RR_DMC_DISTANT_PLATFORM] = Region("DMC Distant Platform", "Death Mountain Crater", {RA_DEATH_MOUNTAIN_CRATER}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_1, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_2, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_3, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_4, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_5, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_6, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_RED_RUPEE, logic->IsAdult), + }, { + //Exits + Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return logic->FireTimer() >= 48 && logic->CanUse(RG_DISTANT_SCARECROW);}}), + }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp index 099996d25..5ba43741b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp @@ -25,7 +25,9 @@ void RegionTable_Init_DekuTree() { EventAccess(&logic->DekuBabaNuts, {[]{return logic->CanGetDekuBabaNuts();}}), }, { //Locations - LOCATION(RC_DEKU_TREE_MAP_CHEST, true), + LOCATION(RC_DEKU_TREE_MAP_CHEST, true), + LOCATION(RC_DEKU_TREE_LOBBY_LOWER_HEART, true), + LOCATION(RC_DEKU_TREE_LOBBY_UPPER_HEART, logic->CanPassEnemy(RE_BIG_SKULLTULA)), }, { //Exits Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return true;}}), @@ -144,7 +146,12 @@ void RegionTable_Init_DekuTree() { 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));});}}), }); - areaTable[RR_DEKU_TREE_OUTSIDE_BOSS_ROOM] = Region("Deku Tree Outside Boss Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DEKU_TREE_OUTSIDE_BOSS_ROOM] = Region("Deku Tree Outside Boss Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + }, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_UPPER, {[]{return true;}}), Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return (logic->HasItem(RG_BRONZE_SCALE) || Here(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return logic->CanUse(RG_IRON_BOOTS);})) && Here(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return logic->CanReflectNuts();});}}), @@ -173,8 +180,9 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_2F] = Region("Deku Tree MQ 2F", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DEKU_TREE_MQ_MAP_CHEST, true), - LOCATION(RC_DEKU_TREE_MQ_GS_LOBBY, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_DEKU_TREE_MQ_MAP_CHEST, true), + LOCATION(RC_DEKU_TREE_MQ_GS_LOBBY, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_DEKU_TREE_MQ_LOBBY_HEART, true), }, { //Exits Entrance(RR_DEKU_TREE_MQ_1F, {[]{return true;}}), @@ -193,6 +201,7 @@ void RegionTable_Init_DekuTree() { //Implies CanKillEnemy(RE_GOHMA_LARVA) LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, logic->CanKillEnemy(RE_DEKU_BABA)), LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, logic->HasFireSourceWithTorch() || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW))), + LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, true), }, { //Exits Entrance(RR_DEKU_TREE_MQ_2F, {[]{return true;}}), @@ -201,7 +210,10 @@ void RegionTable_Init_DekuTree() { Entrance(RR_DEKU_TREE_MQ_BASEMENT, {[]{return true;}}), }); - areaTable[RR_DEKU_TREE_MQ_EYE_TARGET_ROOM] = Region("Deku Tree MQ Eye Target Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DEKU_TREE_MQ_EYE_TARGET_ROOM] = Region("Deku Tree MQ Eye Target Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DEKU_TREE_MQ_DEKU_BABA_HEART, true), + }, { //Exits Entrance(RR_DEKU_TREE_MQ_COMPASS_ROOM, {[]{return Here(RR_DEKU_TREE_MQ_EYE_TARGET_ROOM, []{return logic->CanHitEyeTargets();});}}), Entrance(RR_DEKU_TREE_MQ_2F, {[]{return true;}}), @@ -221,6 +233,7 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_PAST_BOULDER_VINES] = Region("Deku Tree MQ Past Boulder Vines", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, { //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), }, { //Exits Entrance(RR_DEKU_TREE_MQ_COMPASS_ROOM, {[]{return logic->BlastOrSmash();}}), @@ -330,11 +343,14 @@ void RegionTable_Init_DekuTree() { }); areaTable[RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM] = - Region("Deku Tree MQ Outside Boss Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, - { + Region("Deku Tree MQ Outside Boss Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, { + LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + }, { // Exits - Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return logic->HasItem(RG_BRONZE_SCALE);}}), - Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return Here(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, []{return logic->CanReflectNuts();});}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return 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/3drando/location_access/locacc_dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp index 99466692c..b4fb9f735 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp @@ -52,7 +52,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_SE_CORRIDOR] = Region("Dodongos Cavern SE Corridor", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DC_SCARECROW_GS) && (logic->CanAttack()))), + LOCATION(RC_DODONGOS_CAVERN_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DC_SCARECROW_GS) && (logic->CanAttack()))), LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3, logic->CanBreakPots()), @@ -83,10 +83,11 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_LOWER_LIZALFOS] = Region("Dodongos Cavern Lower Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_1, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_2, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_3, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, true), }, { //Exits Entrance(RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, {[]{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || @@ -154,6 +155,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER] = Region("Dodongos Cavern Bomb Room Lower", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, true), }, { //Exits Entrance(RR_DODONGOS_CAVERN_2F_SIDE_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DC_SCRUB_ROOM) && logic->HasItem(RG_GORONS_BRACELET));});}}), @@ -180,7 +182,12 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_UPPER_LIZALFOS, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_DC_SLINGSHOT_SKIP);}}), }); - areaTable[RR_DODONGOS_CAVERN_UPPER_LIZALFOS] = Region("Dodongos Cavern Upper Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_UPPER_LIZALFOS] = Region("Dodongos Cavern Upper Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, true), + LOCATION(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, true), + LOCATION(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, true), + }, { //Exits Entrance(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || @@ -202,8 +209,8 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER] = Region("Dodongos Cavern Bomb Room Upper", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, true), - LOCATION(RC_DODONGOS_CAVERN_BLADE_POT_1, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_BLADE_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_BLADE_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_BLADE_POT_2, logic->CanBreakPots()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), @@ -225,8 +232,8 @@ void RegionTable_Init_DodongosCavern() { EventAccess(&logic->FairyPot, {[]{return true;}}), }, {}, { //Exits - Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_BACK_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOSS_AREA, []{return logic->BlastOrSmash();});}}), + Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_BACK_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOSS_AREA, []{return logic->BlastOrSmash();});}}), Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}), }); @@ -258,10 +265,10 @@ void RegionTable_Init_DodongosCavern() { EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}), }, { //Locations - 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_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), + 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_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), @@ -350,6 +357,7 @@ void RegionTable_Init_DodongosCavern() { }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, true), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return logic->TakeDamage();}}), @@ -386,6 +394,7 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, logic->CanBreakPots()), 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()), }, { //Exits //Falling down gets you stuck with nothing there, not a useful exit for logic @@ -432,9 +441,10 @@ void RegionTable_Init_DodongosCavern() { }); areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS] = Region("Dodongos Cavern MQ Lower Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { - //When you add wonder item logic for behind the lavafall, place the item both here and in RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS - //because the doors are sealed when entering from the top and you can't spawn the lower lizalfos - }, {}, { + }, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, true), + }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}), Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp index bc2259efa..20565d039 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp @@ -133,7 +133,12 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM] = Region("Fire Temple Fire Pillar Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM] = Region("Fire Temple Fire Pillar Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //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), + }, { //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);}}), @@ -175,7 +180,12 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM] = Region("Fire Temple East Central Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM] = Region("Fire Temple East Central Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, true), + LOCATION(RC_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, true), + LOCATION(RC_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, true), + }, { //Exits Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return logic->TakeDamage();}}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 5, 8);}}), @@ -183,7 +193,12 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_MAP_AREA, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW);}}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_WALL_CHASE] = Region("Fire Temple Fire Wall Chase", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_WALL_CHASE] = Region("Fire Temple Fire Wall Chase", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, logic->FireTimer() >= 24 && (logic->IsAdult || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, logic->FireTimer() >= 24 && (logic->IsAdult || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, logic->FireTimer() >= 24), + }, { //Exits Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return logic->FireTimer() >= 24 && logic->SmallKeys(RR_FIRE_TEMPLE, 6, 8);}}), Entrance(RR_FIRE_TEMPLE_MAP_AREA, {[]{return logic->IsAdult;}}), @@ -235,7 +250,13 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_ROOM] = Region("Fire Temple Fire Maze Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_ROOM] = Region("Fire Temple Fire Maze Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + // Locations + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FIRE_TEMPLE_CORRIDOR, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, {[]{return logic->CanUse(RG_HOVER_BOOTS);}}), @@ -278,10 +299,6 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_LATE_FIRE_MAZE] = Region("Fire Temple Late Fire Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { // Locations - LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, logic->CanBreakPots()), - LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, logic->CanBreakPots()), - LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, logic->CanBreakPots()), - LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, logic->CanBreakPots()), @@ -477,16 +494,21 @@ void RegionTable_Init_FireTemple() { EventAccess(&logic->FairyPot, {[]{return logic->CanUse(RG_HOOKSHOT);}}), }, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT)), - 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_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, logic->HookshotOrBoomerang()), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, logic->HookshotOrBoomerang()), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return true;}}), }); //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", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM] = Region("Fire Temple MQ Elevator Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //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), + }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp index 63f51b1cd..1a15a8ae4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp @@ -85,6 +85,8 @@ void RegionTable_Init_ForestTemple() { }, { //Locations LOCATION(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, logic->CanUse(RG_LONGSHOT) || Here(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return logic->HookshotOrBoomerang();})), + LOCATION(RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), + LOCATION(RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), }, { //Exits Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_SONG_OF_TIME);}}), @@ -98,7 +100,11 @@ void RegionTable_Init_ForestTemple() { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->CanGetDekuBabaSticks();}}), EventAccess(&logic->DekuBabaNuts, {[]{return logic->CanGetDekuBabaNuts();}}), - }, {}, { + }, { + //Locations + LOCATION(RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, true), + LOCATION(RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, true), + }, { //Exits Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return true;}}), Entrance(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, {[]{return true;}}), @@ -144,7 +150,9 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_SEWER] = Region("Forest Temple Sewer", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER)), + LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER)), + LOCATION(RC_FOREST_TEMPLE_WELL_WEST_HEART, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)), + 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;}}), @@ -415,7 +423,10 @@ void RegionTable_Init_ForestTemple() { EventAccess(&logic->ForestCanTwistHallway, {[]{return logic->CanHitSwitch();}}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, logic->CanKillEnemy(RE_REDEAD)), + LOCATION(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, logic->CanKillEnemy(RE_REDEAD)), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, true), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, true), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, true), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return true;}}), @@ -424,13 +435,21 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_NW_OUTDOORS] = Region("Forest Temple MQ NW Outdoors", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + //the well checks are considered from both areas instead of being a region because the draining is a temp flag and the skull (as well as the chest with hook glitch) has different breath timers from each side + LOCATION(RC_FOREST_TEMPLE_MQ_GS_WELL, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), + 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_GOLDEN_SCALE)) && logic->WaterTimer() > 10;}}), + 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);}}), }); -//The well is included here because the eye target is a temp flag, making it unwieldy to use as an EventAccess to make it it's own room +//The well only coniders the eye target here because the eye target is a temp flag, making it unwieldy to use as an EventAccess or to make it it's own room areaTable[RR_FOREST_TEMPLE_MQ_NE_OUTDOORS] = Region("Forest Temple MQ NE Outdoors", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->CanGetDekuBabaSticks();}}), @@ -440,9 +459,13 @@ void RegionTable_Init_ForestTemple() { LOCATION(RC_FOREST_TEMPLE_MQ_WELL_CHEST, logic->CanHitEyeTargets()), LOCATION(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), //implies logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) - LOCATION(RC_FOREST_TEMPLE_MQ_GS_WELL, logic->CanHitEyeTargets() || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_WELL, logic->CanHitEyeTargets() || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) || logic->CanHitEyeTargets()), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) || logic->CanHitEyeTargets()), + 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_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);}}), }); @@ -451,9 +474,9 @@ void RegionTable_Init_ForestTemple() { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, true), //Actually killing the skull from the doorframe with melee is annoying. Hammer swing hits low enough unaided, other swords need to crouch stab but the spot is precise based on range. kokiri sword doesn't reach at all for adult. - LOCATION(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, ((logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_FOREST_DOORFRAME))) && logic->CanJumpslash() && - (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_FAIRY_BOW) || logic->HookshotOrBoomerang() || - (logic->CanStandingShield() && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD) || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD)))))), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, ((logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_FOREST_DOORFRAME))) && logic->CanJumpslash() && + (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_FAIRY_BOW) || logic->HookshotOrBoomerang() || + (logic->CanStandingShield() && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD) || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD)))))), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return logic->HasFireSourceWithTorch();}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp index 173fad195..10ae58061 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp @@ -65,10 +65,11 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_FIRE_TRIAL] = Region("Ganon's Castle Fire Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FireTrialClear, {[]{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_LONGSHOT);}}), - }, { + }, { //Locations LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, logic->CanBreakPots() && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LONGSHOT)), LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, logic->CanBreakPots() && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_HEART, logic->CanUse(RG_GORON_TUNIC)), }, {}); areaTable[RR_GANONS_CASTLE_WATER_TRIAL] = Region("Ganon's Castle Water Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { @@ -96,6 +97,9 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT)), LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, logic->CanBreakPots() && logic->CanUse(RG_MEGATON_HAMMER) && ((logic->CanUse(RG_FIRE_ARROWS) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))))))), LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, logic->CanBreakPots() && logic->CanUse(RG_MEGATON_HAMMER) && ((logic->CanUse(RG_FIRE_ARROWS) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))))))), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG))), }, {}); areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Region("Ganon's Castle Spirit Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { @@ -108,6 +112,7 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, true), }, {}); areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL] = Region("Ganon's Castle Light Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { @@ -235,6 +240,7 @@ void RegionTable_Init_GanonsCastle() { }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, logic->BlueFire()), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_MAIN, {[]{return true;}}), @@ -483,5 +489,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_GANON_ARENA] = Region("Ganon's Arena", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GANON, logic->CanKillEnemy(RE_GANON)), + LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->SmallKeys(RR_GANONS_CASTLE, 2)), + LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->SmallKeys(RR_GANONS_CASTLE, 2)), }, {}); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_ground.cpp index 20e4f9f66..079d3f504 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_ground.cpp @@ -25,6 +25,8 @@ void RegionTable_Init_GerudoTrainingGrounds() { LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, true), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp index e98dc853d..dac4db1b3 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp @@ -75,7 +75,17 @@ void RegionTable_Init_GerudoValley() { Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}), }); - areaTable[RR_GV_OCTOROK_GROTTO] = Region("GV Octorok Grotto", "GV Octorok Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GV_OCTOROK_GROTTO] = Region("GV Octorok Grotto", "GV Octorok Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_RED_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + }, { //Exits Entrance(RR_GV_GROTTO_LEDGE, {[]{return true;}}), }); @@ -97,28 +107,28 @@ void RegionTable_Init_GerudoValley() { EventAccess(&logic->GtG_GateOpen, {[]{return logic->GtG_GateOpen || (logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET));}}), }, { //Locations - LOCATION(RC_GF_CHEST, logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_GF_HBA_1000_POINTS, 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->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), - LOCATION(RC_GF_NORTH_F1_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_GF_NORTH_F2_CARPENTER, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))), - LOCATION(RC_GF_SOUTH_F1_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_GF_SOUTH_F2_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_GF_GERUDO_MEMBERSHIP_CARD, logic->CanFinishGerudoFortress()), - LOCATION(RC_GF_GS_ARCHERY_RANGE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->AtNight && logic->CanGetNightTimeGS()), - LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && logic->AtNight && (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)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN) || ctx->GetTrickOption(RT_GF_JUMP)) && logic->CanGetNightTimeGS()), - LOCATION(RC_GF_BREAK_ROOM_POT_1, logic->CanBreakPots()), - LOCATION(RC_GF_BREAK_ROOM_POT_2, logic->CanBreakPots()), - LOCATION(RC_GF_KITCHEN_POT_1, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakPots()), - LOCATION(RC_GF_KITCHEN_POT_2, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakPots()), - LOCATION(RC_GF_NORTH_F1_CARPENTER_POT_1, logic->CanBreakPots()), - LOCATION(RC_GF_NORTH_F1_CARPENTER_POT_2, logic->CanBreakPots()), - LOCATION(RC_GF_NORTH_F1_CARPENTER_POT_3, logic->CanBreakPots()), - LOCATION(RC_GF_NORTH_F2_CARPENTER_POT_1, logic->CanBreakPots()), - LOCATION(RC_GF_NORTH_F2_CARPENTER_POT_2, logic->CanBreakPots()), - LOCATION(RC_GF_SOUTH_F1_CARPENTER_POT_1, logic->CanBreakPots()), - LOCATION(RC_GF_SOUTH_F1_CARPENTER_POT_2, logic->CanBreakPots()), - LOCATION(RC_GF_SOUTH_F1_CARPENTER_POT_3, logic->CanBreakPots()), + LOCATION(RC_GF_CHEST, logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_GF_HBA_1000_POINTS, 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->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), + LOCATION(RC_GF_NORTH_F1_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), + LOCATION(RC_GF_NORTH_F2_CARPENTER, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))), + LOCATION(RC_GF_SOUTH_F1_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), + LOCATION(RC_GF_SOUTH_F2_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), + LOCATION(RC_GF_GERUDO_MEMBERSHIP_CARD, logic->CanFinishGerudoFortress()), + LOCATION(RC_GF_GS_ARCHERY_RANGE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && logic->AtNight && (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)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN) || ctx->GetTrickOption(RT_GF_JUMP)) && logic->CanGetNightTimeGS()), + LOCATION(RC_GF_BREAK_ROOM_POT_1, logic->CanBreakPots()), + LOCATION(RC_GF_BREAK_ROOM_POT_2, logic->CanBreakPots()), + LOCATION(RC_GF_KITCHEN_POT_1, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakPots()), + LOCATION(RC_GF_KITCHEN_POT_2, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakPots()), + LOCATION(RC_GF_NORTH_F1_CARPENTER_POT_1, logic->CanBreakPots()), + LOCATION(RC_GF_NORTH_F1_CARPENTER_POT_2, logic->CanBreakPots()), + LOCATION(RC_GF_NORTH_F1_CARPENTER_POT_3, logic->CanBreakPots()), + LOCATION(RC_GF_NORTH_F2_CARPENTER_POT_1, logic->CanBreakPots()), + LOCATION(RC_GF_NORTH_F2_CARPENTER_POT_2, logic->CanBreakPots()), + LOCATION(RC_GF_SOUTH_F1_CARPENTER_POT_1, logic->CanBreakPots()), + LOCATION(RC_GF_SOUTH_F1_CARPENTER_POT_2, logic->CanBreakPots()), + LOCATION(RC_GF_SOUTH_F1_CARPENTER_POT_3, logic->CanBreakPots()), LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_1, logic->CanBreakPots()), LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_2, logic->CanBreakPots()), LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_3, logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp index 74dba545f..c5ed28242 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp @@ -128,6 +128,9 @@ void RegionTable_Init_HyruleField() { 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->AtNight && logic->CanGetNightTimeGS()), LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) && logic->AtNight && logic->CanGetNightTimeGS() && logic->HasItem(RG_BRONZE_SCALE)), LOCATION(RC_LH_GS_TREE, logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_LH_FRONT_RUPEE, logic->IsChild && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_LH_MIDDLE_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LH_BACK_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LH_LAB_GOSSIP_STONE, true), LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE, true), LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE, true), @@ -155,9 +158,12 @@ void RegionTable_Init_HyruleField() { areaTable[RR_LH_LAB] = Region("LH Lab", "LH Lab", {}, NO_DAY_NIGHT_CYCLE, {}, { //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))), - LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->CanUse(RG_EYEBALL_FROG)), - LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)), + 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))), + LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->CanUse(RG_EYEBALL_FROG)), + LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)), + 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)), + LOCATION(RC_LH_LAB_RIGHT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), }, { //Exits Entrance(RR_LAKE_HYLIA, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp index 02ebb44e4..6648c4463 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp @@ -46,6 +46,13 @@ void RegionTable_Init_IceCavern() { LOCATION(RC_ICE_CAVERN_NEAR_END_POT_1, logic->CanBreakPots() && logic->BlueFire()), LOCATION(RC_ICE_CAVERN_NEAR_END_POT_2, logic->CanBreakPots() && logic->BlueFire()), LOCATION(RC_ICE_CAVERN_FROZEN_POT_1, logic->CanBreakPots() && logic->BlueFire() && logic->IsAdult), + LOCATION(RC_ICE_CAVERN_LOBBY_RUPEE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, logic->IsAdult), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, logic->IsAdult), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, logic->IsAdult), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), }, {}); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp index c3e5d9920..e65a36bc6 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp @@ -162,7 +162,7 @@ void RegionTable_Init_JabuJabusBelly() { }, { //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->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))));}}), }); } @@ -191,6 +191,11 @@ void RegionTable_Init_JabuJabusBelly() { }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, logic->CanUse(RG_IRON_BOOTS)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, logic->CanUse(RG_IRON_BOOTS)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, logic->CanUse(RG_IRON_BOOTS)), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return true;}}), @@ -208,6 +213,10 @@ void RegionTable_Init_JabuJabusBelly() { 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))), 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 + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_BOOMERANG)), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, {[]{return logic->HasItem(RG_BRONZE_SCALE);}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp index a4902117b..eb3b3fd5b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp @@ -270,6 +270,14 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_GY_DAMPES_GRAVE_POT_4, logic->CanBreakPots()), LOCATION(RC_GY_DAMPES_GRAVE_POT_5, logic->CanBreakPots()), LOCATION(RC_GY_DAMPES_GRAVE_POT_6, logic->CanBreakPots()), + 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), }, { //Exits Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp index 7c38e33a5..240f6ced0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp @@ -11,11 +11,29 @@ void RegionTable_Init_LostWoods() { EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}), }, { //Locations - LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild), - LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && logic->AtNight && (/*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->AtNight && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()), - LOCATION(RC_KF_GOSSIP_STONE, true), + LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild), + LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && logic->AtNight && (/*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->AtNight && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()), + LOCATION(RC_KF_BRIDGE_RUPEE, logic->IsChild), + LOCATION(RC_KF_BEHIND_MIDOS_RUPEE, logic->IsChild), + LOCATION(RC_KF_SOUTH_GRASS_WEST_RUPEE, logic->IsChild), + 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_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))), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_SARIAS_ROOF_WEST_HEART, logic->IsChild), + LOCATION(RC_KF_SARIAS_ROOF_EAST_HEART, logic->IsChild), + LOCATION(RC_KF_SARIAS_ROOF_NORTH_HEART, logic->IsChild), + LOCATION(RC_KF_GOSSIP_STONE, true), }, { //Exits Entrance(RR_KF_LINKS_HOUSE, {[]{return true;}}), @@ -65,7 +83,13 @@ void RegionTable_Init_LostWoods() { Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[RR_KF_SARIAS_HOUSE] = Region("KF Saria's House", "KF Saria's House", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KF_SARIAS_HOUSE] = Region("KF Saria's House", "KF Saria's House", {}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_KF_SARIAS_TOP_LEFT_HEART, true), + LOCATION(RC_KF_SARIAS_TOP_RIGHT_HEART, true), + LOCATION(RC_KF_SARIAS_BOTTOM_LEFT_HEART, true), + LOCATION(RC_KF_SARIAS_BOTTOM_RIGHT_HEART, true), + }, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); @@ -143,6 +167,15 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_TARGET_IN_WOODS, logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, logic->IsChild && logic->CanStunDeku()), LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, logic->CanSpawnSoilSkull() && logic->CanAttack()), + //RANDOTODO handle collecting some of these as you leave the shortcut from the other side + LOCATION(RC_LW_SHORTCUT_RUPEE_1, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_2, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_3, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_4, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_5, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_6, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_7, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_8, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LW_GOSSIP_STONE, true), }, { //Exits @@ -163,6 +196,7 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, logic->IsChild && logic->CanStunDeku()), LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && logic->AtNight && ((CanPlantBean(RR_LW_BEYOND_MIDO) && logic->CanAttack()) || (ctx->GetTrickOption(RT_LW_GS_BEAN) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE)))) && logic->CanGetNightTimeGS()), LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, logic->CanSpawnSoilSkull() && (logic->CanAttack() || (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->CanReflectNuts()))), + LOCATION(RC_LW_BOULDER_RUPEE, logic->BlastOrSmash()), }, { //Exits Entrance(RR_LW_FOREST_EXIT, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp index f60989b25..4dadea9f1 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp @@ -70,6 +70,9 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + //We cannot repeat the MQ invisible blades trick for these hearts as the like-like does not respawn if the room is cleared + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, {[]{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3, 4);}}), @@ -83,6 +86,8 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, {[]{return logic->CanJumpslashExceptHammer() && logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5);}}), @@ -90,19 +95,22 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_BEYOND_BOAT] = Region("Shadow Temple Beyond Boat", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, logic->CanJumpslashExceptHammer()), + LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, logic->CanJumpslashExceptHammer()), //RANDOTODO check if child can reach the token - LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->IsAdult && logic->CanAttack()), - LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, logic->CanBreakPots() && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5)))), - LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, logic->CanBreakPots() && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5)))), - LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, logic->CanBreakPots()), - }, { + LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->IsAdult && logic->CanAttack()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, logic->CanBreakPots() && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5)))), + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, logic->CanBreakPots() && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5)))), + LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanUse(RG_HOVER_BOOTS))), + }, { //Exits Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5) && logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}) }); @@ -195,6 +203,8 @@ void RegionTable_Init_ShadowTemple() { (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1)) && ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE))) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1) || logic->CanUse(RG_BOOMERANG)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return true;}}), @@ -303,7 +313,11 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_DOCK] = Region("Shadow Temple MQ Dock", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ShadowShortcutBlock, {[]{return logic->HasItem(RG_GORONS_BRACELET);}}), - }, {}, { + }, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + LOCATION(RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, {[]{return logic->ShadowShortcutBlock;}}), Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}}), @@ -327,6 +341,10 @@ void RegionTable_Init_ShadowTemple() { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, logic->CanUse(RG_SONG_OF_TIME) && logic->CanHitEyeTargets() && logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, logic->CanUse(RG_SONG_OF_TIME) && logic->CanHitEyeTargets() && logic->CanUse(RG_LONGSHOT)), + //There's invisible floor collision that makes aiming for the heart with rang harder than it should be, so it's a trick. + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, logic->IsAdult), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return Here(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->CanDetonateUprightBombFlower();}) && logic->IsAdult;}}), @@ -339,8 +357,8 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_BOSS_DOOR] = Region("Shadow Temple MQ Boss Door", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations //you can drop onto this and the respawn is reasonable - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOOMERANG) || logic->CanUse(RG_MEGATON_HAMMER)) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), - }, { + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER)) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, {[]{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}), Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp index 9a0adbbaf..4c480e196 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp @@ -133,8 +133,10 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Region("Spirit Temple Beyond Final Locked Door", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && ((logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS)) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT)))), - LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanAttack()) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), + LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && ((logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS)) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT)))), + LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanAttack()) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), + LOCATION(RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, logic->CanUse(RG_HOOKSHOT)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->HasExplosives() && logic->CanUse(RG_HOOKSHOT);}}), @@ -178,6 +180,8 @@ void RegionTable_Init_SpiritTemple() { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->MQSpiritTimeTravelChest), 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()), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp index 0f7c22afe..2beb1769b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp @@ -257,10 +257,14 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_RIVER] = Region("Water Temple River", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_RIVER_CHEST, (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))), - LOCATION(RC_WATER_TEMPLE_GS_RIVER, (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_WATER_RIVER_GS) && logic->CanUse(RG_LONGSHOT))), - LOCATION(RC_WATER_TEMPLE_RIVER_POT_1, logic->CanBreakPots()), - LOCATION(RC_WATER_TEMPLE_RIVER_POT_2, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_RIVER_CHEST, (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_WATER_TEMPLE_GS_RIVER, (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_WATER_RIVER_GS) && logic->CanUse(RG_LONGSHOT))), + LOCATION(RC_WATER_TEMPLE_RIVER_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_RIVER_POT_2, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_RIVER_HEART_1, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_WATER_TEMPLE_RIVER_HEART_2, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_WATER_TEMPLE_RIVER_HEART_3, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_WATER_TEMPLE_RIVER_HEART_4, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24) || logic->HasItem(RG_BRONZE_SCALE)), }, { //Exits Entrance(RR_WATER_TEMPLE_DRAGON_ROOM, {[]{return (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp index 578d7921c..596a50f7e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp @@ -21,21 +21,25 @@ void RegionTable_Init_ZorasDomain() { EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || logic->CanCutShrubs();}}), }, { //Locations - LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), - 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)), - LOCATION(RC_ZR_FROGS_EPONAS_SONG, logic->IsChild && logic->CanUse(RG_EPONAS_SONG)), - LOCATION(RC_ZR_FROGS_SARIAS_SONG, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), - LOCATION(RC_ZR_FROGS_SUNS_SONG, logic->IsChild && logic->CanUse(RG_SUNS_SONG)), - LOCATION(RC_ZR_FROGS_SONG_OF_TIME, logic->IsChild && logic->CanUse(RG_SONG_OF_TIME)), - 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->AtNight && logic->CanAttack() && logic->CanGetNightTimeGS()), - LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), - LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->AtNight && logic->CanGetNightTimeGS()), - LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, true), - LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, true), + LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), + 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)), + LOCATION(RC_ZR_FROGS_EPONAS_SONG, logic->IsChild && logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_ZR_FROGS_SARIAS_SONG, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), + LOCATION(RC_ZR_FROGS_SUNS_SONG, logic->IsChild && logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_ZR_FROGS_SONG_OF_TIME, logic->IsChild && logic->CanUse(RG_SONG_OF_TIME)), + 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->AtNight && logic->CanAttack() && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->AtNight && logic->CanGetNightTimeGS()), + 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_NEAR_DOMAIN_GOSSIP_STONE, true), }, { //Exits Entrance(RR_ZR_FRONT, {[]{return true;}}), @@ -162,20 +166,38 @@ void RegionTable_Init_ZorasDomain() { EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}), }, { //Locations - LOCATION(RC_ZF_ICEBERC_FREESTANDING_POH, logic->IsAdult), - LOCATION(RC_ZF_BOTTOM_FREESTANDING_POH, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24), - LOCATION(RC_ZF_GS_TREE, logic->IsChild), - LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), - LOCATION(RC_ZF_GS_HIDDEN_CAVE, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash() && logic->HookshotOrBoomerang() && logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS()), - LOCATION(RC_ZF_HIDDEN_CAVE_POT_1, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), - LOCATION(RC_ZF_HIDDEN_CAVE_POT_2, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), - LOCATION(RC_ZF_HIDDEN_CAVE_POT_3, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), - LOCATION(RC_ZF_FAIRY_GOSSIP_STONE, true), - LOCATION(RC_ZF_JABU_GOSSIP_STONE, true), - LOCATION(RC_ZF_NEAR_JABU_POT_1, logic->IsChild && logic->CanBreakPots()), - 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_ICEBERG_FREESTANDING_POH, logic->IsAdult), + LOCATION(RC_ZF_BOTTOM_FREESTANDING_POH, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_GS_TREE, logic->IsChild), + LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_ZF_GS_HIDDEN_CAVE, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash() && logic->HookshotOrBoomerang() && logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_ZF_HIDDEN_CAVE_POT_1, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), + LOCATION(RC_ZF_HIDDEN_CAVE_POT_2, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), + LOCATION(RC_ZF_HIDDEN_CAVE_POT_3, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), + LOCATION(RC_ZF_BOTTOM_NORTH_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTH_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTH_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTH_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_FAIRY_GOSSIP_STONE, true), + LOCATION(RC_ZF_JABU_GOSSIP_STONE, true), + LOCATION(RC_ZF_NEAR_JABU_POT_1, logic->IsChild && logic->CanBreakPots()), + 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()), }, { //Exits Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/dungeon.cpp b/soh/soh/Enhancements/randomizer/dungeon.cpp index 22d36bde0..faa22e2fa 100644 --- a/soh/soh/Enhancements/randomizer/dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/dungeon.cpp @@ -184,6 +184,11 @@ Dungeons::Dungeons() { RC_DEKU_TREE_GS_BASEMENT_GATE, RC_DEKU_TREE_GS_BASEMENT_VINES, RC_DEKU_TREE_GS_COMPASS_ROOM, + RC_DEKU_TREE_LOBBY_LOWER_HEART, + RC_DEKU_TREE_LOBBY_UPPER_HEART, + RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, + RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, + RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, }, { // MQ Locations @@ -199,6 +204,13 @@ Dungeons::Dungeons() { RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES, RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, + RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, + RC_DEKU_TREE_MQ_DEKU_BABA_HEART, + RC_DEKU_TREE_MQ_LOBBY_HEART, + RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, }, {}, {}, {}, { @@ -224,6 +236,10 @@ Dungeons::Dungeons() { RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, RC_DODONGOS_CAVERN_GS_BACK_ROOM, RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, + RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, + RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, + RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, + RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, }, { // MQ Locations @@ -242,6 +258,8 @@ Dungeons::Dungeons() { RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, + RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, }, { // Vanilla Pots @@ -345,6 +363,11 @@ Dungeons::Dungeons() { RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, + RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, + RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, }, { // Vanilla Pots @@ -417,6 +440,10 @@ Dungeons::Dungeons() { RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, RC_FOREST_TEMPLE_GS_LOBBY, RC_FOREST_TEMPLE_GS_BASEMENT, + RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, + RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, + RC_FOREST_TEMPLE_WELL_WEST_HEART, + RC_FOREST_TEMPLE_WELL_EAST_HEART, }, { // MQ Locations @@ -437,6 +464,12 @@ Dungeons::Dungeons() { RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, RC_FOREST_TEMPLE_MQ_GS_WELL, + RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, + RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, + RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, + RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART, + RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART, + RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART, }, { // Vanilla Pots @@ -514,6 +547,15 @@ Dungeons::Dungeons() { RC_FIRE_TEMPLE_GS_BOULDER_MAZE, RC_FIRE_TEMPLE_GS_SCARECROW_TOP, RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, + RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, + RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, + RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, }, { // MQ Locations @@ -534,6 +576,9 @@ Dungeons::Dungeons() { RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, }, { // Vanilla Pots @@ -610,6 +655,10 @@ Dungeons::Dungeons() { RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, RC_WATER_TEMPLE_GS_RIVER, + RC_WATER_TEMPLE_RIVER_HEART_1, + RC_WATER_TEMPLE_RIVER_HEART_2, + RC_WATER_TEMPLE_RIVER_HEART_3, + RC_WATER_TEMPLE_RIVER_HEART_4, }, { // MQ Locations @@ -718,6 +767,8 @@ Dungeons::Dungeons() { RC_SPIRIT_TEMPLE_GS_LOBBY, RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, RC_SPIRIT_TEMPLE_GS_METAL_FENCE, + RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, + RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, }, { // MQ Locations @@ -746,6 +797,8 @@ Dungeons::Dungeons() { RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, + RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, + RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, }, { // Vanilla Pots @@ -835,6 +888,13 @@ Dungeons::Dungeons() { RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, RC_SHADOW_TEMPLE_GS_NEAR_SHIP, + RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, + RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, + RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, + RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, }, { // MQ Locations @@ -863,6 +923,13 @@ Dungeons::Dungeons() { RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, + RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, + RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, + RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, + RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, }, { // Vanilla Pots @@ -936,6 +1003,13 @@ Dungeons::Dungeons() { RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, + RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, }, { // MQ Locations @@ -947,6 +1021,13 @@ Dungeons::Dungeons() { RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, + RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, }, { // Vanilla Pots @@ -992,6 +1073,13 @@ Dungeons::Dungeons() { RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, + RC_ICE_CAVERN_LOBBY_RUPEE, + RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, + RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, + RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, }, { // MQ Locations @@ -1060,6 +1148,8 @@ Dungeons::Dungeons() { RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, + RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, + RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, }, { // MQ Locations @@ -1113,6 +1203,11 @@ Dungeons::Dungeons() { RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, + RC_GANONS_CASTLE_FIRE_TRIAL_HEART, + RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, }, { // MQ Locations @@ -1134,6 +1229,9 @@ Dungeons::Dungeons() { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, + RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, }, { // Vanilla Pots diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 93213afb8..c94ea2776 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -876,13 +876,24 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; case VB_ITEM00_DESPAWN: { EnItem00* item00 = va_arg(args, EnItem00*); - if (item00->actor.params == ITEM00_HEART_PIECE || item00->actor.params == ITEM00_SMALL_KEY) { - RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(item00->actor.id, gPlayState->sceneNum, item00->ogParams); - if (rc != RC_UNKNOWN_CHECK) { + item00->randoInf = RAND_INF_MAX; + item00->randoCheck = RC_UNKNOWN_CHECK; + + auto pos = item00->actor.world.pos; + uint32_t params = item00->actor.params == ITEM00_HEART_PIECE || item00->actor.params == ITEM00_SMALL_KEY ? item00->ogParams : TWO_ACTOR_PARAMS((int32_t)pos.x, (int32_t)pos.z); + Rando::Location* loc = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(item00->actor.id, gPlayState->sceneNum, params); + + if (loc && loc->GetRandomizerCheck() != RC_UNKNOWN_CHECK && (RAND_GET_OPTION(RSK_SHUFFLE_FREESTANDING) || item00->actor.params == ITEM00_HEART_PIECE || item00->actor.params == ITEM00_SMALL_KEY)) { + // Spawn vanilla item if collected and renewable + if (loc->GetCollectionCheck().type != SPOILER_CHK_RANDOMIZER_INF || !Rando::Context::GetInstance()->GetItemLocation(loc->GetRandomizerCheck())->HasObtained()) { + item00->randoCheck = loc->GetRandomizerCheck(); + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(loc->GetRandomizerCheck(), true); item00->actor.params = ITEM00_SOH_DUMMY; - item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; - *should = Rando::Context::GetInstance()->GetItemLocation(rc)->HasObtained(); + if (loc->GetCollectionCheck().type == SPOILER_CHK_RANDOMIZER_INF) { + item00->randoInf = static_cast(loc->GetCollectionCheck().flag); + } + *should = Rando::Context::GetInstance()->GetItemLocation(loc->GetRandomizerCheck())->HasObtained(); } } else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY || item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY_GI) { GetItemEntry itemEntry = randomizerQueuedItemEntry; diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 86ac2832c..54fbaf8be 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -301,7 +301,7 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_ZD_KING_ZORA_THAWED] = Location::Base(RC_ZD_KING_ZORA_THAWED, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "King Zora Thawed", RHT_ZD_KING_ZORA_THAWED, RG_ZORA_TUNIC, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KING_ZORA_THAWED), true); locationTable[RC_ZD_TRADE_PRESCRIPTION] = Location::Base(RC_ZD_TRADE_PRESCRIPTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "Trade Prescription", RHT_ZD_TRADE_PRESCRIPTION, RG_EYEBALL_FROG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION), true); // Zora's Fountain - locationTable[RC_ZF_ICEBERC_FREESTANDING_POH] = Location::Collectable(RC_ZF_ICEBERC_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 262, 0x01, "Iceberg Freestanding PoH", RHT_ZF_ICEBERG_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_ZF_ICEBERG_FREESTANDING_POH] = Location::Collectable(RC_ZF_ICEBERG_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 262, 0x01, "Iceberg Freestanding PoH", RHT_ZF_ICEBERG_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_ZF_BOTTOM_FREESTANDING_POH] = Location::Collectable(RC_ZF_BOTTOM_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 5126, 0x14, "Bottom Freestanding PoH", RHT_ZF_BOTTOM_FREESTANDING_POH, RG_PIECE_OF_HEART, true); // Lon Lon Ranch locationTable[RC_LLR_TALONS_CHICKENS] = Location::Base(RC_LLR_TALONS_CHICKENS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LON_LON_BUILDINGS, 0x00, "Talons Chickens", RHT_LLR_TALONS_CHICKENS, RG_BOTTLE_WITH_MILK, SpoilerCollectionCheck::ItemGetInf(2), true); @@ -1600,6 +1600,238 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(197, -179), "MQ Lobby Right Pot 2", "Gerudo Training Ground MQ Lobby Right Pot 2", RHT_POT_GERUDO_TRAINING_GROUND, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2)); + // Freestanding Hearts and Rupees + locationTable[RC_KF_BOULDER_RUPEE_2] = Location::Collectable(RC_KF_BOULDER_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-712, 1857), 0x0E, "Boulder Maze Second Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_KF_BOULDER_RUPEE_1] = Location::Collectable(RC_KF_BOULDER_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-1009, 1556), 0x0F, "Boulder Maze First Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_KF_BRIDGE_RUPEE] = Location::Collectable(RC_KF_BRIDGE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(2, -45), 0x11, "Bridge Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_KF_BEHIND_MIDOS_RUPEE] = Location::Collectable(RC_KF_BEHIND_MIDOS_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-364, -783), 0x12, "Behind Mido's House Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_KF_SARIAS_ROOF_WEST_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_WEST_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(451, 810), 0x1C, "Saria's Roof West Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART); + locationTable[RC_KF_SARIAS_ROOF_EAST_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_EAST_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(567, 819), 0x1D, "Saria's Roof East Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART); + locationTable[RC_KF_SARIAS_ROOF_NORTH_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_NORTH_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(509, 725), 0x1E, "Saria's Roof North Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART); + locationTable[RC_KF_SOUTH_GRASS_WEST_RUPEE] = Location::Collectable(RC_KF_SOUTH_GRASS_WEST_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-537, 194), "South Grass West Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE)); + locationTable[RC_KF_NORTH_GRASS_WEST_RUPEE] = Location::Collectable(RC_KF_NORTH_GRASS_WEST_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(35, -418), "North Grass West Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_NORTH_GRASS_WEST_RUPEE)); + locationTable[RC_KF_NORTH_GRASS_EAST_RUPEE] = Location::Collectable(RC_KF_NORTH_GRASS_EAST_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(107, -418), "North Grass East Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_NORTH_GRASS_EAST_RUPEE)); + locationTable[RC_KF_SOUTH_GRASS_EAST_RUPEE] = Location::Collectable(RC_KF_SOUTH_GRASS_EAST_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-459, 181), "South Grass East Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE)); + locationTable[RC_KF_SARIAS_TOP_LEFT_HEART] = Location::Collectable(RC_KF_SARIAS_TOP_LEFT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SARIAS_HOUSE, TWO_ACTOR_PARAMS(45, -52), "Saria's House Top Left Heart", RHT_SARIAS_HOUSE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_TOP_LEFT_HEART)); + locationTable[RC_KF_SARIAS_TOP_RIGHT_HEART] = Location::Collectable(RC_KF_SARIAS_TOP_RIGHT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SARIAS_HOUSE, TWO_ACTOR_PARAMS(46, 56), "Saria's House Top Right Heart", RHT_SARIAS_HOUSE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_TOP_RIGHT_HEART)); + locationTable[RC_KF_SARIAS_BOTTOM_LEFT_HEART] = Location::Collectable(RC_KF_SARIAS_BOTTOM_LEFT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SARIAS_HOUSE, TWO_ACTOR_PARAMS(-46, -51), "Saria's House Bottom Left Heart", RHT_SARIAS_HOUSE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART)); + locationTable[RC_KF_SARIAS_BOTTOM_RIGHT_HEART] = Location::Collectable(RC_KF_SARIAS_BOTTOM_RIGHT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SARIAS_HOUSE, TWO_ACTOR_PARAMS(-46, 57), "Saria's House Bottom Right Heart", RHT_SARIAS_HOUSE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART)); + + locationTable[RC_KF_BEAN_RUPEE_1] = Location::Collectable(RC_KF_BEAN_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1269, -528), "Bean Platform Rupee 1", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_1)); + locationTable[RC_KF_BEAN_RUPEE_2] = Location::Collectable(RC_KF_BEAN_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1269, -567), "Bean Platform Rupee 2", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_2)); + locationTable[RC_KF_BEAN_RUPEE_3] = Location::Collectable(RC_KF_BEAN_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1304, -588), "Bean Platform Rupee 3", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_3)); + locationTable[RC_KF_BEAN_RUPEE_4] = Location::Collectable(RC_KF_BEAN_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1338, -567), "Bean Platform Rupee 4", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_4)); + locationTable[RC_KF_BEAN_RUPEE_5] = Location::Collectable(RC_KF_BEAN_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1338, -528), "Bean Platform Rupee 5", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_5)); + locationTable[RC_KF_BEAN_RUPEE_6] = Location::Collectable(RC_KF_BEAN_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1304, -508), "Bean Platform Rupee 6", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_6)); + locationTable[RC_KF_BEAN_RED_RUPEE] = Location::Collectable(RC_KF_BEAN_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1304, -548), "Bean Platform Red Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RED_RUPEE)); + + locationTable[RC_LW_BOULDER_RUPEE] = Location::Collectable(RC_LW_BOULDER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(1720, -2510), 0x13, "Boulder Rupee", RHT_LOST_WOODS_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_LW_SHORTCUT_RUPEE_1] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2215, -850), "Underwater Shortcut Rupee 1", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_1)); + locationTable[RC_LW_SHORTCUT_RUPEE_2] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2164, -850), "Underwater Shortcut Rupee 2", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_2)); + locationTable[RC_LW_SHORTCUT_RUPEE_3] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2113, -850), "Underwater Shortcut Rupee 3", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_3)); + locationTable[RC_LW_SHORTCUT_RUPEE_4] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2061, -853), "Underwater Shortcut Rupee 4", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_4)); + locationTable[RC_LW_SHORTCUT_RUPEE_5] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2194, -895), "Underwater Shortcut Rupee 5", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_5)); + locationTable[RC_LW_SHORTCUT_RUPEE_6] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2156, -937), "Underwater Shortcut Rupee 6", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_6)); + locationTable[RC_LW_SHORTCUT_RUPEE_7] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_7, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2193, -813), "Underwater Shortcut Rupee 7", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_7)); + locationTable[RC_LW_SHORTCUT_RUPEE_8] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_8, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2153, -779), "Underwater Shortcut Rupee 8", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_8)); + + locationTable[RC_LH_FRONT_RUPEE] = Location::Collectable(RC_LH_FRONT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-940, 3968), "Underwater Front Rupee", RHT_LAKE_HYLIA_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_FRONT_RUPEE)); + locationTable[RC_LH_MIDDLE_RUPEE] = Location::Collectable(RC_LH_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-868, 4090), "Underwater Middle Rupee", RHT_LAKE_HYLIA_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_MIDDLE_RUPEE)); + locationTable[RC_LH_BACK_RUPEE] = Location::Collectable(RC_LH_BACK_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-861, 4212), "Underwater Back Rupee", RHT_LAKE_HYLIA_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BACK_RUPEE)); + locationTable[RC_LH_LAB_FRONT_RUPEE] = Location::Collectable(RC_LH_LAB_FRONT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(68, -207), 0x01, "Lab Front Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE); + locationTable[RC_LH_LAB_LEFT_RUPEE] = Location::Collectable(RC_LH_LAB_LEFT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(-52, -32), 0x02, "Lab Left Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE); + locationTable[RC_LH_LAB_RIGHT_RUPEE] = Location::Collectable(RC_LH_LAB_RIGHT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(-169, -124), 0x03, "Lab Right Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE); + + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_1] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(385, -2766), "Dampe's Grave Rupee 1", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_2] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(528, -3216), "Dampe's Grave Rupee 2", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_3] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(753, -4828), "Dampe's Grave Rupee 3", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_4] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(570, -5599), "Dampe's Grave Rupee 4", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_5] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(1461, -5736), "Dampe's Grave Rupee 5", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_6] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(2376, -4647), "Dampe's Grave Rupee 6", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_7] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_7, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(2573, -3758), "Dampe's Grave Rupee 7", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_8] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_8, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(1511, -3118), "Dampe's Grave Rupee 8", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8)); + + locationTable[RC_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-42, 880), "Octorok Grotto Front Left Blue Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(58, 803), "Octorok Grotto Back Blue Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(90, 910), "Octorok Grotto Front Right Blue Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-68, 959), "Octorok Grotto Front Left Green Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(132, 961), "Octorok Grotto Front Right Green Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-38, 768), "Octorok Grotto Back Left Green Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 784), "Octorok Grotto Back Right Green Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_RED_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(32, 852), "Octorok Grotto Red Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE)); + + locationTable[RC_DMT_RED_RUPEE] = Location::Collectable(RC_DMT_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-625, -55), 0x0A, "Red Rupee Under Boulder", RHT_DEATH_MOUNTAIN_TRAIL_RUPEE, RG_RED_RUPEE); + locationTable[RC_DMT_BLUE_RUPEE] = Location::Collectable(RC_DMT_BLUE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1060, -51), 0x07, "Blue Rupee Under Boulder", RHT_DEATH_MOUNTAIN_TRAIL_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_DMT_COW_GROTTO_LEFT_HEART] = Location::Collectable(RC_DMT_COW_GROTTO_LEFT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2287, -412), "Cow Grotto Left Heart", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_LEFT_HEART)); + locationTable[RC_DMT_COW_GROTTO_MIDDLE_LEFT_HEART] = Location::Collectable(RC_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2371, -532), "Cow Grotto Middle Left Heart", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART)); + locationTable[RC_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART] = Location::Collectable(RC_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2449, -534), "Cow Grotto Middle Right Heart", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART)); + locationTable[RC_DMT_COW_GROTTO_RIGHT_HEART] = Location::Collectable(RC_DMT_COW_GROTTO_RIGHT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2569, -432), "Cow Grotto Right Heart", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RIGHT_HEART)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_1] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2390, -100), "Cow Grotto Rupee 1", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_1)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_2] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2390, -139), "Cow Grotto Rupee 2", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_2)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_3] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2425, -160), "Cow Grotto Rupee 3", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_3)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_4] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2459, -139), "Cow Grotto Rupee 4", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_4)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_5] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2459, -100), "Cow Grotto Rupee 5", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_5)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_6] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2425, -80), "Cow Grotto Rupee 6", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_6)); + locationTable[RC_DMT_COW_GROTTO_RED_RUPEE] = Location::Collectable(RC_DMT_COW_GROTTO_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2425, -120), "Cow Grotto Red Rupee", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RED_RUPEE)); + + locationTable[RC_DMC_NEAR_PLATFORM_RED_RUPEE] = Location::Collectable(RC_DMC_NEAR_PLATFORM_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(675, -718), "Near Warp Platform Red Rupee", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE)); + locationTable[RC_DMC_MIDDLE_PLATFORM_RED_RUPEE] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1117, -185), "Middle Platform Red Rupee", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1117, -248), "Middle Platform Blue Rupee 1", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1116, -128), "Middle Platform Blue Rupee 2", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1159, -162), "Middle Platform Blue Rupee 3", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1158, -227), "Middle Platform Blue Rupee 4", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1078, -226), "Middle Platform Blue Rupee 5", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1078, -164), "Middle Platform Blue Rupee 6", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_1] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1087, 454), "Distant Platform Rupee 1", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_2] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1087, 415), "Distant Platform Rupee 2", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_3] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1122, 395), "Distant Platform Rupee 3", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_4] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1156, 415), "Distant Platform Rupee 4", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_5] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1156, 454), "Distant Platform Rupee 5", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_6] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1122, 475), "Distant Platform Rupee 6", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6)); + locationTable[RC_DMC_DISTANT_PLATFORM_RED_RUPEE] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1122, 435), "Distant Platform Red Rupee", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE)); + + locationTable[RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE] = Location::Collectable(RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(4216, -1464), "Beneath Domain Red Left Rupee", RHT_ZORAS_RIVER_WATERFALL_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE)); + locationTable[RC_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE] = Location::Collectable(RC_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(4171, -1436), "Beneath Domain Red Middle Left Rupee", RHT_ZORAS_RIVER_WATERFALL_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE)); + locationTable[RC_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE] = Location::Collectable(RC_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(4171, -1376), "Beneath Domain Red Middle Right Rupee", RHT_ZORAS_RIVER_WATERFALL_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE)); + locationTable[RC_ZR_BENEATH_WATERFALL_RIGHT_RUPEE] = Location::Collectable(RC_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(4224, -1339), "Beneath Domain Red Right Rupee", RHT_ZORAS_RIVER_WATERFALL_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE)); + + locationTable[RC_ZF_BOTTOM_NORTH_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTH_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(68, -166), "Bottom North Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHEAST_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(172, -35), "Bottom Northeast Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(137, 130), "Bottom Southeast Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTH_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTH_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-76, 172), "Bottom South Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-207, 47), "Bottom Southwest Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHWEST_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-173, -132), "Bottom Northwest Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTH_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(242, -576), "Bottom North Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(540, -124), "Bottom Northeast Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(397, 318), "Bottom Southeast Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-166, 428), "Bottom South Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-574, 163), "Bottom Southwest Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-464, -389), "Bottom Northwest Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTH_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTH_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(353, -934), "Bottom North Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(1032, -254), "Bottom Northeast Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(603, 466), "Bottom Southeast Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTH_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTH_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-227, 696), "Bottom South Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-847, 206), "Bottom Southwest Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-857, -654), "Bottom Northwest Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE)); + + locationTable[RC_DEKU_TREE_LOBBY_LOWER_HEART] = Location::Collectable(RC_DEKU_TREE_LOBBY_LOWER_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-25, -81), "Lobby Lower Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART)); + locationTable[RC_DEKU_TREE_LOBBY_UPPER_HEART] = Location::Collectable(RC_DEKU_TREE_LOBBY_UPPER_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(87, -16), "Lobby Upper Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART)); + locationTable[RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART] = Location::Collectable(RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-885, -185), "Final Room Left Front Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART)); + locationTable[RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART] = Location::Collectable(RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-820, -76), "Final Room Left Back Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART)); + locationTable[RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART] = Location::Collectable(RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-354, -206), "Final Room Right Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART)); + + locationTable[RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4266, -1575), 0x18, "Lower Lizalfos Room Lavafall Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART); + locationTable[RC_DODONGOS_CAVERN_BLADE_ROOM_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2039, -317), "Blade Room Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART)); + locationTable[RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3553, -1962), "Upper Lizalfos Room Left Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART)); + locationTable[RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3580, -2004), "Upper Lizalfos Room Right Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART)); + + locationTable[RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART] = Location::Collectable(RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-1124, -2855), "West Courtyard Right Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART)); + locationTable[RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART] = Location::Collectable(RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-1165, -2788), "West Courtyard Left Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART)); + locationTable[RC_FOREST_TEMPLE_WELL_WEST_HEART] = Location::Collectable(RC_FOREST_TEMPLE_WELL_WEST_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(307, -1734), "Well East Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART)); + locationTable[RC_FOREST_TEMPLE_WELL_EAST_HEART] = Location::Collectable(RC_FOREST_TEMPLE_WELL_EAST_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(251, -1735), "Well West Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART)); + + locationTable[RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3476, -359), "Fire Pillar Room Left Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART)); + locationTable[RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3476, -295), "Fire Pillar Room Right Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART)); + locationTable[RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3526, -339), "Fire Pillar Room Back Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART)); + locationTable[RC_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1753, -136), "East Central Room Left Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART)); + locationTable[RC_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1813, -37), "East Central Room Right Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART)); + locationTable[RC_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART] = Location::Collectable(RC_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1783, -91), "East Central Room Middle Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART)); + locationTable[RC_FIRE_TEMPLE_FIRE_WALL_EAST_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(862, -169), "Fire Wall Chase East Pillar Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART)); + locationTable[RC_FIRE_TEMPLE_FIRE_WALL_WEST_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(603, -190), "Fire Wall Chase West Pillar Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART)); + locationTable[RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1381, -1120), "Fire Wall Chase Exit Platform Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART)); + + locationTable[RC_WATER_TEMPLE_RIVER_HEART_1] = Location::Collectable(RC_WATER_TEMPLE_RIVER_HEART_1, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2781, -2515), "River Heart 1", RHT_WATER_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_RIVER_HEART_1)); + locationTable[RC_WATER_TEMPLE_RIVER_HEART_2] = Location::Collectable(RC_WATER_TEMPLE_RIVER_HEART_2, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2528, -2727), "River Heart 2", RHT_WATER_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_RIVER_HEART_2)); + locationTable[RC_WATER_TEMPLE_RIVER_HEART_3] = Location::Collectable(RC_WATER_TEMPLE_RIVER_HEART_3, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2436, -3348), "River Heart 3", RHT_WATER_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_RIVER_HEART_3)); + locationTable[RC_WATER_TEMPLE_RIVER_HEART_4] = Location::Collectable(RC_WATER_TEMPLE_RIVER_HEART_4, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2021, -2937), "River Heart 4", RHT_WATER_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_RIVER_HEART_4)); + + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5676, 1565), "Invisible Blades Left Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART)); + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5695, 1589), "Invisible Blades Right Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART)); + locationTable[RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3971, -1716), "Scarecrow Near Ship North Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART)); + locationTable[RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3970, -1560), "Scarecrow Near Ship South Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART)); + locationTable[RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3471, -884), "After Ship Upper Left Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART)); + locationTable[RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3473, -927), "After Ship Upper Right Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART)); + locationTable[RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3164, -646), "After Ship Lower Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART)); + + locationTable[RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(708, 227), 0x01, "Adult Climb Left Heart", RHT_SPIRIT_TEMPLE_HEART, RG_RECOVERY_HEART); + locationTable[RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(661, 227), 0x02, "Adult Climb Right Heart", RHT_SPIRIT_TEMPLE_HEART, RG_RECOVERY_HEART); + + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-67, -748), 0x05, "Basement Platform Left Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-19, -828), 0x06, "Basement Platform Back Left Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(47, -805), 0x02, "Basement Platform Middle Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(94, -762), 0x03, "Basement Platform Back Right Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-85, -710), 0x04, "Basement Platform Right Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-1947, -625), 0x1F, "Coffin Room Front Left Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART); + locationTable[RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-2144, -859), "Coffin Room Middle Right Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART)); + + locationTable[RC_ICE_CAVERN_LOBBY_RUPEE] = Location::Collectable(RC_ICE_CAVERN_LOBBY_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-185, 854), "Lobby Rupee", RHT_ICE_CAVERN_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_LOBBY_RUPEE)); + locationTable[RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART] = Location::Collectable(RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1171, -2258), "Map Room Left Heart", RHT_ICE_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART)); + locationTable[RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART] = Location::Collectable(RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1212, -2213), "Map Room Middle Heart", RHT_ICE_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART)); + locationTable[RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART] = Location::Collectable(RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1166, -2173), "Map Room Right Heart", RHT_ICE_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART)); + locationTable[RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1] = Location::Collectable(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1699, -697), "Sliding Block Room Rupee 1", RHT_ICE_CAVERN_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1)); + locationTable[RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2] = Location::Collectable(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1648, -715), "Sliding Block Room Rupee 2", RHT_ICE_CAVERN_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2)); + locationTable[RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3] = Location::Collectable(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1648, -667), "Sliding Block Room Rupee 3", RHT_ICE_CAVERN_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3)); + + locationTable[RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART] = Location::Collectable(RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1486, 204), "Beamos South Heart", RHT_GERUDO_TRAINING_GROUNDS_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART)); + locationTable[RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART] = Location::Collectable(RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1858, -183), "Beamos East Heart", RHT_GERUDO_TRAINING_GROUNDS_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART)); + + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1] = Location::Collectable(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1855, -3953), "Shadow Trial Heart 1", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1)); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2] = Location::Collectable(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1844, -4038), "Shadow Trial Heart 2", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2)); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3] = Location::Collectable(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1827, -4106), "Shadow Trial Heart 3", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3)); + locationTable[RC_GANONS_CASTLE_FIRE_TRIAL_HEART] = Location::Collectable(RC_GANONS_CASTLE_FIRE_TRIAL_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1636, -3069), "Fire Trial Heart", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART)); + locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART] = Location::Collectable(RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-517, 592), "Spirit Trial Heart", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART)); + + locationTable[RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-1128, 1571), "MQ Compass Room Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART)); + locationTable[RC_DEKU_TREE_MQ_DEKU_BABA_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_DEKU_BABA_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-594, 840), "MQ Deku Baba Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART)); + locationTable[RC_DEKU_TREE_MQ_LOBBY_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_LOBBY_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-22, -88), "MQ Lobby Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_LOBBY_HEART)); + locationTable[RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-1165, 325), "MQ Slingshot Room Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART)); + locationTable[RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-885, -185), "MQ Final Room Left Front Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART)); + locationTable[RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-820, -76), "MQ Final Room Left Back Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART)); + locationTable[RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-354, -206), "MQ Final Room Right Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART)); + + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4266, -1575), 0x18, "MQ Lizalfos Room Lavafall Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART); + locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1955, -596), "MQ Torch Room Invisible Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART)); + + locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-390, -1695), 0x01, "MQ Lift Room Underwater Rupee 1", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE); + locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-487, -1701), 0x02, "MQ Lift Room Underwater Rupee 2", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE); + locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-549, -1709), 0x03, "MQ Lift Room Underwater Rupee 3", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE); + locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-217, -1620), "MQ Lift Room Heart 1", RHT_JABU_JABU_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-206, -1797), "MQ Lift Room Heart 2", RHT_JABU_JABU_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2)); + + locationTable[RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-1124, -2855), "MQ West Courtyard Right Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART)); + locationTable[RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-1157, -2798), "MQ West Courtyard Middle Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART)); + locationTable[RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-1184, -2744), "MQ West Courtyard Left Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART)); + locationTable[RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(115, -1755), "MQ Well Middle Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART)); + locationTable[RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(15, -1755), "MQ Well West Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART)); + locationTable[RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(215, -1755), "MQ Well East Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART)); + + locationTable[RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3476, -331), "MQ Fire Pillar Room Left Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART)); + locationTable[RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3502, 320), "MQ Fire Pillar Room Right Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART)); + locationTable[RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART] = Location::Collectable(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3307, 180), "MQ Fire Pillar Room Lower Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART)); + + locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5676, 1565), "MQ Invisible Blades Left Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5695, -1028), "MQ Invisible Blades Right Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3971, -1716), "MQ Scarecrow Near Ship North Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3970, -1560), "MQ Scarecrow Near Ship South Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3471, -884), "MQ After Ship Upper Left Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3473, -927), "MQ After Ship Upper Right Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3164, -646), "MQ After Ship Lower Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART)); + + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1151, -535), "MQ Child Early Left Heart", RHT_SPIRIT_TEMPLE_MQ_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART)); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-976, -535), "MQ Child Early Right Heart", RHT_SPIRIT_TEMPLE_MQ_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART)); + + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-1945, -863), "MQ Coffin Room Front Right Invisible Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-83, -350), "MQ Bomb Alcove Left Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-83, -274), "MQ Bomb Alcove Right Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-2143, -621), "MQ Coffin Room Middle Left Invisible Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(1083, -1174), "MQ Basement Hallway Front Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(1044, -1223), "MQ Basement Hallway Left Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(1114, -1223), "MQ Basement Hallway Right Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART)); + + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART] = Location::Collectable(RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1743, -528), "MQ Water Trial Heart", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART)); + locationTable[RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART] = Location::Collectable(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2506, -1096), "MQ Light Trial Right Heart", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART)); + locationTable[RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART] = Location::Collectable(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2655, -549), "MQ Light Trial Left Heart", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART)); + // Gossip Stones locationTable[RC_DMC_GOSSIP_STONE] = Location::HintStone(RC_DMC_GOSSIP_STONE, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_CRATER, 14341, "Gossip Stone"); locationTable[RC_DMT_GOSSIP_STONE] = Location::HintStone(RC_DMT_GOSSIP_STONE, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 14340, "Gossip Stone"); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index d2588b7ad..4f460e2a9 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1049,6 +1049,7 @@ namespace Rando { return CanUse(RG_GORON_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts() * 8) : 0; } + //Tunic is not required if you are using irons to do something that a simple gold scale dive could do, and you are not in water temple. (celing swimming and long walks through water do not count) uint8_t Logic::WaterTimer(){ return CanUse(RG_ZORA_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts() * 8) : 0; } diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index a23489f5d..b50a02a00 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -436,6 +436,16 @@ void Settings::CreateOptionDescriptions() { "have collected all 100 Gold Skulltula Tokens.\n" "\n" "You can still talk to him multiple times to get Huge Rupees."; + mOptionDescriptions[RSK_SHUFFLE_FREESTANDING] = "Freestanding rupees & hearts are shuffles to random items. " + "Freestanding heart pieces and small keys are already shuffled by default.\n" + "\n" + "Off - freestanding rupees & hearts will not be shuffled.\n" + "\n" + "Dungeons - Only freestanding rupees & hearts that are within dungeons.\n" + "\n" + "Overworld - Only freestanding rupees & hearts that are outside of dungeons.\n" + "\n" + "All Items - Shuffle all freestanding rupees & hearts."; mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS] = "Shuffles the location of Spiritual Stones and medallions.\n" "\n" diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 9818e5e51..88af04f9c 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -268,6 +268,7 @@ typedef enum { RCTYPE_OCARINA, // Ocarina locations RCTYPE_BEEHIVE, // Beehives RCTYPE_FISH, // Fishes + RCTYPE_FREESTANDING, // Freestanding rupees and hearts } RandomizerCheckType; typedef enum { RCQUEST_VANILLA, RCQUEST_MQ, RCQUEST_BOTH } RandomizerCheckQuest; @@ -459,6 +460,7 @@ typedef enum { RR_DMC_UPPER_GROTTO, RR_DMC_HAMMER_GROTTO, RR_DMC_GREAT_FAIRY_FOUNTAIN, + RR_DMC_DISTANT_PLATFORM, RR_ZR_FRONT, RR_ZORAS_RIVER, RR_ZR_BEHIND_WATERFALL, @@ -1264,7 +1266,7 @@ typedef enum { RC_ZD_SHOP_ITEM_7, RC_ZD_SHOP_ITEM_8, RC_ZF_GREAT_FAIRY_REWARD, - RC_ZF_ICEBERC_FREESTANDING_POH, + RC_ZF_ICEBERG_FREESTANDING_POH, RC_ZF_BOTTOM_FREESTANDING_POH, RC_ZF_GS_ABOVE_THE_LOG, RC_ZF_GS_TREE, @@ -2398,6 +2400,207 @@ typedef enum { RC_ZD_FISH_3, RC_ZD_FISH_4, RC_ZD_FISH_5, + RC_KF_BOULDER_RUPEE_1, + RC_KF_BOULDER_RUPEE_2, + RC_KF_BRIDGE_RUPEE, + RC_KF_BEHIND_MIDOS_RUPEE, + RC_KF_SARIAS_ROOF_WEST_HEART, + RC_KF_SARIAS_ROOF_EAST_HEART, + RC_KF_SARIAS_ROOF_NORTH_HEART, + RC_KF_SOUTH_GRASS_WEST_RUPEE, + RC_KF_NORTH_GRASS_WEST_RUPEE, + RC_KF_NORTH_GRASS_EAST_RUPEE, + RC_KF_SOUTH_GRASS_EAST_RUPEE, + RC_KF_SARIAS_TOP_LEFT_HEART, + RC_KF_SARIAS_TOP_RIGHT_HEART, + RC_KF_SARIAS_BOTTOM_LEFT_HEART, + RC_KF_SARIAS_BOTTOM_RIGHT_HEART, + RC_KF_BEAN_RUPEE_1, + RC_KF_BEAN_RUPEE_2, + RC_KF_BEAN_RUPEE_3, + RC_KF_BEAN_RUPEE_4, + RC_KF_BEAN_RUPEE_5, + RC_KF_BEAN_RUPEE_6, + RC_KF_BEAN_RED_RUPEE, + RC_LW_BOULDER_RUPEE, + RC_LW_SHORTCUT_RUPEE_1, + RC_LW_SHORTCUT_RUPEE_2, + RC_LW_SHORTCUT_RUPEE_3, + RC_LW_SHORTCUT_RUPEE_4, + RC_LW_SHORTCUT_RUPEE_5, + RC_LW_SHORTCUT_RUPEE_6, + RC_LW_SHORTCUT_RUPEE_7, + RC_LW_SHORTCUT_RUPEE_8, + RC_LH_FRONT_RUPEE, + RC_LH_MIDDLE_RUPEE, + RC_LH_BACK_RUPEE, + RC_LH_LAB_FRONT_RUPEE, + RC_LH_LAB_LEFT_RUPEE, + RC_LH_LAB_RIGHT_RUPEE, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_1, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_2, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_3, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_4, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_5, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_6, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_7, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_8, + RC_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, + RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, + RC_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, + RC_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, + RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, + RC_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, + RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, + RC_GV_OCTOROK_GROTTO_RED_RUPEE, + RC_DMT_BLUE_RUPEE, + RC_DMT_RED_RUPEE, + RC_DMT_COW_GROTTO_LEFT_HEART, + RC_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, + RC_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, + RC_DMT_COW_GROTTO_RIGHT_HEART, + RC_DMT_COW_GROTTO_RUPEE_1, + RC_DMT_COW_GROTTO_RUPEE_2, + RC_DMT_COW_GROTTO_RUPEE_3, + RC_DMT_COW_GROTTO_RUPEE_4, + RC_DMT_COW_GROTTO_RUPEE_5, + RC_DMT_COW_GROTTO_RUPEE_6, + RC_DMT_COW_GROTTO_RED_RUPEE, + RC_DMC_NEAR_PLATFORM_RED_RUPEE, + RC_DMC_MIDDLE_PLATFORM_RED_RUPEE, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, + RC_DMC_DISTANT_PLATFORM_RED_RUPEE, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_1, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_2, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_3, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_4, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_5, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_6, + RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE, + RC_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, + RC_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, + RC_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, + RC_ZF_BOTTOM_NORTH_INNER_RUPEE, + RC_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, + RC_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, + RC_ZF_BOTTOM_SOUTH_INNER_RUPEE, + RC_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, + RC_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, + RC_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, + RC_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, + RC_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, + RC_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, + RC_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, + RC_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, + RC_ZF_BOTTOM_NORTH_OUTER_RUPEE, + RC_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, + RC_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, + RC_ZF_BOTTOM_SOUTH_OUTER_RUPEE, + RC_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, + RC_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, + RC_DEKU_TREE_LOBBY_LOWER_HEART, + RC_DEKU_TREE_LOBBY_UPPER_HEART, + RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, + RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, + RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, + RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, + RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, + RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, + RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, + RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, + RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, + RC_FOREST_TEMPLE_WELL_WEST_HEART, + RC_FOREST_TEMPLE_WELL_EAST_HEART, + RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, + RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, + RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, + RC_WATER_TEMPLE_RIVER_HEART_1, + RC_WATER_TEMPLE_RIVER_HEART_2, + RC_WATER_TEMPLE_RIVER_HEART_3, + RC_WATER_TEMPLE_RIVER_HEART_4, + RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, + RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, + RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, + RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, + RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, + RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, + RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, + RC_ICE_CAVERN_LOBBY_RUPEE, + RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, + RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, + RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, + RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, + RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, + RC_GANONS_CASTLE_FIRE_TRIAL_HEART, + RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, + RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, + RC_DEKU_TREE_MQ_DEKU_BABA_HEART, + RC_DEKU_TREE_MQ_LOBBY_HEART, + RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, + RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, + RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, + RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, + RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, + RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, + RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, + RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART, + RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART, + RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, + RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, + RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, + RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, + RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, + RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, + RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, + RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, RC_MAX } RandomizerCheck; @@ -2498,6 +2701,7 @@ typedef enum { RT_FOREST_OUTDOORS_LEDGE, RT_FOREST_DOORFRAME, RT_FOREST_OUTSIDE_BACKDOOR, + RT_FOREST_OUTDOORS_HEARTS_BOOMERANG, RT_FOREST_MQ_WELL_SWIM, RT_FOREST_MQ_BLOCK_PUZZLE, RT_FOREST_MQ_JS_HALLWAY_SWITCH, @@ -4433,6 +4637,38 @@ typedef enum { RHT_ISOLATED_PLACE, RHT_DUNGEON_ORDINARY, RHT_DUNGEON_MASTERFUL, + // Shuffle Rupees & Hearts + RHT_KOKIRI_FOREST_RUPEE, + RHT_KOKIRI_FOREST_HEART, + RHT_SARIAS_HOUSE_HEART, + RHT_LOST_WOODS_RUPEE, + RHT_LOST_WOODS_SHORTCUT_RUPEE, + RHT_LAKE_HYLIA_RUPEE, + RHT_LABORATORY_RUPEE, + RHT_DAMPES_GRAVE_RUPEE, + RHT_GERUDO_VALLEY_GROTTO_RUPEE, + RHT_DEATH_MOUNTAIN_TRAIL_RUPEE, + RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, + RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, + RHT_DEATH_MOUNTAIN_CRATER_RUPEE, + RHT_ZORAS_RIVER_WATERFALL_RUPEE, + RHT_ZORAS_FOUNTAIN_RUPEE, + RHT_DEKU_TREE_HEART, + RHT_DODONGOS_CAVERN_HEART, + RHT_JABU_JABU_RUPEE, + RHT_JABU_JABU_HEART, + RHT_FOREST_TEMPLE_HEART, + RHT_FIRE_TEMPLE_HEART, + RHT_WATER_TEMPLE_HEART, + RHT_SHADOW_TEMPLE_HEART, + RHT_SPIRIT_TEMPLE_HEART, + RHT_SPIRIT_TEMPLE_MQ_HEART, + RHT_BOTTOM_OF_THE_WELL_HEART, + RHT_BOTTOM_OF_THE_WELL_RUPEE, + RHT_ICE_CAVERN_HEART, + RHT_ICE_CAVERN_RUPEE, + RHT_GERUDO_TRAINING_GROUNDS_HEART, + RHT_GANONS_CASTLE_HEART, // MAX RHT_MAX } RandomizerHintTextKey; @@ -4722,6 +4958,7 @@ typedef enum { RSK_SKELETON_KEY, RSK_SHUFFLE_DEKU_STICK_BAG, RSK_SHUFFLE_DEKU_NUT_BAG, + RSK_SHUFFLE_FREESTANDING, RSK_MAX } RandomizerSettingKey; @@ -5052,6 +5289,14 @@ typedef enum { RO_TOKENSANITY_ALL, } RandoOptionTokensanity; +//Freestanding Hearts/Rupees settings (off, dungeons, overworld, all) +typedef enum { + RO_FREESTANDING_OFF, + RO_FREESTANDING_DUNGEONS, + RO_FREESTANDING_OVERWORLD, + RO_FREESTANDING_ALL, +} RandoOptionFreestanding; + // Shuffle Pots settings (off, dungeons, overworld, all) typedef enum { RO_SHUFFLE_POTS_OFF, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 1f0358592..86b5c7b81 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -48,6 +48,8 @@ bool showMajorScrubs; bool showMerchants; bool showBeehives; bool showCows; +bool showOverworldFreestanding; +bool showDungeonFreestanding; bool showAdultTrade; bool showKokiriSword; bool showMasterSword; @@ -1251,6 +1253,30 @@ void LoadSettings() { fishsanityMode = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY); fishsanityPondCount = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_POND_COUNT); fishsanityAgeSplit = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_AGE_SPLIT); + + if (IS_RANDO) { + switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FREESTANDING)) { + case RO_FREESTANDING_ALL: + showOverworldFreestanding = true; + showDungeonFreestanding = true; + break; + case RO_FREESTANDING_OVERWORLD: + showOverworldFreestanding = true; + showDungeonFreestanding = false; + break; + case RO_FREESTANDING_DUNGEONS: + showOverworldFreestanding = false; + showDungeonFreestanding = true; + break; + default: + showOverworldFreestanding = false; + showDungeonFreestanding = false; + break; + } + } else { // Vanilla + showOverworldFreestanding = false; + showDungeonFreestanding = true; + } } bool IsCheckShuffled(RandomizerCheck rc) { @@ -1292,6 +1318,10 @@ bool IsCheckShuffled(RandomizerCheck rc) { (showDungeonPots && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && (loc->GetRCType() != RCTYPE_COW || showCows) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && + (loc->GetRCType() != RCTYPE_FREESTANDING || + (showOverworldFreestanding && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonFreestanding && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea())) + ) && (loc->GetRCType() != RCTYPE_ADULT_TRADE || showAdultTrade || rc == RC_KAK_ANJU_AS_ADULT || // adult trade checks that are always shuffled diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 533a5d0dd..8030b0257 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -850,6 +850,188 @@ typedef enum { RAND_INF_CHILD_TRADES_MASK_ZORA, RAND_INF_CHILD_TRADES_MASK_GERUDO, RAND_INF_CHILD_TRADES_MASK_TRUTH, + + RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE, + RAND_INF_KF_NORTH_GRASS_WEST_RUPEE, + RAND_INF_KF_NORTH_GRASS_EAST_RUPEE, + RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE, + RAND_INF_KF_SARIAS_TOP_LEFT_HEART, + RAND_INF_KF_SARIAS_TOP_RIGHT_HEART, + RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART, + RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART, + RAND_INF_KF_BEAN_RUPEE_1, + RAND_INF_KF_BEAN_RUPEE_2, + RAND_INF_KF_BEAN_RUPEE_3, + RAND_INF_KF_BEAN_RUPEE_4, + RAND_INF_KF_BEAN_RUPEE_5, + RAND_INF_KF_BEAN_RUPEE_6, + RAND_INF_KF_BEAN_RED_RUPEE, + RAND_INF_LW_SHORTCUT_RUPEE_1, + RAND_INF_LW_SHORTCUT_RUPEE_2, + RAND_INF_LW_SHORTCUT_RUPEE_3, + RAND_INF_LW_SHORTCUT_RUPEE_4, + RAND_INF_LW_SHORTCUT_RUPEE_5, + RAND_INF_LW_SHORTCUT_RUPEE_6, + RAND_INF_LW_SHORTCUT_RUPEE_7, + RAND_INF_LW_SHORTCUT_RUPEE_8, + RAND_INF_LH_FRONT_RUPEE, + RAND_INF_LH_MIDDLE_RUPEE, + RAND_INF_LH_BACK_RUPEE, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8, + + RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE, + + RAND_INF_DMT_BLUE_RUPEE, + RAND_INF_DMT_COW_GROTTO_LEFT_HEART, + RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, + RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, + RAND_INF_DMT_COW_GROTTO_RIGHT_HEART, + RAND_INF_DMT_COW_GROTTO_RUPEE_1, + RAND_INF_DMT_COW_GROTTO_RUPEE_2, + RAND_INF_DMT_COW_GROTTO_RUPEE_3, + RAND_INF_DMT_COW_GROTTO_RUPEE_4, + RAND_INF_DMT_COW_GROTTO_RUPEE_5, + RAND_INF_DMT_COW_GROTTO_RUPEE_6, + RAND_INF_DMT_COW_GROTTO_RED_RUPEE, + RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE, + RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6, + RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE, + + RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE, + RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, + RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, + RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, + RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, + + RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART, + RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART, + RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, + RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, + RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, + RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART, + RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, + RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, + RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, + RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART, + RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART, + RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, + RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, + RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, + RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, + RAND_INF_WATER_TEMPLE_RIVER_HEART_1, + RAND_INF_WATER_TEMPLE_RIVER_HEART_2, + RAND_INF_WATER_TEMPLE_RIVER_HEART_3, + RAND_INF_WATER_TEMPLE_RIVER_HEART_4, + RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, + RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, + RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, + RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, + RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, + RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, + RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, + RAND_INF_ICE_CAVERN_LOBBY_RUPEE, + RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART, + RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, + RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, + RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, + RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, + RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, + RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, + RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, + RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, + RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, + RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, + RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, + RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART, + RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART, + + RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART, + RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART, + RAND_INF_DEKU_TREE_MQ_LOBBY_HEART, + RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, + RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, + RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, + RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, + RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, + RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, + RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, + RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, + RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, + RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, + RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART, + RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART, + RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, + RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, + RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) RAND_INF_MAX, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index c4a1eab57..68245757b 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -221,6 +221,7 @@ void Settings::CreateOptions() { mOptions[RSK_SHUFFLE_BOSS_SOULS] = Option::U8("Shuffle Boss Souls", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WidgetType::Combobox); mOptions[RSK_SHUFFLE_DEKU_STICK_BAG] = Option::Bool("Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); mOptions[RSK_SHUFFLE_DEKU_NUT_BAG] = Option::Bool("Shuffle Deku Nut Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); + mOptions[RSK_SHUFFLE_FREESTANDING] = Option::U8("Shuffle Freestanding Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), mOptionDescriptions[RSK_SHUFFLE_FREESTANDING], WidgetType::Combobox, RO_TOKENSANITY_OFF); mOptions[RSK_FISHSANITY] = Option::U8("Fishsanity", {"Off", "Shuffle only Hyrule Loach", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WidgetType::Combobox, RO_FISHSANITY_OFF); mOptions[RSK_FISHSANITY_POND_COUNT] = Option::U8("Pond Fish Count", {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), mOptionDescriptions[RSK_FISHSANITY_POND_COUNT], WidgetType::Slider, 0, true, IMFLAG_NONE); mOptions[RSK_FISHSANITY_AGE_SPLIT] = Option::Bool("Pond Age Split", CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT]); @@ -428,6 +429,7 @@ void Settings::CreateOptions() { mTrickOptions[RT_FOREST_OUTDOORS_LEDGE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, false, "Forest Temple NE Outdoors Ledge with Hover Boots", "With precise Hover Boots movement you can fall down to this ledge from upper balconies. If done precisely enough, it is not necessary to take fall damage. In MQ, this skips a Longshot requirement. In Vanilla, this can skip a Hookshot requirement in entrance randomizer."); mTrickOptions[RT_FOREST_DOORFRAME] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Forest Temple East Courtyard Door Frame with Hover Boots", "A precise Hover Boots movement from the upper balconies in this courtyard can be used to get on top of the door frame. Applies to both Vanilla and Master Quest. In Vanilla, from on top the door frame you can summon Pierre, allowing you to access the falling ceiling room early. In Master Quest, this allows you to obtain the GS on the door frame as adult without Hookshot or Song of Time."); mTrickOptions[RT_FOREST_OUTSIDE_BACKDOOR] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Forest Temple Outside Backdoor with Jump Slash", "A jump slash recoil can be used to reach the ledge in the block puzzle room that leads to the west courtyard. This skips a potential Hover Boots requirement in vanilla, and it can sometimes apply in MQ as well. This trick can be performed as both ages."); + mTrickOptions[RT_FOREST_OUTDOORS_HEARTS_BOOMERANG] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, false, "Forest Temple Outside Hearts with Boomerang", "A well aimed boomerang from the water's edge can reach the hearts from ground level. If unable to swim, you can back away from the water while the boomerang is returning so the hearts land on the ground."); mTrickOptions[RT_FOREST_MQ_WELL_SWIM] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Swim Through Forest Temple MQ Well with Hookshot", "Shoot the vines in the well as low and as far to the right as possible, and then immediately swim under the ceiling to the right. This can only be required if Forest Temple is in its Master Quest form."); mTrickOptions[RT_FOREST_MQ_BLOCK_PUZZLE] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, false, "Skip Forest Temple MQ Block Puzzle with Bombchu", "Send the Bombchu straight up the center of the wall directly to the left upon entering the room."); //Child with hovers cannot do this from the lower floor, and most go to the upper floor which needs goron bracelet. Adult can do this with hammer and KSword, But child cannot. @@ -611,6 +613,7 @@ void Settings::CreateOptions() { &mTrickOptions[RT_FOREST_OUTDOORS_LEDGE], &mTrickOptions[RT_FOREST_DOORFRAME], &mTrickOptions[RT_FOREST_OUTSIDE_BACKDOOR], + &mTrickOptions[RT_FOREST_OUTDOORS_HEARTS_BOOMERANG], &mTrickOptions[RT_FOREST_MQ_WELL_SWIM], &mTrickOptions[RT_FOREST_MQ_BLOCK_PUZZLE], &mTrickOptions[RT_FOREST_MQ_JS_HALLWAY_SWITCH], @@ -777,6 +780,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_FISHING_POLE], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], + &mOptions[RSK_SHUFFLE_FREESTANDING], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = OptionGroup::SubGroup("Shuffle NPCs & Merchants", { &mOptions[RSK_SHOPSANITY], @@ -1070,6 +1074,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_BOSS_SOULS], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], + &mOptions[RSK_SHUFFLE_FREESTANDING], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { &mOptions[RSK_SHUFFLE_MAPANDCOMPASS], @@ -1265,6 +1270,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], + &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_ADULT_TRADE], diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 8d59e3111..b8bf964fe 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -350,7 +350,6 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { f32 yOffset = 980.0f; f32 shadowScale = 6.0f; s32 getItemId = GI_NONE; - this->randoGiEntry = (GetItemEntry)GET_ITEM_NONE; this->randoCheck = (RandomizerCheck)RC_UNKNOWN_CHECK; this->itemEntry = (GetItemEntry)GET_ITEM_NONE; s16 spawnParam8000 = this->actor.params & 0x8000; @@ -493,13 +492,6 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->actor.shape.shadowAlpha = 180; this->actor.focus.pos = this->actor.world.pos; this->getItemId = GI_NONE; - this->randoCheck = Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams); - this->randoInf = RAND_INF_MAX; - - if (IS_RANDO && this->randoCheck != RC_UNKNOWN_CHECK) { - this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, getItemId); - this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; - } if (!spawnParam8000) { EnItem00_SetupAction(this, func_8001DFC8);